From dabe17276645632b6da2dd5e26607816e12ebc70 Mon Sep 17 00:00:00 2001 From: lionel untereiner Date: Thu, 8 Oct 2015 17:09:21 +0200 Subject: [PATCH 001/185] removed file from include dir --- include/Container/chunk_array.h | 29 ----------------------------- 1 file changed, 29 deletions(-) delete mode 100644 include/Container/chunk_array.h diff --git a/include/Container/chunk_array.h b/include/Container/chunk_array.h deleted file mode 100644 index 763a36f9..00000000 --- a/include/Container/chunk_array.h +++ /dev/null @@ -1,29 +0,0 @@ -/******************************************************************************* -* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * * -* Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France * -* * -* This library is free software; you can redistribute it and/or modify it * -* under the terms of the GNU Lesser General Public License as published by the * -* Free Software Foundation; either version 2.1 of the License, or (at your * -* option) any later version. * -* * -* This library is distributed in the hope that it will be useful, but WITHOUT * -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * -* for more details. * -* * -* You should have received a copy of the GNU Lesser General Public License * -* along with this library; if not, write to the Free Software Foundation, * -* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * -* * -* Web site: http://cgogn.unistra.fr/ * -* Contact information: cgogn@unistra.fr * -* * -*******************************************************************************/ - -#ifndef __CHUNK_ARRAY__ -#define __CHUNK_ARRAY__ - - - -#endif From ee827f1aa2fc5fb26cb74e65a4640d188f49d156 Mon Sep 17 00:00:00 2001 From: lionel untereiner Date: Thu, 8 Oct 2015 17:10:33 +0200 Subject: [PATCH 002/185] added first version of the build system --- CMakeLists.txt | 81 +++++++++++++++++++++ cmake/platforms/Linux-gcc.cmake | 90 ++++++++++++++++++++++++ cmake/platforms/Linux.cmake | 19 +++++ cmake/platforms/Linux64-gcc/config.cmake | 5 ++ cmake/utilities.cmake | 34 +++++++++ configure.bat | 17 +++++ configure.sh | 34 +++++++++ 7 files changed, 280 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 cmake/platforms/Linux-gcc.cmake create mode 100644 cmake/platforms/Linux.cmake create mode 100644 cmake/platforms/Linux64-gcc/config.cmake create mode 100644 cmake/utilities.cmake create mode 100644 configure.bat create mode 100644 configure.sh diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..8dc31257 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,81 @@ +########################################## +## CGoGN root CMakeList +########################################## + +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "build/") + +cmake_minimum_required(VERSION 2.8.11) + + + +#### Checking the current OS + + + +#CMAKE_SYSTEM_NAME + +# Linux + + #Windows + + #Darwin + +#file(MAKE_DIRECTORY ${directory}) + + +MESSAGE(STATUS "-------------- Checking for Cmake --------------") + + + +foreach(config Release Debug) + #CONACT(PLATFORM ${config}) + MESSAGE(STATUS "-------------- Checking makefiles for ${config} mode --------------") + + + +endforeach(config) + + +#SET(CMAKE_BUILD_TYPE ) + +#SET(CGoGN_PLATFORM ) + + + +# CMAKE_SIZEOF_VOID_P + +##### Basic information + +# Determine the current build-os (build-platform without the compiler info) +#string(REGEX REPLACE "-[^-]+$" "" CGOGN_OS ${CGoGN_PLATFORM}) + +# Determine the current build date +#string(TIMESTAMP CGOGN_BUILD_DATE "%Y-%m-%d %H:%M:%S") +#string(TIMESTAMP YEAR "%Y") +# TODO: Determine the current build number using jenkins + + +##### GIT tag info +# http://stackoverflow.com/a/4120179 +# TODO +# decider d'utiliser les tag de git +# extraire les informations de la commande git describe --always + + +##### Build configuration + +#set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin) +#set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib) +#set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib) + +#include(${CMAKE_SOURCE_DIR}/cmake/utilities.cmake) +#include(${CMAKE_SOURCE_DIR}/cmake/platforms/${CGoGN_PLATFORM}/config.cmake) + +##### CGOGN sources + +#include_directories(${CMAKE_SOURCE_DIR}/src/lib) + +#add_subdirectory(src/lib/core) + +#add_subdirectory(src/bin) +#add_subdirectory(src/test) \ No newline at end of file diff --git a/cmake/platforms/Linux-gcc.cmake b/cmake/platforms/Linux-gcc.cmake new file mode 100644 index 00000000..1094cf32 --- /dev/null +++ b/cmake/platforms/Linux-gcc.cmake @@ -0,0 +1,90 @@ +#------------------------------------------------------------------- +# Flags common to all Linux based platforms with GNU compiler +#------------------------------------------------------------------- + +include(${CMAKE_SOURCE_DIR}/cmake/platforms/Linux.cmake) + +# Warning flags +set(NORMAL_WARNINGS -Wall -Wextra) +set(FULL_WARNINGS + ${NORMAL_WARNINGS} + -pedantic + -Wno-long-long + -Wconversion +) + +# Determine gcc version and activate additional warnings available in latest versions +#execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION) + +if (GCC_VERSION VERSION_GREATER 4.3 OR GCC_VERSION VERSION_EQUAL 4.3) + message(STATUS "GCC version >= 4.3, activating sign conversion warnings") + set(FULL_WARNINGS ${FULL_WARNINGS} -Wsign-conversion) +endif() + +if (GCC_VERSION VERSION_GREATER 4.6 OR GCC_VERSION VERSION_EQUAL 4.6) + message(STATUS "GCC version >= 4.6, activating double promotion warnings") + set(FULL_WARNINGS ${FULL_WARNINGS} -Wdouble-promotion) +endif() + + +# Compile with full warnings by default +add_definitions(${FULL_WARNINGS}) + +# Warn about missing virtual destructor (C++ only) +string_append(CMAKE_CXX_FLAGS -Wnon-virtual-dtor) + +# Add static and dynamic bounds checks (optimization required) +if (GCC_VERSION VERSION_GREATER 4.0) + string_append(CMAKE_CXX_FLAGS_RELEASE -D_FORTIFY_SOURCE=2) + string_append(CMAKE_C_FLAGS_RELEASE -D_FORTIFY_SOURCE=2) +endif() + +# Enable SSE3 instruction set +string_append(CMAKE_CXX_FLAGS -msse3) +string_append(CMAKE_C_FLAGS -msse3) + +# Enable glibc parallel mode +#add_flags(CMAKE_CXX_FLAGS -D_GLIBCXX_PARALLEL) + +# Enable some algebraic transforms +# (necessary for vectorizing certain reductions and dot products) +#!!! -- deactivated, because it breaks Shewchuck's predicates -- +#add_flags(CMAKE_CXX_FLAGS -ffast-math -fassociative-math) +#add_flags(CMAKE_C_FLAGS -ffast-math -fassociative-math) +#-ftree-vectorizer-verbose=2 + +# Generate debug information even in release mode +#add_flags(CMAKE_CXX_FLAGS_RELEASE -g) +#add_flags(CMAKE_C_FLAGS_RELEASE -g) + + +# Additional debug flags +# deactivated for now: I added bound checking in VOR::vector<>. +#add_flags(CMAKE_CXX_FLAGS_DEBUG -D_GLIBCXX_DEBUG) + + +# Compile and link with OpenMP +if (GCC_VERSION VERSION_GREATER 4.0) + string_append(CMAKE_CXX_FLAGS -fopenmp) + string_append(CMAKE_C_FLAGS -fopenmp) +endif() + +# Always generate position independant code +# (to allow linking with DLLs) +string_append(CMAKE_CXX_FLAGS -fPIC) +string_append(CMAKE_C_FLAGS -fPIC) + + +string_append(CMAKE_CXX_FLAGS -std=c++11) + + +macro(m_add_executable) + + # Create a statically linked executable + # Link with static libraries + string_append(CMAKE_CXX_FLAGS -static-libstdc++ -static-libgcc ) + string_append(CMAKE_C_FLAGS -static-libgcc -static) + + add_executable(${ARGN}) +endmacro() + diff --git a/cmake/platforms/Linux.cmake b/cmake/platforms/Linux.cmake new file mode 100644 index 00000000..44a8b339 --- /dev/null +++ b/cmake/platforms/Linux.cmake @@ -0,0 +1,19 @@ +#------------------------------------------------------------------- +# Flags common to all Linux based platforms +#------------------------------------------------------------------- + +# Shell script extension +set(SHELL_SUFFIX "sh") + +# This flag MUST be added to solve a bug related to shared lib dynamic loading +# (std::type_infos representing the same template type do not compare equal, +# introducing subtle bugs) +# IMPORTANT: DO NOT ADD THIS FLAG WITH STATIC LINKING +string_append(CMAKE_EXE_LINKER_FLAGS "-Wl,-E") + +# Forbid undefined symbols at link time (shared libraries and executables) +string_append(CMAKE_SHARED_LINKER_FLAGS "-Wl,--no-undefined") +string_append(CMAKE_EXE_LINKER_FLAGS "-Wl,--no-undefined") + +# Link with the loader library +#list(APPEND SYSLIBS dl) diff --git a/cmake/platforms/Linux64-gcc/config.cmake b/cmake/platforms/Linux64-gcc/config.cmake new file mode 100644 index 00000000..d60eff08 --- /dev/null +++ b/cmake/platforms/Linux64-gcc/config.cmake @@ -0,0 +1,5 @@ +include(${CMAKE_SOURCE_DIR}/cmake/platforms/Linux-gcc.cmake) +string_append(CMAKE_CXX_FLAGS -m64) +string_append(CMAKE_C_FLAGS -m64) + + diff --git a/cmake/utilities.cmake b/cmake/utilities.cmake new file mode 100644 index 00000000..9e6040e7 --- /dev/null +++ b/cmake/utilities.cmake @@ -0,0 +1,34 @@ + +include(CMakeParseArguments) + + +function(string_append _var) + string(REPLACE " " ";" string "${${_var}};${ARGN}") + list(REMOVE_DUPLICATES string) + string(REPLACE ";" " " string "${string}") + set(${_var} ${string} PARENT_SCOPE) +endfunction() + +#! +# @brief Add sources from directories +# @details +# Add the sources from the specified \p directories to variable \p var +# and place them in the specified \p folder if non empty. +# @param[out] var name of the variable that receives the result list +# @param[in] folder the name of the folder +# @param[in] directories list of directories to scan +# +function(aux_source_directories var folder) + set(sources) + foreach(dir ${ARGN}) + file(GLOB _sources RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "${dir}/*.[ch]" "${dir}/*.[ch]pp") + list(APPEND sources ${_sources}) + endforeach() + + if( NOT folder STREQUAL "") + source_group(${folder} FILES ${sources}) + endif() + + #message("\nDEBUG: aux_source_directories: current_source_dir=${CMAKE_CURRENT_SOURCE_DIR} dirs=${ARGN}):\n${sources}\n") + set(${var} ${${var}} ${sources} PARENT_SCOPE) +endfunction() \ No newline at end of file diff --git a/configure.bat b/configure.bat new file mode 100644 index 00000000..c5d31016 --- /dev/null +++ b/configure.bat @@ -0,0 +1,17 @@ + +@echo off + +setlocal EnableDelayedExpansion + +echo. +echo -------------- Checking for Cmake -------------- +echo. + +cmake --version +if %errorlevel% ==0 ( + echo CMake found +) else ( + echo Error: CMake not found, please install it (see http://www.cmake.org) + exit /B 1 +) + diff --git a/configure.sh b/configure.sh new file mode 100644 index 00000000..0745d404 --- /dev/null +++ b/configure.sh @@ -0,0 +1,34 @@ +#!/bin/sh + + +echo "-------------- Checking for Cmake --------------" + +if (cmake --version) ; then + echo "CMake found" + echo +else + echo "Error: CMake not found, please install it (see http://www.cmake.org)" + exit 1 +fi + + +os="Linux64-gcc" +for config in Release Debug +do + echo + echo "-------------- Checking makefiles for $config mode --------------" + echo + + mkdir -p build/$os-$config + (cd build/$os-$config; cmake -DCMAKE_BUILD_TYPE:STRING=$config -DCGoGN_PLATFORM:STRING=$os ../../) +done + +echo +echo "-------------- CGoGN build configured --------------" +echo + +cat << EOF +to build CGoGN: + - go to build/$os-Release or build/$os-Debug + - and 'make' or 'cmake --build .' +EOF From ef0bee0de51d407d7af2b4a148772c27b186b183 Mon Sep 17 00:00:00 2001 From: lionel untereiner Date: Thu, 8 Oct 2015 17:11:11 +0200 Subject: [PATCH 003/185] added the first file of the new source tree --- cgogn/core/CMakeLists.txt | 8 ++ cgogn/core/basic/definitions.h | 33 +++++++ cgogn/core/container/chunk_array.h | 148 +++++++++++++++++++++++++++++ 3 files changed, 189 insertions(+) create mode 100644 cgogn/core/CMakeLists.txt create mode 100644 cgogn/core/basic/definitions.h create mode 100644 cgogn/core/container/chunk_array.h diff --git a/cgogn/core/CMakeLists.txt b/cgogn/core/CMakeLists.txt new file mode 100644 index 00000000..9f0ec05a --- /dev/null +++ b/cgogn/core/CMakeLists.txt @@ -0,0 +1,8 @@ + +aux_source_directories(SOURCES "Source Files" .) +aux_source_directories(SOURCES "Source Files\\container" container) + +include_directories(${CMAKE_BINARY_DIR}/src/lib) + +add_library(cgogn ${SOURCES} ) + diff --git a/cgogn/core/basic/definitions.h b/cgogn/core/basic/definitions.h new file mode 100644 index 00000000..dc338d86 --- /dev/null +++ b/cgogn/core/basic/definitions.h @@ -0,0 +1,33 @@ +/* + * CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps + * Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Web site: http://cgogn.unistra.fr/ + * Contact information: cgogn@unistra.fr + * + */ + +#ifndef __DEFINITIONS__ +#define __DEFINITIONS__ + +/** + * \file basic/definitions.h + * \brief Basic definitions for CGOGN API + */ + + +#endif \ No newline at end of file diff --git a/cgogn/core/container/chunk_array.h b/cgogn/core/container/chunk_array.h new file mode 100644 index 00000000..1d90b8b6 --- /dev/null +++ b/cgogn/core/container/chunk_array.h @@ -0,0 +1,148 @@ +/* + * CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps + * Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Web site: http://cgogn.unistra.fr/ + * Contact information: cgogn@unistra.fr + * + */ + +#ifndef __CORE_CONTAINER_CHUNK_ARRAY__ +#define __CORE_CONTAINER_CHUNK_ARRAY__ + +#include + +/** + * \file cgogn/container/chunk_array.h + * \brief The class that stores data + */ +namespace cgogn { + + /** + * \brief Class for blocks of data storage. + * \details + * ChunckArray is not a two-dimensional array. It is a vector + * of values where each value is itself an array. + * ChunckArrays provides functions to efficiently setting and getting + * arrays. + * \todo + * - multi-threaded environment : a thread safety mode to access in read each chunck with a different thread ? + * - use std::array instead of T[] ? + * \relates ChunckArrayContainer + */ + // template + template + class CGOGN_API ChunkArray { + + private: + /** + * \brief Vector of chunks + */ + std::vector table_data_; + + /** + * \brief A symbolic constant that represents the size of a chunk + */ + const unsigned int kChunkSize = 4096; + + /** + * \brief A symbolic constant that represents the initial size of a vector of chunks + */ + const unsigned int kVectorSize = 1024; + + /** + * \brief Represents size type of the vector of chunks + */ + typedef typename std::vector::size_type size_type; + + public: + + /** + * \brief Constructs a new ChunckArray. + */ + ChunkArray() { + table_data_.reserve(kVectorSize); + } + + /** + * \brief ChunckArray destructor. + */ + ~ChunckArray() { + for(size_type i = 0 ; i < table_data_.size() ; ++i) + delete[] table_data_[i]; + } + + /** + * \brief Add a new chunk to the vector of chunks + */ + inline void addChunk() { + T* ptr = new T[kChunkSize]; + table_data_.push_back(ptr); + + // TODO test to replace with c++11 version + // table_data_.emplace_back(kChunkSize); + } + + /** + * \brief Gets the number of chunks of the array + * \retval the actual number of chunks + */ + inline unsigned int getNbChunks() const { + //TODO add a typedef for basic types to avoid cast + return uint32(table_data_.size()); + } + + /** + * \brief Sets the number of chunks of the array + * \param[in] nbc the number of chuncks + */ + inline void setNbChunks(unsigned int nbc) { + if (nbc >= table_data_.size()) { + for (size_type i = table_data_.size(); i < nbc; ++i) + addBlock(); + } else { + for (size_type i = nbc; i < table_data_.size(); ++i) + delete[] table_data_[i]; + table_data_.resize(nbc); + } + } + + private: + /** + * Forbid copy constructor + */ + ChunkArray(const ChunkArray& rhs); + + /** + * Forbid assignment operator + */ + ChunkArray& operator=(const ChunkArray& rhs); + }; + + /** + * + */ + // template using ChunkArray = ChunkArray; + + /** + * + */ + // template using ConcurrentChunkArray = ChunkArray; + +} + +#endif // __CORE_CONTAINER_CHUNK_ARRAY__ \ No newline at end of file From 356cdd03b83165b1cc464406e70c61bfa34ebf93 Mon Sep 17 00:00:00 2001 From: lionel untereiner Date: Thu, 8 Oct 2015 17:12:16 +0200 Subject: [PATCH 004/185] added the first file for test suite --- test/CMakeLists.txt | 6 ++++++ test/test_chunk_array.cpp | 8 ++++++++ 2 files changed, 14 insertions(+) create mode 100644 test/CMakeLists.txt create mode 100644 test/test_chunk_array.cpp diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 00000000..2896faba --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,6 @@ + +aux_source_directories(SOURCES "" .) + +add_executable(test_chunk_array ${SOURCES}) + +target_link_libraries(test_chunk_array cgogn) diff --git a/test/test_chunk_array.cpp b/test/test_chunk_array.cpp new file mode 100644 index 00000000..fa9b6a40 --- /dev/null +++ b/test/test_chunk_array.cpp @@ -0,0 +1,8 @@ +#include + +int main() +{ + ChunkArray array; + + return 0; +} \ No newline at end of file From 32d6013b7123dc0b47ca985aa138246502049c97 Mon Sep 17 00:00:00 2001 From: lionel untereiner Date: Thu, 8 Oct 2015 18:24:28 +0200 Subject: [PATCH 005/185] improvement of configure.sh and master CMakeList --- CMakeLists.txt | 66 ++++++++++---------------------------------------- configure.sh | 39 ++++++++++++++++++++++------- 2 files changed, 43 insertions(+), 62 deletions(-) mode change 100644 => 100755 configure.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index 8dc31257..f6c351a9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,56 +2,18 @@ ## CGoGN root CMakeList ########################################## -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "build/") - cmake_minimum_required(VERSION 2.8.11) - -#### Checking the current OS - - - -#CMAKE_SYSTEM_NAME - -# Linux - - #Windows - - #Darwin - -#file(MAKE_DIRECTORY ${directory}) - - -MESSAGE(STATUS "-------------- Checking for Cmake --------------") - - - -foreach(config Release Debug) - #CONACT(PLATFORM ${config}) - MESSAGE(STATUS "-------------- Checking makefiles for ${config} mode --------------") - - - -endforeach(config) - - -#SET(CMAKE_BUILD_TYPE ) - -#SET(CGoGN_PLATFORM ) - - - -# CMAKE_SIZEOF_VOID_P - ##### Basic information # Determine the current build-os (build-platform without the compiler info) -#string(REGEX REPLACE "-[^-]+$" "" CGOGN_OS ${CGoGN_PLATFORM}) +string(REGEX REPLACE "-[^-]+$" "" CGOGN_OS ${CGoGN_PLATFORM}) # Determine the current build date -#string(TIMESTAMP CGOGN_BUILD_DATE "%Y-%m-%d %H:%M:%S") -#string(TIMESTAMP YEAR "%Y") +string(TIMESTAMP CGOGN_BUILD_DATE "%Y-%m-%d %H:%M:%S") +string(TIMESTAMP YEAR "%Y") + # TODO: Determine the current build number using jenkins @@ -63,19 +25,17 @@ endforeach(config) ##### Build configuration +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib) +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib) -#set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin) -#set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib) -#set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib) +include(${CMAKE_SOURCE_DIR}/cmake/utilities.cmake) +include(${CMAKE_SOURCE_DIR}/cmake/platforms/${CGoGN_PLATFORM}/config.cmake) -#include(${CMAKE_SOURCE_DIR}/cmake/utilities.cmake) -#include(${CMAKE_SOURCE_DIR}/cmake/platforms/${CGoGN_PLATFORM}/config.cmake) ##### CGOGN sources +include_directories(${CMAKE_SOURCE_DIR}/cgogn) -#include_directories(${CMAKE_SOURCE_DIR}/src/lib) - -#add_subdirectory(src/lib/core) - -#add_subdirectory(src/bin) -#add_subdirectory(src/test) \ No newline at end of file +# add each subdirectory with a CMakeList +add_subdirectory(cgogn/core) +add_subdirectory(test) \ No newline at end of file diff --git a/configure.sh b/configure.sh old mode 100644 new mode 100755 index 0745d404..e623e6a9 --- a/configure.sh +++ b/configure.sh @@ -11,24 +11,45 @@ else exit 1 fi - -os="Linux64-gcc" +usage="usage : ./configure.sh build-platform" + + +# Check the current OS +os="$1" +if [ -z "$os"] #if os is empty + then + os=`uname -a` +fi + +case "$os" in + Linux*x86_64*) + os=Linux64-gcc;; + Linux*amd64*) + os=Linux64-gcc;; + Darwin) + os=Darwin-clang;; + *) + echo "Error: OS not supported: $os" + exit 1;; +esac + +# Generate the Makefiles for config in Release Debug do + platform=$os-$config echo echo "-------------- Checking makefiles for $config mode --------------" echo - mkdir -p build/$os-$config - (cd build/$os-$config; cmake -DCMAKE_BUILD_TYPE:STRING=$config -DCGoGN_PLATFORM:STRING=$os ../../) + mkdir -p build/$platform + (cd build/$platform; cmake -DCMAKE_BUILD_TYPE:STRING=$config -DCGoGN_PLATFORM:STRING=$os ../../) done echo echo "-------------- CGoGN build configured --------------" echo +echo "to build CGoGN: +- go to build/$os-Release or build/$os-Debug +- and 'make' or 'cmake --build .'" -cat << EOF -to build CGoGN: - - go to build/$os-Release or build/$os-Debug - - and 'make' or 'cmake --build .' -EOF +exit $? \ No newline at end of file From 7eb0298b63c782ba32d9fdd6e34a42937fc2155a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Schmitt?= Date: Tue, 13 Oct 2015 14:46:13 +0200 Subject: [PATCH 006/185] Added a .clang_format based on google c++ style MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Étienne Schmitt --- .clang_format | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 .clang_format diff --git a/.clang_format b/.clang_format new file mode 100644 index 00000000..355f43f8 --- /dev/null +++ b/.clang_format @@ -0,0 +1,67 @@ +--- +Language: Cpp +# BasedOnStyle: Google +AccessModifierOffset: -1 +AlignAfterOpenBracket: true +AlignConsecutiveAssignments: false +AlignEscapedNewlinesLeft: true +AlignOperands: true +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: All +AllowShortIfStatementsOnASingleLine: true +AllowShortLoopsOnASingleLine: true +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakBeforeMultilineStrings: true +AlwaysBreakTemplateDeclarations: true +BinPackArguments: true +BinPackParameters: true +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Attach +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +ColumnLimit: 80 +CommentPragmas: '^ IWYU pragma:' +ConstructorInitializerAllOnOneLineOrOnePerLine: true +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: true +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] +IndentCaseLabels: true +IndentWidth: 2 +IndentWrappedFunctionNames: false +KeepEmptyLinesAtTheStartOfBlocks: false +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBlockIndentWidth: 2 +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: false +PenaltyBreakBeforeFirstCallParameter: 1 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 200 +PointerAlignment: Left +SpaceAfterCStyleCast: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 2 +SpacesInAngles: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Auto +TabWidth: 8 +UseTab: Never +... + From 156ee01dfc42029e0ca74484d87ba380bb30b704 Mon Sep 17 00:00:00 2001 From: Sylvain Thery Date: Tue, 13 Oct 2015 17:16:58 +0200 Subject: [PATCH 007/185] first working version of ChunkArrayContainer --- cgogn/core/basic/nameTypes.h | 70 ++ cgogn/core/basic/static_assert.h | 41 + cgogn/core/container/chunk_array.cpp | 0 cgogn/core/container/chunk_array.h | 606 ++++++++++++--- cgogn/core/container/chunk_array_container.h | 749 +++++++++++++++++++ cgogn/core/container/chunk_array_factory.h | 93 +++ cgogn/core/container/chunk_array_gen.h | 138 ++++ cgogn/core/container/chunk_heap.h | 139 ++++ test/test_chunk_array.cpp | 244 +++++- 9 files changed, 1957 insertions(+), 123 deletions(-) create mode 100644 cgogn/core/basic/nameTypes.h create mode 100644 cgogn/core/basic/static_assert.h create mode 100644 cgogn/core/container/chunk_array.cpp create mode 100644 cgogn/core/container/chunk_array_container.h create mode 100644 cgogn/core/container/chunk_array_factory.h create mode 100644 cgogn/core/container/chunk_array_gen.h create mode 100644 cgogn/core/container/chunk_heap.h diff --git a/cgogn/core/basic/nameTypes.h b/cgogn/core/basic/nameTypes.h new file mode 100644 index 00000000..a1f6cbad --- /dev/null +++ b/cgogn/core/basic/nameTypes.h @@ -0,0 +1,70 @@ +/******************************************************************************* +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * * * +* Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France * +* * +* This library is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by the * +* Free Software Foundation; either version 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: http://cgogn.unistra.fr/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ + +#ifndef __CORE_BASIC_NAME_TYPES_H__ +#define __CORE_BASIC_NAME_TYPES_H__ + +#include + +namespace cgogn +{ +/** + * @brief function that give a name to a type. + */ +template +std::string nameOfType(const T& v) +{ + return v.CGoGNnameOfType(); +} + +template <> inline std::string nameOfType(const bool& /*v*/) { return "bool"; } + +template <> inline std::string nameOfType(const char& /*v*/) { return "char"; } + +template <> inline std::string nameOfType(const short& /*v*/) { return "short"; } + +template <> inline std::string nameOfType(const int& /*v*/) { return "int"; } + +template <> inline std::string nameOfType(const long& /*v*/) { return "long"; } + +template <> inline std::string nameOfType(const long long& /*v*/) { return "long long"; } + +template <> inline std::string nameOfType(const unsigned char& /*v*/) { return "unsigned char"; } + +template <> inline std::string nameOfType(const unsigned short& /*v*/) { return "unsigned short"; } + +template <> inline std::string nameOfType(const unsigned int& /*v*/) { return "unsigned int"; } + +template <> inline std::string nameOfType(const unsigned long& /*v*/) { return "unsigned long"; } + +template <> inline std::string nameOfType(const unsigned long long& /*v*/) { return "unsigned long long"; } + +template <> inline std::string nameOfType(const float& /*v*/) { return "float"; } + +template <> inline std::string nameOfType(const double& /*v*/) { return "double"; } + +template <> inline std::string nameOfType(const std::string& /*v*/) { return "std::string"; } + +} + +#endif diff --git a/cgogn/core/basic/static_assert.h b/cgogn/core/basic/static_assert.h new file mode 100644 index 00000000..78fedbce --- /dev/null +++ b/cgogn/core/basic/static_assert.h @@ -0,0 +1,41 @@ +/* + * CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps + * Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Web site: http://cgogn.unistra.fr/ + * Contact information: cgogn@unistra.fr + * + */ + +#ifndef __CORE_BASIC_STATIC_ASSERT__ +#define __CORE_BASIC_STATIC_ASSERT__ + +namespace cgogn +{ + template struct CompileTimeError; + template <> struct CompileTimeError {}; + +#ifdef CGOGN_NO_STATIC_ASSERT + #define CGoGN_STATIC_ASSERT(expr, msg) +#else + #define CGoGN_STATIC_ASSERT(expr, msg) \ + { cgogn::CompileTimeError<((expr) != 0)> STATIC_ASSERT_ERROR_##msg; (void)STATIC_ASSERT_ERROR_##msg; } +#endif + +} + +#endif diff --git a/cgogn/core/container/chunk_array.cpp b/cgogn/core/container/chunk_array.cpp new file mode 100644 index 00000000..e69de29b diff --git a/cgogn/core/container/chunk_array.h b/cgogn/core/container/chunk_array.h index 1d90b8b6..897a3a0f 100644 --- a/cgogn/core/container/chunk_array.h +++ b/cgogn/core/container/chunk_array.h @@ -1,148 +1,516 @@ /* - * CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps - * Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France - * - * This library is free software; you can redistribute it and/or modify it + * CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps + * Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France + * + * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation; either version 2.1 of the License, or (at your - * option) any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Web site: http://cgogn.unistra.fr/ - * Contact information: cgogn@unistra.fr - * + * Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Web site: http://cgogn.unistra.fr/ + * Contact information: cgogn@unistra.fr + * */ #ifndef __CORE_CONTAINER_CHUNK_ARRAY__ #define __CORE_CONTAINER_CHUNK_ARRAY__ -#include +#include "core/container/chunk_array_gen.h" +#include +#include +#include +#include + +namespace cgogn +{ /** - * \file cgogn/container/chunk_array.h - * \brief The class that stores data + * @brief chunk array class storage + * @tparam CHUNKSIZE size of each chunk (in T, not in bytes!), must be a power of 2 >=32 + * @tparam T type of stored data */ -namespace cgogn { +template +class ChunkArray : public ChunkArrayGen +{ +protected: + + /// vector of block pointers + std::vector tableData_; + +public: /** - * \brief Class for blocks of data storage. - * \details - * ChunckArray is not a two-dimensional array. It is a vector - * of values where each value is itself an array. - * ChunckArrays provides functions to efficiently setting and getting - * arrays. - * \todo - * - multi-threaded environment : a thread safety mode to access in read each chunck with a different thread ? - * - use std::array instead of T[] ? - * \relates ChunckArrayContainer + * @brief Constructor of ChunkArray */ - // template - template - class CGOGN_API ChunkArray { - - private: - /** - * \brief Vector of chunks - */ - std::vector table_data_; - - /** - * \brief A symbolic constant that represents the size of a chunk - */ - const unsigned int kChunkSize = 4096; - - /** - * \brief A symbolic constant that represents the initial size of a vector of chunks - */ - const unsigned int kVectorSize = 1024; - - /** - * \brief Represents size type of the vector of chunks - */ - typedef typename std::vector::size_type size_type; - - public: - - /** - * \brief Constructs a new ChunckArray. - */ - ChunkArray() { - table_data_.reserve(kVectorSize); - } + ChunkArray() + { + tableData_.reserve(1024); + } - /** - * \brief ChunckArray destructor. - */ - ~ChunckArray() { - for(size_type i = 0 ; i < table_data_.size() ; ++i) - delete[] table_data_[i]; - } + /** + * @brief Destructor of ChunkArray + */ + ~ChunkArray() + { + for(auto chunk: tableData_) + delete[] chunk; + } - /** - * \brief Add a new chunk to the vector of chunks - */ - inline void addChunk() { - T* ptr = new T[kChunkSize]; - table_data_.push_back(ptr); + /** + * @brief create a ChunkArray + * @return generic pointer + */ + ChunkArrayGen* clone() + { + ChunkArrayGen* ptr = new ChunkArray(); + return ptr; + } - // TODO test to replace with c++11 version - // table_data_.emplace_back(kChunkSize); - } + /** + * @brief add a chunk (T[CHUNKSIZE]) + */ + void addChunk() + { + T* ptr = new T[CHUNKSIZE](); + tableData_.push_back(ptr); + } - /** - * \brief Gets the number of chunks of the array - * \retval the actual number of chunks - */ - inline unsigned int getNbChunks() const { - //TODO add a typedef for basic types to avoid cast - return uint32(table_data_.size()); - } - /** - * \brief Sets the number of chunks of the array - * \param[in] nbc the number of chuncks - */ - inline void setNbChunks(unsigned int nbc) { - if (nbc >= table_data_.size()) { - for (size_type i = table_data_.size(); i < nbc; ++i) - addBlock(); - } else { - for (size_type i = nbc; i < table_data_.size(); ++i) - delete[] table_data_[i]; - table_data_.resize(nbc); - } + /** + * @brief set number of chunks + * @param nbc number of chunks + */ + void setNbChunks(unsigned int nbc) + { + if (nbc >= tableData_.size()) + { + for (std::size_t i= tableData_.size(); i using ChunkArray = ChunkArray; + void clear() + { + for(auto chunk: tableData_) + delete[] chunk; + tableData_.clear(); + } /** - * + * @brief ref operator [] + * @param i index of element to access + * @return ref of element */ - // template using ConcurrentChunkArray = ChunkArray; + T& operator[](unsigned int i) + { + return tableData_[i / CHUNKSIZE][i % CHUNKSIZE]; + } + + /** + * @brief const ref operator [] + * @param i index of element to access + * @return const ref of element + */ + const T& operator[](unsigned int i) const + { + return tableData_[i / CHUNKSIZE][i % CHUNKSIZE]; + } + + /** + * @brief set the value of an element (work also with bool + * @param i index of element to set + * @param v value + */ + void setVal(unsigned int i, const T& v) + { + tableData_[i / CHUNKSIZE][i % CHUNKSIZE] = v; + } + + + /** + * @brief get pointer on all chunks data + * @param addr vector to fill + * @param byteBlockSize filled with CHUNKSIZE*sizeof(T) + * @return addr.size() + */ + unsigned int getChunksPointers(std::vector& addr, unsigned int& byteBlockSize) const + { + byteBlockSize = CHUNKSIZE * sizeof(T); + + addr.reserve(tableData_.size()); + addr.clear(); + + for (typename std::vector::const_iterator it = tableData_.begin(); it != tableData_.end(); ++it) + addr.push_back(*it); + + return (unsigned int)(addr.size()); + } + + /** + * @brief init an element (overwrite with T()) + * @param id index of element + */ + void initElt(unsigned int id) + { + tableData_[id / CHUNKSIZE][id % CHUNKSIZE] = T(); + } + + + /** + * @brief copy element + * @param dst destination + * @param src source + */ + void copyElt(unsigned int dst, unsigned int src) + { + tableData_[dst / CHUNKSIZE][dst % CHUNKSIZE] = tableData_[src / CHUNKSIZE][src % CHUNKSIZE]; + } + + /** + * @brief swap two elements + * @param id1 idx first + * @param id2 idx second + */ + void swapElt(unsigned int id1, unsigned int id2) + { + T data = tableData_[id1 / CHUNKSIZE][id1 % CHUNKSIZE] ; + tableData_[id1 / CHUNKSIZE][id1 % CHUNKSIZE] = tableData_[id2 / CHUNKSIZE][id2 % CHUNKSIZE] ; + tableData_[id2 / CHUNKSIZE][id2 % CHUNKSIZE] = data ; + } + + + void save(std::ostream& fs, unsigned int nbLines) const + { + unsigned int nbs[3]; + nbs[0] = (unsigned int)(tableData_.size()); + nbs[1] = nbLines; + nbs[2] = CHUNKSIZE*sizeof(T); + + assert(nbLines/CHUNKSIZE <= tableData_.size()); + // TODO: if (nbLines==0) nbLines=CHUNKSIZE*tableData_.size(); ?? + + fs.write(reinterpret_cast(nbs),3*sizeof(unsigned int)); + + // no data -> finished + if (nbs[0] == 0) + return; + + unsigned int nbca = nbs[0]-1; + // save data chunks except last + for(unsigned int i=0; i(tableData_[i]),CHUNKSIZE*sizeof(T)); + } + + // save last + unsigned nbl = nbLines - nbca*CHUNKSIZE; + fs.write(reinterpret_cast(tableData_[nbca]),nbl*sizeof(T)); + } + + + bool load(std::istream& fs) + { + unsigned int nbs[3]; + fs.read(reinterpret_cast(nbs), 3*sizeof(unsigned int)); + + if (nbs[2] != CHUNKSIZE*sizeof(T)) + { + std::cerr << "Error loading ChunkArray wrong CHUNKSIZE"<< std::endl; + return false; + } + + this->setNbChunks(nbs[0]); + + // no data -> finished + if (nbs[0] == 0) + return true; + + // load data chunks except last + unsigned int nbca = nbs[0]-1; + for(unsigned int i = 0; i < nbca; ++i) + fs.read(reinterpret_cast(tableData_[i]),CHUNKSIZE*sizeof(T)); + + // load last chunk + unsigned int nbl = nbs[1] - CHUNKSIZE*nbca; + fs.read(reinterpret_cast(tableData_[nbca]),nbl*sizeof(T)); + + return true; + } + +}; + + + + + +/** + * @brief specialized version of ChunkArray for bool data. One bit per bool + */ +template +class ChunkArray : public ChunkArrayGen +{ +protected: + + /// vector of block pointers + std::vector tableData_; + +public: + + ChunkArray() + { + tableData_.reserve(1024); + } + + + ~ChunkArray() + { + for(auto chunk: tableData_) + delete[] chunk; + } + + + ChunkArrayGen* clone() + { + ChunkArrayGen* ptr = new ChunkArray; + return ptr; + } + + + void addChunk() + { + unsigned int* ptr = new unsigned int[CHUNKSIZE/32]; +// memset(ptr,0,CHUNKSIZE/8); + tableData_.push_back(ptr); + for (unsigned int i=CHUNKSIZE/32; i!=0; --i) + *ptr++ = 0; + } + + + + void setNbChunks(unsigned int nbc) + { + if (nbc >= tableData_.size()) + { + for (std::size_t i= tableData_.size(); i & addr, unsigned int& byteBlockSize) const + { + byteBlockSize = CHUNKSIZE / 8; + + addr.reserve(tableData_.size()); + addr.clear(); + + for (typename std::vector::const_iterator it = tableData_.begin(); it != tableData_.end(); ++it) + addr.push_back(*it); + + return (unsigned int)(addr.size()); + } + + + void initElt(unsigned int id) + { + setFalse(id); + } + + + void copyElt(unsigned int dst, unsigned int src) + { + setVal(dst,this->operator [](src)); + } + + + void swapElt(unsigned int id1, unsigned int id2) + { + bool data = this->operator [](id1); + setVal(id1,this->operator [](id2)); + setVal(id2,data); + } + + + void save(std::ostream& fs, unsigned int nbLines) const + { + // round nbLines to 32 multiple + if (nbLines%32) + nbLines = ((nbLines/32)+1)*32; + + unsigned int nbs[3]; + nbs[0] = (unsigned int)(tableData_.size()); + nbs[1] = nbLines; + nbs[2] = CHUNKSIZE/8; + + assert(nbLines/CHUNKSIZE <= tableData_.size()); + // TODO: if (nbLines==0) nbLines=CHUNKSIZE*tableData_.size(); ?? + + fs.write(reinterpret_cast(nbs),3*sizeof(unsigned int)); + + // no data -> finished + if (nbs[0] == 0) + return; + + unsigned int nbca = nbs[0]-1; + // save data chunks except last + for(unsigned int i=0; i(tableData_[i]),CHUNKSIZE/8);// /8 because bool = 1 bit & octet = 8 bit + } + + // save last + unsigned int nbl = nbLines - nbca*CHUNKSIZE/8; + fs.write(reinterpret_cast(tableData_[nbca]),nbl/8); + } + + + bool load(std::istream& fs) + { + unsigned int nbs[3]; + fs.read(reinterpret_cast(nbs), 3*sizeof(unsigned int)); + + if (nbs[2] != CHUNKSIZE/8) + { + std::cerr << "Error loading ChunkArray wrong CHUNKSIZE"<< std::endl; + return false; + } + + this->setNbChunks(nbs[0]); + + // no data -> finished + if (nbs[0] == 0) + return true; + + // load data chunks except last + unsigned int nbca = nbs[0]-1; + for(unsigned int i = 0; i < nbca; ++i) + fs.read(reinterpret_cast(tableData_[i]),CHUNKSIZE/8);// /8 because bool = 1 bit & octet = 8 bit + + // load last chunk + unsigned int nbl = nbs[1] - nbca*CHUNKSIZE/8; + fs.read(reinterpret_cast(tableData_[nbca]),nbl/8); + + return true; + } + +}; + -} +} // namespace CGoGN -#endif // __CORE_CONTAINER_CHUNK_ARRAY__ \ No newline at end of file +#endif diff --git a/cgogn/core/container/chunk_array_container.h b/cgogn/core/container/chunk_array_container.h new file mode 100644 index 00000000..b5e971fb --- /dev/null +++ b/cgogn/core/container/chunk_array_container.h @@ -0,0 +1,749 @@ +/* + * CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps + * Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Web site: http://cgogn.unistra.fr/ + * Contact information: cgogn@unistra.fr + * + */ + +#ifndef __CORE_CONTAINER_CHUNK_ARRAY_CONTAINER__ +#define __CORE_CONTAINER_CHUNK_ARRAY_CONTAINER__ + + +#include "core/container/chunk_array.h" +#include "core/container/chunk_heap.h" +#include "core/basic/static_assert.h" +#include "core/basic/nameTypes.h" +#include "core/container/chunk_array_factory.h" + +#include +#include +#include +#include +#include +#include + +namespace cgogn +{ + +class ContainerBrowser +{ +public: + virtual unsigned int begin() const = 0; + virtual unsigned int end() const = 0; + virtual void next(unsigned int &it) const = 0; + virtual void enable() = 0; + virtual void disable() = 0; +}; + + +/** + * @brief class that manage the storage of several ChunkArray + * @tparam CHUNKSIZE chunk size for ChunkArray + * @tparam PRIMSIZE number of lines used as primitive (grouped lines) + * @detail + * + */ +template +class ChunkArrayContainer +{ +public: + /** + * constante d'attribut inconnu + */ + static const unsigned int UNKNOWN = 0xffffffff; + +protected: + /** + * vector of pointers to ChunkVector + */ + std::vector*> tableArrays_; + + std::vector names_; + + std::vector typeNames_; + + ChunkArray refs_; + + /** + * heap of holes + */ + ChunkHeap holesHeap_; + + /** + * size (number of elts) of the container + */ + unsigned int nbUsedLines_; + + /** + * size of the container with holes (also index of next inserted line if no holes) + */ + unsigned int nbMaxLines_; + + /** + * Browser that allow special traversals + */ + ContainerBrowser* currentBrowser_; + + + /** + * @brief get array index from name + * @warning do not store index (not stable) + * @param attribName name of ChunkArray + * @return the index in table + */ + unsigned int getArrayIndex(const std::string& attribName) const + { + for (unsigned int i=0; i != names_.size(); ++i) + { + if (names_[i] == attribName) + return i; + } + return UNKNOWN; + } + + /** + * @brief get array index from ptr + * @warning do not store index (not stable) + * @param ptr of ChunkArray + * @return the index in table + */ + unsigned int getArrayIndex(const ChunkArrayGen* ptr) const + { + for (unsigned int i=0; i != tableArrays_.size(); ++i) + { + if (tableArrays_[i] == ptr) + return i; + } + return UNKNOWN; + } + + + + /** + * @brief remove an attribute by its name + * @param attribName name of attribute to remove + * @return true if attribute exist and has been removed + */ + bool removeAttribute(unsigned int index) + { + delete tableArrays_[index] ; + + if (index != tableArrays_.size()-1) + { + tableArrays_[index] = tableArrays_.back(); + names_[index] = names_.back(); + typeNames_[index] = typeNames_.back(); + } + + tableArrays_.pop_back(); + names_.pop_back(); + typeNames_.pop_back(); + + return true ; + } + + + +public: + /** + * @brief ChunkArrayContainer constructor + */ + ChunkArrayContainer(): + nbUsedLines_(0), + nbMaxLines_(0), + currentBrowser_(NULL) + { + } + + /** + * @brief ChunkArrayContainer destructor + */ + ~ChunkArrayContainer() + { + for (auto ptr: tableArrays_) + delete ptr; + } + + + + template + ChunkArray* getAttribute(const std::string& attribName) + { + + // first check if attribute already exist + unsigned int index = getArrayIndex(attribName) ; + if (index == UNKNOWN) + { + std::cerr << "attribute " << attribName << " not found." << std::endl ; + return NULL ; + } + + return static_cast*>(tableArrays_[index]); + } + + + + /** + * @brief add an attribute + * @param attribName name of attribute + * @tparam T type of attribute + * @return pointer on created ChunkArray + */ + template + ChunkArray* addAttribute(const std::string& attribName) + { + assert(attribName.size() != 0); + + // first check if attribute already exist + unsigned int index = getArrayIndex(attribName) ; + if (index != UNKNOWN) + { + std::cerr << "attribute " << attribName << " already found.." << std::endl ; + return NULL ; + } + + // create the new attribute + std::string typeName = nameOfType(T()) ; + ChunkArray* carr = new ChunkArray() ; + + // reserve memory + carr->setNbChunks(refs_.getNbChunks()) ; + + // store pointer, name & typename. + tableArrays_.push_back(carr) ; + names_.push_back(attribName); + typeNames_.push_back(typeName); + + return carr ; + } + + /** + * @brief remove an attribute by its name + * @param attribName name of attribute to remove + * @return true if attribute exist and has been removed + */ + bool removeAttribute(const std::string& attribName) + { + unsigned int index = getArrayIndex(attribName) ; + + if (index == UNKNOWN) + { + std::cerr << "removeAttribute by name: attribute not found (" << attribName << ")"<< std::endl ; + return false ; + } + + removeAttribute(index); + + return true; + } + + + /** + * @brief remove an attribute by its name + * @param attribName name of attribute to remove + * @return true if attribute exist and has been removed + */ + bool removeAttribute(const ChunkArrayGen* ptr) + { + unsigned int index = getArrayIndex(ptr) ; + + if (index == UNKNOWN) + { + std::cerr << "removeAttribute by ptr: attribute not found (" << std::endl ; + return false ; + } + + removeAttribute(index); + + return true; + } + + + /** + * @brief Number of attributes of the container + * @return number of attributes + */ + unsigned int getNbAttributes() const + { + return tableArrays_.size(); + } + + + /** + * @brief size (number of used lines) + * @return the number of lines + */ + unsigned int size() const + { + return nbUsedLines_; + } + + /** + * @brief capacity (number of reserved lines) + * @return number of reserved lines + */ + unsigned int capacity() const + { + return refs_.capacity(); + } + + + /** + * @brief is a line used + * @param index index of line + * @return true if used + */ + bool used(unsigned int index) const + { + return refs_[index] != 0; + } + + /** + * @brief begin + * @return the index of the first used line of the container + */ + unsigned int begin() const + { + if (currentBrowser_ != NULL) + return currentBrowser_->begin(); + return realBegin(); + } + + + /** + * @brief end + * @return the index after the last used line of the container + */ + unsigned int end() const + { + if (currentBrowser_ != NULL) + return currentBrowser_->end(); + return realEnd(); + } + + /** + * @brief next it <- next used index in the containere + * @param it index to "increment" + */ + void next(unsigned int &it) const + { + if (currentBrowser_ != NULL) + currentBrowser_->next(it); + else + realNext(it); + } + + /** + * @brief begin of container without browser + * @return + */ + unsigned int realBegin() const + { + unsigned int it = 0; + while ((it < nbMaxLines_) && (!used(it))) + ++it; + return it; + } + + /** + * @brief end of container without browser + * @return + */ + unsigned int realEnd() const + { + return nbMaxLines_; + } + + + /** + * @brief next without browser + * @param it + */ + void realNext(unsigned int &it) const + { + do + { + ++it; + } while ((it < nbMaxLines_) && (!used(it))); + } + + + /** + * @brief real reverse begin + * @return rbegin() + */ + unsigned int realRBegin() const + { + unsigned int it = nbMaxLines_-1; + while ((it != 0xffffffff) && (!used(it))) + --it; + return it; + } + + /** + * return the index before the first line of the container + */ + /** + * @brief real reverse end + * @return rend() + */ + unsigned int realREnd() const + { + return 0xffffffff; // -1 + } + + /** + * @brief real next of reverse index + * @param it reverse index + */ + void realRNext(unsigned int &it) const + { + do + { + --it; + } while ((it !=0xffffffff) && (!used(it))); + } + + + + /** + * @brief clear the container + * @param removeAttrib remove the attributes (not only their data) + */ + void clear(bool removeAttrib = false) + { + nbUsedLines_ = 0; + nbMaxLines_ = 0; + + // clear CA of refs + refs_.clear(); + + // clear holes + holesHeap_.clear(); + + //clear data + for (auto arr: tableArrays_) + arr->clear(); + + // remove CA ? + if (removeAttrib) + { + for (auto arr: tableArrays_) + delete arr; + tableArrays_.clear(); + } + } + + /** + * @brief fragmentation of container (size/index of last lines): 100% = no holes + * @return 1 if full filled - 0 is lots of holes + */ + float fragmentation() const + { + return float(size()) / float(realEnd()); + } + + /** + * @brief container compacting + * @param mapOldNew table that contains a map from old indices to new indices (holes -> 0xffffffff) + */ + void compact(std::vector& mapOldNew) + { + mapOldNew.clear(); + mapOldNew.resize(realEnd(),0xffffffff); + + unsigned int up = realRBegin(); + unsigned int down = 0; + + while (down < up) + { + if (!used(down)) + { + for(unsigned int i=0; isetNbChunks(newNbBlocks); + refs_.setNbChunks(newNbBlocks); + + // clear holes + holesHeap_.clear(); + + } + + + /************************************** + * LINES MANAGEMENT * + **************************************/ + + /** + * @brief insert a group of PRIMSIZE consecutive lines in the container + * @return index of the first line of group + */ + unsigned int insertLines() + { + unsigned int index; + + if (holesHeap_.empty()) // no holes -> insert at the end + { + index = nbMaxLines_; + nbMaxLines_ += PRIMSIZE; + + if (nbMaxLines_%CHUNKSIZE <= PRIMSIZE) // prim on next block ? -> add block to C.A. + { + for (auto arr: tableArrays_) + arr->addChunk(); + refs_.addChunk(); + } + } + else + { + index = holesHeap_.head(); + holesHeap_.pop(); + } + + // mark lines as used + for(unsigned int i=0; iused(beginPrimIdx)) // replace this IF by an assert ?? + { + holesHeap_.push(beginPrimIdx); + + /// mark lines as unused + for(unsigned int i=0; iinitElt(index); + } + + + /** + * @brief copy the content of line src in line dst (with refs) + * @param dstIndex destination + * @param srcIndex source + */ + void copyLine(unsigned int dstIndex, unsigned int srcIndex) + { + for (auto ptrAtt: tableArrays_) + if (ptrAtt != NULL) + ptrAtt->copyElt(dstIndex, srcIndex); + refs_[dstIndex] = refs_[srcIndex]; + } + + /** + * @brief increment the reference counter of the given line (only for PRIMSIZE==1) + * @param index index of the line + */ + void refLine(unsigned int index) + { + CGoGN_STATIC_ASSERT(PRIMSIZE == 1, refLine_with_container_where_PRIMSIZE=1); + refs_[index]++; + } + + + /** + * @brief decrement the reference counter of the given line (only for PRIMSIZE==1) + * @param index index of the line + * @return true if the line was removed + */ + bool unrefLine(unsigned int index) + { + CGoGN_STATIC_ASSERT(PRIMSIZE == 1, refLine_with_container_where_PRIMSIZE=1); + + refs_[index]--; + if (refs_[index] == 1) + { + holesHeap_.push(index); + refs_[index] = 0; // same as removeLine without the "if" + --nbUsedLines_; + return true; + } + return false; + } + + /** + * @brief get the number of references of the given line + * @param index index of the line + * @return number of references of the line + */ + T_REF getNbRefs(unsigned int index) const + { + CGoGN_STATIC_ASSERT(PRIMSIZE == 1, refLine_with_container_where_PRIMSIZE=1); + return refs_[index]; + } + + + /** + * @brief get a chunk_array + * @param attribName name of the array + * @return pointer on typed chunk_array + */ + template + ChunkArray* getDataArray(const std::string& attribName) + { + unsigned int index = getArrayIndex(attribName) ; + if(index == UNKNOWN) + return NULL ; + + ChunkArray* atm = dynamic_cast*>(tableArrays_[index]); + assert((atm != NULL) || !"getDataVector: wrong type"); + return atm; + } + + + /** + * @brief get a chunk_array + * @param attribName name of the array + * @return pointer on virtual chunk_array + */ + ChunkArrayGen* getVirtualDataArray(const std::string& attribName) + { + unsigned int index = getArrayIndex(attribName) ; + if(index == UNKNOWN) + return NULL ; + + return tableArrays_[index]; + } + + + void save(std::ofstream& fs) + { + // save info (size+used_lines+max_lines+sizeof names) + std::vector buffer; + buffer.push_back((unsigned int)(tableArrays_.size())); + buffer.push_back(nbUsedLines_); + buffer.push_back(nbMaxLines_); + for(unsigned int i=0; i(&(buffer[0])),buffer.size()*sizeof(unsigned int)); + + // save names + for(unsigned int i=0; isave(fs,nbMaxLines_); + } + // save uses/refs + refs_.save(fs,nbMaxLines_); + + // save heap + holesHeap_.save(fs,holesHeap_.size()); + } + + + bool load(std::ifstream& fs) + { + // read info + unsigned int buff1[3]; + fs.read(reinterpret_cast(buff1),3*sizeof(unsigned int)); + + nbUsedLines_ = buff1[1]; + nbMaxLines_ = buff1[2]; + + std::vector buff2(2*buff1[0]); + fs.read(reinterpret_cast(&(buff2[0])),2*buff1[0]*sizeof(unsigned int)); + + names_.resize(buff1[0]); + typeNames_.resize(buff1[0]); + + // read name + char buff3[256]; + for(unsigned int i=0; i::create(typeNames_[i]); + ok &= tableArrays_[i]->load(fs); + } + ok &= refs_.load(fs); + + return ok; + } + + +}; + +} // namespace CGoGN + +#endif diff --git a/cgogn/core/container/chunk_array_factory.h b/cgogn/core/container/chunk_array_factory.h new file mode 100644 index 00000000..a14bda46 --- /dev/null +++ b/cgogn/core/container/chunk_array_factory.h @@ -0,0 +1,93 @@ +/* + * CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps + * Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Web site: http://cgogn.unistra.fr/ + * Contact information: cgogn@unistra.fr + * + */ + +#ifndef __CORE_CONTAINER_CHUNK_ARRAY_FACTORY__ +#define __CORE_CONTAINER_CHUNK_ARRAY_FACTORY__ + + +#include "core/container/chunk_array.h" + +#include +#include + +namespace cgogn +{ + + +template +class ChunkArrayFactory +{ +public: + static std::map*> mapCA_; + +public: + /** + * @brief register a type + * @param keyType name of type + * @param obj a ptr on object (new ChunkArray<32,int> for example) ptr will be deleted by clean method + */ + static void registerCA(const std::string& keyType, ChunkArrayGen* obj) + { + if(mapCA_.find(keyType) == mapCA_.end()) + mapCA_[keyType]=obj; + } + + /** + * @brief create a ChunkArray from a typename + * @param keyType typename of type store in ChunkArray + * @return ptr on created ChunkArray + */ + static ChunkArrayGen* create(const std::string& keyType) + { + ChunkArrayGen* tmp=NULL; + typename std::map*>::const_iterator it = mapCA_.find(keyType); + + if(it != mapCA_.end()) + { + tmp = (it->second)->clone(); + } + else + std::cerr << "type "< +std::map*> ChunkArrayFactory::mapCA_= std::map*>(); + + + +} // namespace CGoGN + +#endif diff --git a/cgogn/core/container/chunk_array_gen.h b/cgogn/core/container/chunk_array_gen.h new file mode 100644 index 00000000..6d25c260 --- /dev/null +++ b/cgogn/core/container/chunk_array_gen.h @@ -0,0 +1,138 @@ +/* + * CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps + * Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Web site: http://cgogn.unistra.fr/ + * Contact information: cgogn@unistra.fr + * + */ + +#ifndef __CORE_CONTAINER_CHUNK_ARRAY_GEN__ +#define __CORE_CONTAINER_CHUNK_ARRAY_GEN__ + + +#include +#include + +namespace cgogn +{ + + + +/** + * @brief Virtual version of ChunkArray + */ +template +class ChunkArrayGen +{ +public: + + /** + * @brief virtual destructor + */ + virtual ~ChunkArrayGen() {} + + /** + * @brief create a ChunkArray object without knowning type + * @return generic pointer + */ + virtual ChunkArrayGen* clone() = 0; + + + /** + * @brief add a chunk (T[CHUNKSIZE]) + */ + virtual void addChunk() = 0; + + /** + * @brief set number of chunks + * @param nbc number of chunks + */ + virtual void setNbChunks(unsigned int nbb) = 0; + + + /** + * @brief get the number of chunks of the array + * @return the number of chunks + */ + virtual unsigned int getNbChunks() const = 0; + + /** + * @brief number of allocated elements + * @return allocated lines + */ + virtual unsigned int capacity() const = 0; + + /** + * @brief clear + */ + virtual void clear() = 0; + + /** + * @brief get pointer on all chunks data + * @param addr vector to fill + * @param byteBlockSize filled with CHUNKSIZE*sizeof(T) + * @return addr.size() + */ + virtual unsigned int getChunksPointers(std::vector& addr, unsigned int& byteBlockSize) const = 0; + + /** + * @brief init an element (overwrite with T()) + * @param id index of element + */ + virtual void initElt(unsigned int id) = 0; + + /** + * @brief copy element + * @param dst destination + * @param src source + */ + virtual void copyElt(unsigned int dst, unsigned int src) = 0; + + /** + * @brief swap two elements + * @param id1 idx first + * @param id2 idx second + */ + virtual void swapElt(unsigned int id1, unsigned int id2) = 0; + + /** + * @brief save + * @param fs file stream + * @param nbLines number of line to save + */ + virtual void save(std::ostream& fs, unsigned int nbLines) const = 0; + + + /** + * @brief load + * @param fs file stream + * @return ok + */ + virtual bool load(std::istream& fs) = 0; + +}; + + +//template +//ChunkArrayGen::~ChunkArrayGen() +//{} + + +} // namespace CGoGN + +#endif diff --git a/cgogn/core/container/chunk_heap.h b/cgogn/core/container/chunk_heap.h new file mode 100644 index 00000000..8b2a3488 --- /dev/null +++ b/cgogn/core/container/chunk_heap.h @@ -0,0 +1,139 @@ +/* + * CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps + * Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Web site: http://cgogn.unistra.fr/ + * Contact information: cgogn@unistra.fr + * + */ + +#ifndef __CORE_CONTAINER_CHUNK_HEAP__ +#define __CORE_CONTAINER_CHUNK_HEAP__ + +#include "core/container/chunk_array.h" + +#include + +namespace cgogn +{ + +/** + * @brief Heap implemented in a chunk array + * @tparam CHUNKSIZE chunk size of array + * @tparam T type stored in heap + */ +template +class ChunkHeap : public ChunkArray +{ + unsigned int heapSize_; + +public: + /** + * @brief ChunkHeap constructor + */ + ChunkHeap(): + heapSize_(0) + {} + + /** + * @brief ChunkHeap destructor + */ + ~ChunkHeap() {} + + /** + * @brief push a value on top of heap + * @param val + */ + void push(const T& val) + { + heapSize_++; + unsigned int offset = heapSize_ % CHUNKSIZE; + unsigned int blkId = heapSize_ / CHUNKSIZE; + + if (blkId >= this->tableData_.size()) + this->addChunk(); + + this->tableData_[blkId][offset] = val; + } + + /** + * @brief empty + * @return true if heap empty + */ + bool empty() + { + return heapSize_==0; + } + + /** + * @return number of elements in the heap + */ + unsigned int size() + { + return heapSize_; + } + + /** + * @brief pop the head of heap + */ + void pop() + { + assert(heapSize_>0); + heapSize_--; + } + + /** + * @brief get head of heap + * @return copy of head element + */ + T head() const + { + unsigned int offset = heapSize_ % CHUNKSIZE; + unsigned int blkId = heapSize_ / CHUNKSIZE; + + return this->tableData_[blkId][offset]; + } + + /** + * @brief compact the heap (free useless memory) + */ + void compact() + { + unsigned int keep = (heapSize_+CHUNKSIZE-1) / CHUNKSIZE; + while (this->tableData_.size() > keep) + { + delete[] this->tableData_.back(); + this->tableData_.pop_back(); + } + } + + /** + * @brief clear the heap and free memory + */ + void clear() + { + heapSize_=0; + ChunkArray::clear(); + } +}; + + +} + + + +#endif diff --git a/test/test_chunk_array.cpp b/test/test_chunk_array.cpp index fa9b6a40..bc5cacbc 100644 --- a/test/test_chunk_array.cpp +++ b/test/test_chunk_array.cpp @@ -1,8 +1,244 @@ -#include -int main() +#include "core/container/chunk_array_container.h" + +#define BLK_SZ 32 + +using namespace cgogn; + + +int test1() { - ChunkArray array; + std::cout << "=============== TEST 1 ===============" << std::endl; + + ChunkArrayContainer container; + ChunkArray* att1 = container.addAttribute("entier"); + ChunkArray* att2 = container.addAttribute("reel"); + + + for (int i=0;i<21;++i) + container.insertLines(); + + + for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) + { + (*att1)[i] = 1+i; + (*att2)[i] = 3.0f + 0.1f*float(i); + } + + container.removeLines(3); + container.removeLines(11); + container.removeLines(19); + + + for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) + { + std::cout << i << ": "<< (*att1)[i] << " / " << (*att2)[i] << std::endl; + } + std::cout << "----------------------------------------" << std::endl; + + unsigned int li = container.insertLines(); + + (*att1)[li] = 110; + (*att2)[li] = 123.1f; + + li = container.insertLines(); + + (*att1)[li] = 111; + (*att2)[li] = 223.1f; + + li = container.insertLines(); + + (*att1)[li] = 112; + (*att2)[li] = 323.1f; + + for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) + { + std::cout << i << ": "<< (*att1)[i] << " / " << (*att2)[i] << std::endl; + } + std::cout << "----------------------------------------" << std::endl; + + container.removeLines(3); + container.removeLines(11); + container.removeLines(19); + + std::vector mapOldNew; + container.compact(mapOldNew); + + for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) + { + std::cout << i << ": "<< (*att1)[i] << " / " << (*att2)[i] << std::endl; + } + std::cout << "----------------------------------------" << std::endl; + return 0; -} \ No newline at end of file +} + + + +int test2() +{ + std::cout << "=============== TEST 2 ===============" << std::endl; + + ChunkArrayContainer container; + ChunkArray* att1 = container.addAttribute("entier"); + + for (int i=0;i<7;++i) + container.insertLines(); + + for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) + (*att1)[i] = 1+i; + + for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) + { + std::cout << i << ": "<< (*att1)[i] << std::endl; + } + std::cout << "----------------------------------------" << std::endl; + + container.removeLines(2); + container.removeLines(15); + + unsigned int li = container.insertLines(); + + (*att1)[li] = 110; + (*att1)[li+1] = 111; + (*att1)[li+2] = 112; + + for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) + std::cout << i << ": "<< (*att1)[i] << std::endl; + std::cout << "----------------------------------------" << std::endl; + + + container.removeLines(8); + container.removeLines(17); + + for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) + std::cout << i << ": "<< (*att1)[i] << std::endl; + std::cout << "-Compact--------------------------------------" << std::endl; + + std::vector mapOldNew; + container.compact(mapOldNew); + + for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) + std::cout << i << ": "<< (*att1)[i] << std::endl; + std::cout << "----------------------------------------" << std::endl; + + li = container.insertLines(); + + (*att1)[li] = 110; + (*att1)[li+1] = 111; + (*att1)[li+2] = 112; + + li = container.insertLines(); + + (*att1)[li] = 210; + (*att1)[li+1] = 211; + (*att1)[li+2] = 212; + + for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) + std::cout << i << ": "<< (*att1)[i] << std::endl; + std::cout << "----------------------------------------" << std::endl; + + + ChunkArray* attB = container.addAttribute("bools"); + + for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) + std::cout << i << ": "<< (*att1)[i]<< " / "<< (*attB)[i] << std::endl; + std::cout << "----------------------------------------" << std::endl; + + + return 0; + +} + + +int test3() +{ + std::cout << "=============== TEST 3 ===============" << std::endl; + + ChunkArrayContainer container; + ChunkArray* att1 = container.addAttribute("entier"); + + for (int i=0;i<7;++i) + container.insertLines(); + + for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) + (*att1)[i] = 1+i; + + container.removeLines(3); + container.removeLines(11); + container.removeLines(19); + + for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) + { + std::cout << i << ": "<< (*att1)[i] << std::endl; + } + std::cout << "----------------------------------------" << std::endl; + + return 0; +} + + +int test4() +{ + std::cout << "=============== TEST 4 ===============" << std::endl; + + ChunkArrayFactory::registerCA("float",new ChunkArray()); + ChunkArrayFactory::registerCA("int",new ChunkArray()); + ChunkArrayFactory::registerCA("char",new ChunkArray()); + + + ChunkArrayContainer container; + ChunkArray* att2 = container.addAttribute("reel"); + ChunkArray* att1 = container.addAttribute("entier"); + +// ChunkArrayGen* att3 = att2->clone(); + + + for (int i=0;i<7;++i) + container.insertLines(); + + + for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) + { + (*att1)[i] = 1+i; + (*att2)[i] = 3.0f + 0.1f*float(i); + } + + container.removeLines(3); + container.removeLines(13); + + + std::ofstream of("pipo.map"); + container.save(of); + of.close(); + + ChunkArrayContainer cont2; + std::ifstream ifi("pipo.map"); + cont2.load(ifi); + ifi.close(); + + ChunkArray* load_att1 = cont2.getAttribute("entier"); + ChunkArray* load_att2 = cont2.getAttribute("reel"); + + + for(unsigned int i=cont2.begin(); i!=cont2.end(); cont2.next(i)) + { + std::cout << i << ": "<< (*load_att1)[i] << " / " << (*load_att2)[i] << std::endl; + } + std::cout << "----------------------------------------" << std::endl; + + + ChunkArrayFactory::clean(); + + return 0; +} + + +int main() +{ + test1(); + test2(); + test3(); + test4(); +} From 55e681fa5b59892f0fed0f23801f66fc9fd1e9f9 Mon Sep 17 00:00:00 2001 From: Lionel Untereiner Date: Mon, 19 Oct 2015 10:03:24 +0200 Subject: [PATCH 008/185] changes to cmake files --- cmake/platforms/Linux-gcc.cmake | 2 +- configure.sh | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmake/platforms/Linux-gcc.cmake b/cmake/platforms/Linux-gcc.cmake index 1094cf32..64ed9e1c 100644 --- a/cmake/platforms/Linux-gcc.cmake +++ b/cmake/platforms/Linux-gcc.cmake @@ -14,7 +14,7 @@ set(FULL_WARNINGS ) # Determine gcc version and activate additional warnings available in latest versions -#execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION) +execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION) if (GCC_VERSION VERSION_GREATER 4.3 OR GCC_VERSION VERSION_EQUAL 4.3) message(STATUS "GCC version >= 4.3, activating sign conversion warnings") diff --git a/configure.sh b/configure.sh index e623e6a9..c3192e7c 100755 --- a/configure.sh +++ b/configure.sh @@ -26,8 +26,8 @@ case "$os" in os=Linux64-gcc;; Linux*amd64*) os=Linux64-gcc;; - Darwin) - os=Darwin-clang;; + Darwin*) + os=Darwin64-clang;; *) echo "Error: OS not supported: $os" exit 1;; From f4d7f740f9d7ac8d9d9362ac6ea4274bfc96992b Mon Sep 17 00:00:00 2001 From: Lionel Untereiner Date: Mon, 19 Oct 2015 10:40:25 +0200 Subject: [PATCH 009/185] adding cmake files for Darwin/clang --- cmake/platforms/Darwin-clang.cmake | 52 +++++++++++++++++++++ cmake/platforms/Darwin.cmake | 19 ++++++++ cmake/platforms/Darwin64-clang/config.cmake | 5 ++ configure.sh | 2 +- 4 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 cmake/platforms/Darwin-clang.cmake create mode 100644 cmake/platforms/Darwin.cmake create mode 100644 cmake/platforms/Darwin64-clang/config.cmake diff --git a/cmake/platforms/Darwin-clang.cmake b/cmake/platforms/Darwin-clang.cmake new file mode 100644 index 00000000..6e57fe6b --- /dev/null +++ b/cmake/platforms/Darwin-clang.cmake @@ -0,0 +1,52 @@ +#------------------------------------------------------------------- +# Flags common to all Darwin based platforms with CLANG compiler +#------------------------------------------------------------------- + +include(${CMAKE_SOURCE_DIR}/cmake/platforms/Darwin.cmake) + +#Warning flags +set(NORMAL_WARNINGS -Wall -Wextra) +set(FULL_WARNINGS + -Weverything + -Wno-unused-macros + -Wno-disabled-macro-expansion + -Wno-covered-switch-default + -Wno-padded + -Wno-float-equal + # Ignore warnings about global variables ctors and dtors + -Wno-global-constructors + -Wno-exit-time-destructors + # Turn this on to detect documentation errors (very useful) + -Wno-documentation + # Too many of sign conversion problems. Ignore them for the moment. + #-Wno-sign- + # Ignore warnings about C++98 compatibility + -Wno-c++98-compat +) + +# Compile with full warnings by default +add_definitions(${FULL_WARNINGS}) + +# Add static and dynamic bounds checks (optimization required) +string_append(CMAKE_CXX_FLAGS_RELEASE -D_FORTIFY_SOURCE=2) +string_append(CMAKE_C_FLAGS_RELEASE -D_FORTIFY_SOURCE=2) + +# Enable SSE3 instruction set +string_append(CMAKE_CXX_FLAGS -msse3) +string_append(CMAKE_C_FLAGS -msse3) + +# Additional debug flags +string_append(CMAKE_CXX_FLAGS_DEBUG -D_GLIBCXX_DEBUG) + + +string_append(CMAKE_CXX_FLAGS -std=c++11) + +macro(m_add_executable) + + # Create a statically linked executable + # Link with static libraries + string_append(CMAKE_CXX_FLAGS -static-libstdc++ -static-libgcc ) + string_append(CMAKE_C_FLAGS -static-libgcc -static) + + add_executable(${ARGN}) +endmacro() \ No newline at end of file diff --git a/cmake/platforms/Darwin.cmake b/cmake/platforms/Darwin.cmake new file mode 100644 index 00000000..86ca211a --- /dev/null +++ b/cmake/platforms/Darwin.cmake @@ -0,0 +1,19 @@ +#------------------------------------------------------------------- +# Flags common to all Darwin based platforms +#------------------------------------------------------------------- + +# Shell script extension +set(SHELL_SUFFIX "sh") + +# This flag MUST be added to solve a bug related to shared lib dynamic loading +# (std::type_infos representing the same template type do not compare equal, +# introducing subtle bugs) +# IMPORTANT: DO NOT ADD THIS FLAG WITH STATIC LINKING +string_append(CMAKE_EXE_LINKER_FLAGS "-Wl,-E") + +# Forbid undefined symbols at link time (shared libraries and executables) +string_append(CMAKE_SHARED_LINKER_FLAGS "-Wl,--no-undefined") +string_append(CMAKE_EXE_LINKER_FLAGS "-Wl,--no-undefined") + +# Link with the loader library +#list(APPEND SYSLIBS dl) diff --git a/cmake/platforms/Darwin64-clang/config.cmake b/cmake/platforms/Darwin64-clang/config.cmake new file mode 100644 index 00000000..dfb0bcd9 --- /dev/null +++ b/cmake/platforms/Darwin64-clang/config.cmake @@ -0,0 +1,5 @@ +include(${CMAKE_SOURCE_DIR}/cmake/platforms/Darwin-clang.cmake) +string_append(CMAKE_CXX_FLAGS -m64) +string_append(CMAKE_C_FLAGS -m64) + + diff --git a/configure.sh b/configure.sh index c3192e7c..d18fd237 100755 --- a/configure.sh +++ b/configure.sh @@ -31,7 +31,7 @@ case "$os" in *) echo "Error: OS not supported: $os" exit 1;; -esac +esac # Generate the Makefiles for config in Release Debug From 10ec8e7d8d75858b5c8b1ce802d58e981ae3fdbb Mon Sep 17 00:00:00 2001 From: Sylvain Thery Date: Tue, 20 Oct 2015 10:24:07 +0200 Subject: [PATCH 010/185] benching bool array --- CMakeLists.txt | 2 +- cgogn/core/CMakeLists.txt | 3 + cgogn/core/basic/nameTypes.h | 23 +++ cgogn/core/container/chunk_array.h | 22 +- cgogn/core/container/chunk_array_container.h | 53 +++-- test/CMakeLists.txt | 6 +- test/bench_chunk_array.cpp | 201 +++++++++++++++++++ test/test_chunk_array.cpp | 55 ++++- 8 files changed, 332 insertions(+), 33 deletions(-) create mode 100644 test/bench_chunk_array.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index f6c351a9..0910394c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,4 +38,4 @@ include_directories(${CMAKE_SOURCE_DIR}/cgogn) # add each subdirectory with a CMakeList add_subdirectory(cgogn/core) -add_subdirectory(test) \ No newline at end of file +add_subdirectory(test) diff --git a/cgogn/core/CMakeLists.txt b/cgogn/core/CMakeLists.txt index 9f0ec05a..0eb655dd 100644 --- a/cgogn/core/CMakeLists.txt +++ b/cgogn/core/CMakeLists.txt @@ -1,8 +1,11 @@ aux_source_directories(SOURCES "Source Files" .) aux_source_directories(SOURCES "Source Files\\container" container) +aux_source_directories(SOURCES "Source Files\\basic" basic) include_directories(${CMAKE_BINARY_DIR}/src/lib) +message(STATUS, ${SOURCES}) + add_library(cgogn ${SOURCES} ) diff --git a/cgogn/core/basic/nameTypes.h b/cgogn/core/basic/nameTypes.h index a1f6cbad..6a815e2d 100644 --- a/cgogn/core/basic/nameTypes.h +++ b/cgogn/core/basic/nameTypes.h @@ -25,6 +25,8 @@ #define __CORE_BASIC_NAME_TYPES_H__ #include +#include +#include namespace cgogn { @@ -65,6 +67,27 @@ template <> inline std::string nameOfType(const double& /*v*/) { return "double" template <> inline std::string nameOfType(const std::string& /*v*/) { return "std::string"; } +template inline std::string nameOfType(const std::vector& /*v*/) { return "std::vector"; } + +template inline std::string nameOfType(const std::list& /*v*/) { return "std::list"; } + + +/** + * @brief add CGoGNnameOfType member to a class + * + * If the class that you want to use as attribute is not basic type nor std::list/std::vector, + * use AddTypeName instead of T. + * If you develop the class T, just add as public member: static std::string CGoGNnameOfType() { return "type_name_you_develop"; } + */ +template +class AddTypeName : public T +{ +public: + static std::string CGoGNnameOfType() { return "UNKNOWN"; } +}; + + + } #endif diff --git a/cgogn/core/container/chunk_array.h b/cgogn/core/container/chunk_array.h index 897a3a0f..776fea77 100644 --- a/cgogn/core/container/chunk_array.h +++ b/cgogn/core/container/chunk_array.h @@ -316,11 +316,8 @@ class ChunkArray : public ChunkArrayGen void addChunk() { - unsigned int* ptr = new unsigned int[CHUNKSIZE/32]; -// memset(ptr,0,CHUNKSIZE/8); + unsigned int* ptr = new unsigned int[CHUNKSIZE/32](); tableData_.push_back(ptr); - for (unsigned int i=CHUNKSIZE/32; i!=0; --i) - *ptr++ = 0; } @@ -361,7 +358,6 @@ class ChunkArray : public ChunkArrayGen tableData_.clear(); } - void setFalse(unsigned int i) { unsigned int jj = i / CHUNKSIZE; @@ -396,6 +392,21 @@ class ChunkArray : public ChunkArrayGen tableData_[jj][x] &= ~mask; } + /** + * @brief special optimized version of setFalse when goal is to set all to false; + * @param i index of element to set to false + * + * This version overwrite element AND SOME OF THIS NEIGHBOURS with 0 + * Use only if final goal is to set all array to 0 (MarkerStore) + * @todo find another name for the method! + */ + void setFalseDirty(unsigned int i) + { + unsigned int jj = i / CHUNKSIZE; + unsigned int j = (i % CHUNKSIZE)/32; + tableData_[jj][j] = 0; + } + bool operator[](unsigned int i) const @@ -511,6 +522,7 @@ class ChunkArray : public ChunkArrayGen }; + } // namespace CGoGN #endif diff --git a/cgogn/core/container/chunk_array_container.h b/cgogn/core/container/chunk_array_container.h index b5e971fb..1fc8a544 100644 --- a/cgogn/core/container/chunk_array_container.h +++ b/cgogn/core/container/chunk_array_container.h @@ -44,9 +44,11 @@ namespace cgogn class ContainerBrowser { public: + inline virtual ~ContainerBrowser() {}; virtual unsigned int begin() const = 0; virtual unsigned int end() const = 0; virtual void next(unsigned int &it) const = 0; + virtual void nextPrimitive(unsigned int &it) const = 0; virtual void enable() = 0; virtual void disable() = 0; }; @@ -338,7 +340,7 @@ class ChunkArrayContainer } /** - * @brief next it <- next used index in the containere + * @brief next it <- next used index in the container * @param it index to "increment" */ void next(unsigned int &it) const @@ -349,6 +351,20 @@ class ChunkArrayContainer realNext(it); } + + /** + * @brief next primitive: it <- next primitive used index in the container (eq to PRIMSIZE next) + * @param it index to "increment" + */ + void nextPrimitive(unsigned int &it) const + { + if (currentBrowser_ != NULL) + currentBrowser_->nextPrimitive(it); + else + realNextPrimitive(it); + } + + /** * @brief begin of container without browser * @return @@ -383,6 +399,18 @@ class ChunkArrayContainer } while ((it < nbMaxLines_) && (!used(it))); } + /** + * @brief next primitive without browser + * @param it + */ + void realNextPrimitive(unsigned int &it) const + { + do + { + it+=PRIMSIZE; + } while ((it < nbMaxLines_) && (!used(it))); + } + /** * @brief real reverse begin @@ -549,18 +577,14 @@ class ChunkArrayContainer { unsigned int beginPrimIdx = (index/PRIMSIZE) * PRIMSIZE; - if (this->used(beginPrimIdx)) // replace this IF by an assert ?? - { - holesHeap_.push(beginPrimIdx); + assert(this->used(beginPrimIdx)|!" Error removing non existing index"); + holesHeap_.push(beginPrimIdx); - /// mark lines as unused - for(unsigned int i=0; i container; + ChunkArray* att1 = container.addAttribute("entier"); + ChunkArray* att2 = container.addAttribute("reel"); + ChunkArray* att3 = container.addAttribute("Vec3f"); + + + for (unsigned int i=0;i OK" << std::endl; + return 0; +} + +int test2() +{ + std::cout << "= TEST 2 = ref bool" << std::endl; + + ChunkArrayContainer container; + ChunkArray* att1 = container.addAttribute("entier"); + ChunkArray* att2 = container.addAttribute("reel"); + ChunkArray* att3 = container.addAttribute("Vec3f"); + + + for (unsigned int i=0;i OK" << std::endl; + return 0; +} + + + +int test3() +{ + std::cout << "= TEST 3 = random bool cleaning" << std::endl; + + ChunkArrayContainer container; + ChunkArray* att1 = container.addAttribute("bools"); + + for (unsigned int i=0;isetVal(i,true); + } + + for (unsigned int j=0; j<40; ++j) + { + for (unsigned int i=0;isetFalse(i); + att1->setFalse(NB_LINES-1-i); + } + } + + std::cout << "---> OK" << std::endl; + return 0; +} + + +int test4() +{ + std::cout << "= TEST 4 = random bool cleaning with setFalseDirty" << std::endl; + + ChunkArrayContainer container; + ChunkArray* att1 = container.addAttribute("bools"); + + for (unsigned int i=0;isetVal(i,true); + } + + for (unsigned int j=0; j<40; ++j) + { + for (unsigned int i=0;isetFalseDirty(i); + att1->setFalseDirty(NB_LINES-1-i); + } + } + + std::cout << "---> OK" << std::endl; + return 0; +} + + + + + + +int main(int argc, char **argv) +{ + if (argc==1) + { + std::cout <<" PARAMETER: 1 (for unsigned int refs) / 2 (for bool refs)"; + return 1; + } + + int c = atoi(argv[1]); + switch(c) + { + case 1: test1(); + break; + case 2: test2(); + break; + case 3: test3(); + break; + case 4: test4(); + break; + default: + break; + } + + return 0; +} diff --git a/test/test_chunk_array.cpp b/test/test_chunk_array.cpp index bc5cacbc..797b48b7 100644 --- a/test/test_chunk_array.cpp +++ b/test/test_chunk_array.cpp @@ -1,11 +1,14 @@ #include "core/container/chunk_array_container.h" +#include + #define BLK_SZ 32 using namespace cgogn; + int test1() { std::cout << "=============== TEST 1 ===============" << std::endl; @@ -15,7 +18,7 @@ int test1() ChunkArray* att2 = container.addAttribute("reel"); - for (int i=0;i<21;++i) + for (int i=0;i<41;++i) container.insertLines(); @@ -26,8 +29,8 @@ int test1() } container.removeLines(3); - container.removeLines(11); container.removeLines(19); + container.removeLines(35); for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) @@ -58,8 +61,8 @@ int test1() std::cout << "----------------------------------------" << std::endl; container.removeLines(3); - container.removeLines(11); container.removeLines(19); + container.removeLines(35); std::vector mapOldNew; container.compact(mapOldNew); @@ -83,7 +86,7 @@ int test2() ChunkArrayContainer container; ChunkArray* att1 = container.addAttribute("entier"); - for (int i=0;i<7;++i) + for (int i=0;i<13;++i) container.insertLines(); for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) @@ -96,7 +99,7 @@ int test2() std::cout << "----------------------------------------" << std::endl; container.removeLines(2); - container.removeLines(15); + container.removeLines(35); unsigned int li = container.insertLines(); @@ -158,20 +161,53 @@ int test3() ChunkArrayContainer container; ChunkArray* att1 = container.addAttribute("entier"); + ChunkArray >* att2 = container.addAttribute >("V_entier"); + ChunkArray >* att3 = container.addAttribute >("L_entier"); - for (int i=0;i<7;++i) + + for (int i=0;i<13;++i) container.insertLines(); + std::vector vect = (*att2)[0]; + + for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) + { (*att1)[i] = 1+i; + for (unsigned int j=0; j* att2 = container.addAttribute("reel"); ChunkArray* att1 = container.addAttribute("entier"); -// ChunkArrayGen* att3 = att2->clone(); - for (int i=0;i<7;++i) container.insertLines(); @@ -242,3 +276,4 @@ int main() test3(); test4(); } + From 305b24911b03747f38e58e7bbf8815b5a98553d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Schmitt?= Date: Tue, 20 Oct 2015 12:20:59 +0200 Subject: [PATCH 011/185] Many updates in the build system. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit -added some rules to install cgogn for the headers, libraries and binaries -using PUBLIC target_compile_features to propagate compile flags, so a library linking against CGoGN automatically add cgogn's compile flags -rewriting build scripts in cmake Signed-off-by: Étienne Schmitt --- CMakeLists.txt | 60 +++++++++--------- cgogn/CMakeLists.txt | 1 + cgogn/core/CMakeLists.txt | 65 ++++++++++++++++++-- cmake/CompilerOptions.cmake | 26 ++++++++ configure.bat | 17 ----- configure.sh | 55 ----------------- test/CMakeLists.txt | 9 +-- test/chunck_array/CMakeLists.txt | 19 ++++++ test/{ => chunck_array}/test_chunk_array.cpp | 0 9 files changed, 142 insertions(+), 110 deletions(-) create mode 100644 cgogn/CMakeLists.txt create mode 100644 cmake/CompilerOptions.cmake delete mode 100644 configure.bat delete mode 100755 configure.sh create mode 100644 test/chunck_array/CMakeLists.txt rename test/{ => chunck_array}/test_chunk_array.cpp (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index f6c351a9..44b42929 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,41 +1,41 @@ -########################################## -## CGoGN root CMakeList -########################################## +cmake_minimum_required(VERSION 3.3 FATAL_ERROR) -cmake_minimum_required(VERSION 2.8.11) - - -##### Basic information - -# Determine the current build-os (build-platform without the compiler info) -string(REGEX REPLACE "-[^-]+$" "" CGOGN_OS ${CGoGN_PLATFORM}) - -# Determine the current build date -string(TIMESTAMP CGOGN_BUILD_DATE "%Y-%m-%d %H:%M:%S") -string(TIMESTAMP YEAR "%Y") - -# TODO: Determine the current build number using jenkins - - -##### GIT tag info -# http://stackoverflow.com/a/4120179 -# TODO -# decider d'utiliser les tag de git -# extraire les informations de la commande git describe --always +set(CGOGN_VERSION_MAJOR 2) +set(CGOGN_VERSION_MINOR 0) +set(CGOGN_VERSION_PATCH 0) +project(CGoGN + VERSION ${CGOGN_VERSION_MAJOR}.${CGOGN_VERSION_MINOR}.${CGOGN_VERSION_PATCH} + LANGUAGES CXX + ) +#### Compile Options +include(cmake/CompilerOptions.cmake) ##### Build configuration set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib) - -include(${CMAKE_SOURCE_DIR}/cmake/utilities.cmake) -include(${CMAKE_SOURCE_DIR}/cmake/platforms/${CGoGN_PLATFORM}/config.cmake) - +set(CGOGN_SOURCE_DIR ${CMAKE_SOURCE_DIR}/cgogn) + +##### RPATH +if(UNIX) + # RPATH is a field in ELF binaries that is used as a hint by the system + # loader to find needed shared libraries. + # + # In the build directory, cmake creates binaries with absolute paths in + # RPATH. And by default, it strips RPATH from installed binaries. Here we + # use CMAKE_INSTALL_RPATH to set a relative RPATH. By doing so, we avoid + # the need to play with LD_LIBRARY_PATH to get applications to run. + set(CMAKE_INSTALL_RPATH "../lib:../../lib") + + if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + set(CMAKE_MACOSX_RPATH ON) + endif() +endif(UNIX) ##### CGOGN sources -include_directories(${CMAKE_SOURCE_DIR}/cgogn) - # add each subdirectory with a CMakeList -add_subdirectory(cgogn/core) +add_subdirectory(${CGOGN_SOURCE_DIR}) + +##### test add_subdirectory(test) \ No newline at end of file diff --git a/cgogn/CMakeLists.txt b/cgogn/CMakeLists.txt new file mode 100644 index 00000000..82bfe4a4 --- /dev/null +++ b/cgogn/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(core) \ No newline at end of file diff --git a/cgogn/core/CMakeLists.txt b/cgogn/core/CMakeLists.txt index 9f0ec05a..b004134d 100644 --- a/cgogn/core/CMakeLists.txt +++ b/cgogn/core/CMakeLists.txt @@ -1,8 +1,65 @@ +project(cgogn_core + LANGUAGES CXX) + +set(HEADER_FILES + basic/definitions.h + basic/nameTypes.h + basic/static_assert.h + + container/chunk_array_container.h + container/chunk_array_factory.h + container/chunk_array_gen.h + container/chunk_array.h + container/chunk_heap.h + ) + +set(SOURCE_FILES + container/chunk_array.cpp + ) + +add_library(${PROJECT_NAME} SHARED ${HEADER_FILES} ${SOURCE_FILES}) + +set_target_properties(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX "_d") +target_compile_features(${PROJECT_NAME} PUBLIC + cxx_nullptr + cxx_range_for + cxx_static_assert + cxx_deleted_functions + cxx_defaulted_functions + cxx_auto_type + cxx_alias_templates + cxx_final + cxx_defaulted_move_initializers + cxx_default_function_template_args + cxx_decltype + cxx_lambdas + cxx_override + cxx_return_type_deduction + cxx_strong_enums + cxx_template_template_parameters + ) + +target_include_directories(${PROJECT_NAME} PUBLIC + $ + $ + ) + +install(DIRECTORY basic container + DESTINATION include/cgogn/cgogn_core + FILES_MATCHING PATTERN "*.h" +) + +install(TARGETS ${PROJECT_NAME} + EXPORT ${PROJECT_NAME}Targets + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib + ) + + + + -aux_source_directories(SOURCES "Source Files" .) -aux_source_directories(SOURCES "Source Files\\container" container) -include_directories(${CMAKE_BINARY_DIR}/src/lib) -add_library(cgogn ${SOURCES} ) diff --git a/cmake/CompilerOptions.cmake b/cmake/CompilerOptions.cmake new file mode 100644 index 00000000..7f58ed02 --- /dev/null +++ b/cmake/CompilerOptions.cmake @@ -0,0 +1,26 @@ +include(cmake/utilities.cmake) + +if (UNIX AND NOT APPLE) + if(${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU") + include(cmake/platforms/Linux-gcc.cmake) + endif() + + if(${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang") + include(cmake/platforms/Linux.cmake) + endif() +endif() + +if(APPLE) + if(${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU") + include(cmake/platforms/Darwin.cmake) + endif() + + if(${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang") + include(cmake/platforms/Darwing-clang.cmake) + endif() +endif() + +if(WIN32) + #TODO +endif() + diff --git a/configure.bat b/configure.bat deleted file mode 100644 index c5d31016..00000000 --- a/configure.bat +++ /dev/null @@ -1,17 +0,0 @@ - -@echo off - -setlocal EnableDelayedExpansion - -echo. -echo -------------- Checking for Cmake -------------- -echo. - -cmake --version -if %errorlevel% ==0 ( - echo CMake found -) else ( - echo Error: CMake not found, please install it (see http://www.cmake.org) - exit /B 1 -) - diff --git a/configure.sh b/configure.sh deleted file mode 100755 index d18fd237..00000000 --- a/configure.sh +++ /dev/null @@ -1,55 +0,0 @@ -#!/bin/sh - - -echo "-------------- Checking for Cmake --------------" - -if (cmake --version) ; then - echo "CMake found" - echo -else - echo "Error: CMake not found, please install it (see http://www.cmake.org)" - exit 1 -fi - -usage="usage : ./configure.sh build-platform" - - -# Check the current OS -os="$1" -if [ -z "$os"] #if os is empty - then - os=`uname -a` -fi - -case "$os" in - Linux*x86_64*) - os=Linux64-gcc;; - Linux*amd64*) - os=Linux64-gcc;; - Darwin*) - os=Darwin64-clang;; - *) - echo "Error: OS not supported: $os" - exit 1;; -esac - -# Generate the Makefiles -for config in Release Debug -do - platform=$os-$config - echo - echo "-------------- Checking makefiles for $config mode --------------" - echo - - mkdir -p build/$platform - (cd build/$platform; cmake -DCMAKE_BUILD_TYPE:STRING=$config -DCGoGN_PLATFORM:STRING=$os ../../) -done - -echo -echo "-------------- CGoGN build configured --------------" -echo -echo "to build CGoGN: -- go to build/$os-Release or build/$os-Debug -- and 'make' or 'cmake --build .'" - -exit $? \ No newline at end of file diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 2896faba..e281bdc6 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,6 +1,7 @@ +cmake_minimum_required(VERSION 3.3 FATAL_ERROR) -aux_source_directories(SOURCES "" .) +project(cgogn_test + LANGUAGES CXX) +set(CGOGN_TEST_PREFIX "test_") -add_executable(test_chunk_array ${SOURCES}) - -target_link_libraries(test_chunk_array cgogn) +add_subdirectory(chunck_array) \ No newline at end of file diff --git a/test/chunck_array/CMakeLists.txt b/test/chunck_array/CMakeLists.txt new file mode 100644 index 00000000..427ab18a --- /dev/null +++ b/test/chunck_array/CMakeLists.txt @@ -0,0 +1,19 @@ +project(${CGOGN_TEST_PREFIX}chunck_array + LANGUAGES CXX + ) + +set(HEADER_FILES + ) + +set(SOURCE_FILES + test_chunk_array.cpp + ) + +add_executable(${PROJECT_NAME} ${HEADER_FILES} ${SOURCE_FILES}) + +target_link_libraries(${PROJECT_NAME} cgogn_core) + +install(TARGETS ${PROJECT_NAME} + EXPORT ${PROJECT_NAME}Targets + RUNTIME DESTINATION "bin/test" + ) \ No newline at end of file diff --git a/test/test_chunk_array.cpp b/test/chunck_array/test_chunk_array.cpp similarity index 100% rename from test/test_chunk_array.cpp rename to test/chunck_array/test_chunk_array.cpp From 6884fb7aea1e8bc6f7c68cc41e20b4cc45ecb51e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Schmitt?= Date: Tue, 20 Oct 2015 14:50:53 +0200 Subject: [PATCH 012/185] Fixed a typo and added a virtual dtor to ContainerBrowser class. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Étienne Schmitt --- CMakeLists.txt | 10 +++++----- cgogn/core/container/chunk_array_container.h | 1 + test/CMakeLists.txt | 5 +++-- test/{chunck_array => chunk_array}/CMakeLists.txt | 4 ++-- .../{chunck_array => chunk_array}/test_chunk_array.cpp | 0 5 files changed, 11 insertions(+), 9 deletions(-) rename test/{chunck_array => chunk_array}/CMakeLists.txt (87%) rename test/{chunck_array => chunk_array}/test_chunk_array.cpp (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 44b42929..c2b182f3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,13 +11,13 @@ project(CGoGN #### Compile Options include(cmake/CompilerOptions.cmake) -##### Build configuration +#### Build configuration set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib) set(CGOGN_SOURCE_DIR ${CMAKE_SOURCE_DIR}/cgogn) -##### RPATH +#### RPATH if(UNIX) # RPATH is a field in ELF binaries that is used as a hint by the system # loader to find needed shared libraries. @@ -33,9 +33,9 @@ if(UNIX) endif() endif(UNIX) -##### CGOGN sources +#### CGOGN sources # add each subdirectory with a CMakeList add_subdirectory(${CGOGN_SOURCE_DIR}) -##### test -add_subdirectory(test) \ No newline at end of file +#### test +add_subdirectory(test) diff --git a/cgogn/core/container/chunk_array_container.h b/cgogn/core/container/chunk_array_container.h index b5e971fb..eadaf422 100644 --- a/cgogn/core/container/chunk_array_container.h +++ b/cgogn/core/container/chunk_array_container.h @@ -49,6 +49,7 @@ class ContainerBrowser virtual void next(unsigned int &it) const = 0; virtual void enable() = 0; virtual void disable() = 0; + virtual ~ContainerBrowser() {} }; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index e281bdc6..78cb6a36 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,7 +1,8 @@ cmake_minimum_required(VERSION 3.3 FATAL_ERROR) project(cgogn_test - LANGUAGES CXX) + LANGUAGES CXX) + set(CGOGN_TEST_PREFIX "test_") -add_subdirectory(chunck_array) \ No newline at end of file +add_subdirectory(chunk_array) diff --git a/test/chunck_array/CMakeLists.txt b/test/chunk_array/CMakeLists.txt similarity index 87% rename from test/chunck_array/CMakeLists.txt rename to test/chunk_array/CMakeLists.txt index 427ab18a..ac231ba1 100644 --- a/test/chunck_array/CMakeLists.txt +++ b/test/chunk_array/CMakeLists.txt @@ -1,4 +1,4 @@ -project(${CGOGN_TEST_PREFIX}chunck_array +project(${CGOGN_TEST_PREFIX}chunk_array LANGUAGES CXX ) @@ -16,4 +16,4 @@ target_link_libraries(${PROJECT_NAME} cgogn_core) install(TARGETS ${PROJECT_NAME} EXPORT ${PROJECT_NAME}Targets RUNTIME DESTINATION "bin/test" - ) \ No newline at end of file + ) diff --git a/test/chunck_array/test_chunk_array.cpp b/test/chunk_array/test_chunk_array.cpp similarity index 100% rename from test/chunck_array/test_chunk_array.cpp rename to test/chunk_array/test_chunk_array.cpp From ad515237788d7eb2695b666eef86d900b5a8e727 Mon Sep 17 00:00:00 2001 From: Sylvain Thery Date: Tue, 20 Oct 2015 15:18:24 +0200 Subject: [PATCH 013/185] warnings --- cgogn/core/CMakeLists.txt | 3 +- cgogn/core/basic/static_assert.h | 41 -------------------- cgogn/core/container/chunk_array.h | 12 +++--- cgogn/core/container/chunk_array_container.h | 13 +++---- test/bench_chunk_array.cpp | 4 +- test/test_chunk_array.cpp | 12 +++--- 6 files changed, 21 insertions(+), 64 deletions(-) delete mode 100644 cgogn/core/basic/static_assert.h diff --git a/cgogn/core/CMakeLists.txt b/cgogn/core/CMakeLists.txt index 0eb655dd..941d1f93 100644 --- a/cgogn/core/CMakeLists.txt +++ b/cgogn/core/CMakeLists.txt @@ -1,11 +1,10 @@ aux_source_directories(SOURCES "Source Files" .) aux_source_directories(SOURCES "Source Files\\container" container) +aux_source_directories(SOURCES "Source Files\\map" container) aux_source_directories(SOURCES "Source Files\\basic" basic) include_directories(${CMAKE_BINARY_DIR}/src/lib) -message(STATUS, ${SOURCES}) - add_library(cgogn ${SOURCES} ) diff --git a/cgogn/core/basic/static_assert.h b/cgogn/core/basic/static_assert.h deleted file mode 100644 index 78fedbce..00000000 --- a/cgogn/core/basic/static_assert.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps - * Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation; either version 2.1 of the License, or (at your - * option) any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Web site: http://cgogn.unistra.fr/ - * Contact information: cgogn@unistra.fr - * - */ - -#ifndef __CORE_BASIC_STATIC_ASSERT__ -#define __CORE_BASIC_STATIC_ASSERT__ - -namespace cgogn -{ - template struct CompileTimeError; - template <> struct CompileTimeError {}; - -#ifdef CGOGN_NO_STATIC_ASSERT - #define CGoGN_STATIC_ASSERT(expr, msg) -#else - #define CGoGN_STATIC_ASSERT(expr, msg) \ - { cgogn::CompileTimeError<((expr) != 0)> STATIC_ASSERT_ERROR_##msg; (void)STATIC_ASSERT_ERROR_##msg; } -#endif - -} - -#endif diff --git a/cgogn/core/container/chunk_array.h b/cgogn/core/container/chunk_array.h index 776fea77..f2f13f3b 100644 --- a/cgogn/core/container/chunk_array.h +++ b/cgogn/core/container/chunk_array.h @@ -242,7 +242,7 @@ class ChunkArray : public ChunkArrayGen // save last unsigned nbl = nbLines - nbca*CHUNKSIZE; - fs.write(reinterpret_cast(tableData_[nbca]),nbl*sizeof(T)); + fs.write(reinterpret_cast(tableData_[nbca]),std::streamsize(nbl*sizeof(T))); } @@ -270,7 +270,7 @@ class ChunkArray : public ChunkArrayGen // load last chunk unsigned int nbl = nbs[1] - CHUNKSIZE*nbca; - fs.read(reinterpret_cast(tableData_[nbca]),nbl*sizeof(T)); + fs.read(reinterpret_cast(tableData_[nbca]),std::streamsize(nbl*sizeof(T))); return true; } @@ -364,7 +364,7 @@ class ChunkArray : public ChunkArrayGen unsigned int j = i % CHUNKSIZE; unsigned int x = j/32; unsigned int y = j%32; - unsigned int mask = 1 << y; + unsigned int mask = (unsigned int)(1) << y; tableData_[jj][x] &= ~mask; } @@ -374,7 +374,7 @@ class ChunkArray : public ChunkArrayGen unsigned int j = i % CHUNKSIZE; unsigned int x = j/32; unsigned int y = j%32; - unsigned int mask = 1 << y; + unsigned int mask = (unsigned int)(1) << y; tableData_[jj][x] |= mask; } @@ -384,7 +384,7 @@ class ChunkArray : public ChunkArrayGen unsigned int j = i % CHUNKSIZE; unsigned int x = j/32; unsigned int y = j%32; - unsigned int mask = 1 << y; + unsigned int mask = (unsigned int)(1) << y; if (b) tableData_[jj][x] |= mask; @@ -416,7 +416,7 @@ class ChunkArray : public ChunkArrayGen unsigned int x = j/32; unsigned int y = j%32; - unsigned int mask = 1 << y; + unsigned int mask = (unsigned int)(1) << y; return (tableData_[jj][x] & mask) != 0; } diff --git a/cgogn/core/container/chunk_array_container.h b/cgogn/core/container/chunk_array_container.h index 1fc8a544..ae849e87 100644 --- a/cgogn/core/container/chunk_array_container.h +++ b/cgogn/core/container/chunk_array_container.h @@ -27,7 +27,6 @@ #include "core/container/chunk_array.h" #include "core/container/chunk_heap.h" -#include "core/basic/static_assert.h" #include "core/basic/nameTypes.h" #include "core/container/chunk_array_factory.h" @@ -701,15 +700,15 @@ class ChunkArrayContainer buffer.push_back((unsigned int)(names_[i].size()+1)); buffer.push_back((unsigned int)(typeNames_[i].size()+1)); } - fs.write(reinterpret_cast(&(buffer[0])),buffer.size()*sizeof(unsigned int)); + fs.write(reinterpret_cast(&(buffer[0])),std::streamsize(buffer.size()*sizeof(unsigned int))); // save names for(unsigned int i=0; i buff2(2*buff1[0]); - fs.read(reinterpret_cast(&(buff2[0])),2*buff1[0]*sizeof(unsigned int)); + fs.read(reinterpret_cast(&(buff2[0])),std::streamsize(2*buff1[0]*sizeof(unsigned int))); names_.resize(buff1[0]); typeNames_.resize(buff1[0]); @@ -744,10 +743,10 @@ class ChunkArrayContainer char buff3[256]; for(unsigned int i=0; i Date: Wed, 21 Oct 2015 17:55:49 +0200 Subject: [PATCH 014/185] auto build type --- .gitignore | 4 ++++ CMakeLists.txt | 3 +++ cmake/utilities.cmake | 19 ++++++++++++++++++- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index b8bd0267..3f57688c 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,7 @@ *.exe *.out *.app + +# QtCreator local project file +CMakeLists.txt.user + diff --git a/CMakeLists.txt b/CMakeLists.txt index 92571ef4..7f81af99 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,6 +33,9 @@ if(UNIX) endif() endif(UNIX) +## Deduce build type of not forced by setting the CMAKE_BUILD_TYPE var +setBuildType() + #### CGOGN sources # add each subdirectory with a CMakeList diff --git a/cmake/utilities.cmake b/cmake/utilities.cmake index 9e6040e7..c8d55822 100644 --- a/cmake/utilities.cmake +++ b/cmake/utilities.cmake @@ -31,4 +31,21 @@ function(aux_source_directories var folder) #message("\nDEBUG: aux_source_directories: current_source_dir=${CMAKE_CURRENT_SOURCE_DIR} dirs=${ARGN}):\n${sources}\n") set(${var} ${${var}} ${sources} PARENT_SCOPE) -endfunction() \ No newline at end of file +endfunction() + +#! +# @brief automatic deduction of CMAKE_BUILD_TYPE from CMAKE_CURRENT_BINARY_DIR +# @details +# if CMAKE_CURRENT_BINARY_DIR end with Debug/debug/DEBUG, set Debug mode else Release mode. +# +function(setBuildType) +IF (NOT (${CMAKE_BUILD_TYPE} MATCHES "Debug|Release")) + IF (${CMAKE_CURRENT_BINARY_DIR} MATCHES "(.*)Debug|(.*)debug|(.*)DEBUG") + SET(CMAKE_BUILD_TYPE "Debug" PARENT_SCOPE) + ELSE() + SET(CMAKE_BUILD_TYPE "Release" PARENT_SCOPE) + ENDIF() +ENDIF() +endfunction(setBuildType) + + From b219f22ccdce79f6ad1f1af8282a3a44c9aa850e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Schmitt?= Date: Thu, 22 Oct 2015 18:46:50 +0200 Subject: [PATCH 015/185] nameOfType : improved the std::vector and std::list specialization. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Étienne Schmitt --- cgogn/core/basic/nameTypes.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/cgogn/core/basic/nameTypes.h b/cgogn/core/basic/nameTypes.h index 6a815e2d..953ffce6 100644 --- a/cgogn/core/basic/nameTypes.h +++ b/cgogn/core/basic/nameTypes.h @@ -67,9 +67,8 @@ template <> inline std::string nameOfType(const double& /*v*/) { return "double" template <> inline std::string nameOfType(const std::string& /*v*/) { return "std::string"; } -template inline std::string nameOfType(const std::vector& /*v*/) { return "std::vector"; } - -template inline std::string nameOfType(const std::list& /*v*/) { return "std::list"; } +template inline std::string nameOfType(const std::vector& /*v*/) { return std::string("std::vector<") + nameOfType(T()) + std::string(">"); } +template inline std::string nameOfType(const std::list& /*v*/) { return "std::list<"+ nameOfType(T()) + std::string(">"); } /** From 9781cfe8fb71b2e5bacde482cea405befb94423b Mon Sep 17 00:00:00 2001 From: Sylvain Thery Date: Thu, 22 Oct 2015 19:18:21 +0200 Subject: [PATCH 016/185] first test map/attributeHandler --- cgogn/core/CMakeLists.txt | 11 +- cgogn/core/basic/cell.h | 115 ++++++++ cgogn/core/basic/dart.h | 67 +++++ cgogn/core/container/chunk_array_container.h | 77 +++--- cgogn/core/map/attribute_handler.h | 264 +++++++++++++++++++ cgogn/core/map/map1.h | 67 +++++ cgogn/core/map/map2.h | 39 +++ cgogn/core/map/map_base.h | 80 ++++++ cgogn/core/map/map_base_data.h | 79 ++++++ cgogn/core/map/map_tri.h | 43 +++ test/CMakeLists.txt | 1 + test/chunk_array/bench_chunk_array.cpp | 40 +-- test/chunk_array/test_chunk_array.cpp | 68 ++--- test/map/CMakeLists.txt | 7 + test/map/test_map.cpp | 44 ++++ 15 files changed, 915 insertions(+), 87 deletions(-) create mode 100644 cgogn/core/basic/cell.h create mode 100644 cgogn/core/basic/dart.h create mode 100644 cgogn/core/map/attribute_handler.h create mode 100644 cgogn/core/map/map1.h create mode 100644 cgogn/core/map/map2.h create mode 100644 cgogn/core/map/map_base.h create mode 100644 cgogn/core/map/map_base_data.h create mode 100644 cgogn/core/map/map_tri.h create mode 100644 test/map/CMakeLists.txt create mode 100644 test/map/test_map.cpp diff --git a/cgogn/core/CMakeLists.txt b/cgogn/core/CMakeLists.txt index 212e79c8..0c65f1ed 100644 --- a/cgogn/core/CMakeLists.txt +++ b/cgogn/core/CMakeLists.txt @@ -4,12 +4,21 @@ project(cgogn_core set(HEADER_FILES basic/definitions.h basic/nameTypes.h - + basic/dart.h + basic/cell.h container/chunk_array_container.h container/chunk_array_factory.h container/chunk_array_gen.h container/chunk_array.h container/chunk_heap.h + + map/map_base_data.h + map/map_base.h + map/map1.h + map/map2.h + map/map_tri.h + + map/attribute_handler.h ) set(SOURCE_FILES diff --git a/cgogn/core/basic/cell.h b/cgogn/core/basic/cell.h new file mode 100644 index 00000000..6e70f353 --- /dev/null +++ b/cgogn/core/basic/cell.h @@ -0,0 +1,115 @@ +/******************************************************************************* +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * * * +* Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France * +* * +* This library is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by the * +* Free Software Foundation; either version 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: http://cgogn.unistra.fr/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ + +#ifndef __CORE_BASIC_CELL_H__ +#define __CORE_BASIC_CELL_H__ + +#include "core/basic/dart.h" + + +namespace cgogn +{ + +const unsigned int NB_ORBITS = 8; +const unsigned int DART = 0; +const unsigned int VERTEX2 = 1; +const unsigned int EDGE2 = 2; +const unsigned int FACE2 = 3; +const unsigned int VERTEX3 = 4; +const unsigned int EDGE3 = 5; +const unsigned int FACE3 = 6; +const unsigned int VOLUME3 = 7; + + +inline std::string orbitName(unsigned int orbit) +{ + switch(orbit) + { + case DART: + return "DART"; + break; + case VERTEX2: + return "VERTEX2"; + break; + case EDGE2: + return "EDGE2"; + break; + case FACE2: + return "FACE2"; + break; + case VERTEX3: + return "VERTEX3"; + break; + case EDGE3: + return "EDGE3"; + break; + case FACE3: + return "FACE3"; + break; + case VOLUME3: + return "VOLUME3"; + default: + break; + + } + return "UNKNOWN"; +} + + + +/** + * class for cellular typing + * + * warning to automatic conversion + * cell -> Dart (or const Dart&) ok + * Dart -> Cell (or const Cell&) ok + */ + +template +class Cell +{ +public: + Dart dart; + + /// empty construtor + Cell(): dart() {} + + /// constructor from Dart + inline Cell(Dart d): dart(d) {} + + /// copy constructor + inline Cell(const Cell& c): dart(c.dart) {} + + /// Dart cast operator + inline operator Dart() const { return dart; } + + friend std::ostream& operator<<( std::ostream &out, const Cell& fa ) { return out << fa.dart; } + + inline bool valid() const { return !dart.isNil(); } + +}; + + +} + +#endif diff --git a/cgogn/core/basic/dart.h b/cgogn/core/basic/dart.h new file mode 100644 index 00000000..a4ee1cad --- /dev/null +++ b/cgogn/core/basic/dart.h @@ -0,0 +1,67 @@ +/******************************************************************************* +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * * * +* Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France * +* * +* This library is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by the * +* Free Software Foundation; either version 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: http://cgogn.unistra.fr/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ + +#ifndef __CORE_BASIC_DART_H__ +#define __CORE_BASIC_DART_H__ + + + +namespace cgogn +{ + +struct Dart +{ + unsigned int index; + + Dart(): index(0xffffffff) {} + + static Dart nil() { Dart d; d.index = 0xffffffff; return d; } + + static Dart create(unsigned int i) { Dart d; d.index = i; return d; } + + static std::string CGoGNnameOfType() { return "Dart"; } + + explicit Dart(unsigned int v): index(v) {} + + bool isNil() const { return index == 0xffffffff ; } + + Dart operator=(Dart d) { index = d.index; return *this; } + + bool operator==(Dart d) const { return d.index == index; } + + bool operator!=(Dart d) const { return d.index != index; } + + bool operator<(Dart d) const { return index < d.index; } + + friend std::ostream& operator<<( std::ostream &out, const Dart& fa ) { return out << fa.index; } + friend std::istream& operator>>( std::istream &in, Dart& fa ) { in >> fa.index; return in; } + + +}; + +const Dart NIL = Dart::nil(); + + +} + +#endif diff --git a/cgogn/core/container/chunk_array_container.h b/cgogn/core/container/chunk_array_container.h index 7b389e6a..21051523 100644 --- a/cgogn/core/container/chunk_array_container.h +++ b/cgogn/core/container/chunk_array_container.h @@ -46,23 +46,37 @@ class ContainerBrowser virtual unsigned int begin() const = 0; virtual unsigned int end() const = 0; virtual void next(unsigned int &it) const = 0; - virtual void nextPrimitive(unsigned int &it) const = 0; + virtual void nextPrimitive(unsigned int &it, unsigned int primSz) const = 0; virtual void enable() = 0; virtual void disable() = 0; virtual ~ContainerBrowser() {} }; +template +class ContainerStandardBrowser:public ContainerBrowser +{ + const CONTAINER* cac_; +public: + ContainerStandardBrowser(const CONTAINER* cac) : cac_(cac) {} + virtual unsigned int begin() const { return cac_->realBegin(); } + virtual unsigned int end() const { return cac_->realEnd(); } + virtual void next(unsigned int &it) const { cac_->realNext(it); } + virtual void nextPrimitive(unsigned int &it, unsigned int primSz) const { cac_->realNextPrimitive(it,primSz); } + virtual void enable() {} + virtual void disable() {} +}; + /** * @brief class that manage the storage of several ChunkArray * @tparam CHUNKSIZE chunk size for ChunkArray - * @tparam PRIMSIZE number of lines used as primitive (grouped lines) * @detail * */ -template +template class ChunkArrayContainer { + public: /** * constante d'attribut inconnu @@ -101,6 +115,10 @@ class ChunkArrayContainer */ ContainerBrowser* currentBrowser_; + /** + * Browser that allow special traversals + */ + ContainerStandardBrowser< ChunkArrayContainer >* stdBrowser_; /** * @brief get array index from name @@ -167,11 +185,13 @@ class ChunkArrayContainer */ ChunkArrayContainer(): nbUsedLines_(0), - nbMaxLines_(0), - currentBrowser_(NULL) + nbMaxLines_(0) { + stdBrowser_ = new ContainerStandardBrowser< ChunkArrayContainer >(this); + currentBrowser_= stdBrowser_; } + /** * @brief ChunkArrayContainer destructor */ @@ -319,11 +339,9 @@ class ChunkArrayContainer * @brief begin * @return the index of the first used line of the container */ - unsigned int begin() const + inline unsigned int begin() const { - if (currentBrowser_ != NULL) - return currentBrowser_->begin(); - return realBegin(); + return currentBrowser_->begin(); } @@ -331,23 +349,18 @@ class ChunkArrayContainer * @brief end * @return the index after the last used line of the container */ - unsigned int end() const + inline unsigned int end() const { - if (currentBrowser_ != NULL) - return currentBrowser_->end(); - return realEnd(); + return currentBrowser_->end(); } /** * @brief next it <- next used index in the container * @param it index to "increment" */ - void next(unsigned int &it) const + inline void next(unsigned int &it) const { - if (currentBrowser_ != NULL) - currentBrowser_->next(it); - else - realNext(it); + currentBrowser_->next(it); } @@ -355,12 +368,9 @@ class ChunkArrayContainer * @brief next primitive: it <- next primitive used index in the container (eq to PRIMSIZE next) * @param it index to "increment" */ - void nextPrimitive(unsigned int &it) const + inline void nextPrimitive(unsigned int &it, unsigned int primSz) const { - if (currentBrowser_ != NULL) - currentBrowser_->nextPrimitive(it); - else - realNextPrimitive(it); + currentBrowser_->nextPrimitive(it, primSz); } @@ -368,7 +378,7 @@ class ChunkArrayContainer * @brief begin of container without browser * @return */ - unsigned int realBegin() const + inline unsigned int realBegin() const { unsigned int it = 0; while ((it < nbMaxLines_) && (!used(it))) @@ -380,7 +390,7 @@ class ChunkArrayContainer * @brief end of container without browser * @return */ - unsigned int realEnd() const + inline unsigned int realEnd() const { return nbMaxLines_; } @@ -390,7 +400,7 @@ class ChunkArrayContainer * @brief next without browser * @param it */ - void realNext(unsigned int &it) const + inline void realNext(unsigned int &it) const { do { @@ -402,11 +412,11 @@ class ChunkArrayContainer * @brief next primitive without browser * @param it */ - void realNextPrimitive(unsigned int &it) const + inline void realNextPrimitive(unsigned int &it, unsigned int primSz) const { do { - it+=PRIMSIZE; + it+=primSz; } while ((it < nbMaxLines_) && (!used(it))); } @@ -490,6 +500,7 @@ class ChunkArrayContainer * @brief container compacting * @param mapOldNew table that contains a map from old indices to new indices (holes -> 0xffffffff) */ + template void compact(std::vector& mapOldNew) { mapOldNew.clear(); @@ -537,6 +548,7 @@ class ChunkArrayContainer * @brief insert a group of PRIMSIZE consecutive lines in the container * @return index of the first line of group */ + template unsigned int insertLines() { unsigned int index; @@ -569,9 +581,10 @@ class ChunkArrayContainer } /** - * remove a group of PRIMSIZE lines in the container + * @brief remove a group of PRIMSIZE lines in the container * @param index index of one line of group to remove */ + template void removeLines(unsigned int index) { unsigned int beginPrimIdx = (index/PRIMSIZE) * PRIMSIZE; @@ -619,7 +632,7 @@ class ChunkArrayContainer */ void refLine(unsigned int index) { - static_assert(PRIMSIZE == 1, "refLine with container where PRIMSIZE!=1"); +// static_assert(PRIMSIZE == 1, "refLine with container where PRIMSIZE!=1"); refs_[index]++; } @@ -631,7 +644,7 @@ class ChunkArrayContainer */ bool unrefLine(unsigned int index) { - static_assert(PRIMSIZE == 1, "unrefLine with container where PRIMSIZE!=1"); +// static_assert(PRIMSIZE == 1, "unrefLine with container where PRIMSIZE!=1"); refs_[index]--; if (refs_[index] == 1) { @@ -650,7 +663,7 @@ class ChunkArrayContainer */ T_REF getNbRefs(unsigned int index) const { - static_assert(PRIMSIZE == 1, "getNbRefs with container where PRIMSIZE!=1"); +// static_assert(PRIMSIZE == 1, "getNbRefs with container where PRIMSIZE!=1"); return refs_[index]; } diff --git a/cgogn/core/map/attribute_handler.h b/cgogn/core/map/attribute_handler.h new file mode 100644 index 00000000..cbaecb9e --- /dev/null +++ b/cgogn/core/map/attribute_handler.h @@ -0,0 +1,264 @@ +/******************************************************************************* +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * * * +* Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France * +* * +* This library is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by the * +* Free Software Foundation; either version 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: http://cgogn.unistra.fr/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ + +#ifndef __CORE_MAP_ATTRIBUTE_HANDLER_H__ +#define __CORE_MAP_ATTRIBUTE_HANDLER_H__ + +#include "core/map/map_base.h" +#include "core/basic/cell.h" + + + + +namespace cgogn +{ + +template +class AttributeHandlerGen +{ +protected: + + MapBaseData* map_; + + // boolean that states the validity of the handler + bool valid_; + +public: + AttributeHandlerGen(bool v) : + map_(NULL),valid_(v) + {} + + + inline bool isValid() const { return valid_; } + + virtual unsigned int getOrbit() const = 0; + +protected: + + inline void setInvalid() { valid_ = false ; } + + inline void setValid() { valid_ = true ; } +} ; + + + + +template +class AttributeHandlerOrbit : public AttributeHandlerGen +{ +protected: + ChunkArrayContainer* chunck_array_cont_; + +public: + AttributeHandlerOrbit(MapBaseData* map) : + AttributeHandlerGen(map) + { + chunck_array_cont_ = &(map->getAttributeContainer(ORBIT)); + } + + unsigned int getOrbit() const { return ORBIT;} +}; + + + + + +template +class AttributeHandler: public AttributeHandlerOrbit +{ +protected: + ChunkArray* chunk_array_; + +public: + /** + * @brief Default constructor + * + * Construct a non-valid AttributeHandler (i.e. not linked to any attribute) + */ + AttributeHandler(): + AttributeHandlerGen(false) + {} + + + /** + * @brief Constructor + * @param m the map which belong attribute + * @param attribName name of attribute + */ + AttributeHandler(MapBaseData* m, const std::string& attribName): + AttributeHandlerOrbit(m) + { + chunk_array_ = this->chunck_array_cont_->getAttribute(attribName); + if (chunk_array_ == NULL) + { + this->setInvalid(); + } + } + + + AttributeHandler(MapBaseData* m, ChunkArray* ca): + AttributeHandlerOrbit(m),chunk_array_(ca) + { + if (chunk_array_ == NULL) + { + this->setInvalid(); + } + } + + /** + * @brief Copy constructor + * @param att + */ + AttributeHandler(const AttributeHandler& att): + AttributeHandlerOrbit(att.map_)/*, + chunk_array_(att.chunk_array_)*/ + { + this->chunk_array_= att.chunk_array_; + this->valid_ = att.valid_; + } + + /** + * @brief operator = + * @param att + * @return + */ + AttributeHandler& operator=(const AttributeHandler& att) + { + this->valid_ = att.valid_; + this->map_ = att.map_; + this->chunck_array_cont_ = att.chunck_array_cont_; + this->chunck_array_ = att.chunck_array_; + } + + /** + * @brief getDataVector + * @return + */ + ChunkArray* getDataVector() const + { + return chunk_array_; + } + + + /** + * @brief operator [] + * @param c + * @return + */ + T& operator[](Cell c) + { + assert(this->valid || !"Invalid AttributeHandler") ; + unsigned int i = this->map_->getEmbedding(c) ; + return chunk_array_->operator[](i) ; + } + + /** + * @brief operator [] + * @param c + * @return + */ + const T& operator[](Cell c) const + { + assert(this->valid || !"Invalid AttributeHandler") ; + unsigned int i = this->map_->getEmbedding(c) ; + return chunk_array_->operator[](i) ; + } + + /** + * @brief operator [] + * @param a + * @return + */ + T& operator[](unsigned int i) + { + assert(this->valid || !"Invalid AttributeHandler") ; + return chunk_array_->operator[](i) ; + } + + /** + * @brief operator [] + * @param a + * @return + */ + const T& operator[](unsigned int i) const + { + assert(this->valid || !"Invalid AttributeHandler") ; + return chunk_array_->operator[](i) ; + } + + + + class iterator + { + AttributeHandler* ah_ptr_; + unsigned int index_; + + public: + + inline iterator(AttributeHandler* ah, unsigned int i): + ah_ptr_(ah),index_(i){} + + inline iterator& operator++() + { + ah_ptr_->chunck_array_cont_->next(index_); + return *this; + } + + inline iterator operator++(int) + { + iterator temp(*this); + ah_ptr_->chunck_array_cont_->next(index_); + return temp; + } + + + inline T& operator*() + { + T& v = ah_ptr_->operator[](index_); + return v; + } + + inline bool operator!=(iterator it) + { + assert(ah_ptr_ == it.ah_ptr_); + return index_ != it.index_; + } + + }; + + inline iterator begin() + { + return iterator(this,this->chunck_array_cont_->begin()); + } + + inline iterator end() + { + return iterator(this,this->chunck_array_cont_->end()); + } + + +}; + +} + +#endif diff --git a/cgogn/core/map/map1.h b/cgogn/core/map/map1.h new file mode 100644 index 00000000..b49e1dcd --- /dev/null +++ b/cgogn/core/map/map1.h @@ -0,0 +1,67 @@ +/******************************************************************************* +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * * * +* Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France * +* * +* This library is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by the * +* Free Software Foundation; either version 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: http://cgogn.unistra.fr/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ + +#ifndef __CORE_MAP_MAP1_H__ +#define __CORE_MAP_MAP1_H__ + +#include "core/map/map_base.h" + +namespace cgogn +{ + +class Topo_Traits_map1 +{ +// static const int CHUNK_SIZE=4096; + static const int PRIM_SIZE=1; +}; + + +template +class Map1: public MapBase +{ +public: + + static const unsigned int VERTEX = VERTEX2; + static const unsigned int EDGE = EDGE2; + static const unsigned int FACE = FACE2; + + + template + using VertexAttributeHandler = AttributeHandler; + + template + using EdgeAttributeHandler = AttributeHandler; + + template + using FaceAttributeHandler = AttributeHandler; + + template + using AttributeHandler = AttributeHandler; + + +}; + + + +} +#endif diff --git a/cgogn/core/map/map2.h b/cgogn/core/map/map2.h new file mode 100644 index 00000000..a4c2e7ea --- /dev/null +++ b/cgogn/core/map/map2.h @@ -0,0 +1,39 @@ +/******************************************************************************* +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * * * +* Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France * +* * +* This library is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by the * +* Free Software Foundation; either version 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: http://cgogn.unistra.fr/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ + +#ifndef __CORE_MAP_MAP2_H__ +#define __CORE_MAP_MAP2_H__ + +#include "core/map/map1.h" + +class Map2: public Map1 +{ + + + + +}; + + + +#endif diff --git a/cgogn/core/map/map_base.h b/cgogn/core/map/map_base.h new file mode 100644 index 00000000..0e1871b6 --- /dev/null +++ b/cgogn/core/map/map_base.h @@ -0,0 +1,80 @@ +/******************************************************************************* +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * * * +* Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France * +* * +* This library is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by the * +* Free Software Foundation; either version 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: http://cgogn.unistra.fr/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ + +#ifndef __CORE_MAP_MAP_BASE_H__ +#define __CORE_MAP_MAP_BASE_H__ + +#include "core/map/map_base_data.h" +#include "core/map/attribute_handler.h" + +namespace cgogn +{ + + + +template +class MapBase: public MapBaseData +{ +public: + + MapBase() {} + + template + inline AttributeHandler addAttribute(const std::string& nameAttr = "") + { +// if(!this->template isOrbitEmbedded()) +// this->template addEmbedding() ; + + ChunkArray* ca = this->attributes_[ORBIT].template addAttribute(nameAttr) ; + return AttributeHandler(this, ca) ; + } + + /** + * remove an attribute + * @param attr a handler to the attribute to remove + * @return true if remove succeed else false + */ + template + inline bool removeAttribute(AttributeHandler& attr) + { + + return true; + } + + /** + * search an attribute for a given orbit + * @param nameAttr attribute name + * @return an AttributeHandler + */ + template + inline AttributeHandler getAttribute(const std::string& nameAttr) + { + ChunkArray* ca = this->attribs_[ORBIT].template getAttribute(nameAttr) ; + return AttributeHandler(this, ca) ; + } + +}; + +} + +#endif diff --git a/cgogn/core/map/map_base_data.h b/cgogn/core/map/map_base_data.h new file mode 100644 index 00000000..efdc986c --- /dev/null +++ b/cgogn/core/map/map_base_data.h @@ -0,0 +1,79 @@ +/******************************************************************************* +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * * * +* Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France * +* * +* This library is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by the * +* Free Software Foundation; either version 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: http://cgogn.unistra.fr/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ + +#ifndef __CORE_MAP_MAP_BASE_DATA_H__ +#define __CORE_MAP_MAP_BASE_DATA_H__ + +#include "core/container/chunk_array_container.h" +#include "core/basic/cell.h" + +namespace cgogn +{ + + +/** + * @brief Generic Map class for SCHNApps + */ +class MapGen +{ +}; + + + +/** + * @brief The MapBase class + */ +template +class MapBaseData: public MapGen +{ +protected: + + /// topooly & embedding indices + ChunkArrayContainer topology_; + + /// embedding attributes + ChunkArrayContainer attributes_[NB_ORBITS]; + + ChunkArray embeddings_[NB_ORBITS]; + +public: + MapBaseData() {} + + ChunkArrayContainer& getAttributeContainer(unsigned int orbit) + { + return attributes_[orbit]; + } + + + template + inline unsigned int getEmbedding(Cell c) const + { +// assert(this->template isOrbitEmbedded() || !"Invalid parameter: orbit not embedded"); + return (*this->embeddings_[ORBIT])[this->dartIndex(c.dart)] ; + } + +}; + +} + +#endif diff --git a/cgogn/core/map/map_tri.h b/cgogn/core/map/map_tri.h new file mode 100644 index 00000000..02b46dbb --- /dev/null +++ b/cgogn/core/map/map_tri.h @@ -0,0 +1,43 @@ +/******************************************************************************* +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * * * +* Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France * +* * +* This library is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by the * +* Free Software Foundation; either version 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: http://cgogn.unistra.fr/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ + +#ifndef __CORE_MAP_MAP_TRI_H__ +#define __CORE_MAP_MAP_TRI_H__ + +#include "core/map/map_base.h" + +class Traits_map_tri +{ + static const int CHUNK_SIZE=4096; + static const int PRIM_SIZE=3; +}; + +class MapTri: public MapBase +{ + + + +}; + + +#endif diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index ca8ac835..a9728a90 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -6,4 +6,5 @@ project(cgogn_test set(CGOGN_TEST_PREFIX "test_") add_subdirectory(chunk_array) +add_subdirectory(map) diff --git a/test/chunk_array/bench_chunk_array.cpp b/test/chunk_array/bench_chunk_array.cpp index d6e33bed..7ec20315 100644 --- a/test/chunk_array/bench_chunk_array.cpp +++ b/test/chunk_array/bench_chunk_array.cpp @@ -32,14 +32,14 @@ int test1() { std::cout << "= TEST 1 = ref unsigned char" << std::endl; - ChunkArrayContainer container; + ChunkArrayContainer container; ChunkArray* att1 = container.addAttribute("entier"); ChunkArray* att2 = container.addAttribute("reel"); ChunkArray* att3 = container.addAttribute("Vec3f"); for (unsigned int i=0;i(); @@ -51,18 +51,18 @@ int test1() } - for (unsigned int j=0; j<40; ++j) + for (unsigned int j=0; j<100; ++j) { for (unsigned int i=0;i(j%2+1+i*10); + container.removeLines<1>(j%2+3+i*10); + container.removeLines<1>(j%2+8+i*10); } for (unsigned int i=0;i<3*NB_LINES/10;++i) - container.insertLines(); + container.insertLines<1>(); } std::cout << "---> OK" << std::endl; @@ -73,14 +73,14 @@ int test2() { std::cout << "= TEST 2 = ref bool" << std::endl; - ChunkArrayContainer container; + ChunkArrayContainer container; ChunkArray* att1 = container.addAttribute("entier"); ChunkArray* att2 = container.addAttribute("reel"); ChunkArray* att3 = container.addAttribute("Vec3f"); for (unsigned int i=0;i(); @@ -92,18 +92,18 @@ int test2() } - for (unsigned int j=0; j<40; ++j) + for (unsigned int j=0; j<100; ++j) { for (unsigned int i=0;i(j%2+1+i*10); + container.removeLines<1>(j%2+3+i*10); + container.removeLines<1>(j%2+8+i*10); } for (unsigned int i=0;i<3*NB_LINES/10;++i) - container.insertLines(); + container.insertLines<1>(); } std::cout << "---> OK" << std::endl; @@ -116,18 +116,18 @@ int test3() { std::cout << "= TEST 3 = random bool cleaning" << std::endl; - ChunkArrayContainer container; + ChunkArrayContainer container; ChunkArray* att1 = container.addAttribute("bools"); for (unsigned int i=0;i(); for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) { att1->setVal(i,true); } - for (unsigned int j=0; j<40; ++j) + for (unsigned int j=0; j<100; ++j) { for (unsigned int i=0;i container; + ChunkArrayContainer container; ChunkArray* att1 = container.addAttribute("bools"); for (unsigned int i=0;i(); for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) { att1->setVal(i,true); } - for (unsigned int j=0; j<40; ++j) + for (unsigned int j=0; j<100; ++j) { for (unsigned int i=0;i container; + ChunkArrayContainer container; ChunkArray* att1 = container.addAttribute("entier"); ChunkArray* att2 = container.addAttribute("reel"); for (int i=0;i<41;++i) - container.insertLines(); + container.insertLines<1>(); for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) @@ -28,9 +28,9 @@ int test1() (*att2)[i] = 3.0f + 0.1f*float(i); } - container.removeLines(3); - container.removeLines(19); - container.removeLines(35); + container.removeLines<1>(3); + container.removeLines<1>(19); + container.removeLines<1>(35); for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) @@ -39,17 +39,17 @@ int test1() } std::cout << "----------------------------------------" << std::endl; - unsigned int li = container.insertLines(); + unsigned int li = container.insertLines<1>(); (*att1)[li] = 110; (*att2)[li] = 123.1f; - li = container.insertLines(); + li = container.insertLines<1>(); (*att1)[li] = 111; (*att2)[li] = 223.1f; - li = container.insertLines(); + li = container.insertLines<1>(); (*att1)[li] = 112; (*att2)[li] = 323.1f; @@ -60,12 +60,12 @@ int test1() } std::cout << "----------------------------------------" << std::endl; - container.removeLines(3); - container.removeLines(19); - container.removeLines(35); + container.removeLines<1>(3); + container.removeLines<1>(19); + container.removeLines<1>(35); std::vector mapOldNew; - container.compact(mapOldNew); + container.compact<1>(mapOldNew); for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) { @@ -83,11 +83,11 @@ int test2() { std::cout << "=============== TEST 2 ===============" << std::endl; - ChunkArrayContainer container; + ChunkArrayContainer container; ChunkArray* att1 = container.addAttribute("entier"); for (int i=0;i<13;++i) - container.insertLines(); + container.insertLines<3>(); for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) (*att1)[i] = 1+int(i); @@ -98,10 +98,10 @@ int test2() } std::cout << "----------------------------------------" << std::endl; - container.removeLines(2); - container.removeLines(35); + container.removeLines<3>(2); + container.removeLines<3>(35); - unsigned int li = container.insertLines(); + unsigned int li = container.insertLines<3>(); (*att1)[li] = 110; (*att1)[li+1] = 111; @@ -112,27 +112,27 @@ int test2() std::cout << "----------------------------------------" << std::endl; - container.removeLines(8); - container.removeLines(17); + container.removeLines<3>(8); + container.removeLines<3>(17); for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) std::cout << i << ": "<< (*att1)[i] << std::endl; std::cout << "-Compact--------------------------------------" << std::endl; std::vector mapOldNew; - container.compact(mapOldNew); + container.compact<3>(mapOldNew); for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) std::cout << i << ": "<< (*att1)[i] << std::endl; std::cout << "----------------------------------------" << std::endl; - li = container.insertLines(); + li = container.insertLines<3>(); (*att1)[li] = 110; (*att1)[li+1] = 111; (*att1)[li+2] = 112; - li = container.insertLines(); + li = container.insertLines<3>(); (*att1)[li] = 210; (*att1)[li+1] = 211; @@ -159,14 +159,14 @@ int test3() { std::cout << "=============== TEST 3 ===============" << std::endl; - ChunkArrayContainer container; + ChunkArrayContainer container; ChunkArray* att1 = container.addAttribute("entier"); ChunkArray >* att2 = container.addAttribute >("V_entier"); ChunkArray >* att3 = container.addAttribute >("L_entier"); for (int i=0;i<13;++i) - container.insertLines(); + container.insertLines<3>(); std::vector vect = (*att2)[0]; @@ -180,11 +180,11 @@ int test3() (*att3)[i].push_front(int(j)); } - container.removeLines(3); - container.removeLines(19); - container.removeLines(35); + container.removeLines<3>(3); + container.removeLines<3>(19); + container.removeLines<3>(35); - container.insertLines(); + container.insertLines<3>(); for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) { @@ -199,7 +199,7 @@ int test3() std::cout << "----------------------------------------" << std::endl; - for(unsigned int i=container.begin(); i!=container.end(); container.nextPrimitive(i)) + for(unsigned int i=container.begin(); i!=container.end(); container.nextPrimitive(i,3)) { std::cout << i << ": "<< (*att1)[i]<< " // "; for (auto j:(*att2)[i]) @@ -224,13 +224,13 @@ int test4() ChunkArrayFactory::registerCA("char",new ChunkArray()); - ChunkArrayContainer container; + ChunkArrayContainer container; ChunkArray* att2 = container.addAttribute("reel"); ChunkArray* att1 = container.addAttribute("entier"); for (int i=0;i<7;++i) - container.insertLines(); + container.insertLines<3>(); for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) @@ -239,15 +239,15 @@ int test4() (*att2)[i] = 3.0f + 0.1f*float(i); } - container.removeLines(3); - container.removeLines(13); + container.removeLines<3>(3); + container.removeLines<3>(13); std::ofstream of("pipo.map"); container.save(of); of.close(); - ChunkArrayContainer cont2; + ChunkArrayContainer cont2; std::ifstream ifi("pipo.map"); cont2.load(ifi); ifi.close(); diff --git a/test/map/CMakeLists.txt b/test/map/CMakeLists.txt new file mode 100644 index 00000000..321c5665 --- /dev/null +++ b/test/map/CMakeLists.txt @@ -0,0 +1,7 @@ +project(${CGOGN_TEST_PREFIX}map + LANGUAGES CXX + ) + +add_executable(test_map test_map.cpp) +target_link_libraries(test_map cgogn_core) + diff --git a/test/map/test_map.cpp b/test/map/test_map.cpp new file mode 100644 index 00000000..58e9385a --- /dev/null +++ b/test/map/test_map.cpp @@ -0,0 +1,44 @@ + +#include "core/map/map1.h" + +using namespace cgogn; + + + +struct My_Data_Traits +{ + static const int CHUNK_SIZE=64; +}; + + + +int test1() +{ + typedef Map1 MAP1; + + MAP1 map; + + MAP1::VertexAttributeHandler ah = map.addAttribute("floats"); + + ChunkArrayContainer& container = map.getAttributeContainer(VERTEX2); + ChunkArray* att = container.getAttribute("floats"); + for (int i=0;i<10;++i) + container.insertLines<1>(); + for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) + (*att)[i] = 3.0f + 0.1f*float(i); + + for (float f:ah) + std::cout << f << std::endl; + + return 0; +} + + + + +int main() +{ + test1(); + return 0; +} + From 456090ef7978f4038b86c8c804bf1fb008426c2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Schmitt?= Date: Thu, 22 Oct 2015 19:28:33 +0200 Subject: [PATCH 017/185] chunk_array : some tiny improvements : - postfixed by an 'u' the unsigned constants - added c++ 'override' keyword when possible - added 'const' when possible - replaced NULL by nullptr - ChunkArrayGen clone() method is now const MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Étienne Schmitt --- cgogn/core/container/chunk_array.h | 861 +++++++++---------- cgogn/core/container/chunk_array_container.h | 92 +- cgogn/core/container/chunk_array_gen.h | 2 +- cgogn/core/container/chunk_heap.h | 30 +- test/chunk_array/CMakeLists.txt | 23 +- test/chunk_array/bench_chunk_array.cpp | 2 +- test/chunk_array/test_chunk_array.cpp | 2 +- 7 files changed, 500 insertions(+), 512 deletions(-) diff --git a/cgogn/core/container/chunk_array.h b/cgogn/core/container/chunk_array.h index f2f13f3b..6ae63f4f 100644 --- a/cgogn/core/container/chunk_array.h +++ b/cgogn/core/container/chunk_array.h @@ -43,237 +43,233 @@ class ChunkArray : public ChunkArrayGen { protected: - /// vector of block pointers - std::vector tableData_; + /// vector of block pointers + std::vector tableData_; public: - /** - * @brief Constructor of ChunkArray - */ - ChunkArray() - { - tableData_.reserve(1024); - } - - /** - * @brief Destructor of ChunkArray - */ - ~ChunkArray() - { - for(auto chunk: tableData_) - delete[] chunk; - } - - /** - * @brief create a ChunkArray - * @return generic pointer - */ - ChunkArrayGen* clone() - { - ChunkArrayGen* ptr = new ChunkArray(); - return ptr; - } - - /** - * @brief add a chunk (T[CHUNKSIZE]) - */ - void addChunk() - { - T* ptr = new T[CHUNKSIZE](); - tableData_.push_back(ptr); - } - - - /** - * @brief set number of chunks - * @param nbc number of chunks - */ - void setNbChunks(unsigned int nbc) - { - if (nbc >= tableData_.size()) - { - for (std::size_t i= tableData_.size(); i & addr, unsigned int& byteBlockSize) const - { - byteBlockSize = CHUNKSIZE * sizeof(T); - - addr.reserve(tableData_.size()); - addr.clear(); - - for (typename std::vector::const_iterator it = tableData_.begin(); it != tableData_.end(); ++it) - addr.push_back(*it); - - return (unsigned int)(addr.size()); - } - - /** - * @brief init an element (overwrite with T()) - * @param id index of element - */ - void initElt(unsigned int id) - { - tableData_[id / CHUNKSIZE][id % CHUNKSIZE] = T(); - } - - - /** - * @brief copy element - * @param dst destination - * @param src source - */ - void copyElt(unsigned int dst, unsigned int src) - { - tableData_[dst / CHUNKSIZE][dst % CHUNKSIZE] = tableData_[src / CHUNKSIZE][src % CHUNKSIZE]; - } - - /** - * @brief swap two elements - * @param id1 idx first - * @param id2 idx second - */ - void swapElt(unsigned int id1, unsigned int id2) - { - T data = tableData_[id1 / CHUNKSIZE][id1 % CHUNKSIZE] ; - tableData_[id1 / CHUNKSIZE][id1 % CHUNKSIZE] = tableData_[id2 / CHUNKSIZE][id2 % CHUNKSIZE] ; - tableData_[id2 / CHUNKSIZE][id2 % CHUNKSIZE] = data ; - } - - - void save(std::ostream& fs, unsigned int nbLines) const - { - unsigned int nbs[3]; - nbs[0] = (unsigned int)(tableData_.size()); - nbs[1] = nbLines; - nbs[2] = CHUNKSIZE*sizeof(T); - - assert(nbLines/CHUNKSIZE <= tableData_.size()); - // TODO: if (nbLines==0) nbLines=CHUNKSIZE*tableData_.size(); ?? - - fs.write(reinterpret_cast(nbs),3*sizeof(unsigned int)); - - // no data -> finished - if (nbs[0] == 0) - return; - - unsigned int nbca = nbs[0]-1; - // save data chunks except last - for(unsigned int i=0; i(tableData_[i]),CHUNKSIZE*sizeof(T)); - } - - // save last - unsigned nbl = nbLines - nbca*CHUNKSIZE; - fs.write(reinterpret_cast(tableData_[nbca]),std::streamsize(nbl*sizeof(T))); - } - - - bool load(std::istream& fs) - { - unsigned int nbs[3]; - fs.read(reinterpret_cast(nbs), 3*sizeof(unsigned int)); - - if (nbs[2] != CHUNKSIZE*sizeof(T)) - { - std::cerr << "Error loading ChunkArray wrong CHUNKSIZE"<< std::endl; - return false; - } - - this->setNbChunks(nbs[0]); - - // no data -> finished - if (nbs[0] == 0) - return true; - - // load data chunks except last - unsigned int nbca = nbs[0]-1; - for(unsigned int i = 0; i < nbca; ++i) - fs.read(reinterpret_cast(tableData_[i]),CHUNKSIZE*sizeof(T)); - - // load last chunk - unsigned int nbl = nbs[1] - CHUNKSIZE*nbca; - fs.read(reinterpret_cast(tableData_[nbca]),std::streamsize(nbl*sizeof(T))); - - return true; - } + /** + * @brief Constructor of ChunkArray + */ + inline ChunkArray() : ChunkArrayGen() + { + tableData_.reserve(1024u); + } + + /** + * @brief Destructor of ChunkArray + */ + ~ChunkArray() override + { + for(auto chunk: tableData_) + delete[] chunk; + } + + /** + * @brief create a ChunkArray + * @return generic pointer + */ + ChunkArrayGen* clone() const override + { + return new ChunkArray(); + } + + /** + * @brief add a chunk (T[CHUNKSIZE]) + */ + void addChunk() override + { + tableData_.emplace_back(new T[CHUNKSIZE]()); + } + + + /** + * @brief set number of chunks + * @param nbc number of chunks + */ + void setNbChunks(unsigned int nbc) override + { + if (nbc >= tableData_.size()) + { + for (std::size_t i= tableData_.size(); i (tableData_.size()); + } + + /** + * @brief number of allocated elements + * @return allocated lines + */ + unsigned int capacity() const override + { + return static_cast(tableData_.size())*CHUNKSIZE; + } + + + /** + * @brief clear + */ + void clear() override + { + for(auto chunk: tableData_) + delete[] chunk; + tableData_.clear(); + } + + /** + * @brief ref operator [] + * @param i index of element to access + * @return ref of element + */ + inline T& operator[](unsigned int i) + { + return tableData_[i / CHUNKSIZE][i % CHUNKSIZE]; + } + + /** + * @brief const ref operator [] + * @param i index of element to access + * @return const ref of element + */ + inline const T& operator[](unsigned int i) const + { + return tableData_[i / CHUNKSIZE][i % CHUNKSIZE]; + } + + /** + * @brief set the value of an element (work also with bool + * @param i index of element to set + * @param v value + */ + inline void setVal(unsigned int i, const T& v) + { + tableData_[i / CHUNKSIZE][i % CHUNKSIZE] = v; + } + + + /** + * @brief get pointer on all chunks data + * @param addr vector to fill + * @param byteBlockSize filled with CHUNKSIZE*sizeof(T) + * @return addr.size() + */ + unsigned int getChunksPointers(std::vector& addr, unsigned int& byteBlockSize) const override + { + byteBlockSize = CHUNKSIZE * sizeof(T); + + addr.reserve(tableData_.size()); + addr.clear(); + + for (typename std::vector::const_iterator it = tableData_.begin(); it != tableData_.end(); ++it) + addr.push_back(*it); + + return (unsigned int)(addr.size()); + } + + /** + * @brief init an element (overwrite with T()) + * @param id index of element + */ + void initElt(unsigned int id) override + { + tableData_[id / CHUNKSIZE][id % CHUNKSIZE] = T(); + } + + + /** + * @brief copy element + * @param dst destination + * @param src source + */ + void copyElt(unsigned int dst, unsigned int src) override + { + tableData_[dst / CHUNKSIZE][dst % CHUNKSIZE] = tableData_[src / CHUNKSIZE][src % CHUNKSIZE]; + } + + /** + * @brief swap two elements + * @param id1 idx first + * @param id2 idx second + */ + void swapElt(unsigned int id1, unsigned int id2) override + { + std::swap(tableData_[id1 / CHUNKSIZE][id1 % CHUNKSIZE], tableData_[id2 / CHUNKSIZE][id2 % CHUNKSIZE] ); + } + + + void save(std::ostream& fs, unsigned int nbLines) const override + { + unsigned int nbs[3]; + nbs[0] = (unsigned int)(tableData_.size()); + nbs[1] = nbLines; + nbs[2] = CHUNKSIZE*sizeof(T); + + assert(nbLines/CHUNKSIZE <= tableData_.size()); + // TODO: if (nbLines==0) nbLines=CHUNKSIZE*tableData_.size(); ?? + + fs.write(reinterpret_cast(nbs),3*sizeof(unsigned int)); + + // no data -> finished + if (nbs[0] == 0) + return; + + unsigned int nbca = nbs[0]-1; + // save data chunks except last + for(unsigned int i=0; i(tableData_[i]),CHUNKSIZE*sizeof(T)); + } + + // save last + unsigned nbl = nbLines - nbca*CHUNKSIZE; + fs.write(reinterpret_cast(tableData_[nbca]),nbl*sizeof(T)); + } + + + bool load(std::istream& fs) override + { + unsigned int nbs[3]; + fs.read(reinterpret_cast(nbs), 3*sizeof(unsigned int)); + + if (nbs[2] != CHUNKSIZE*sizeof(T)) + { + std::cerr << "Error loading ChunkArray wrong CHUNKSIZE"<< std::endl; + return false; + } + + this->setNbChunks(nbs[0]); + + // no data -> finished + if (nbs[0] == 0) + return true; + + // load data chunks except last + unsigned int nbca = nbs[0]-1; + for(unsigned int i = 0; i < nbca; ++i) + fs.read(reinterpret_cast(tableData_[i]),CHUNKSIZE*sizeof(T)); + + // load last chunk + unsigned int nbl = nbs[1] - CHUNKSIZE*nbca; + fs.read(reinterpret_cast(tableData_[nbca]),nbl*sizeof(T)); + + return true; + } }; @@ -289,235 +285,234 @@ class ChunkArray : public ChunkArrayGen { protected: - /// vector of block pointers - std::vector tableData_; + /// vector of block pointers + std::vector tableData_; public: - ChunkArray() - { - tableData_.reserve(1024); - } - - - ~ChunkArray() - { - for(auto chunk: tableData_) - delete[] chunk; - } - - - ChunkArrayGen* clone() - { - ChunkArrayGen* ptr = new ChunkArray; - return ptr; - } - - - void addChunk() - { - unsigned int* ptr = new unsigned int[CHUNKSIZE/32](); - tableData_.push_back(ptr); - } - - - - void setNbChunks(unsigned int nbc) - { - if (nbc >= tableData_.size()) - { - for (std::size_t i= tableData_.size(); i () + { + tableData_.reserve(1024u); + } + + + ~ChunkArray() override + { + for(auto chunk: tableData_) + delete[] chunk; + } + + + ChunkArrayGen* clone() const override + { + return new ChunkArray(); + } + + + void addChunk() override + { + // adding the empty parentheses for default-initialization + tableData_.push_back(new unsigned int[CHUNKSIZE/32u]()); + } + + + + void setNbChunks(unsigned int nbc) override + { + if (nbc >= tableData_.size()) + { + for (std::size_t i= tableData_.size(); i (tableData_.size()); + } + + + unsigned int capacity() const override + { + return static_cast(tableData_.size())*CHUNKSIZE/32u; + } - void setFalse(unsigned int i) - { - unsigned int jj = i / CHUNKSIZE; - unsigned int j = i % CHUNKSIZE; - unsigned int x = j/32; - unsigned int y = j%32; - unsigned int mask = (unsigned int)(1) << y; - tableData_[jj][x] &= ~mask; - } - void setTrue(unsigned int i) - { - unsigned int jj = i / CHUNKSIZE; - unsigned int j = i % CHUNKSIZE; - unsigned int x = j/32; - unsigned int y = j%32; - unsigned int mask = (unsigned int)(1) << y; - tableData_[jj][x] |= mask; - } + void clear() override + { + for(auto chunk: tableData_) + delete[] chunk; + tableData_.clear(); + } - void setVal(unsigned int i, bool b) - { - unsigned int jj = i / CHUNKSIZE; - unsigned int j = i % CHUNKSIZE; - unsigned int x = j/32; - unsigned int y = j%32; - unsigned int mask = (unsigned int)(1) << y; - - if (b) - tableData_[jj][x] |= mask; - else - tableData_[jj][x] &= ~mask; - } + void setFalse(unsigned int i) + { + const unsigned int jj = i / CHUNKSIZE; + const unsigned int j = i % CHUNKSIZE; + const unsigned int x = j/32u; + const unsigned int y = j%32u; + const unsigned int mask = 1u << y; + tableData_[jj][x] &= ~mask; + } - /** - * @brief special optimized version of setFalse when goal is to set all to false; - * @param i index of element to set to false - * - * This version overwrite element AND SOME OF THIS NEIGHBOURS with 0 - * Use only if final goal is to set all array to 0 (MarkerStore) - * @todo find another name for the method! - */ - void setFalseDirty(unsigned int i) - { - unsigned int jj = i / CHUNKSIZE; - unsigned int j = (i % CHUNKSIZE)/32; - tableData_[jj][j] = 0; - } - - - - bool operator[](unsigned int i) const - { - unsigned int jj = i / CHUNKSIZE; - unsigned int j = i % CHUNKSIZE; - unsigned int x = j/32; - unsigned int y = j%32; - - unsigned int mask = (unsigned int)(1) << y; - - return (tableData_[jj][x] & mask) != 0; - } - - - - unsigned int getChunksPointers(std::vector& addr, unsigned int& byteBlockSize) const - { - byteBlockSize = CHUNKSIZE / 8; - - addr.reserve(tableData_.size()); - addr.clear(); - - for (typename std::vector::const_iterator it = tableData_.begin(); it != tableData_.end(); ++it) - addr.push_back(*it); - - return (unsigned int)(addr.size()); - } + void setTrue(unsigned int i) + { + const unsigned int jj = i / CHUNKSIZE; + const unsigned int j = i % CHUNKSIZE; + const unsigned int x = j/32u; + const unsigned int y = j%32u; + const unsigned int mask = 1u << y; + tableData_[jj][x] |= mask; + } + void setVal(unsigned int i, bool b) + { + const unsigned int jj = i / CHUNKSIZE; + const unsigned int j = i % CHUNKSIZE; + const unsigned int x = j/32; + const unsigned int y = j%32; + const unsigned int mask = 1u << y; + + if (b) + tableData_[jj][x] |= mask; + else + tableData_[jj][x] &= ~mask; + } - void initElt(unsigned int id) - { - setFalse(id); - } - - - void copyElt(unsigned int dst, unsigned int src) - { - setVal(dst,this->operator [](src)); - } - - - void swapElt(unsigned int id1, unsigned int id2) - { - bool data = this->operator [](id1); - setVal(id1,this->operator [](id2)); - setVal(id2,data); - } - - - void save(std::ostream& fs, unsigned int nbLines) const - { - // round nbLines to 32 multiple - if (nbLines%32) - nbLines = ((nbLines/32)+1)*32; - - unsigned int nbs[3]; - nbs[0] = (unsigned int)(tableData_.size()); - nbs[1] = nbLines; - nbs[2] = CHUNKSIZE/8; + /** + * @brief special optimized version of setFalse when goal is to set all to false; + * @param i index of element to set to false + * + * This version overwrite element AND SOME OF THIS NEIGHBOURS with 0 + * Use only if final goal is to set all array to 0 (MarkerStore) + * @todo find another name for the method! + */ + void setFalseDirty(unsigned int i) + { + const unsigned int jj = i / CHUNKSIZE; + const unsigned int j = (i % CHUNKSIZE)/32u; + tableData_[jj][j] = 0u; + } - assert(nbLines/CHUNKSIZE <= tableData_.size()); - // TODO: if (nbLines==0) nbLines=CHUNKSIZE*tableData_.size(); ?? - - fs.write(reinterpret_cast(nbs),3*sizeof(unsigned int)); - // no data -> finished - if (nbs[0] == 0) - return; - unsigned int nbca = nbs[0]-1; - // save data chunks except last - for(unsigned int i=0; i(tableData_[i]),CHUNKSIZE/8);// /8 because bool = 1 bit & octet = 8 bit - } + bool operator[](unsigned int i) const + { + const unsigned int jj = i / CHUNKSIZE; + const unsigned int j = i % CHUNKSIZE; + const unsigned int x = j/32u; + const unsigned int y = j%32u; + + const unsigned int mask = 1u << y; + + return (tableData_[jj][x] & mask) != 0u; + } + + + + unsigned int getChunksPointers(std::vector& addr, unsigned int& byteBlockSize) const + { + byteBlockSize = CHUNKSIZE / 8u; + + addr.reserve(tableData_.size()); + addr.clear(); + + for (typename std::vector::const_iterator it = tableData_.begin(); it != tableData_.end(); ++it) + addr.push_back(*it); + + return static_cast(addr.size()); + } + + + void initElt(unsigned int id) override + { + setFalse(id); + } + + + void copyElt(unsigned int dst, unsigned int src) override + { + setVal(dst,this->operator [](src)); + } + + + void swapElt(unsigned int id1, unsigned int id2) override + { + bool data = this->operator [](id1); + setVal(id1,this->operator [](id2)); + setVal(id2,data); + } + + + void save(std::ostream& fs, unsigned int nbLines) const override + { + // round nbLines to 32 multiple + if (nbLines%32u) + nbLines = ((nbLines/32u)+1u)*32u; + + unsigned int nbs[3]; + nbs[0] = static_cast(tableData_.size()); + nbs[1] = nbLines; + nbs[2] = CHUNKSIZE/8; - // save last - unsigned int nbl = nbLines - nbca*CHUNKSIZE/8; - fs.write(reinterpret_cast(tableData_[nbca]),nbl/8); - } + assert(nbLines/CHUNKSIZE <= tableData_.size()); + // TODO: if (nbLines==0) nbLines=CHUNKSIZE*tableData_.size(); ?? + + fs.write(reinterpret_cast(nbs),3*sizeof(unsigned int)); + // no data -> finished + if (nbs[0] == 0u) + return; - bool load(std::istream& fs) - { - unsigned int nbs[3]; - fs.read(reinterpret_cast(nbs), 3*sizeof(unsigned int)); + unsigned int nbca = nbs[0]-1u; + // save data chunks except last + for(unsigned int i=0u; i(tableData_[i]),CHUNKSIZE/8u);// /8 because bool = 1 bit & octet = 8 bit + } - if (nbs[2] != CHUNKSIZE/8) - { - std::cerr << "Error loading ChunkArray wrong CHUNKSIZE"<< std::endl; - return false; - } + // save last + unsigned int nbl = nbLines - nbca*CHUNKSIZE/8u; + fs.write(reinterpret_cast(tableData_[nbca]),nbl/8u); + } - this->setNbChunks(nbs[0]); - // no data -> finished - if (nbs[0] == 0) - return true; + bool load(std::istream& fs) override + { + unsigned int nbs[3]; + fs.read(reinterpret_cast(nbs), 3u*sizeof(unsigned int)); - // load data chunks except last - unsigned int nbca = nbs[0]-1; - for(unsigned int i = 0; i < nbca; ++i) - fs.read(reinterpret_cast(tableData_[i]),CHUNKSIZE/8);// /8 because bool = 1 bit & octet = 8 bit + if (nbs[2] != CHUNKSIZE/8u) + { + std::cerr << "Error loading ChunkArray wrong CHUNKSIZE"<< std::endl; + return false; + } - // load last chunk - unsigned int nbl = nbs[1] - nbca*CHUNKSIZE/8; - fs.read(reinterpret_cast(tableData_[nbca]),nbl/8); + this->setNbChunks(nbs[0]); - return true; - } + // no data -> finished + if (nbs[0] == 0u) + return true; + + // load data chunks except last + unsigned int nbca = nbs[0]-1u; + for(unsigned int i = 0u; i < nbca; ++i) + fs.read(reinterpret_cast(tableData_[i]),CHUNKSIZE/8u);// /8 because bool = 1 bit & octet = 8 bit + + // load last chunk + unsigned int nbl = nbs[1] - nbca*CHUNKSIZE/8u; + fs.read(reinterpret_cast(tableData_[nbca]),nbl/8u); + + return true; + } }; diff --git a/cgogn/core/container/chunk_array_container.h b/cgogn/core/container/chunk_array_container.h index 7b389e6a..8ca38b28 100644 --- a/cgogn/core/container/chunk_array_container.h +++ b/cgogn/core/container/chunk_array_container.h @@ -126,7 +126,7 @@ class ChunkArrayContainer */ unsigned int getArrayIndex(const ChunkArrayGen* ptr) const { - for (unsigned int i=0; i != tableArrays_.size(); ++i) + for (unsigned int i=0u; i != tableArrays_.size(); ++i) { if (tableArrays_[i] == ptr) return i; @@ -145,7 +145,7 @@ class ChunkArrayContainer { delete tableArrays_[index] ; - if (index != tableArrays_.size()-1) + if (index != tableArrays_.size()- std::size_t(1u)) { tableArrays_[index] = tableArrays_.back(); names_[index] = names_.back(); @@ -166,9 +166,9 @@ class ChunkArrayContainer * @brief ChunkArrayContainer constructor */ ChunkArrayContainer(): - nbUsedLines_(0), - nbMaxLines_(0), - currentBrowser_(NULL) + nbUsedLines_(0u), + nbMaxLines_(0u), + currentBrowser_(nullptr) { } @@ -192,7 +192,7 @@ class ChunkArrayContainer if (index == UNKNOWN) { std::cerr << "attribute " << attribName << " not found." << std::endl ; - return NULL ; + return nullptr ; } return static_cast*>(tableArrays_[index]); @@ -216,7 +216,7 @@ class ChunkArrayContainer if (index != UNKNOWN) { std::cerr << "attribute " << attribName << " already found.." << std::endl ; - return NULL ; + return nullptr ; } // create the new attribute @@ -321,7 +321,7 @@ class ChunkArrayContainer */ unsigned int begin() const { - if (currentBrowser_ != NULL) + if (currentBrowser_ != nullptr) return currentBrowser_->begin(); return realBegin(); } @@ -333,7 +333,7 @@ class ChunkArrayContainer */ unsigned int end() const { - if (currentBrowser_ != NULL) + if (currentBrowser_ != nullptr) return currentBrowser_->end(); return realEnd(); } @@ -344,7 +344,7 @@ class ChunkArrayContainer */ void next(unsigned int &it) const { - if (currentBrowser_ != NULL) + if (currentBrowser_ != nullptr) currentBrowser_->next(it); else realNext(it); @@ -357,7 +357,7 @@ class ChunkArrayContainer */ void nextPrimitive(unsigned int &it) const { - if (currentBrowser_ != NULL) + if (currentBrowser_ != nullptr) currentBrowser_->nextPrimitive(it); else realNextPrimitive(it); @@ -370,7 +370,7 @@ class ChunkArrayContainer */ unsigned int realBegin() const { - unsigned int it = 0; + unsigned int it = 0u; while ((it < nbMaxLines_) && (!used(it))) ++it; return it; @@ -417,7 +417,7 @@ class ChunkArrayContainer */ unsigned int realRBegin() const { - unsigned int it = nbMaxLines_-1; + unsigned int it = nbMaxLines_-1u; while ((it != 0xffffffff) && (!used(it))) --it; return it; @@ -455,8 +455,8 @@ class ChunkArrayContainer */ void clear(bool removeAttrib = false) { - nbUsedLines_ = 0; - nbMaxLines_ = 0; + nbUsedLines_ = 0u; + nbMaxLines_ = 0u; // clear CA of refs refs_.clear(); @@ -496,15 +496,15 @@ class ChunkArrayContainer mapOldNew.resize(realEnd(),0xffffffff); unsigned int up = realRBegin(); - unsigned int down = 0; + unsigned int down = 0u; while (down < up) { if (!used(down)) { - for(unsigned int i=0; isetNbChunks(newNbBlocks); refs_.setNbChunks(newNbBlocks); @@ -560,8 +560,8 @@ class ChunkArrayContainer } // mark lines as used - for(unsigned int i=0; iinitElt(index); } @@ -608,7 +608,7 @@ class ChunkArrayContainer void copyLine(unsigned int dstIndex, unsigned int srcIndex) { for (auto ptrAtt: tableArrays_) - if (ptrAtt != NULL) + if (ptrAtt != nullptr) ptrAtt->copyElt(dstIndex, srcIndex); refs_[dstIndex] = refs_[srcIndex]; } @@ -619,7 +619,7 @@ class ChunkArrayContainer */ void refLine(unsigned int index) { - static_assert(PRIMSIZE == 1, "refLine with container where PRIMSIZE!=1"); + static_assert(PRIMSIZE == 1u, "refLine with container where PRIMSIZE!=1"); refs_[index]++; } @@ -631,12 +631,12 @@ class ChunkArrayContainer */ bool unrefLine(unsigned int index) { - static_assert(PRIMSIZE == 1, "unrefLine with container where PRIMSIZE!=1"); + static_assert(PRIMSIZE == 1u, "unrefLine with container where PRIMSIZE!=1"); refs_[index]--; - if (refs_[index] == 1) + if (refs_[index] == 1u) { holesHeap_.push(index); - refs_[index] = 0; // same as removeLine without the "if" + refs_[index] = 0u; // same as removeLine without the "if" --nbUsedLines_; return true; } @@ -650,7 +650,7 @@ class ChunkArrayContainer */ T_REF getNbRefs(unsigned int index) const { - static_assert(PRIMSIZE == 1, "getNbRefs with container where PRIMSIZE!=1"); + static_assert(PRIMSIZE == 1u, "getNbRefs with container where PRIMSIZE!=1"); return refs_[index]; } @@ -665,10 +665,10 @@ class ChunkArrayContainer { unsigned int index = getArrayIndex(attribName) ; if(index == UNKNOWN) - return NULL ; + return nullptr ; ChunkArray* atm = dynamic_cast*>(tableArrays_[index]); - assert((atm != NULL) || !"getDataVector: wrong type"); + assert((atm != nullptr) || !"getDataVector: wrong type"); return atm; } @@ -682,7 +682,7 @@ class ChunkArrayContainer { unsigned int index = getArrayIndex(attribName) ; if(index == UNKNOWN) - return NULL ; + return nullptr ; return tableArrays_[index]; } @@ -695,10 +695,10 @@ class ChunkArrayContainer buffer.push_back((unsigned int)(tableArrays_.size())); buffer.push_back(nbUsedLines_); buffer.push_back(nbMaxLines_); - for(unsigned int i=0; i(names_[i].size()+1)); + buffer.push_back(static_cast(typeNames_[i].size()+1)); } fs.write(reinterpret_cast(&(buffer[0])),std::streamsize(buffer.size()*sizeof(unsigned int))); @@ -707,12 +707,12 @@ class ChunkArrayContainer { const char* s1 = names_[i].c_str(); const char* s2 = typeNames_[i].c_str(); - fs.write(s1,std::streamsize((names_[i].size()+1)*sizeof(char))); - fs.write(s2,std::streamsize((typeNames_[i].size()+1)*sizeof(char))); + fs.write(s1,std::streamsize((names_[i].size()+1u)*sizeof(char))); + fs.write(s2,std::streamsize((typeNames_[i].size()+1u)*sizeof(char))); } // save chunk arrays - for(unsigned int i=0; isave(fs,nbMaxLines_); } @@ -728,32 +728,32 @@ class ChunkArrayContainer { // read info unsigned int buff1[3]; - fs.read(reinterpret_cast(buff1),3*sizeof(unsigned int)); + fs.read(reinterpret_cast(buff1),3u*sizeof(unsigned int)); nbUsedLines_ = buff1[1]; nbMaxLines_ = buff1[2]; - std::vector buff2(2*buff1[0]); - fs.read(reinterpret_cast(&(buff2[0])),std::streamsize(2*buff1[0]*sizeof(unsigned int))); + std::vector buff2(2u*buff1[0]); + fs.read(reinterpret_cast(&(buff2[0])),std::streamsize(2u*buff1[0]*sizeof(unsigned int))); names_.resize(buff1[0]); typeNames_.resize(buff1[0]); // read name char buff3[256]; - for(unsigned int i=0; i::create(typeNames_[i]); ok &= tableArrays_[i]->load(fs); diff --git a/cgogn/core/container/chunk_array_gen.h b/cgogn/core/container/chunk_array_gen.h index 6d25c260..b5d6988e 100644 --- a/cgogn/core/container/chunk_array_gen.h +++ b/cgogn/core/container/chunk_array_gen.h @@ -50,7 +50,7 @@ class ChunkArrayGen * @brief create a ChunkArray object without knowning type * @return generic pointer */ - virtual ChunkArrayGen* clone() = 0; + virtual ChunkArrayGen* clone() const = 0; /** diff --git a/cgogn/core/container/chunk_heap.h b/cgogn/core/container/chunk_heap.h index 8b2a3488..7728062a 100644 --- a/cgogn/core/container/chunk_heap.h +++ b/cgogn/core/container/chunk_heap.h @@ -45,14 +45,14 @@ class ChunkHeap : public ChunkArray /** * @brief ChunkHeap constructor */ - ChunkHeap(): - heapSize_(0) + ChunkHeap() : ChunkArray() + ,heapSize_(0u) {} /** * @brief ChunkHeap destructor */ - ~ChunkHeap() {} + ~ChunkHeap() override {} /** * @brief push a value on top of heap @@ -74,15 +74,15 @@ class ChunkHeap : public ChunkArray * @brief empty * @return true if heap empty */ - bool empty() + inline bool empty() const { - return heapSize_==0; + return heapSize_ == 0u; } /** * @return number of elements in the heap */ - unsigned int size() + unsigned int size() const { return heapSize_; } @@ -90,9 +90,9 @@ class ChunkHeap : public ChunkArray /** * @brief pop the head of heap */ - void pop() + inline void pop() { - assert(heapSize_>0); + assert(heapSize_ > 0u); heapSize_--; } @@ -100,10 +100,10 @@ class ChunkHeap : public ChunkArray * @brief get head of heap * @return copy of head element */ - T head() const + inline T head() const { - unsigned int offset = heapSize_ % CHUNKSIZE; - unsigned int blkId = heapSize_ / CHUNKSIZE; + const unsigned int offset = heapSize_ % CHUNKSIZE; + const unsigned int blkId = heapSize_ / CHUNKSIZE; return this->tableData_[blkId][offset]; } @@ -111,9 +111,9 @@ class ChunkHeap : public ChunkArray /** * @brief compact the heap (free useless memory) */ - void compact() + void compact() { - unsigned int keep = (heapSize_+CHUNKSIZE-1) / CHUNKSIZE; + const unsigned int keep = (heapSize_+CHUNKSIZE-1u) / CHUNKSIZE; while (this->tableData_.size() > keep) { delete[] this->tableData_.back(); @@ -124,9 +124,9 @@ class ChunkHeap : public ChunkArray /** * @brief clear the heap and free memory */ - void clear() + void clear() override { - heapSize_=0; + heapSize_ = 0u; ChunkArray::clear(); } }; diff --git a/test/chunk_array/CMakeLists.txt b/test/chunk_array/CMakeLists.txt index f7ce9144..77ae0f59 100644 --- a/test/chunk_array/CMakeLists.txt +++ b/test/chunk_array/CMakeLists.txt @@ -2,16 +2,6 @@ project(${CGOGN_TEST_PREFIX}chunk_array LANGUAGES CXX ) -#set(HEADER_FILES -# ) - -#set(SOURCE_FILES -# test_chunk_array.cpp -# ) - -#add_executable(${PROJECT_NAME} ${HEADER_FILES} ${SOURCE_FILES}) - -#target_link_libraries(${PROJECT_NAME} cgogn_core) add_executable(test_chunk_array test_chunk_array.cpp) target_link_libraries(test_chunk_array cgogn_core) @@ -20,9 +10,12 @@ add_executable(bench_chunk_array bench_chunk_array.cpp) target_link_libraries(bench_chunk_array cgogn_core) +install(TARGETS test_chunk_array + EXPORT ${PROJECT_NAME}Targets + RUNTIME DESTINATION "bin/test" + ) - -#install(TARGETS ${PROJECT_NAME} -# EXPORT ${PROJECT_NAME}Targets -# RUNTIME DESTINATION "bin/test" -# ) +install(TARGETS bench_chunk_array + EXPORT ${PROJECT_NAME}Targets + RUNTIME DESTINATION "bin/bench" + ) diff --git a/test/chunk_array/bench_chunk_array.cpp b/test/chunk_array/bench_chunk_array.cpp index d6e33bed..0ac683e7 100644 --- a/test/chunk_array/bench_chunk_array.cpp +++ b/test/chunk_array/bench_chunk_array.cpp @@ -1,5 +1,5 @@ -#include "core/container/chunk_array_container.h" +#include #define BLK_SZ 4096 diff --git a/test/chunk_array/test_chunk_array.cpp b/test/chunk_array/test_chunk_array.cpp index 4e90742d..6d0883fe 100644 --- a/test/chunk_array/test_chunk_array.cpp +++ b/test/chunk_array/test_chunk_array.cpp @@ -1,5 +1,5 @@ -#include "core/container/chunk_array_container.h" +#include #include From 6228887093d78f549adc64e6bf5caf086ec08dd1 Mon Sep 17 00:00:00 2001 From: Etienne Schmitt Date: Fri, 23 Oct 2015 14:04:44 +0200 Subject: [PATCH 018/185] CMakeLists : CMAKE_BUILD_TYPE has "Release" as default value * updated README.md with build and install instructions Signed-off-by: Etienne Schmitt --- CMakeLists.txt | 6 ++++++ README.md | 12 ++++++++++++ 2 files changed, 18 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7f81af99..fc3db95d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,6 +8,12 @@ project(CGoGN VERSION ${CGOGN_VERSION_MAJOR}.${CGOGN_VERSION_MINOR}.${CGOGN_VERSION_PATCH} LANGUAGES CXX ) + +#### Default build type +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Release") +endif() + #### Compile Options include(cmake/CompilerOptions.cmake) diff --git a/README.md b/README.md index aa85d976..fc938fc9 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,18 @@ CGoGN is a geometric modeling C++ library that provides an efficient implementation of combinatorial maps. +## Building and installing CGoGN +* run cmake from the build directory of your choice (this build directory must not be cgogn_path) +* you can specify build type and install path by modifying CMAKE_BUILD_TYPE and CMAKE_INSTALL_PREFIX either by using cmake-gui or ccmake, or by specifying -DCMAKE_BUILD_TYPE="" -DCMAKE_INSTALL_PREFIX="" when running cmake +* CMAKE_BUILD_TYPE default value is "Release" +* LINUX and MacOS + * make -jN or ninja in the build directory + * make (or ninja) install in the build directory if you want to install +* Windows + * VS 2013 or better required + * Installation : open INSTALL solution in VS and build it + + ## Contribution HowTo * Fork this GitHub repository From 821a1520bb075cd92fefaa54d6ae1a6cb98b83e5 Mon Sep 17 00:00:00 2001 From: Lionel Untereiner Date: Sun, 25 Oct 2015 16:04:41 +0100 Subject: [PATCH 019/185] changed path to cmake config file and corrected CMAKE_CXX_COMPILER_ID in order to work on os x --- cmake/CompilerOptions.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/CompilerOptions.cmake b/cmake/CompilerOptions.cmake index 7f58ed02..6ea27dab 100644 --- a/cmake/CompilerOptions.cmake +++ b/cmake/CompilerOptions.cmake @@ -15,8 +15,8 @@ if(APPLE) include(cmake/platforms/Darwin.cmake) endif() - if(${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang") - include(cmake/platforms/Darwing-clang.cmake) + if(${CMAKE_CXX_COMPILER_ID} STREQUAL "AppleClang") + include(cmake/platforms/Darwin64-clang/config.cmake) endif() endif() From 53109f3597fb68e38dfa388a670919628d497888 Mon Sep 17 00:00:00 2001 From: Lionel Untereiner Date: Sun, 25 Oct 2015 16:08:54 +0100 Subject: [PATCH 020/185] Removed unused flags --- cmake/platforms/Darwin.cmake | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmake/platforms/Darwin.cmake b/cmake/platforms/Darwin.cmake index 86ca211a..804dc491 100644 --- a/cmake/platforms/Darwin.cmake +++ b/cmake/platforms/Darwin.cmake @@ -9,11 +9,11 @@ set(SHELL_SUFFIX "sh") # (std::type_infos representing the same template type do not compare equal, # introducing subtle bugs) # IMPORTANT: DO NOT ADD THIS FLAG WITH STATIC LINKING -string_append(CMAKE_EXE_LINKER_FLAGS "-Wl,-E") +string_append(CMAKE_EXE_LINKER_FLAGS "-Wl") # Forbid undefined symbols at link time (shared libraries and executables) -string_append(CMAKE_SHARED_LINKER_FLAGS "-Wl,--no-undefined") -string_append(CMAKE_EXE_LINKER_FLAGS "-Wl,--no-undefined") +string_append(CMAKE_SHARED_LINKER_FLAGS "-Wl") +string_append(CMAKE_EXE_LINKER_FLAGS "-Wl") # Link with the loader library #list(APPEND SYSLIBS dl) From 812cba8b33cc721bf43402642b3e732ef31c5fa8 Mon Sep 17 00:00:00 2001 From: Lionel Untereiner Date: Sun, 25 Oct 2015 16:09:41 +0100 Subject: [PATCH 021/185] Added a flag to ignore warnings about c++11 extensions --- cmake/platforms/Darwin-clang.cmake | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cmake/platforms/Darwin-clang.cmake b/cmake/platforms/Darwin-clang.cmake index 6e57fe6b..a8f82b3a 100644 --- a/cmake/platforms/Darwin-clang.cmake +++ b/cmake/platforms/Darwin-clang.cmake @@ -22,6 +22,8 @@ set(FULL_WARNINGS #-Wno-sign- # Ignore warnings about C++98 compatibility -Wno-c++98-compat + # Ignore warnings about C++11 extensions (cgogn is promoting c++11 ) + -Wno-c++11-extensions ) # Compile with full warnings by default @@ -49,4 +51,5 @@ macro(m_add_executable) string_append(CMAKE_C_FLAGS -static-libgcc -static) add_executable(${ARGN}) -endmacro() \ No newline at end of file +endmacro() + From 0fec50bf12b577ac6b836e6aabbc1ca947028b9c Mon Sep 17 00:00:00 2001 From: Lionel Untereiner Date: Sun, 25 Oct 2015 17:10:36 +0100 Subject: [PATCH 022/185] added a new flag to ignore unknown doc type --- cmake/platforms/Darwin-clang.cmake | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cmake/platforms/Darwin-clang.cmake b/cmake/platforms/Darwin-clang.cmake index a8f82b3a..395bb9f8 100644 --- a/cmake/platforms/Darwin-clang.cmake +++ b/cmake/platforms/Darwin-clang.cmake @@ -18,6 +18,8 @@ set(FULL_WARNINGS -Wno-exit-time-destructors # Turn this on to detect documentation errors (very useful) -Wno-documentation + # Ignore unknown documentation command (There are nrecognized but valid doxygen commands !) + -Wno-documentation-unknown-command # Too many of sign conversion problems. Ignore them for the moment. #-Wno-sign- # Ignore warnings about C++98 compatibility From 4aef6666fb6749f4c8e7744894ae447910521c27 Mon Sep 17 00:00:00 2001 From: lionel untereiner Date: Mon, 26 Oct 2015 09:02:04 +0100 Subject: [PATCH 023/185] tiny correction in path of cmake configuration file --- cmake/CompilerOptions.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/CompilerOptions.cmake b/cmake/CompilerOptions.cmake index 7f58ed02..5cd0f1fc 100644 --- a/cmake/CompilerOptions.cmake +++ b/cmake/CompilerOptions.cmake @@ -2,7 +2,7 @@ include(cmake/utilities.cmake) if (UNIX AND NOT APPLE) if(${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU") - include(cmake/platforms/Linux-gcc.cmake) + include(cmake/platforms/Linux64-gcc/config.cmake) endif() if(${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang") From eb92bda824dc0aff535f7b8a87030beb9cc7f07a Mon Sep 17 00:00:00 2001 From: Sylvain Thery Date: Tue, 3 Nov 2015 09:00:07 +0100 Subject: [PATCH 024/185] map1... --- .clang_format | 67 ----------- QTcreator_IGGstyle.xml | 39 +++++++ cgogn/core/basic/dart.h | 11 +- cgogn/core/basic/nameTypes.h | 8 ++ cgogn/core/container/chunk_array.h | 11 ++ cgogn/core/container/chunk_array_container.h | 73 ++++++++++-- cgogn/core/container/chunk_array_gen.h | 4 + cgogn/core/map/attribute_handler.h | 14 ++- cgogn/core/map/map1.h | 112 ++++++++++++++++++- cgogn/core/map/map_base.h | 39 ++++++- cgogn/core/map/map_base_data.h | 9 ++ test/chunk_array/bench_chunk_array.cpp | 37 +++++- test/map/test_map.cpp | 12 ++ 13 files changed, 352 insertions(+), 84 deletions(-) delete mode 100644 .clang_format create mode 100644 QTcreator_IGGstyle.xml diff --git a/.clang_format b/.clang_format deleted file mode 100644 index 355f43f8..00000000 --- a/.clang_format +++ /dev/null @@ -1,67 +0,0 @@ ---- -Language: Cpp -# BasedOnStyle: Google -AccessModifierOffset: -1 -AlignAfterOpenBracket: true -AlignConsecutiveAssignments: false -AlignEscapedNewlinesLeft: true -AlignOperands: true -AlignTrailingComments: true -AllowAllParametersOfDeclarationOnNextLine: true -AllowShortBlocksOnASingleLine: false -AllowShortCaseLabelsOnASingleLine: false -AllowShortFunctionsOnASingleLine: All -AllowShortIfStatementsOnASingleLine: true -AllowShortLoopsOnASingleLine: true -AlwaysBreakAfterDefinitionReturnType: None -AlwaysBreakBeforeMultilineStrings: true -AlwaysBreakTemplateDeclarations: true -BinPackArguments: true -BinPackParameters: true -BreakBeforeBinaryOperators: None -BreakBeforeBraces: Attach -BreakBeforeTernaryOperators: true -BreakConstructorInitializersBeforeComma: false -ColumnLimit: 80 -CommentPragmas: '^ IWYU pragma:' -ConstructorInitializerAllOnOneLineOrOnePerLine: true -ConstructorInitializerIndentWidth: 4 -ContinuationIndentWidth: 4 -Cpp11BracedListStyle: true -DerivePointerAlignment: true -DisableFormat: false -ExperimentalAutoDetectBinPacking: false -ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] -IndentCaseLabels: true -IndentWidth: 2 -IndentWrappedFunctionNames: false -KeepEmptyLinesAtTheStartOfBlocks: false -MacroBlockBegin: '' -MacroBlockEnd: '' -MaxEmptyLinesToKeep: 1 -NamespaceIndentation: None -ObjCBlockIndentWidth: 2 -ObjCSpaceAfterProperty: false -ObjCSpaceBeforeProtocolList: false -PenaltyBreakBeforeFirstCallParameter: 1 -PenaltyBreakComment: 300 -PenaltyBreakFirstLessLess: 120 -PenaltyBreakString: 1000 -PenaltyExcessCharacter: 1000000 -PenaltyReturnTypeOnItsOwnLine: 200 -PointerAlignment: Left -SpaceAfterCStyleCast: false -SpaceBeforeAssignmentOperators: true -SpaceBeforeParens: ControlStatements -SpaceInEmptyParentheses: false -SpacesBeforeTrailingComments: 2 -SpacesInAngles: false -SpacesInContainerLiterals: true -SpacesInCStyleCastParentheses: false -SpacesInParentheses: false -SpacesInSquareBrackets: false -Standard: Auto -TabWidth: 8 -UseTab: Never -... - diff --git a/QTcreator_IGGstyle.xml b/QTcreator_IGGstyle.xml new file mode 100644 index 00000000..223bba21 --- /dev/null +++ b/QTcreator_IGGstyle.xml @@ -0,0 +1,39 @@ + + + + + + CodeStyleData + + false + false + false + false + false + true + true + false + true + false + false + false + true + true + false + true + false + false + false + 4 + true + true + 2 + false + 4 + + + + DisplayName + IGGstyle + + diff --git a/cgogn/core/basic/dart.h b/cgogn/core/basic/dart.h index a4ee1cad..6861dced 100644 --- a/cgogn/core/basic/dart.h +++ b/cgogn/core/basic/dart.h @@ -53,13 +53,20 @@ struct Dart bool operator<(Dart d) const { return index < d.index; } - friend std::ostream& operator<<( std::ostream &out, const Dart& fa ) { return out << fa.index; } - friend std::istream& operator>>( std::istream &in, Dart& fa ) { in >> fa.index; return in; } + + friend std::ostream& operator<<( std::ostream &out, const Dart& fa ); + friend std::istream& operator>>( std::istream &in, Dart& fa ); }; + +std::ostream& operator<<( std::ostream &out, const Dart& fa ) { return out << fa.index; } +std::istream& operator>>( std::istream &in, Dart& fa ) { in >> fa.index; return in; } + + const Dart NIL = Dart::nil(); +const unsigned int EMBNULL = 0xffffffff; } diff --git a/cgogn/core/basic/nameTypes.h b/cgogn/core/basic/nameTypes.h index 6a815e2d..e8d5ad23 100644 --- a/cgogn/core/basic/nameTypes.h +++ b/cgogn/core/basic/nameTypes.h @@ -87,6 +87,14 @@ class AddTypeName : public T }; +template +bool typeIsBool(T) +{ + return false; +} + +template <> bool typeIsBool(bool) { return true; } + } diff --git a/cgogn/core/container/chunk_array.h b/cgogn/core/container/chunk_array.h index f2f13f3b..b7fddfd5 100644 --- a/cgogn/core/container/chunk_array.h +++ b/cgogn/core/container/chunk_array.h @@ -65,6 +65,12 @@ class ChunkArray : public ChunkArrayGen delete[] chunk; } + + bool isBooleanArray() const + { + return false; + } + /** * @brief create a ChunkArray * @return generic pointer @@ -306,6 +312,11 @@ class ChunkArray : public ChunkArrayGen delete[] chunk; } + bool isBooleanArray() const + { + return true; + } + ChunkArrayGen* clone() { diff --git a/cgogn/core/container/chunk_array_container.h b/cgogn/core/container/chunk_array_container.h index 21051523..b8d96ddc 100644 --- a/cgogn/core/container/chunk_array_container.h +++ b/cgogn/core/container/chunk_array_container.h @@ -110,6 +110,11 @@ class ChunkArrayContainer */ unsigned int nbMaxLines_; + /** + * @brief number of bool attribs (which are alway in front of all others) + */ + unsigned int nbBoolAttribs_; + /** * Browser that allow special traversals */ @@ -153,7 +158,6 @@ class ChunkArrayContainer } - /** * @brief remove an attribute by its name * @param attribName name of attribute to remove @@ -161,7 +165,23 @@ class ChunkArrayContainer */ bool removeAttribute(unsigned int index) { - delete tableArrays_[index] ; + // store ptr for using it before delete + ChunkArrayGen* ptrToDel = tableArrays_[index]; + + // in case of bool, keep booleans first ! + if (tableArrays_[index]->isBooleanArray()) + { + nbBoolAttribs_--; + + if (index < nbBoolAttribs_) // if attribute is not last of boolean + { + tableArrays_[index] = tableArrays_[nbBoolAttribs_]; // copy last of boolean on index + names_[index] = names_[nbBoolAttribs_]; + typeNames_[index] = typeNames_[nbBoolAttribs_]; + } + // now overwrite last of bool with last + index = nbBoolAttribs_; + } if (index != tableArrays_.size()-1) { @@ -174,6 +194,9 @@ class ChunkArrayContainer names_.pop_back(); typeNames_.pop_back(); + delete ptrToDel ; + + return true ; } @@ -251,6 +274,23 @@ class ChunkArrayContainer names_.push_back(attribName); typeNames_.push_back(typeName); + // move bool in front of others + if (typeIsBool(T())) + { + if (tableArrays_.size() > nbBoolAttribs_) + { + // swap ptrs + auto tmp = tableArrays_.back(); + tableArrays_.back() = tableArrays_[nbBoolAttribs_]; + tableArrays_[nbBoolAttribs_] = tmp; + // swap names & typenames + names_.back().swap(names_[nbBoolAttribs_]); + typeNames_.back().swap(typeNames_[nbBoolAttribs_]); + } + nbBoolAttribs_++; + + } + return carr ; } @@ -608,10 +648,26 @@ class ChunkArrayContainer { assert( used(index) && "initLine only with allocated lines"); for (auto ptrAtt: tableArrays_) - if (ptrAtt != NULL) +// if (ptrAtt != NULL) never null ! ptrAtt->initElt(index); } + void initBooleansOfLine(unsigned int index) + { + assert( used(index) && "initBooleansOfLine only with allocated lines"); + for (unsigned int i=0; iinitElt(index); + } + + + void initBoolsOfLine(unsigned int index) + { +// assert( used(index) && "initLine only with allocated lines"); +// for (auto ptrAtt: tableArrays_) +// if (ptrAtt != NULL) +// ptrAtt->initElt(index); + } + /** * @brief copy the content of line src in line dst (with refs) @@ -705,9 +761,11 @@ class ChunkArrayContainer { // save info (size+used_lines+max_lines+sizeof names) std::vector buffer; + buffer.reserve(1024); buffer.push_back((unsigned int)(tableArrays_.size())); buffer.push_back(nbUsedLines_); buffer.push_back(nbMaxLines_); + buffer.push_back(nbBoolAttribs_); for(unsigned int i=0; i(buff1),3*sizeof(unsigned int)); + unsigned int buff1[4]; + fs.read(reinterpret_cast(buff1),4*sizeof(unsigned int)); - nbUsedLines_ = buff1[1]; - nbMaxLines_ = buff1[2]; + nbUsedLines_ = buff1[1]; + nbMaxLines_ = buff1[2]; + nbBoolAttribs_ = buff1[3]; std::vector buff2(2*buff1[0]); fs.read(reinterpret_cast(&(buff2[0])),std::streamsize(2*buff1[0]*sizeof(unsigned int))); diff --git a/cgogn/core/container/chunk_array_gen.h b/cgogn/core/container/chunk_array_gen.h index 6d25c260..c0363978 100644 --- a/cgogn/core/container/chunk_array_gen.h +++ b/cgogn/core/container/chunk_array_gen.h @@ -82,6 +82,10 @@ class ChunkArrayGen */ virtual void clear() = 0; + + virtual bool isBooleanArray() const = 0; + + /** * @brief get pointer on all chunks data * @param addr vector to fill diff --git a/cgogn/core/map/attribute_handler.h b/cgogn/core/map/attribute_handler.h index cbaecb9e..5820ca19 100644 --- a/cgogn/core/map/attribute_handler.h +++ b/cgogn/core/map/attribute_handler.h @@ -28,11 +28,14 @@ #include "core/basic/cell.h" - +///TODO ajouter enregistrement dans la map de la carte. namespace cgogn { - +/** + * @brief Generic AttributeHandler class + * @TPARAM DATA_TRAITS stprage traits (for MapBase ptr) + */ template class AttributeHandlerGen { @@ -48,6 +51,8 @@ class AttributeHandlerGen map_(NULL),valid_(v) {} + virtual ~AttributeHandlerGen() {} + inline bool isValid() const { return valid_; } @@ -62,7 +67,10 @@ class AttributeHandlerGen - +/** + * @brief Generic AttributeHandler class with orbit parameter + * @TPARAM ORBIT the orbit of attribute to handlde + */ template class AttributeHandlerOrbit : public AttributeHandlerGen { diff --git a/cgogn/core/map/map1.h b/cgogn/core/map/map1.h index b49e1dcd..3892aa3b 100644 --- a/cgogn/core/map/map1.h +++ b/cgogn/core/map/map1.h @@ -25,6 +25,7 @@ #define __CORE_MAP_MAP1_H__ #include "core/map/map_base.h" +#include "core/basic/dart.h" namespace cgogn { @@ -45,7 +46,6 @@ class Map1: public MapBase static const unsigned int EDGE = EDGE2; static const unsigned int FACE = FACE2; - template using VertexAttributeHandler = AttributeHandler; @@ -59,6 +59,116 @@ class Map1: public MapBase using AttributeHandler = AttributeHandler; + /** + * @brief phi1 + * @param d + * @return + */ + Dart phi1(Dart d) const + { + // phi1 first topo relation + return (*(this->topo_relations_[0]))[d.index]; + } + + /** + * @brief phi_1 + * @param d + * @return + */ + Dart phi_1(Dart d) const + { + // phi1 first topo relation + return (*(this->topo_relations_[1]))[d.index]; + } + + + /** + * @brief add_cycle + * @param nbEdges + * @return + */ + Dart add_cycle(unsigned int nbEdges) ; + + /** + * @brief remove_cycle + * @param d + */ + void remove_cycle(Dart d) ; + + /** + * @brief cut_edge + * @param d + * @return + */ + Dart cut_edge(Dart d) + { + Dart e = this->newDart() ; // Create a new dart + phi1sew(d, e) ; // Insert dart e between d and phi1(d) + + + // TODO: doit on traiter les marker de bord 2/3 dans Map1 + if (this->template isBoundaryMarked<2>(d)) + this->template boundaryMark<2>(e); + + if (this->template isBoundaryMarked<3>(d)) + this->template boundaryMark<3>(e); + + return e ; + } + + /** + * @brief uncut_edge + * @param d + * @return + */ + Dart uncut_edge(Dart d) + { + Dart d1 = phi1(d) ; + phi1unsew(d) ; // Dart d is linked to the successor of its successor + this->deleteDart(d1) ; // Dart d1 is erased + } + + + /** + * @brief collapse_edge + * @param d + * @return + */ + Dart collapse_edge(Dart d); + + + +protected: + + void init() + { + ChunkArray* rel_phi1 = this->topology_.template addAttribute("phi1"); + ChunkArray* rel_phi_1 = this->topology_.template addAttribute("phi1"); + + this->topo_relations_.push_back(rel_phi1); + this->topo_relations_.push_back(rel_phi_1); + } + + + //! Link the current dart to dart d with a permutation + /*! @param d the dart to which the current is linked + * - Before: d->f and e->g + * - After: d->g and e->f + * Join the permutations cycles of dart d and e + * - Starting from two cycles : d->f->...->d and e->g->...->e + * - It makes one cycle d->g->...->e->f->...->d + * If e = g then insert e in the cycle of d : d->e->f->...->d + */ + void phi1sew(Dart d, Dart e); + + //! Unlink the successor of a given dart in a permutation + /*! @param d a dart + * - Before: d->e->f + * - After: d->f and e->e + */ + void phi1unsew(Dart d); + + }; diff --git a/cgogn/core/map/map_base.h b/cgogn/core/map/map_base.h index 0e1871b6..31acd908 100644 --- a/cgogn/core/map/map_base.h +++ b/cgogn/core/map/map_base.h @@ -35,6 +35,9 @@ namespace cgogn template class MapBase: public MapBaseData { +protected: + std::multimap*, AttributeHandlerGen*> attributeHandlers_ ; + public: MapBase() {} @@ -55,10 +58,21 @@ class MapBase: public MapBaseData * @return true if remove succeed else false */ template - inline bool removeAttribute(AttributeHandler& attr) + inline bool removeAttribute(AttributeHandler& attr_handl) { - return true; + ChunkArray* ca = attr_handl.getDataVector(); + + if (this->attributes_[ORBIT].removeAttribute(ca)) + { + typedef typename std::multimap*, AttributeHandlerGen*>::iterator IT ; + std::pair bounds = attributeHandlers_.equal_range(ca) ; + for(IT i = bounds.first; i != bounds.second; ++i) + (*i).second->setInvalid() ; + attributeHandlers_.erase(bounds.first, bounds.second) ; + return true ; + } + return false ; } /** @@ -73,6 +87,27 @@ class MapBase: public MapBaseData return AttributeHandler(this, ca) ; } + + inline Dart add_dart() + { + + unsigned int di = this->topology_.template insertLines<1>(); // insert a new dart line + this->topology_.initBooleansOfLine(di); + + for(unsigned int i = 0; i < NB_ORBITS; ++i) + { + if (this->embeddings_[i]) // set all its embeddings + (*(this->embeddings_[i]))[di] = EMBNULL ; // to EMBNULL + } + + Dart d = Dart::create(di) ; + + for (auto relPtr: this->topo_relations_) + (*relPtr)[di] = d; + + return d ; + } + }; } diff --git a/cgogn/core/map/map_base_data.h b/cgogn/core/map/map_base_data.h index efdc986c..a065a696 100644 --- a/cgogn/core/map/map_base_data.h +++ b/cgogn/core/map/map_base_data.h @@ -54,8 +54,17 @@ class MapBaseData: public MapGen /// embedding attributes ChunkArrayContainer attributes_[NB_ORBITS]; + /// embedding indices shortcuts ChunkArray embeddings_[NB_ORBITS]; + /// boundary markers shortcuts + ChunkArray* boundaryMarkers_[2]; + // TODO: ?? store in a std::vector ? + + /// topo relations shortcuts + std::vector*> topo_relations_; + + public: MapBaseData() {} diff --git a/test/chunk_array/bench_chunk_array.cpp b/test/chunk_array/bench_chunk_array.cpp index 7ec20315..941bfe23 100644 --- a/test/chunk_array/bench_chunk_array.cpp +++ b/test/chunk_array/bench_chunk_array.cpp @@ -83,7 +83,6 @@ int test2() container.insertLines<1>(); - for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) { (*att1)[i] = 1+int(i); @@ -171,6 +170,38 @@ int test4() +int test5() +{ + std::cout << "= TEST 5 = Traversal" << std::endl; + + ChunkArrayContainer container; + ChunkArray* att1 = container.addAttribute("ints"); + + for (unsigned int i=0;i(); + + for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) + att1->operator [](i) = i; + + for(unsigned int i=container.begin(); i(i); + + + int total = 0; + for (unsigned int j=0; j<50; ++j) + { + for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) + { + if (att1->operator [](i)%i != 0) + total += att1->operator [](i); + } + total = - total; + } + + std::cout << "---> OK " << total << std::endl; + return 0; +} + @@ -178,7 +209,7 @@ int main(int argc, char **argv) { if (argc==1) { - std::cout <<" PARAMETER: 1 (for unsigned int refs) / 2 (for bool refs)"; + std::cout <<" PARAMETER: 1/2 for uint/bool refs ; 3/4 for random clear bool; 5 for traversal"; return 1; } @@ -193,6 +224,8 @@ int main(int argc, char **argv) break; case 4: test4(); break; + case 5: test5(); + break; default: break; } diff --git a/test/map/test_map.cpp b/test/map/test_map.cpp index 58e9385a..d2b9ccf5 100644 --- a/test/map/test_map.cpp +++ b/test/map/test_map.cpp @@ -14,12 +14,16 @@ struct My_Data_Traits int test1() { + // typedef for short writing typedef Map1 MAP1; + // declare a map MAP1 map; + // add an attribute on vertex of map with MAP1::VertexAttributeHandler ah = map.addAttribute("floats"); + // get ChunkArrayContainer -> get ChunkArray -> fill ChunkArrayContainer& container = map.getAttributeContainer(VERTEX2); ChunkArray* att = container.getAttribute("floats"); for (int i=0;i<10;++i) @@ -27,9 +31,17 @@ int test1() for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) (*att)[i] = 3.0f + 0.1f*float(i); + // access with index + std::cout << ah[0] << std::endl; + + // traverse container with for range for (float f:ah) std::cout << f << std::endl; + // equivalent to + for (MAP1::VertexAttributeHandler::iterator it = ah.begin(); it != ah.end(); ++it) + std::cout << *it << std::endl; + return 0; } From 1355849ca69613374ec2ba2c9b9939fd80da7936 Mon Sep 17 00:00:00 2001 From: Sylvain Thery Date: Tue, 3 Nov 2015 09:00:42 +0100 Subject: [PATCH 025/185] missing file --- .clang-format | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 .clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 00000000..355f43f8 --- /dev/null +++ b/.clang-format @@ -0,0 +1,67 @@ +--- +Language: Cpp +# BasedOnStyle: Google +AccessModifierOffset: -1 +AlignAfterOpenBracket: true +AlignConsecutiveAssignments: false +AlignEscapedNewlinesLeft: true +AlignOperands: true +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: All +AllowShortIfStatementsOnASingleLine: true +AllowShortLoopsOnASingleLine: true +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakBeforeMultilineStrings: true +AlwaysBreakTemplateDeclarations: true +BinPackArguments: true +BinPackParameters: true +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Attach +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +ColumnLimit: 80 +CommentPragmas: '^ IWYU pragma:' +ConstructorInitializerAllOnOneLineOrOnePerLine: true +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: true +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] +IndentCaseLabels: true +IndentWidth: 2 +IndentWrappedFunctionNames: false +KeepEmptyLinesAtTheStartOfBlocks: false +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBlockIndentWidth: 2 +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: false +PenaltyBreakBeforeFirstCallParameter: 1 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 200 +PointerAlignment: Left +SpaceAfterCStyleCast: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 2 +SpacesInAngles: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Auto +TabWidth: 8 +UseTab: Never +... + From f4892eb99214c14085a8dd5a2f02bedc5f0b5c88 Mon Sep 17 00:00:00 2001 From: Sylvain Thery Date: Tue, 3 Nov 2015 13:14:53 +0100 Subject: [PATCH 026/185] minor modifs --- cgogn/core/basic/cell.h | 8 ++++---- cgogn/core/container/chunk_array.h | 2 ++ cgogn/core/map/map1.h | 1 + cgogn/core/map/map_base_data.h | 4 ++-- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/cgogn/core/basic/cell.h b/cgogn/core/basic/cell.h index 6e70f353..f225a6d3 100644 --- a/cgogn/core/basic/cell.h +++ b/cgogn/core/basic/cell.h @@ -31,7 +31,7 @@ namespace cgogn { const unsigned int NB_ORBITS = 8; -const unsigned int DART = 0; +const unsigned int VERTEX1 = 0; const unsigned int VERTEX2 = 1; const unsigned int EDGE2 = 2; const unsigned int FACE2 = 3; @@ -45,8 +45,8 @@ inline std::string orbitName(unsigned int orbit) { switch(orbit) { - case DART: - return "DART"; + case VERTEX1: + return "VERTEX1"; break; case VERTEX2: return "VERTEX2"; @@ -92,7 +92,7 @@ class Cell Dart dart; /// empty construtor - Cell(): dart() {} + inline Cell(): dart() {} /// constructor from Dart inline Cell(Dart d): dart(d) {} diff --git a/cgogn/core/container/chunk_array.h b/cgogn/core/container/chunk_array.h index b7fddfd5..280858ae 100644 --- a/cgogn/core/container/chunk_array.h +++ b/cgogn/core/container/chunk_array.h @@ -157,6 +157,8 @@ class ChunkArray : public ChunkArrayGen */ const T& operator[](unsigned int i) const { + //TODO le faire partout !!!! + assert(i/CHUNKSIZE < tableData_.size()); return tableData_[i / CHUNKSIZE][i % CHUNKSIZE]; } diff --git a/cgogn/core/map/map1.h b/cgogn/core/map/map1.h index 3892aa3b..62e54bc5 100644 --- a/cgogn/core/map/map1.h +++ b/cgogn/core/map/map1.h @@ -55,6 +55,7 @@ class Map1: public MapBase template using FaceAttributeHandler = AttributeHandler; + //TODO remonter dans map_base template using AttributeHandler = AttributeHandler; diff --git a/cgogn/core/map/map_base_data.h b/cgogn/core/map/map_base_data.h index a065a696..f3cba132 100644 --- a/cgogn/core/map/map_base_data.h +++ b/cgogn/core/map/map_base_data.h @@ -55,7 +55,7 @@ class MapBaseData: public MapGen ChunkArrayContainer attributes_[NB_ORBITS]; /// embedding indices shortcuts - ChunkArray embeddings_[NB_ORBITS]; + ChunkArray* embeddings_[NB_ORBITS]; /// boundary markers shortcuts ChunkArray* boundaryMarkers_[2]; @@ -78,7 +78,7 @@ class MapBaseData: public MapGen inline unsigned int getEmbedding(Cell c) const { // assert(this->template isOrbitEmbedded() || !"Invalid parameter: orbit not embedded"); - return (*this->embeddings_[ORBIT])[this->dartIndex(c.dart)] ; + return (*this->embeddings_[ORBIT])[c.dart.index] ; } }; From 19fdb4bdcebc8ae827f642bce0a9203a309c2ccb Mon Sep 17 00:00:00 2001 From: Etienne Schmitt Date: Tue, 3 Nov 2015 14:23:28 +0100 Subject: [PATCH 027/185] using IGG style. Signed-off-by: Etienne Schmitt --- cgogn/core/basic/nameTypes.h | 4 +- cgogn/core/container/chunk_array.h | 850 +++++++++---------- cgogn/core/container/chunk_array_container.h | 100 +-- cgogn/core/container/chunk_array_gen.h | 2 +- cgogn/core/container/chunk_heap.h | 30 +- 5 files changed, 493 insertions(+), 493 deletions(-) diff --git a/cgogn/core/basic/nameTypes.h b/cgogn/core/basic/nameTypes.h index 953ffce6..517c8a9b 100644 --- a/cgogn/core/basic/nameTypes.h +++ b/cgogn/core/basic/nameTypes.h @@ -34,9 +34,9 @@ namespace cgogn * @brief function that give a name to a type. */ template -std::string nameOfType(const T& v) +std::string nameOfType(const T& /*v*/) { - return v.CGoGNnameOfType(); + return T::CGoGNnameOfType(); } template <> inline std::string nameOfType(const bool& /*v*/) { return "bool"; } diff --git a/cgogn/core/container/chunk_array.h b/cgogn/core/container/chunk_array.h index 6ae63f4f..930bc261 100644 --- a/cgogn/core/container/chunk_array.h +++ b/cgogn/core/container/chunk_array.h @@ -43,233 +43,233 @@ class ChunkArray : public ChunkArrayGen { protected: - /// vector of block pointers - std::vector tableData_; + /// vector of block pointers + std::vector tableData_; public: - /** - * @brief Constructor of ChunkArray - */ - inline ChunkArray() : ChunkArrayGen() - { - tableData_.reserve(1024u); - } - - /** - * @brief Destructor of ChunkArray - */ - ~ChunkArray() override - { - for(auto chunk: tableData_) - delete[] chunk; - } - - /** - * @brief create a ChunkArray - * @return generic pointer - */ - ChunkArrayGen* clone() const override - { - return new ChunkArray(); - } - - /** - * @brief add a chunk (T[CHUNKSIZE]) - */ - void addChunk() override - { - tableData_.emplace_back(new T[CHUNKSIZE]()); - } - - - /** - * @brief set number of chunks - * @param nbc number of chunks - */ - void setNbChunks(unsigned int nbc) override - { - if (nbc >= tableData_.size()) - { - for (std::size_t i= tableData_.size(); i (tableData_.size()); - } - - /** - * @brief number of allocated elements - * @return allocated lines - */ - unsigned int capacity() const override - { - return static_cast(tableData_.size())*CHUNKSIZE; - } - - - /** - * @brief clear - */ - void clear() override - { - for(auto chunk: tableData_) - delete[] chunk; - tableData_.clear(); - } - - /** - * @brief ref operator [] - * @param i index of element to access - * @return ref of element - */ - inline T& operator[](unsigned int i) - { - return tableData_[i / CHUNKSIZE][i % CHUNKSIZE]; - } - - /** - * @brief const ref operator [] - * @param i index of element to access - * @return const ref of element - */ - inline const T& operator[](unsigned int i) const - { - return tableData_[i / CHUNKSIZE][i % CHUNKSIZE]; - } - - /** - * @brief set the value of an element (work also with bool - * @param i index of element to set - * @param v value - */ - inline void setVal(unsigned int i, const T& v) - { - tableData_[i / CHUNKSIZE][i % CHUNKSIZE] = v; - } - - - /** - * @brief get pointer on all chunks data - * @param addr vector to fill - * @param byteBlockSize filled with CHUNKSIZE*sizeof(T) - * @return addr.size() - */ - unsigned int getChunksPointers(std::vector& addr, unsigned int& byteBlockSize) const override - { - byteBlockSize = CHUNKSIZE * sizeof(T); - - addr.reserve(tableData_.size()); - addr.clear(); - - for (typename std::vector::const_iterator it = tableData_.begin(); it != tableData_.end(); ++it) - addr.push_back(*it); - - return (unsigned int)(addr.size()); - } - - /** - * @brief init an element (overwrite with T()) - * @param id index of element - */ - void initElt(unsigned int id) override - { - tableData_[id / CHUNKSIZE][id % CHUNKSIZE] = T(); - } - - - /** - * @brief copy element - * @param dst destination - * @param src source - */ - void copyElt(unsigned int dst, unsigned int src) override - { - tableData_[dst / CHUNKSIZE][dst % CHUNKSIZE] = tableData_[src / CHUNKSIZE][src % CHUNKSIZE]; - } - - /** - * @brief swap two elements - * @param id1 idx first - * @param id2 idx second - */ - void swapElt(unsigned int id1, unsigned int id2) override - { - std::swap(tableData_[id1 / CHUNKSIZE][id1 % CHUNKSIZE], tableData_[id2 / CHUNKSIZE][id2 % CHUNKSIZE] ); - } - - - void save(std::ostream& fs, unsigned int nbLines) const override - { - unsigned int nbs[3]; - nbs[0] = (unsigned int)(tableData_.size()); - nbs[1] = nbLines; - nbs[2] = CHUNKSIZE*sizeof(T); - - assert(nbLines/CHUNKSIZE <= tableData_.size()); - // TODO: if (nbLines==0) nbLines=CHUNKSIZE*tableData_.size(); ?? - - fs.write(reinterpret_cast(nbs),3*sizeof(unsigned int)); - - // no data -> finished - if (nbs[0] == 0) - return; - - unsigned int nbca = nbs[0]-1; - // save data chunks except last - for(unsigned int i=0; i(tableData_[i]),CHUNKSIZE*sizeof(T)); - } - - // save last - unsigned nbl = nbLines - nbca*CHUNKSIZE; - fs.write(reinterpret_cast(tableData_[nbca]),nbl*sizeof(T)); - } - - - bool load(std::istream& fs) override - { - unsigned int nbs[3]; - fs.read(reinterpret_cast(nbs), 3*sizeof(unsigned int)); - - if (nbs[2] != CHUNKSIZE*sizeof(T)) - { - std::cerr << "Error loading ChunkArray wrong CHUNKSIZE"<< std::endl; - return false; - } - - this->setNbChunks(nbs[0]); - - // no data -> finished - if (nbs[0] == 0) - return true; - - // load data chunks except last - unsigned int nbca = nbs[0]-1; - for(unsigned int i = 0; i < nbca; ++i) - fs.read(reinterpret_cast(tableData_[i]),CHUNKSIZE*sizeof(T)); - - // load last chunk - unsigned int nbl = nbs[1] - CHUNKSIZE*nbca; - fs.read(reinterpret_cast(tableData_[nbca]),nbl*sizeof(T)); - - return true; - } + /** + * @brief Constructor of ChunkArray + */ + inline ChunkArray() : ChunkArrayGen() + { + tableData_.reserve(1024u); + } + + /** + * @brief Destructor of ChunkArray + */ + ~ChunkArray() override + { + for(auto chunk: tableData_) + delete[] chunk; + } + + /** + * @brief create a ChunkArray + * @return generic pointer + */ + ChunkArrayGen* clone() const override + { + return new ChunkArray(); + } + + /** + * @brief add a chunk (T[CHUNKSIZE]) + */ + void addChunk() override + { + tableData_.emplace_back(new T[CHUNKSIZE]()); + } + + + /** + * @brief set number of chunks + * @param nbc number of chunks + */ + void setNbChunks(unsigned int nbc) override + { + if (nbc >= tableData_.size()) + { + for (std::size_t i= tableData_.size(); i (tableData_.size()); + } + + /** + * @brief number of allocated elements + * @return allocated lines + */ + unsigned int capacity() const override + { + return static_cast(tableData_.size())*CHUNKSIZE; + } + + + /** + * @brief clear + */ + void clear() override + { + for(auto chunk: tableData_) + delete[] chunk; + tableData_.clear(); + } + + /** + * @brief ref operator [] + * @param i index of element to access + * @return ref of element + */ + inline T& operator[](unsigned int i) + { + return tableData_[i / CHUNKSIZE][i % CHUNKSIZE]; + } + + /** + * @brief const ref operator [] + * @param i index of element to access + * @return const ref of element + */ + inline const T& operator[](unsigned int i) const + { + return tableData_[i / CHUNKSIZE][i % CHUNKSIZE]; + } + + /** + * @brief set the value of an element (work also with bool + * @param i index of element to set + * @param v value + */ + inline void setVal(unsigned int i, const T& v) + { + tableData_[i / CHUNKSIZE][i % CHUNKSIZE] = v; + } + + + /** + * @brief get pointer on all chunks data + * @param addr vector to fill + * @param byteBlockSize filled with CHUNKSIZE*sizeof(T) + * @return addr.size() + */ + unsigned int getChunksPointers(std::vector& addr, unsigned int& byteBlockSize) const override + { + byteBlockSize = CHUNKSIZE * sizeof(T); + + addr.reserve(tableData_.size()); + addr.clear(); + + for (typename std::vector::const_iterator it = tableData_.begin(); it != tableData_.end(); ++it) + addr.push_back(*it); + + return (unsigned int)(addr.size()); + } + + /** + * @brief init an element (overwrite with T()) + * @param id index of element + */ + void initElt(unsigned int id) override + { + tableData_[id / CHUNKSIZE][id % CHUNKSIZE] = T(); + } + + + /** + * @brief copy element + * @param dst destination + * @param src source + */ + void copyElt(unsigned int dst, unsigned int src) override + { + tableData_[dst / CHUNKSIZE][dst % CHUNKSIZE] = tableData_[src / CHUNKSIZE][src % CHUNKSIZE]; + } + + /** + * @brief swap two elements + * @param id1 idx first + * @param id2 idx second + */ + void swapElt(unsigned int id1, unsigned int id2) override + { + std::swap(tableData_[id1 / CHUNKSIZE][id1 % CHUNKSIZE], tableData_[id2 / CHUNKSIZE][id2 % CHUNKSIZE] ); + } + + + void save(std::ostream& fs, unsigned int nbLines) const override + { + unsigned int nbs[3]; + nbs[0] = (unsigned int)(tableData_.size()); + nbs[1] = nbLines; + nbs[2] = CHUNKSIZE*sizeof(T); + + assert(nbLines/CHUNKSIZE <= tableData_.size()); + // TODO: if (nbLines==0) nbLines=CHUNKSIZE*tableData_.size(); ?? + + fs.write(reinterpret_cast(nbs),3*sizeof(unsigned int)); + + // no data -> finished + if (nbs[0] == 0) + return; + + unsigned int nbca = nbs[0]-1; + // save data chunks except last + for(unsigned int i=0; i(tableData_[i]),CHUNKSIZE*sizeof(T)); + } + + // save last + unsigned nbl = nbLines - nbca*CHUNKSIZE; + fs.write(reinterpret_cast(tableData_[nbca]),nbl*sizeof(T)); + } + + + bool load(std::istream& fs) override + { + unsigned int nbs[3]; + fs.read(reinterpret_cast(nbs), 3*sizeof(unsigned int)); + + if (nbs[2] != CHUNKSIZE*sizeof(T)) + { + std::cerr << "Error loading ChunkArray wrong CHUNKSIZE"<< std::endl; + return false; + } + + this->setNbChunks(nbs[0]); + + // no data -> finished + if (nbs[0] == 0) + return true; + + // load data chunks except last + unsigned int nbca = nbs[0]-1; + for(unsigned int i = 0; i < nbca; ++i) + fs.read(reinterpret_cast(tableData_[i]),CHUNKSIZE*sizeof(T)); + + // load last chunk + unsigned int nbl = nbs[1] - CHUNKSIZE*nbca; + fs.read(reinterpret_cast(tableData_[nbca]),nbl*sizeof(T)); + + return true; + } }; @@ -285,234 +285,234 @@ class ChunkArray : public ChunkArrayGen { protected: - /// vector of block pointers - std::vector tableData_; + /// vector of block pointers + std::vector tableData_; public: - ChunkArray() : ChunkArrayGen() - { - tableData_.reserve(1024u); - } - - - ~ChunkArray() override - { - for(auto chunk: tableData_) - delete[] chunk; - } - - - ChunkArrayGen* clone() const override - { - return new ChunkArray(); - } - - - void addChunk() override - { - // adding the empty parentheses for default-initialization - tableData_.push_back(new unsigned int[CHUNKSIZE/32u]()); - } - - - - void setNbChunks(unsigned int nbc) override - { - if (nbc >= tableData_.size()) - { - for (std::size_t i= tableData_.size(); i () + { + tableData_.reserve(1024u); + } + + + ~ChunkArray() override + { + for(auto chunk: tableData_) + delete[] chunk; + } + + + ChunkArrayGen* clone() const override + { + return new ChunkArray(); + } + + + void addChunk() override + { + // adding the empty parentheses for default-initialization + tableData_.push_back(new unsigned int[CHUNKSIZE/32u]()); + } + + + + void setNbChunks(unsigned int nbc) override + { + if (nbc >= tableData_.size()) + { + for (std::size_t i= tableData_.size(); i (tableData_.size()); - } - - - unsigned int capacity() const override - { - return static_cast(tableData_.size())*CHUNKSIZE/32u; - } + unsigned int getNbChunks() const override + { + return static_cast(tableData_.size()); + } + + + unsigned int capacity() const override + { + return static_cast(tableData_.size())*CHUNKSIZE/32u; + } - void clear() override - { - for(auto chunk: tableData_) - delete[] chunk; - tableData_.clear(); - } + void clear() override + { + for(auto chunk: tableData_) + delete[] chunk; + tableData_.clear(); + } - void setFalse(unsigned int i) - { - const unsigned int jj = i / CHUNKSIZE; - const unsigned int j = i % CHUNKSIZE; - const unsigned int x = j/32u; - const unsigned int y = j%32u; - const unsigned int mask = 1u << y; - tableData_[jj][x] &= ~mask; - } + void setFalse(unsigned int i) + { + const unsigned int jj = i / CHUNKSIZE; + const unsigned int j = i % CHUNKSIZE; + const unsigned int x = j/32u; + const unsigned int y = j%32u; + const unsigned int mask = 1u << y; + tableData_[jj][x] &= ~mask; + } - void setTrue(unsigned int i) - { - const unsigned int jj = i / CHUNKSIZE; - const unsigned int j = i % CHUNKSIZE; - const unsigned int x = j/32u; - const unsigned int y = j%32u; - const unsigned int mask = 1u << y; - tableData_[jj][x] |= mask; - } + void setTrue(unsigned int i) + { + const unsigned int jj = i / CHUNKSIZE; + const unsigned int j = i % CHUNKSIZE; + const unsigned int x = j/32u; + const unsigned int y = j%32u; + const unsigned int mask = 1u << y; + tableData_[jj][x] |= mask; + } - void setVal(unsigned int i, bool b) - { - const unsigned int jj = i / CHUNKSIZE; - const unsigned int j = i % CHUNKSIZE; - const unsigned int x = j/32; - const unsigned int y = j%32; - const unsigned int mask = 1u << y; - - if (b) - tableData_[jj][x] |= mask; - else - tableData_[jj][x] &= ~mask; - } + void setVal(unsigned int i, bool b) + { + const unsigned int jj = i / CHUNKSIZE; + const unsigned int j = i % CHUNKSIZE; + const unsigned int x = j/32; + const unsigned int y = j%32; + const unsigned int mask = 1u << y; + + if (b) + tableData_[jj][x] |= mask; + else + tableData_[jj][x] &= ~mask; + } - /** - * @brief special optimized version of setFalse when goal is to set all to false; - * @param i index of element to set to false - * - * This version overwrite element AND SOME OF THIS NEIGHBOURS with 0 - * Use only if final goal is to set all array to 0 (MarkerStore) - * @todo find another name for the method! - */ - void setFalseDirty(unsigned int i) - { - const unsigned int jj = i / CHUNKSIZE; - const unsigned int j = (i % CHUNKSIZE)/32u; - tableData_[jj][j] = 0u; - } + /** + * @brief special optimized version of setFalse when goal is to set all to false; + * @param i index of element to set to false + * + * This version overwrite element AND SOME OF THIS NEIGHBOURS with 0 + * Use only if final goal is to set all array to 0 (MarkerStore) + * @todo find another name for the method! + */ + void setFalseDirty(unsigned int i) + { + const unsigned int jj = i / CHUNKSIZE; + const unsigned int j = (i % CHUNKSIZE)/32u; + tableData_[jj][j] = 0u; + } - bool operator[](unsigned int i) const - { - const unsigned int jj = i / CHUNKSIZE; - const unsigned int j = i % CHUNKSIZE; - const unsigned int x = j/32u; - const unsigned int y = j%32u; - - const unsigned int mask = 1u << y; - - return (tableData_[jj][x] & mask) != 0u; - } - - - - unsigned int getChunksPointers(std::vector& addr, unsigned int& byteBlockSize) const - { - byteBlockSize = CHUNKSIZE / 8u; - - addr.reserve(tableData_.size()); - addr.clear(); - - for (typename std::vector::const_iterator it = tableData_.begin(); it != tableData_.end(); ++it) - addr.push_back(*it); - - return static_cast(addr.size()); - } - - - void initElt(unsigned int id) override - { - setFalse(id); - } - - - void copyElt(unsigned int dst, unsigned int src) override - { - setVal(dst,this->operator [](src)); - } - - - void swapElt(unsigned int id1, unsigned int id2) override - { - bool data = this->operator [](id1); - setVal(id1,this->operator [](id2)); - setVal(id2,data); - } - - - void save(std::ostream& fs, unsigned int nbLines) const override - { - // round nbLines to 32 multiple - if (nbLines%32u) - nbLines = ((nbLines/32u)+1u)*32u; - - unsigned int nbs[3]; - nbs[0] = static_cast(tableData_.size()); - nbs[1] = nbLines; - nbs[2] = CHUNKSIZE/8; + bool operator[](unsigned int i) const + { + const unsigned int jj = i / CHUNKSIZE; + const unsigned int j = i % CHUNKSIZE; + const unsigned int x = j/32u; + const unsigned int y = j%32u; + + const unsigned int mask = 1u << y; + + return (tableData_[jj][x] & mask) != 0u; + } + + + + unsigned int getChunksPointers(std::vector& addr, unsigned int& byteBlockSize) const + { + byteBlockSize = CHUNKSIZE / 8u; + + addr.reserve(tableData_.size()); + addr.clear(); + + for (typename std::vector::const_iterator it = tableData_.begin(); it != tableData_.end(); ++it) + addr.push_back(*it); + + return static_cast(addr.size()); + } + + + void initElt(unsigned int id) override + { + setFalse(id); + } + + + void copyElt(unsigned int dst, unsigned int src) override + { + setVal(dst,this->operator [](src)); + } + + + void swapElt(unsigned int id1, unsigned int id2) override + { + bool data = this->operator [](id1); + setVal(id1,this->operator [](id2)); + setVal(id2,data); + } + + + void save(std::ostream& fs, unsigned int nbLines) const override + { + // round nbLines to 32 multiple + if (nbLines%32u) + nbLines = ((nbLines/32u)+1u)*32u; + + unsigned int nbs[3]; + nbs[0] = static_cast(tableData_.size()); + nbs[1] = nbLines; + nbs[2] = CHUNKSIZE/8; - assert(nbLines/CHUNKSIZE <= tableData_.size()); - // TODO: if (nbLines==0) nbLines=CHUNKSIZE*tableData_.size(); ?? - - fs.write(reinterpret_cast(nbs),3*sizeof(unsigned int)); + assert(nbLines/CHUNKSIZE <= tableData_.size()); + // TODO: if (nbLines==0) nbLines=CHUNKSIZE*tableData_.size(); ?? + + fs.write(reinterpret_cast(nbs),3*sizeof(unsigned int)); - // no data -> finished - if (nbs[0] == 0u) - return; + // no data -> finished + if (nbs[0] == 0u) + return; - unsigned int nbca = nbs[0]-1u; - // save data chunks except last - for(unsigned int i=0u; i(tableData_[i]),CHUNKSIZE/8u);// /8 because bool = 1 bit & octet = 8 bit - } + unsigned int nbca = nbs[0]-1u; + // save data chunks except last + for(unsigned int i=0u; i(tableData_[i]),CHUNKSIZE/8u);// /8 because bool = 1 bit & octet = 8 bit + } - // save last - unsigned int nbl = nbLines - nbca*CHUNKSIZE/8u; - fs.write(reinterpret_cast(tableData_[nbca]),nbl/8u); - } + // save last + unsigned int nbl = nbLines - nbca*CHUNKSIZE/8u; + fs.write(reinterpret_cast(tableData_[nbca]),nbl/8u); + } - bool load(std::istream& fs) override - { - unsigned int nbs[3]; - fs.read(reinterpret_cast(nbs), 3u*sizeof(unsigned int)); + bool load(std::istream& fs) override + { + unsigned int nbs[3]; + fs.read(reinterpret_cast(nbs), 3u*sizeof(unsigned int)); - if (nbs[2] != CHUNKSIZE/8u) - { - std::cerr << "Error loading ChunkArray wrong CHUNKSIZE"<< std::endl; - return false; - } + if (nbs[2] != CHUNKSIZE/8u) + { + std::cerr << "Error loading ChunkArray wrong CHUNKSIZE"<< std::endl; + return false; + } - this->setNbChunks(nbs[0]); + this->setNbChunks(nbs[0]); - // no data -> finished - if (nbs[0] == 0u) - return true; + // no data -> finished + if (nbs[0] == 0u) + return true; - // load data chunks except last - unsigned int nbca = nbs[0]-1u; - for(unsigned int i = 0u; i < nbca; ++i) - fs.read(reinterpret_cast(tableData_[i]),CHUNKSIZE/8u);// /8 because bool = 1 bit & octet = 8 bit + // load data chunks except last + unsigned int nbca = nbs[0]-1u; + for(unsigned int i = 0u; i < nbca; ++i) + fs.read(reinterpret_cast(tableData_[i]),CHUNKSIZE/8u);// /8 because bool = 1 bit & octet = 8 bit - // load last chunk - unsigned int nbl = nbs[1] - nbca*CHUNKSIZE/8u; - fs.read(reinterpret_cast(tableData_[nbca]),nbl/8u); + // load last chunk + unsigned int nbl = nbs[1] - nbca*CHUNKSIZE/8u; + fs.read(reinterpret_cast(tableData_[nbca]),nbl/8u); - return true; - } + return true; + } }; diff --git a/cgogn/core/container/chunk_array_container.h b/cgogn/core/container/chunk_array_container.h index 8ca38b28..194855e3 100644 --- a/cgogn/core/container/chunk_array_container.h +++ b/cgogn/core/container/chunk_array_container.h @@ -49,7 +49,7 @@ class ContainerBrowser virtual void nextPrimitive(unsigned int &it) const = 0; virtual void enable() = 0; virtual void disable() = 0; - virtual ~ContainerBrowser() {} + virtual ~ContainerBrowser() {} }; @@ -126,7 +126,7 @@ class ChunkArrayContainer */ unsigned int getArrayIndex(const ChunkArrayGen* ptr) const { - for (unsigned int i=0u; i != tableArrays_.size(); ++i) + for (unsigned int i=0u; i != tableArrays_.size(); ++i) { if (tableArrays_[i] == ptr) return i; @@ -145,7 +145,7 @@ class ChunkArrayContainer { delete tableArrays_[index] ; - if (index != tableArrays_.size()- std::size_t(1u)) + if (index != tableArrays_.size()- std::size_t(1u)) { tableArrays_[index] = tableArrays_.back(); names_[index] = names_.back(); @@ -166,9 +166,9 @@ class ChunkArrayContainer * @brief ChunkArrayContainer constructor */ ChunkArrayContainer(): - nbUsedLines_(0u), - nbMaxLines_(0u), - currentBrowser_(nullptr) + nbUsedLines_(0u), + nbMaxLines_(0u), + currentBrowser_(nullptr) { } @@ -192,7 +192,7 @@ class ChunkArrayContainer if (index == UNKNOWN) { std::cerr << "attribute " << attribName << " not found." << std::endl ; - return nullptr ; + return nullptr ; } return static_cast*>(tableArrays_[index]); @@ -216,7 +216,7 @@ class ChunkArrayContainer if (index != UNKNOWN) { std::cerr << "attribute " << attribName << " already found.." << std::endl ; - return nullptr ; + return nullptr ; } // create the new attribute @@ -321,7 +321,7 @@ class ChunkArrayContainer */ unsigned int begin() const { - if (currentBrowser_ != nullptr) + if (currentBrowser_ != nullptr) return currentBrowser_->begin(); return realBegin(); } @@ -333,7 +333,7 @@ class ChunkArrayContainer */ unsigned int end() const { - if (currentBrowser_ != nullptr) + if (currentBrowser_ != nullptr) return currentBrowser_->end(); return realEnd(); } @@ -344,7 +344,7 @@ class ChunkArrayContainer */ void next(unsigned int &it) const { - if (currentBrowser_ != nullptr) + if (currentBrowser_ != nullptr) currentBrowser_->next(it); else realNext(it); @@ -357,7 +357,7 @@ class ChunkArrayContainer */ void nextPrimitive(unsigned int &it) const { - if (currentBrowser_ != nullptr) + if (currentBrowser_ != nullptr) currentBrowser_->nextPrimitive(it); else realNextPrimitive(it); @@ -370,7 +370,7 @@ class ChunkArrayContainer */ unsigned int realBegin() const { - unsigned int it = 0u; + unsigned int it = 0u; while ((it < nbMaxLines_) && (!used(it))) ++it; return it; @@ -417,7 +417,7 @@ class ChunkArrayContainer */ unsigned int realRBegin() const { - unsigned int it = nbMaxLines_-1u; + unsigned int it = nbMaxLines_-1u; while ((it != 0xffffffff) && (!used(it))) --it; return it; @@ -455,8 +455,8 @@ class ChunkArrayContainer */ void clear(bool removeAttrib = false) { - nbUsedLines_ = 0u; - nbMaxLines_ = 0u; + nbUsedLines_ = 0u; + nbMaxLines_ = 0u; // clear CA of refs refs_.clear(); @@ -466,7 +466,7 @@ class ChunkArrayContainer //clear data for (auto arr: tableArrays_) - arr->clear(); + arr->clear(); // remove CA ? if (removeAttrib) @@ -496,15 +496,15 @@ class ChunkArrayContainer mapOldNew.resize(realEnd(),0xffffffff); unsigned int up = realRBegin(); - unsigned int down = 0u; + unsigned int down = 0u; while (down < up) { if (!used(down)) { - for(unsigned int i=0u; isetNbChunks(newNbBlocks); + arr->setNbChunks(newNbBlocks); refs_.setNbChunks(newNbBlocks); // clear holes @@ -549,7 +549,7 @@ class ChunkArrayContainer if (nbMaxLines_%CHUNKSIZE <= PRIMSIZE) // prim on next block ? -> add block to C.A. { for (auto arr: tableArrays_) - arr->addChunk(); + arr->addChunk(); refs_.addChunk(); } } @@ -560,8 +560,8 @@ class ChunkArrayContainer } // mark lines as used - for(unsigned int i=0u; iinitElt(index); } @@ -608,7 +608,7 @@ class ChunkArrayContainer void copyLine(unsigned int dstIndex, unsigned int srcIndex) { for (auto ptrAtt: tableArrays_) - if (ptrAtt != nullptr) + if (ptrAtt != nullptr) ptrAtt->copyElt(dstIndex, srcIndex); refs_[dstIndex] = refs_[srcIndex]; } @@ -619,7 +619,7 @@ class ChunkArrayContainer */ void refLine(unsigned int index) { - static_assert(PRIMSIZE == 1u, "refLine with container where PRIMSIZE!=1"); + static_assert(PRIMSIZE == 1u, "refLine with container where PRIMSIZE!=1"); refs_[index]++; } @@ -631,12 +631,12 @@ class ChunkArrayContainer */ bool unrefLine(unsigned int index) { - static_assert(PRIMSIZE == 1u, "unrefLine with container where PRIMSIZE!=1"); + static_assert(PRIMSIZE == 1u, "unrefLine with container where PRIMSIZE!=1"); refs_[index]--; - if (refs_[index] == 1u) + if (refs_[index] == 1u) { holesHeap_.push(index); - refs_[index] = 0u; // same as removeLine without the "if" + refs_[index] = 0u; // same as removeLine without the "if" --nbUsedLines_; return true; } @@ -650,7 +650,7 @@ class ChunkArrayContainer */ T_REF getNbRefs(unsigned int index) const { - static_assert(PRIMSIZE == 1u, "getNbRefs with container where PRIMSIZE!=1"); + static_assert(PRIMSIZE == 1u, "getNbRefs with container where PRIMSIZE!=1"); return refs_[index]; } @@ -665,10 +665,10 @@ class ChunkArrayContainer { unsigned int index = getArrayIndex(attribName) ; if(index == UNKNOWN) - return nullptr ; + return nullptr ; ChunkArray* atm = dynamic_cast*>(tableArrays_[index]); - assert((atm != nullptr) || !"getDataVector: wrong type"); + assert((atm != nullptr) || !"getDataVector: wrong type"); return atm; } @@ -682,7 +682,7 @@ class ChunkArrayContainer { unsigned int index = getArrayIndex(attribName) ; if(index == UNKNOWN) - return nullptr ; + return nullptr ; return tableArrays_[index]; } @@ -695,10 +695,10 @@ class ChunkArrayContainer buffer.push_back((unsigned int)(tableArrays_.size())); buffer.push_back(nbUsedLines_); buffer.push_back(nbMaxLines_); - for(unsigned int i=0u; i(names_[i].size()+1)); - buffer.push_back(static_cast(typeNames_[i].size()+1)); + buffer.push_back(static_cast(names_[i].size()+1)); + buffer.push_back(static_cast(typeNames_[i].size()+1)); } fs.write(reinterpret_cast(&(buffer[0])),std::streamsize(buffer.size()*sizeof(unsigned int))); @@ -707,12 +707,12 @@ class ChunkArrayContainer { const char* s1 = names_[i].c_str(); const char* s2 = typeNames_[i].c_str(); - fs.write(s1,std::streamsize((names_[i].size()+1u)*sizeof(char))); - fs.write(s2,std::streamsize((typeNames_[i].size()+1u)*sizeof(char))); + fs.write(s1,std::streamsize((names_[i].size()+1u)*sizeof(char))); + fs.write(s2,std::streamsize((typeNames_[i].size()+1u)*sizeof(char))); } // save chunk arrays - for(unsigned int i=0u; isave(fs,nbMaxLines_); } @@ -728,32 +728,32 @@ class ChunkArrayContainer { // read info unsigned int buff1[3]; - fs.read(reinterpret_cast(buff1),3u*sizeof(unsigned int)); + fs.read(reinterpret_cast(buff1),3u*sizeof(unsigned int)); nbUsedLines_ = buff1[1]; nbMaxLines_ = buff1[2]; - std::vector buff2(2u*buff1[0]); - fs.read(reinterpret_cast(&(buff2[0])),std::streamsize(2u*buff1[0]*sizeof(unsigned int))); + std::vector buff2(2u*buff1[0]); + fs.read(reinterpret_cast(&(buff2[0])),std::streamsize(2u*buff1[0]*sizeof(unsigned int))); names_.resize(buff1[0]); typeNames_.resize(buff1[0]); // read name char buff3[256]; - for(unsigned int i=0u; i::create(typeNames_[i]); ok &= tableArrays_[i]->load(fs); diff --git a/cgogn/core/container/chunk_array_gen.h b/cgogn/core/container/chunk_array_gen.h index b5d6988e..355bd21f 100644 --- a/cgogn/core/container/chunk_array_gen.h +++ b/cgogn/core/container/chunk_array_gen.h @@ -50,7 +50,7 @@ class ChunkArrayGen * @brief create a ChunkArray object without knowning type * @return generic pointer */ - virtual ChunkArrayGen* clone() const = 0; + virtual ChunkArrayGen* clone() const = 0; /** diff --git a/cgogn/core/container/chunk_heap.h b/cgogn/core/container/chunk_heap.h index 7728062a..0da52bd4 100644 --- a/cgogn/core/container/chunk_heap.h +++ b/cgogn/core/container/chunk_heap.h @@ -45,14 +45,14 @@ class ChunkHeap : public ChunkArray /** * @brief ChunkHeap constructor */ - ChunkHeap() : ChunkArray() - ,heapSize_(0u) + ChunkHeap() : ChunkArray() + ,heapSize_(0u) {} /** * @brief ChunkHeap destructor */ - ~ChunkHeap() override {} + ~ChunkHeap() override {} /** * @brief push a value on top of heap @@ -74,15 +74,15 @@ class ChunkHeap : public ChunkArray * @brief empty * @return true if heap empty */ - inline bool empty() const + inline bool empty() const { - return heapSize_ == 0u; + return heapSize_ == 0u; } /** * @return number of elements in the heap */ - unsigned int size() const + unsigned int size() const { return heapSize_; } @@ -90,9 +90,9 @@ class ChunkHeap : public ChunkArray /** * @brief pop the head of heap */ - inline void pop() + inline void pop() { - assert(heapSize_ > 0u); + assert(heapSize_ > 0u); heapSize_--; } @@ -100,10 +100,10 @@ class ChunkHeap : public ChunkArray * @brief get head of heap * @return copy of head element */ - inline T head() const + inline T head() const { - const unsigned int offset = heapSize_ % CHUNKSIZE; - const unsigned int blkId = heapSize_ / CHUNKSIZE; + const unsigned int offset = heapSize_ % CHUNKSIZE; + const unsigned int blkId = heapSize_ / CHUNKSIZE; return this->tableData_[blkId][offset]; } @@ -111,9 +111,9 @@ class ChunkHeap : public ChunkArray /** * @brief compact the heap (free useless memory) */ - void compact() + void compact() { - const unsigned int keep = (heapSize_+CHUNKSIZE-1u) / CHUNKSIZE; + const unsigned int keep = (heapSize_+CHUNKSIZE-1u) / CHUNKSIZE; while (this->tableData_.size() > keep) { delete[] this->tableData_.back(); @@ -124,9 +124,9 @@ class ChunkHeap : public ChunkArray /** * @brief clear the heap and free memory */ - void clear() override + void clear() override { - heapSize_ = 0u; + heapSize_ = 0u; ChunkArray::clear(); } }; From 6164ba1eb641c33a87142fb26d6c2295421f2af4 Mon Sep 17 00:00:00 2001 From: Sylvain Thery Date: Tue, 3 Nov 2015 15:04:15 +0100 Subject: [PATCH 028/185] const iterator --- cgogn/core/CMakeLists.txt | 2 +- cgogn/core/container/chunk_array.h | 170 ++++++++++++------ cgogn/core/container/chunk_array_container.h | 24 +-- .../container/{chunk_heap.h => chunk_stack.h} | 10 +- cgogn/core/map/attribute_handler.h | 61 +++++-- cgogn/core/map/map1.h | 6 +- cgogn/core/map/map_base.h | 17 +- test/chunk_array/test_chunk_array.cpp | 10 +- test/map/test_map.cpp | 57 ++++-- 9 files changed, 240 insertions(+), 117 deletions(-) rename cgogn/core/container/{chunk_heap.h => chunk_stack.h} (94%) diff --git a/cgogn/core/CMakeLists.txt b/cgogn/core/CMakeLists.txt index 0c65f1ed..e8e209bf 100644 --- a/cgogn/core/CMakeLists.txt +++ b/cgogn/core/CMakeLists.txt @@ -10,7 +10,7 @@ set(HEADER_FILES container/chunk_array_factory.h container/chunk_array_gen.h container/chunk_array.h - container/chunk_heap.h + container/chunk_stack.h map/map_base_data.h map/map_base.h diff --git a/cgogn/core/container/chunk_array.h b/cgogn/core/container/chunk_array.h index 280858ae..098fe6a5 100644 --- a/cgogn/core/container/chunk_array.h +++ b/cgogn/core/container/chunk_array.h @@ -147,6 +147,7 @@ class ChunkArray : public ChunkArrayGen */ T& operator[](unsigned int i) { + assert(i/CHUNKSIZE < tableData_.size()); return tableData_[i / CHUNKSIZE][i % CHUNKSIZE]; } @@ -157,7 +158,6 @@ class ChunkArray : public ChunkArrayGen */ const T& operator[](unsigned int i) const { - //TODO le faire partout !!!! assert(i/CHUNKSIZE < tableData_.size()); return tableData_[i / CHUNKSIZE][i % CHUNKSIZE]; } @@ -169,6 +169,7 @@ class ChunkArray : public ChunkArrayGen */ void setVal(unsigned int i, const T& v) { + assert(i/CHUNKSIZE < tableData_.size()); tableData_[i / CHUNKSIZE][i % CHUNKSIZE] = v; } @@ -225,60 +226,113 @@ class ChunkArray : public ChunkArrayGen } +// void save(std::ostream& fs, unsigned int nbLines) const +// { +// unsigned int nbs[3]; +// nbs[0] = (unsigned int)(tableData_.size()); +// nbs[1] = nbLines; +// nbs[2] = CHUNKSIZE*sizeof(T); + +// assert(nbLines/CHUNKSIZE <= tableData_.size()); +// // TODO: if (nbLines==0) nbLines=CHUNKSIZE*tableData_.size(); ?? + +// fs.write(reinterpret_cast(nbs),3*sizeof(unsigned int)); + +// // no data -> finished +// if (nbs[0] == 0) +// return; + +// unsigned int nbca = nbs[0]-1; +// // save data chunks except last +// for(unsigned int i=0; i(tableData_[i]),CHUNKSIZE*sizeof(T)); +// } + +// // save last +// unsigned nbl = nbLines - nbca*CHUNKSIZE; +// fs.write(reinterpret_cast(tableData_[nbca]),std::streamsize(nbl*sizeof(T))); +// } + + +// bool load(std::istream& fs) +// { +// unsigned int nbs[3]; +// fs.read(reinterpret_cast(nbs), 3*sizeof(unsigned int)); + +// if (nbs[2] != CHUNKSIZE*sizeof(T)) +// { +// std::cerr << "Error loading ChunkArray wrong CHUNKSIZE"<< std::endl; +// return false; +// } + +// this->setNbChunks(nbs[0]); + +// // no data -> finished +// if (nbs[0] == 0) +// return true; + +// // load data chunks except last +// unsigned int nbca = nbs[0]-1; +// for(unsigned int i = 0; i < nbca; ++i) +// fs.read(reinterpret_cast(tableData_[i]),CHUNKSIZE*sizeof(T)); + +// // load last chunk +// unsigned int nbl = nbs[1] - CHUNKSIZE*nbca; +// fs.read(reinterpret_cast(tableData_[nbca]),std::streamsize(nbl*sizeof(T))); + +// return true; +// } + + void save(std::ostream& fs, unsigned int nbLines) const { - unsigned int nbs[3]; - nbs[0] = (unsigned int)(tableData_.size()); - nbs[1] = nbLines; - nbs[2] = CHUNKSIZE*sizeof(T); + assert(nbLines/CHUNKSIZE <= getNbChunks()); - assert(nbLines/CHUNKSIZE <= tableData_.size()); - // TODO: if (nbLines==0) nbLines=CHUNKSIZE*tableData_.size(); ?? - - fs.write(reinterpret_cast(nbs),3*sizeof(unsigned int)); + fs.write(reinterpret_cast(&nbLines),sizeof(unsigned int)); // no data -> finished - if (nbs[0] == 0) + if (nbLines == 0) return; - unsigned int nbca = nbs[0]-1; + unsigned int nbc = getNbChunks() - 1; + // save data chunks except last - for(unsigned int i=0; i(tableData_[i]),CHUNKSIZE*sizeof(T)); } - // save last - unsigned nbl = nbLines - nbca*CHUNKSIZE; - fs.write(reinterpret_cast(tableData_[nbca]),std::streamsize(nbl*sizeof(T))); + // save last incomplete chunk + unsigned nb = nbLines - nbc*CHUNKSIZE; + fs.write(reinterpret_cast(tableData_[nbc]),std::streamsize(nb*sizeof(T))); } bool load(std::istream& fs) { - unsigned int nbs[3]; - fs.read(reinterpret_cast(nbs), 3*sizeof(unsigned int)); - - if (nbs[2] != CHUNKSIZE*sizeof(T)) - { - std::cerr << "Error loading ChunkArray wrong CHUNKSIZE"<< std::endl; - return false; - } - - this->setNbChunks(nbs[0]); + unsigned int nbLines; + fs.read(reinterpret_cast(&nbLines), sizeof(unsigned int)); // no data -> finished - if (nbs[0] == 0) + if (nbLines == 0) return true; + // compute number of chunks + unsigned int nbc = nbLines / CHUNKSIZE; + if (nbLines % CHUNKSIZE != 0) + nbc++; + + this->setNbChunks(nbc); + // load data chunks except last - unsigned int nbca = nbs[0]-1; - for(unsigned int i = 0; i < nbca; ++i) + nbc--; + for(unsigned int i = 0; i < nbc; ++i) fs.read(reinterpret_cast(tableData_[i]),CHUNKSIZE*sizeof(T)); - // load last chunk - unsigned int nbl = nbs[1] - CHUNKSIZE*nbca; - fs.read(reinterpret_cast(tableData_[nbca]),std::streamsize(nbl*sizeof(T))); + // load last incomplete chunk + unsigned int nb = nbLines - nbc*CHUNKSIZE; + fs.read(reinterpret_cast(tableData_[nbc]),std::streamsize(nb*sizeof(T))); return true; } @@ -374,6 +428,7 @@ class ChunkArray : public ChunkArrayGen void setFalse(unsigned int i) { unsigned int jj = i / CHUNKSIZE; + assert(jj < tableData_.size()); unsigned int j = i % CHUNKSIZE; unsigned int x = j/32; unsigned int y = j%32; @@ -384,6 +439,7 @@ class ChunkArray : public ChunkArrayGen void setTrue(unsigned int i) { unsigned int jj = i / CHUNKSIZE; + assert(jj < tableData_.size()); unsigned int j = i % CHUNKSIZE; unsigned int x = j/32; unsigned int y = j%32; @@ -394,6 +450,7 @@ class ChunkArray : public ChunkArrayGen void setVal(unsigned int i, bool b) { unsigned int jj = i / CHUNKSIZE; + assert(jj < tableData_.size()); unsigned int j = i % CHUNKSIZE; unsigned int x = j/32; unsigned int y = j%32; @@ -416,6 +473,7 @@ class ChunkArray : public ChunkArrayGen void setFalseDirty(unsigned int i) { unsigned int jj = i / CHUNKSIZE; + assert(jj < tableData_.size()); unsigned int j = (i % CHUNKSIZE)/32; tableData_[jj][j] = 0; } @@ -425,6 +483,7 @@ class ChunkArray : public ChunkArrayGen bool operator[](unsigned int i) const { unsigned int jj = i / CHUNKSIZE; + assert(jj < tableData_.size()); unsigned int j = i % CHUNKSIZE; unsigned int x = j/32; unsigned int y = j%32; @@ -476,62 +535,59 @@ class ChunkArray : public ChunkArrayGen if (nbLines%32) nbLines = ((nbLines/32)+1)*32; - unsigned int nbs[3]; - nbs[0] = (unsigned int)(tableData_.size()); - nbs[1] = nbLines; - nbs[2] = CHUNKSIZE/8; - assert(nbLines/CHUNKSIZE <= tableData_.size()); // TODO: if (nbLines==0) nbLines=CHUNKSIZE*tableData_.size(); ?? - fs.write(reinterpret_cast(nbs),3*sizeof(unsigned int)); + // save number of lines + fs.write(reinterpret_cast(&nbLines),sizeof(unsigned int)); // no data -> finished - if (nbs[0] == 0) + if (nbLines == 0) return; - unsigned int nbca = nbs[0]-1; + unsigned int nbc = getNbChunks()-1; // save data chunks except last - for(unsigned int i=0; i(tableData_[i]),CHUNKSIZE/8);// /8 because bool = 1 bit & octet = 8 bit } // save last - unsigned int nbl = nbLines - nbca*CHUNKSIZE/8; - fs.write(reinterpret_cast(tableData_[nbca]),nbl/8); + unsigned int nb = nbLines - nbc*CHUNKSIZE; + fs.write(reinterpret_cast(tableData_[nbc]),nb/8); } bool load(std::istream& fs) { - unsigned int nbs[3]; - fs.read(reinterpret_cast(nbs), 3*sizeof(unsigned int)); - - if (nbs[2] != CHUNKSIZE/8) - { - std::cerr << "Error loading ChunkArray wrong CHUNKSIZE"<< std::endl; - return false; - } - - this->setNbChunks(nbs[0]); + // get number of lines to load + unsigned int nbLines; + fs.read(reinterpret_cast(&nbLines), sizeof(unsigned int)); // no data -> finished - if (nbs[0] == 0) + if (nbLines == 0) return true; + // compute number of chunks + unsigned int nbc = nbLines / CHUNKSIZE; + if (nbLines % CHUNKSIZE != 0) + nbc++; + + this->setNbChunks(nbc); + // load data chunks except last - unsigned int nbca = nbs[0]-1; - for(unsigned int i = 0; i < nbca; ++i) + nbc--; + for(unsigned int i = 0; i < nbc; ++i) fs.read(reinterpret_cast(tableData_[i]),CHUNKSIZE/8);// /8 because bool = 1 bit & octet = 8 bit // load last chunk - unsigned int nbl = nbs[1] - nbca*CHUNKSIZE/8; - fs.read(reinterpret_cast(tableData_[nbca]),nbl/8); + unsigned int nb = nbLines - nbc*CHUNKSIZE; + fs.read(reinterpret_cast(tableData_[nbc]),nb/8); return true; } + }; diff --git a/cgogn/core/container/chunk_array_container.h b/cgogn/core/container/chunk_array_container.h index b8d96ddc..59a4a4bf 100644 --- a/cgogn/core/container/chunk_array_container.h +++ b/cgogn/core/container/chunk_array_container.h @@ -26,7 +26,7 @@ #include "core/container/chunk_array.h" -#include "core/container/chunk_heap.h" +#include "core/container/chunk_stack.h" #include "core/basic/nameTypes.h" #include "core/container/chunk_array_factory.h" @@ -96,9 +96,9 @@ class ChunkArrayContainer ChunkArray refs_; /** - * heap of holes + * stack of holes */ - ChunkHeap holesHeap_; + ChunkStack holesStack_; /** * size (number of elts) of the container @@ -512,7 +512,7 @@ class ChunkArrayContainer refs_.clear(); // clear holes - holesHeap_.clear(); + holesStack_.clear(); //clear data for (auto arr: tableArrays_) @@ -575,7 +575,7 @@ class ChunkArrayContainer refs_.setNbChunks(newNbBlocks); // clear holes - holesHeap_.clear(); + holesStack_.clear(); } @@ -593,7 +593,7 @@ class ChunkArrayContainer { unsigned int index; - if (holesHeap_.empty()) // no holes -> insert at the end + if (holesStack_.empty()) // no holes -> insert at the end { index = nbMaxLines_; nbMaxLines_ += PRIMSIZE; @@ -607,8 +607,8 @@ class ChunkArrayContainer } else { - index = holesHeap_.head(); - holesHeap_.pop(); + index = holesStack_.head(); + holesStack_.pop(); } // mark lines as used @@ -630,7 +630,7 @@ class ChunkArrayContainer unsigned int beginPrimIdx = (index/PRIMSIZE) * PRIMSIZE; assert(this->used(beginPrimIdx)|!" Error removing non existing index"); - holesHeap_.push(beginPrimIdx); + holesStack_.push(beginPrimIdx); // mark lines as unused for(unsigned int i=0; i -class ChunkHeap : public ChunkArray +class ChunkStack : public ChunkArray { unsigned int heapSize_; public: /** - * @brief ChunkHeap constructor + * @brief ChunkStack constructor */ - ChunkHeap(): + ChunkStack(): heapSize_(0) {} /** - * @brief ChunkHeap destructor + * @brief ChunkStack destructor */ - ~ChunkHeap() {} + ~ChunkStack() {} /** * @brief push a value on top of heap diff --git a/cgogn/core/map/attribute_handler.h b/cgogn/core/map/attribute_handler.h index 5820ca19..191a71b3 100644 --- a/cgogn/core/map/attribute_handler.h +++ b/cgogn/core/map/attribute_handler.h @@ -199,7 +199,7 @@ class AttributeHandler: public AttributeHandlerOrbit */ T& operator[](unsigned int i) { - assert(this->valid || !"Invalid AttributeHandler") ; + assert(this->valid_ || !"Invalid AttributeHandler") ; return chunk_array_->operator[](i) ; } @@ -210,48 +210,77 @@ class AttributeHandler: public AttributeHandlerOrbit */ const T& operator[](unsigned int i) const { - assert(this->valid || !"Invalid AttributeHandler") ; + assert(this->valid_ || !"Invalid AttributeHandler") ; return chunk_array_->operator[](i) ; } - class iterator + class const_iterator { - AttributeHandler* ah_ptr_; - unsigned int index_; - public: + const AttributeHandler* ah_ptr_; + unsigned int index_; - inline iterator(AttributeHandler* ah, unsigned int i): + inline const_iterator(const AttributeHandler* ah, unsigned int i): ah_ptr_(ah),index_(i){} - inline iterator& operator++() + inline const_iterator& operator++() { ah_ptr_->chunck_array_cont_->next(index_); return *this; } - inline iterator operator++(int) + inline const T& operator*() const { - iterator temp(*this); - ah_ptr_->chunck_array_cont_->next(index_); - return temp; + return ah_ptr_->operator[](index_); } + inline bool operator!=(const_iterator it) const + { + assert(ah_ptr_ == it.ah_ptr_); + return index_ != it.index_; + } + }; + + inline const_iterator begin() const + { + return const_iterator(this,this->chunck_array_cont_->begin()); + } + + inline const_iterator end() const + { + return const_iterator(this,this->chunck_array_cont_->end()); + } + + + class iterator + { + public: + AttributeHandler* ah_ptr_; + unsigned int index_; + + inline iterator(AttributeHandler* ah, unsigned int i): + ah_ptr_(ah),index_(i){} + + + + inline iterator& operator++() + { + ah_ptr_->chunck_array_cont_->next(index_); + return *this; + } inline T& operator*() { - T& v = ah_ptr_->operator[](index_); - return v; + return ah_ptr_->operator[](index_); } - inline bool operator!=(iterator it) + inline bool operator!=(iterator it) const { assert(ah_ptr_ == it.ah_ptr_); return index_ != it.index_; } - }; inline iterator begin() diff --git a/cgogn/core/map/map1.h b/cgogn/core/map/map1.h index 62e54bc5..d4220196 100644 --- a/cgogn/core/map/map1.h +++ b/cgogn/core/map/map1.h @@ -55,10 +55,6 @@ class Map1: public MapBase template using FaceAttributeHandler = AttributeHandler; - //TODO remonter dans map_base - template - using AttributeHandler = AttributeHandler; - /** * @brief phi1 @@ -122,7 +118,7 @@ class Map1: public MapBase * @param d * @return */ - Dart uncut_edge(Dart d) + void uncut_edge(Dart d) { Dart d1 = phi1(d) ; phi1unsew(d) ; // Dart d is linked to the successor of its successor diff --git a/cgogn/core/map/map_base.h b/cgogn/core/map/map_base.h index 31acd908..d92600c2 100644 --- a/cgogn/core/map/map_base.h +++ b/cgogn/core/map/map_base.h @@ -40,16 +40,21 @@ class MapBase: public MapBaseData public: + //TODO remonter dans map_base + template + using AttributeHandler = AttributeHandler; + + MapBase() {} template - inline AttributeHandler addAttribute(const std::string& nameAttr = "") + inline AttributeHandler addAttribute(const std::string& nameAttr = "") { // if(!this->template isOrbitEmbedded()) // this->template addEmbedding() ; - ChunkArray* ca = this->attributes_[ORBIT].template addAttribute(nameAttr) ; - return AttributeHandler(this, ca) ; + ChunkArray* ca = this->attributes_[ORBIT].template addAttribute(nameAttr) ; + return AttributeHandler(this, ca) ; } /** @@ -58,7 +63,7 @@ class MapBase: public MapBaseData * @return true if remove succeed else false */ template - inline bool removeAttribute(AttributeHandler& attr_handl) + inline bool removeAttribute(AttributeHandler& attr_handl) { ChunkArray* ca = attr_handl.getDataVector(); @@ -81,10 +86,10 @@ class MapBase: public MapBaseData * @return an AttributeHandler */ template - inline AttributeHandler getAttribute(const std::string& nameAttr) + inline AttributeHandler< T, ORBIT> getAttribute(const std::string& nameAttr) { ChunkArray* ca = this->attribs_[ORBIT].template getAttribute(nameAttr) ; - return AttributeHandler(this, ca) ; + return AttributeHandler(this, ca) ; } diff --git a/test/chunk_array/test_chunk_array.cpp b/test/chunk_array/test_chunk_array.cpp index 185d72f6..cd6bf442 100644 --- a/test/chunk_array/test_chunk_array.cpp +++ b/test/chunk_array/test_chunk_array.cpp @@ -221,12 +221,13 @@ int test4() ChunkArrayFactory::registerCA("float",new ChunkArray()); ChunkArrayFactory::registerCA("int",new ChunkArray()); - ChunkArrayFactory::registerCA("char",new ChunkArray()); + ChunkArrayFactory::registerCA("bool",new ChunkArray()); ChunkArrayContainer container; - ChunkArray* att2 = container.addAttribute("reel"); ChunkArray* att1 = container.addAttribute("entier"); + ChunkArray* att2 = container.addAttribute("reel"); + ChunkArray* att3 = container.addAttribute("bools"); for (int i=0;i<7;++i) @@ -237,6 +238,7 @@ int test4() { (*att1)[i] = 1+int(i); (*att2)[i] = 3.0f + 0.1f*float(i); + (*att3).setVal(i,i%2); } container.removeLines<3>(3); @@ -254,11 +256,11 @@ int test4() ChunkArray* load_att1 = cont2.getAttribute("entier"); ChunkArray* load_att2 = cont2.getAttribute("reel"); - + ChunkArray* load_att3 = cont2.getAttribute("bools"); for(unsigned int i=cont2.begin(); i!=cont2.end(); cont2.next(i)) { - std::cout << i << ": "<< (*load_att1)[i] << " / " << (*load_att2)[i] << std::endl; + std::cout << i << ": "<< (*load_att1)[i] << " / " << (*load_att2)[i] << " / " << (*load_att3)[i] < MAP1; +// declare a map +MAP1 map; -int test1() + + +void fonc_const(const MAP1::VertexAttributeHandler& ah) +{ + for (const float& f:ah) + { + std::cout << f << std::endl; + } + + // equivalent to + for (MAP1::VertexAttributeHandler::const_iterator it = ah.begin(); it != ah.end(); ++it) + std::cout << *it << std::endl; + + +} + +void fonc_non_const(MAP1::VertexAttributeHandler& ah) { - // typedef for short writing - typedef Map1 MAP1; - // declare a map - MAP1 map; + for (float& f:ah) + { + f *= 2.0f; + std::cout << f << std::endl; + } + + // equivalent to + for (MAP1::VertexAttributeHandler::iterator it = ah.begin(); it != ah.end(); ++it) + { + *it /= 2.0f; + } +} + + + +int test1() +{ // add an attribute on vertex of map with MAP1::VertexAttributeHandler ah = map.addAttribute("floats"); @@ -34,13 +67,15 @@ int test1() // access with index std::cout << ah[0] << std::endl; - // traverse container with for range - for (float f:ah) - std::cout << f << std::endl; - // equivalent to - for (MAP1::VertexAttributeHandler::iterator it = ah.begin(); it != ah.end(); ++it) - std::cout << *it << std::endl; + fonc_non_const(ah); + + fonc_const(ah); + +// // traverse container with for range +// for (float f:ah) +// std::cout << f << std::endl; + return 0; } From c4c062ed557959df197aa1d02aa6b6761cb5177a Mon Sep 17 00:00:00 2001 From: Lionel Untereiner Date: Tue, 3 Nov 2015 19:53:57 +0100 Subject: [PATCH 029/185] added new assert macro and macro for contract programing Three levels of macro (cgogn_assert, debug_assert, parano_assert) with a message function --- cgogn/core/basic/assert.cpp | 43 +++++++++++ cgogn/core/basic/assert.h | 149 ++++++++++++++++++++++++++++++++++++ 2 files changed, 192 insertions(+) create mode 100644 cgogn/core/basic/assert.cpp create mode 100644 cgogn/core/basic/assert.h diff --git a/cgogn/core/basic/assert.cpp b/cgogn/core/basic/assert.cpp new file mode 100644 index 00000000..dd06948d --- /dev/null +++ b/cgogn/core/basic/assert.cpp @@ -0,0 +1,43 @@ +/* + * CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps + * Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Web site: http://cgogn.unistra.fr/ + * Contact information: cgogn@unistra.fr + * + */ + +#include + +namespace cgogn +{ + + void assertion_failed(const std::string& expression, const std::string& message, + const std::string& file_name, const std::string& function_name, int line_number ) + { + std::ostringstream os; + os << "Assertion failed: " << expression; + if(message.empty()) + os << ".\n"; + else + os<< " (" << message << ").\n"; + os << "file: " << file_name << ", function: " << function_name << ", line: " << line_number ; + + std::cerr << os.str() << std::endl; + std::abort(); + } +} diff --git a/cgogn/core/basic/assert.h b/cgogn/core/basic/assert.h new file mode 100644 index 00000000..49a5f5a8 --- /dev/null +++ b/cgogn/core/basic/assert.h @@ -0,0 +1,149 @@ +/* + * CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps + * Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Web site: http://cgogn.unistra.fr/ + * Contact information: cgogn@unistra.fr + * + */ + +#ifndef CORE_BASIC_ASSERT_ +#define CORE_BASIC_ASSERT_ + +#include +#include +#include + +/** + * \file cgogn/core/basic/assert.h + * \brief Assertion checking mechanism. + * + * Allows the user to add a specific message to output + */ +namespace cgogn +{ + + /** + * Prints an assertion failure. + * This function is called when a boolean condition is not met. + * It prints an error message and terminates the program. + * \param[in] expression string representation of the condition. + * \param[in] message string information message to print out. + * \param[in] file_name file where the assertion failed. + * \param[in] function_name function where the assertion failed. + * \param[in] line_number line where the assertion failed. + * + * \todo Add attribute [[noreturn]] when MSVC min version = 14 + */ + void assertion_failed(const std::string& expression, const std::string& message, + const std::string& file_name, const std::string& function_name, int line_number ); + +} + +/** + * \brief Verifies that a condition is met. + * \details + * \param[in] x the boolean expression of the condition + * \see assertion_failed() + */ +#define cgogn_assert(x) \ + (!(x)) ? cgogn::assertion_failed(#x, "", __FILE__, __func__, __LINE__) : (void)0 + +/** + * \brief Verifies that a condition is met and take a specific message. + * \details + * \param[in] x the boolean expression of the condition + * \parap[in] msg the specific message about the condition + * \see assertion_failed() + */ +#define cgogn_message_assert(x, msg) \ + (!(x)) ? cgogn::assertion_failed(#x, msg, __FILE__, __func__, __LINE__) : (void)0 + +/** + * \brief Verifies that the required contract condition is met. + * \details + * + * \param[in] x the boolean expression of the condition + * \see assertion_failed() + */ +#define cgogn_require(x) \ + (!(x)) ? cgogn::assertion_failed(#x, "", __FILE__, __func__, __LINE__) : (void)0 + +/** + * \brief Verifies that the ensured contract condition is met. + * \details + * + * \param[in] x the boolean expression of the condition + * \see assertion_failed() + */ +#define cgogn_ensure(x) \ + (!(x)) ? cgogn::assertion_failed(#x, "", __FILE__, __func__, __LINE__) : (void)0 + +/** + * \brief Verifies that the invariant contract condition is met. + * \details + * + * \param[in] x the boolean expression of the condition + * \see assertion_failed() + */ +#define cgogn_invariant(x) \ + (!(x)) ? cgogn::assertion_failed(#x, "", __FILE__, __func__, __LINE__) : (void)0 + + +/** + * \def debug_assert(x) + * \copydoc cgogn_assert() + * \note This assertion check is only active in debug mode. + */ + /** + * \def debug_message_assert(x, msg) + * \copydoc cgogn_assert() + * \note This assertion check is only active in debug mode. + */ +#ifdef CGOGN_DEBUG + #define debug_assert(x) cgogn_assert(x) + #define debug_message_assert(x, msg) cgogn_message_assert(x, msg) + #define debug_require(x) cgogn_require(x) + #define debug_ensure(x) cgogn_ensure(x) + #define debug_invariant(x) cgogn_invariant(x) +#else + #define debug_assert(x) + #define debug_message_assert(x, msg) + #define debug_require(x) + #define debug_ensure(x) + #define debug_invariant(x) +#endif + +/** + * \def parano_assert(x) + * \copydoc cgogn_assert() + * \note This assertion check is only active in parano mode. + */ + /** + * \def parano_message_assert(x, msg) + * \copydoc cgogn_assert() + * \note This assertion check is only active in parano mode. + */ +#ifdef CGOGN_PARANO + #define parano_assert(x) cgogn_assert(x) + #define parano_message_assert(x, msg) cgogn_message_assert(x, msg) +#else + #define parano_assert(x) + #define parano_message_assert(x, msg) +#endif + +#endif \ No newline at end of file From bb79bc92ac6d8124e4719907a04c70fd6e2444dc Mon Sep 17 00:00:00 2001 From: Etienne Schmitt Date: Wed, 4 Nov 2015 11:55:20 +0100 Subject: [PATCH 030/185] fixed compilation with VS 2013 Signed-off-by: Etienne Schmitt --- cgogn/core/basic/definitions.h | 11 +++++++++++ cgogn/core/map/map1.h | 6 +++--- test/chunk_array/CMakeLists.txt | 11 ++++++++--- test/map/CMakeLists.txt | 8 ++++++-- 4 files changed, 28 insertions(+), 8 deletions(-) diff --git a/cgogn/core/basic/definitions.h b/cgogn/core/basic/definitions.h index dc338d86..7ac8a0e2 100644 --- a/cgogn/core/basic/definitions.h +++ b/cgogn/core/basic/definitions.h @@ -29,5 +29,16 @@ * \brief Basic definitions for CGOGN API */ +#ifdef WIN32 +#ifndef CGoGN_CORE_API +#if defined CGoGN_CORE_DLL_EXPORT +#define CGoGN_CORE_API __declspec(dllexport) +#else +#define CGoGN_CORE_API __declspec(dllimport) +#endif +#endif +#else +#define CGoGN_CORE_API +#endif #endif \ No newline at end of file diff --git a/cgogn/core/map/map1.h b/cgogn/core/map/map1.h index d4220196..9f832cc2 100644 --- a/cgogn/core/map/map1.h +++ b/cgogn/core/map/map1.h @@ -47,13 +47,13 @@ class Map1: public MapBase static const unsigned int FACE = FACE2; template - using VertexAttributeHandler = AttributeHandler; + using VertexAttributeHandler = cgogn::AttributeHandler; template - using EdgeAttributeHandler = AttributeHandler; + using EdgeAttributeHandler = cgogn::AttributeHandler; template - using FaceAttributeHandler = AttributeHandler; + using FaceAttributeHandler = cgogn::AttributeHandler; /** diff --git a/test/chunk_array/CMakeLists.txt b/test/chunk_array/CMakeLists.txt index 77ae0f59..af7992cc 100644 --- a/test/chunk_array/CMakeLists.txt +++ b/test/chunk_array/CMakeLists.txt @@ -2,13 +2,18 @@ project(${CGOGN_TEST_PREFIX}chunk_array LANGUAGES CXX ) +get_property(cgogn_core_includes + TARGET cgogn_core + PROPERTY INCLUDE_DIRECTORIES + ) add_executable(test_chunk_array test_chunk_array.cpp) -target_link_libraries(test_chunk_array cgogn_core) +#target_link_libraries(test_chunk_array cgogn_core) +target_include_directories(test_chunk_array PRIVATE ${cgogn_core_includes}) add_executable(bench_chunk_array bench_chunk_array.cpp) -target_link_libraries(bench_chunk_array cgogn_core) - +#target_link_libraries(bench_chunk_array cgogn_core) +target_include_directories(bench_chunk_array PRIVATE ${cgogn_core_includes}) install(TARGETS test_chunk_array EXPORT ${PROJECT_NAME}Targets diff --git a/test/map/CMakeLists.txt b/test/map/CMakeLists.txt index 321c5665..101083a3 100644 --- a/test/map/CMakeLists.txt +++ b/test/map/CMakeLists.txt @@ -3,5 +3,9 @@ project(${CGOGN_TEST_PREFIX}map ) add_executable(test_map test_map.cpp) -target_link_libraries(test_map cgogn_core) - +#target_link_libraries(test_map cgogn_core) +get_property(cgogn_core_includes + TARGET cgogn_core + PROPERTY INCLUDE_DIRECTORIES + ) +target_include_directories(test_map PRIVATE ${cgogn_core_includes}) \ No newline at end of file From 7aa229ff7700b6f1f864ce72a3491fe00465eadd Mon Sep 17 00:00:00 2001 From: Pierre Kraemer Date: Wed, 4 Nov 2015 12:38:44 +0100 Subject: [PATCH 031/185] cosmetic updates + first proposition for thread-safe management of pre-allocated dart & uint vectors --- cgogn/CMakeLists.txt | 2 +- cgogn/core/basic/cell.h | 47 +++----- cgogn/core/basic/dart.h | 11 +- cgogn/core/basic/definitions.h | 56 +++++---- cgogn/core/basic/nameTypes.h | 9 +- cgogn/core/container/chunk_array.h | 100 ++++++---------- cgogn/core/container/chunk_array_container.h | 93 ++++++--------- cgogn/core/container/chunk_array_factory.h | 67 +++++------ cgogn/core/container/chunk_array_gen.h | 65 +++++------ cgogn/core/container/chunk_stack.h | 88 +++++++------- cgogn/core/map/attribute_handler.h | 99 ++++++++-------- cgogn/core/map/map1.h | 114 ++++++++++--------- cgogn/core/map/map2.h | 73 +++++++++++- cgogn/core/map/map_base.h | 70 ++++++------ cgogn/core/map/map_base_data.h | 81 ++++++++++--- cgogn/core/map/map_tri.h | 11 +- cgogn/utils/buffers.h | 71 ++++++++++++ test/map/test_map.cpp | 24 ++-- 18 files changed, 591 insertions(+), 490 deletions(-) create mode 100644 cgogn/utils/buffers.h diff --git a/cgogn/CMakeLists.txt b/cgogn/CMakeLists.txt index 82bfe4a4..ad6d4787 100644 --- a/cgogn/CMakeLists.txt +++ b/cgogn/CMakeLists.txt @@ -1 +1 @@ -add_subdirectory(core) \ No newline at end of file +add_subdirectory(core) diff --git a/cgogn/core/basic/cell.h b/cgogn/core/basic/cell.h index f225a6d3..c4cb32a3 100644 --- a/cgogn/core/basic/cell.h +++ b/cgogn/core/basic/cell.h @@ -1,5 +1,5 @@ /******************************************************************************* -* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * * * +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * * Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France * * * * This library is free software; you can redistribute it and/or modify it * @@ -26,7 +26,6 @@ #include "core/basic/dart.h" - namespace cgogn { @@ -40,43 +39,24 @@ const unsigned int EDGE3 = 5; const unsigned int FACE3 = 6; const unsigned int VOLUME3 = 7; - inline std::string orbitName(unsigned int orbit) { switch(orbit) { - case VERTEX1: - return "VERTEX1"; - break; - case VERTEX2: - return "VERTEX2"; - break; - case EDGE2: - return "EDGE2"; - break; - case FACE2: - return "FACE2"; - break; - case VERTEX3: - return "VERTEX3"; - break; - case EDGE3: - return "EDGE3"; - break; - case FACE3: - return "FACE3"; - break; - case VOLUME3: - return "VOLUME3"; - default: - break; - + case VERTEX1: return "VERTEX1"; break; + case VERTEX2: return "VERTEX2"; break; + case EDGE2: return "EDGE2"; break; + case FACE2: return "FACE2"; break; + case VERTEX3: return "VERTEX3"; break; + case EDGE3: return "EDGE3"; break; + case FACE3: return "FACE3"; break; + case VOLUME3: return "VOLUME3"; + default: break; } return "UNKNOWN"; } - /** * class for cellular typing * @@ -89,6 +69,7 @@ template class Cell { public: + Dart dart; /// empty construtor @@ -106,10 +87,8 @@ class Cell friend std::ostream& operator<<( std::ostream &out, const Cell& fa ) { return out << fa.dart; } inline bool valid() const { return !dart.isNil(); } - }; +} // namespace cgogn -} - -#endif +#endif // __CORE_BASIC_CELL_H__ diff --git a/cgogn/core/basic/dart.h b/cgogn/core/basic/dart.h index 6861dced..6bde6daf 100644 --- a/cgogn/core/basic/dart.h +++ b/cgogn/core/basic/dart.h @@ -1,5 +1,5 @@ /******************************************************************************* -* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * * * +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * * Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France * * * * This library is free software; you can redistribute it and/or modify it * @@ -24,8 +24,6 @@ #ifndef __CORE_BASIC_DART_H__ #define __CORE_BASIC_DART_H__ - - namespace cgogn { @@ -56,8 +54,6 @@ struct Dart friend std::ostream& operator<<( std::ostream &out, const Dart& fa ); friend std::istream& operator>>( std::istream &in, Dart& fa ); - - }; @@ -68,7 +64,6 @@ std::istream& operator>>( std::istream &in, Dart& fa ) { in >> fa.index; return const Dart NIL = Dart::nil(); const unsigned int EMBNULL = 0xffffffff; +} // namespace cgogn -} - -#endif +#endif // __CORE_BASIC_DART_H__ diff --git a/cgogn/core/basic/definitions.h b/cgogn/core/basic/definitions.h index dc338d86..48c84b92 100644 --- a/cgogn/core/basic/definitions.h +++ b/cgogn/core/basic/definitions.h @@ -1,33 +1,39 @@ -/* - * CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps - * Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation; either version 2.1 of the License, or (at your - * option) any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Web site: http://cgogn.unistra.fr/ - * Contact information: cgogn@unistra.fr - * - */ +/******************************************************************************* +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * +* Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France * +* * +* This library is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by the * +* Free Software Foundation; either version 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: http://cgogn.unistra.fr/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ -#ifndef __DEFINITIONS__ -#define __DEFINITIONS__ +#ifndef __CORE_BASIC_DEFINITIONS_H__ +#define __CORE_BASIC_DEFINITIONS_H__ /** * \file basic/definitions.h * \brief Basic definitions for CGOGN API */ +namespace cgogn +{ + +const unsigned int NB_THREADS = 8; + +} // namespace cgogn -#endif \ No newline at end of file +#endif // __CORE_BASIC_DEFINITIONS_H__ diff --git a/cgogn/core/basic/nameTypes.h b/cgogn/core/basic/nameTypes.h index 157e7dc6..3f8759e6 100644 --- a/cgogn/core/basic/nameTypes.h +++ b/cgogn/core/basic/nameTypes.h @@ -1,5 +1,5 @@ /******************************************************************************* -* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * * * +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * * Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France * * * * This library is free software; you can redistribute it and/or modify it * @@ -30,6 +30,7 @@ namespace cgogn { + /** * @brief function that give a name to a type. */ @@ -85,7 +86,6 @@ class AddTypeName : public T static std::string CGoGNnameOfType() { return "UNKNOWN"; } }; - template bool typeIsBool(T) { @@ -94,7 +94,6 @@ bool typeIsBool(T) template <> bool typeIsBool(bool) { return true; } +} // namespace cgogn -} - -#endif +#endif // __CORE_BASIC_NAME_TYPES_H__ diff --git a/cgogn/core/container/chunk_array.h b/cgogn/core/container/chunk_array.h index 4d665cb8..51be440f 100644 --- a/cgogn/core/container/chunk_array.h +++ b/cgogn/core/container/chunk_array.h @@ -1,28 +1,28 @@ -/* - * CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps - * Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation; either version 2.1 of the License, or (at your - * option) any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Web site: http://cgogn.unistra.fr/ - * Contact information: cgogn@unistra.fr - * - */ - -#ifndef __CORE_CONTAINER_CHUNK_ARRAY__ -#define __CORE_CONTAINER_CHUNK_ARRAY__ +/******************************************************************************* +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * +* Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France * +* * +* This library is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by the * +* Free Software Foundation; either version 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: http://cgogn.unistra.fr/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ + +#ifndef __CORE_CONTAINER_CHUNK_ARRAY_H__ +#define __CORE_CONTAINER_CHUNK_ARRAY_H__ #include "core/container/chunk_array_gen.h" #include @@ -30,9 +30,9 @@ #include #include - namespace cgogn { + /** * @brief chunk array class storage * @tparam CHUNKSIZE size of each chunk (in T, not in bytes!), must be a power of 2 >=32 @@ -65,7 +65,6 @@ class ChunkArray : public ChunkArrayGen delete[] chunk; } - bool isBooleanArray() const { return false; @@ -88,7 +87,6 @@ class ChunkArray : public ChunkArrayGen tableData_.emplace_back(new T[CHUNKSIZE]()); } - /** * @brief set number of chunks * @param nbc number of chunks @@ -108,7 +106,6 @@ class ChunkArray : public ChunkArrayGen } } - /** * @brief get the number of chunks of the array * @return the number of chunks @@ -127,7 +124,6 @@ class ChunkArray : public ChunkArrayGen return static_cast(tableData_.size())*CHUNKSIZE; } - /** * @brief clear */ @@ -161,7 +157,7 @@ class ChunkArray : public ChunkArrayGen } /** - * @brief set the value of an element (work also with bool + * @brief set the value of an element (works also with bool) * @param i index of element to set * @param v value */ @@ -171,7 +167,6 @@ class ChunkArray : public ChunkArrayGen tableData_[i / CHUNKSIZE][i % CHUNKSIZE] = v; } - /** * @brief get pointer on all chunks data * @param addr vector to fill @@ -188,7 +183,7 @@ class ChunkArray : public ChunkArrayGen for (typename std::vector::const_iterator it = tableData_.begin(); it != tableData_.end(); ++it) addr.push_back(*it); - return (unsigned int)(addr.size()); + return static_cast(addr.size()); } /** @@ -200,7 +195,6 @@ class ChunkArray : public ChunkArrayGen tableData_[id / CHUNKSIZE][id % CHUNKSIZE] = T(); } - /** * @brief copy element * @param dst destination @@ -221,8 +215,6 @@ class ChunkArray : public ChunkArrayGen std::swap(tableData_[id1 / CHUNKSIZE][id1 % CHUNKSIZE], tableData_[id2 / CHUNKSIZE][id2 % CHUNKSIZE] ); } - - // void save(std::ostream& fs, unsigned int nbLines) const // { // unsigned int nbs[3]; @@ -251,7 +243,6 @@ class ChunkArray : public ChunkArrayGen // fs.write(reinterpret_cast(tableData_[nbca]),std::streamsize(nbl*sizeof(T))); // } - // bool load(std::istream& fs) // { // unsigned int nbs[3]; @@ -281,7 +272,6 @@ class ChunkArray : public ChunkArrayGen // return true; // } - void save(std::ostream& fs, unsigned int nbLines) const override { assert(nbLines/CHUNKSIZE <= getNbChunks()); @@ -305,7 +295,6 @@ class ChunkArray : public ChunkArrayGen fs.write(reinterpret_cast(tableData_[nbc]),std::streamsize(nb*sizeof(T))); } - bool load(std::istream& fs) override { unsigned int nbLines; @@ -333,13 +322,9 @@ class ChunkArray : public ChunkArrayGen return true; } - }; - - - /** * @brief specialized version of ChunkArray for bool data. One bit per bool */ @@ -358,7 +343,6 @@ class ChunkArray : public ChunkArrayGen tableData_.reserve(1024u); } - ~ChunkArray() override { for(auto chunk: tableData_) @@ -370,21 +354,17 @@ class ChunkArray : public ChunkArrayGen return true; } - ChunkArrayGen* clone() const override { return new ChunkArray(); } - void addChunk() override { // adding the empty parentheses for default-initialization tableData_.push_back(new unsigned int[CHUNKSIZE/32u]()); } - - void setNbChunks(unsigned int nbc) override { if (nbc >= tableData_.size()) @@ -400,20 +380,16 @@ class ChunkArray : public ChunkArrayGen } } - - unsigned int getNbChunks() const override { return static_cast(tableData_.size()); } - unsigned int capacity() const override { return static_cast(tableData_.size())*CHUNKSIZE/32u; } - void clear() override { for(auto chunk: tableData_) @@ -462,7 +438,7 @@ class ChunkArray : public ChunkArrayGen * @brief special optimized version of setFalse when goal is to set all to false; * @param i index of element to set to false * - * This version overwrite element AND SOME OF THIS NEIGHBOURS with 0 + * This version overwrites element AND SOME OF HIS NEIGHBOURS with 0 * Use only if final goal is to set all array to 0 (MarkerStore) * @todo find another name for the method! */ @@ -474,8 +450,6 @@ class ChunkArray : public ChunkArrayGen tableData_[jj][j] = 0u; } - - bool operator[](unsigned int i) const { const unsigned int jj = i / CHUNKSIZE; @@ -489,9 +463,7 @@ class ChunkArray : public ChunkArrayGen return (tableData_[jj][x] & mask) != 0u; } - - - unsigned int getChunksPointers(std::vector& addr, unsigned int& byteBlockSize) const + unsigned int getChunksPointers(std::vector& addr, unsigned int& byteBlockSize) const override { byteBlockSize = CHUNKSIZE / 8u; @@ -504,13 +476,11 @@ class ChunkArray : public ChunkArrayGen return static_cast(addr.size()); } - void initElt(unsigned int id) override { setFalse(id); } - void copyElt(unsigned int dst, unsigned int src) override { setVal(dst,this->operator [](src)); @@ -524,7 +494,6 @@ class ChunkArray : public ChunkArrayGen setVal(id2,data); } - void save(std::ostream& fs, unsigned int nbLines) const override { // round nbLines to 32 multiple @@ -554,7 +523,6 @@ class ChunkArray : public ChunkArrayGen fs.write(reinterpret_cast(tableData_[nbc]),nb/8u); } - bool load(std::istream& fs) override { // get number of lines to load @@ -583,12 +551,8 @@ class ChunkArray : public ChunkArrayGen return true; } - - }; +} // namespace cgogn - -} // namespace CGoGN - -#endif +#endif // __CORE_CONTAINER_CHUNK_ARRAY_H__ diff --git a/cgogn/core/container/chunk_array_container.h b/cgogn/core/container/chunk_array_container.h index ff64e5ba..f97db1a7 100644 --- a/cgogn/core/container/chunk_array_container.h +++ b/cgogn/core/container/chunk_array_container.h @@ -1,29 +1,28 @@ -/* - * CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps - * Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation; either version 2.1 of the License, or (at your - * option) any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Web site: http://cgogn.unistra.fr/ - * Contact information: cgogn@unistra.fr - * - */ - -#ifndef __CORE_CONTAINER_CHUNK_ARRAY_CONTAINER__ -#define __CORE_CONTAINER_CHUNK_ARRAY_CONTAINER__ - +/******************************************************************************* +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * +* Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France * +* * +* This library is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by the * +* Free Software Foundation; either version 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: http://cgogn.unistra.fr/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ + +#ifndef __CORE_CONTAINER_CHUNK_ARRAY_CONTAINER_H__ +#define __CORE_CONTAINER_CHUNK_ARRAY_CONTAINER_H__ #include "core/container/chunk_array.h" #include "core/container/chunk_stack.h" @@ -43,6 +42,7 @@ namespace cgogn class ContainerBrowser { public: + virtual unsigned int begin() const = 0; virtual unsigned int end() const = 0; virtual void next(unsigned int &it) const = 0; @@ -56,7 +56,9 @@ template class ContainerStandardBrowser:public ContainerBrowser { const CONTAINER* cac_; + public: + ContainerStandardBrowser(const CONTAINER* cac) : cac_(cac) {} virtual unsigned int begin() const { return cac_->realBegin(); } virtual unsigned int end() const { return cac_->realEnd(); } @@ -76,14 +78,15 @@ class ContainerStandardBrowser:public ContainerBrowser template class ChunkArrayContainer { - public: + /** * constante d'attribut inconnu */ static const unsigned int UNKNOWN = 0xffffffff; protected: + /** * vector of pointers to ChunkVector */ @@ -157,7 +160,6 @@ class ChunkArrayContainer return UNKNOWN; } - /** * @brief remove an attribute by its name * @param attribName name of attribute to remove @@ -200,9 +202,8 @@ class ChunkArrayContainer return true ; } - - public: + /** * @brief ChunkArrayContainer constructor */ @@ -214,7 +215,6 @@ class ChunkArrayContainer currentBrowser_= stdBrowser_; } - /** * @brief ChunkArrayContainer destructor */ @@ -224,8 +224,6 @@ class ChunkArrayContainer delete ptr; } - - template ChunkArray* getAttribute(const std::string& attribName) { @@ -241,8 +239,6 @@ class ChunkArrayContainer return static_cast*>(tableArrays_[index]); } - - /** * @brief add an attribute * @param attribName name of attribute @@ -314,7 +310,6 @@ class ChunkArrayContainer return true; } - /** * @brief remove an attribute by its name * @param attribName name of attribute to remove @@ -335,7 +330,6 @@ class ChunkArrayContainer return true; } - /** * @brief Number of attributes of the container * @return number of attributes @@ -345,7 +339,6 @@ class ChunkArrayContainer return tableArrays_.size(); } - /** * @brief size (number of used lines) * @return the number of lines @@ -364,7 +357,6 @@ class ChunkArrayContainer return refs_.capacity(); } - /** * @brief is a line used * @param index index of line @@ -384,7 +376,6 @@ class ChunkArrayContainer return currentBrowser_->begin(); } - /** * @brief end * @return the index after the last used line of the container @@ -403,7 +394,6 @@ class ChunkArrayContainer currentBrowser_->next(it); } - /** * @brief next primitive: it <- next primitive used index in the container (eq to PRIMSIZE next) * @param it index to "increment" @@ -413,7 +403,6 @@ class ChunkArrayContainer currentBrowser_->nextPrimitive(it, primSz); } - /** * @brief begin of container without browser * @return @@ -435,7 +424,6 @@ class ChunkArrayContainer return nbMaxLines_; } - /** * @brief next without browser * @param it @@ -460,7 +448,6 @@ class ChunkArrayContainer } while ((it < nbMaxLines_) && (!used(it))); } - /** * @brief real reverse begin * @return rbegin() @@ -497,8 +484,6 @@ class ChunkArrayContainer } while ((it !=0xffffffff) && (!used(it))); } - - /** * @brief clear the container * @param removeAttrib remove the attributes (not only their data) @@ -576,10 +561,8 @@ class ChunkArrayContainer // clear holes holesStack_.clear(); - } - /************************************** * LINES MANAGEMENT * **************************************/ @@ -639,7 +622,6 @@ class ChunkArrayContainer nbUsedLines_ -= PRIMSIZE; } - /** * @brief initialize a line of the container (an element of each attribute) * @param index line index @@ -659,7 +641,6 @@ class ChunkArrayContainer tableArrays_[i]->initElt(index); } - void initBoolsOfLine(unsigned int index) { // assert( used(index) && "initLine only with allocated lines"); @@ -668,7 +649,6 @@ class ChunkArrayContainer // ptrAtt->initElt(index); } - /** * @brief copy the content of line src in line dst (with refs) * @param dstIndex destination @@ -692,7 +672,6 @@ class ChunkArrayContainer refs_[index]++; } - /** * @brief decrement the reference counter of the given line (only for PRIMSIZE==1) * @param index index of the line @@ -723,7 +702,6 @@ class ChunkArrayContainer return refs_[index]; } - /** * @brief get a chunk_array * @param attribName name of the array @@ -741,7 +719,6 @@ class ChunkArrayContainer return atm; } - /** * @brief get a chunk_array * @param attribName name of the array @@ -756,7 +733,6 @@ class ChunkArrayContainer return tableArrays_[index]; } - void save(std::ofstream& fs) { // save info (size+used_lines+max_lines+sizeof names) @@ -794,7 +770,6 @@ class ChunkArrayContainer holesStack_.save(fs,holesStack_.size()); } - bool load(std::ifstream& fs) { // read info @@ -834,10 +809,8 @@ class ChunkArrayContainer return ok; } - - }; -} // namespace CGoGN +} // namespace cgogn -#endif +#endif // __CORE_CONTAINER_CHUNK_ARRAY_CONTAINER_H__ diff --git a/cgogn/core/container/chunk_array_factory.h b/cgogn/core/container/chunk_array_factory.h index a14bda46..5558034e 100644 --- a/cgogn/core/container/chunk_array_factory.h +++ b/cgogn/core/container/chunk_array_factory.h @@ -1,29 +1,28 @@ -/* - * CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps - * Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation; either version 2.1 of the License, or (at your - * option) any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Web site: http://cgogn.unistra.fr/ - * Contact information: cgogn@unistra.fr - * - */ - -#ifndef __CORE_CONTAINER_CHUNK_ARRAY_FACTORY__ -#define __CORE_CONTAINER_CHUNK_ARRAY_FACTORY__ - +/******************************************************************************* +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * +* Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France * +* * +* This library is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by the * +* Free Software Foundation; either version 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: http://cgogn.unistra.fr/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ + +#ifndef __CORE_CONTAINER_CHUNK_ARRAY_FACTORY_H__ +#define __CORE_CONTAINER_CHUNK_ARRAY_FACTORY_H__ #include "core/container/chunk_array.h" @@ -33,14 +32,13 @@ namespace cgogn { - template class ChunkArrayFactory { public: + static std::map*> mapCA_; -public: /** * @brief register a type * @param keyType name of type @@ -49,7 +47,7 @@ class ChunkArrayFactory static void registerCA(const std::string& keyType, ChunkArrayGen* obj) { if(mapCA_.find(keyType) == mapCA_.end()) - mapCA_[keyType]=obj; + mapCA_[keyType] = obj; } /** @@ -59,7 +57,7 @@ class ChunkArrayFactory */ static ChunkArrayGen* create(const std::string& keyType) { - ChunkArrayGen* tmp=NULL; + ChunkArrayGen* tmp = NULL; typename std::map*>::const_iterator it = mapCA_.find(keyType); if(it != mapCA_.end()) @@ -67,7 +65,7 @@ class ChunkArrayFactory tmp = (it->second)->clone(); } else - std::cerr << "type "< std::map*> ChunkArrayFactory::mapCA_= std::map*>(); +} // namespace cgogn - -} // namespace CGoGN - -#endif +#endif // __CORE_CONTAINER_CHUNK_ARRAY_FACTORY_H__ diff --git a/cgogn/core/container/chunk_array_gen.h b/cgogn/core/container/chunk_array_gen.h index c2e81bec..c5849a96 100644 --- a/cgogn/core/container/chunk_array_gen.h +++ b/cgogn/core/container/chunk_array_gen.h @@ -1,29 +1,28 @@ -/* - * CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps - * Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation; either version 2.1 of the License, or (at your - * option) any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Web site: http://cgogn.unistra.fr/ - * Contact information: cgogn@unistra.fr - * - */ - -#ifndef __CORE_CONTAINER_CHUNK_ARRAY_GEN__ -#define __CORE_CONTAINER_CHUNK_ARRAY_GEN__ - +/******************************************************************************* +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * +* Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France * +* * +* This library is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by the * +* Free Software Foundation; either version 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: http://cgogn.unistra.fr/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ + +#ifndef __CORE_CONTAINER_CHUNK_ARRAY_GEN_H__ +#define __CORE_CONTAINER_CHUNK_ARRAY_GEN_H__ #include #include @@ -31,8 +30,6 @@ namespace cgogn { - - /** * @brief Virtual version of ChunkArray */ @@ -52,7 +49,6 @@ class ChunkArrayGen */ virtual ChunkArrayGen* clone() const = 0; - /** * @brief add a chunk (T[CHUNKSIZE]) */ @@ -64,7 +60,6 @@ class ChunkArrayGen */ virtual void setNbChunks(unsigned int nbb) = 0; - /** * @brief get the number of chunks of the array * @return the number of chunks @@ -82,10 +77,8 @@ class ChunkArrayGen */ virtual void clear() = 0; - virtual bool isBooleanArray() const = 0; - /** * @brief get pointer on all chunks data * @param addr vector to fill @@ -121,22 +114,18 @@ class ChunkArrayGen */ virtual void save(std::ostream& fs, unsigned int nbLines) const = 0; - /** * @brief load * @param fs file stream * @return ok */ virtual bool load(std::istream& fs) = 0; - }; - //template //ChunkArrayGen::~ChunkArrayGen() //{} +} // namespace cgogn -} // namespace CGoGN - -#endif +#endif // __CORE_CONTAINER_CHUNK_ARRAY_GEN_H__ diff --git a/cgogn/core/container/chunk_stack.h b/cgogn/core/container/chunk_stack.h index 732677ce..c7afc31e 100644 --- a/cgogn/core/container/chunk_stack.h +++ b/cgogn/core/container/chunk_stack.h @@ -1,28 +1,28 @@ -/* - * CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps - * Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation; either version 2.1 of the License, or (at your - * option) any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Web site: http://cgogn.unistra.fr/ - * Contact information: cgogn@unistra.fr - * - */ - -#ifndef __CORE_CONTAINER_CHUNK_HEAP__ -#define __CORE_CONTAINER_CHUNK_HEAP__ +/******************************************************************************* +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * +* Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France * +* * +* This library is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by the * +* Free Software Foundation; either version 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: http://cgogn.unistra.fr/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ + +#ifndef __CORE_CONTAINER_CHUNK_STACK_H__ +#define __CORE_CONTAINER_CHUNK_STACK_H__ #include "core/container/chunk_array.h" @@ -39,20 +39,23 @@ namespace cgogn template class ChunkStack : public ChunkArray { - unsigned int heapSize_; +protected: + + unsigned int stackSize_; public: /** * @brief ChunkStack constructor */ ChunkStack(): - heapSize_(0u) + stackSize_(0u) {} /** * @brief ChunkStack destructor */ - inline ~ChunkStack() override {} + inline ~ChunkStack() override + {} /** * @brief push a value on top of heap @@ -60,9 +63,9 @@ class ChunkStack : public ChunkArray */ void push(const T& val) { - heapSize_++; - unsigned int offset = heapSize_ % CHUNKSIZE; - unsigned int blkId = heapSize_ / CHUNKSIZE; + stackSize_++; + unsigned int offset = stackSize_ % CHUNKSIZE; + unsigned int blkId = stackSize_ / CHUNKSIZE; if (blkId >= this->tableData_.size()) this->addChunk(); @@ -76,7 +79,7 @@ class ChunkStack : public ChunkArray */ inline bool empty() const { - return heapSize_ == 0u; + return stackSize_ == 0u; } /** @@ -84,7 +87,7 @@ class ChunkStack : public ChunkArray */ unsigned int size() const { - return heapSize_; + return stackSize_; } /** @@ -92,8 +95,8 @@ class ChunkStack : public ChunkArray */ inline void pop() { - assert(heapSize_ > 0u); - heapSize_--; + assert(stackSize_ > 0u); + stackSize_--; } /** @@ -102,8 +105,8 @@ class ChunkStack : public ChunkArray */ inline T head() const { - const unsigned int offset = heapSize_ % CHUNKSIZE; - const unsigned int blkId = heapSize_ / CHUNKSIZE; + const unsigned int offset = stackSize_ % CHUNKSIZE; + const unsigned int blkId = stackSize_ / CHUNKSIZE; return this->tableData_[blkId][offset]; } @@ -113,7 +116,7 @@ class ChunkStack : public ChunkArray */ void compact() { - const unsigned int keep = (heapSize_+CHUNKSIZE-1u) / CHUNKSIZE; + const unsigned int keep = (stackSize_+CHUNKSIZE-1u) / CHUNKSIZE; while (this->tableData_.size() > keep) { delete[] this->tableData_.back(); @@ -126,14 +129,11 @@ class ChunkStack : public ChunkArray */ void clear() override { - heapSize_ = 0u; + stackSize_ = 0u; ChunkArray::clear(); } }; +} // namespace cgogn -} - - - -#endif +#endif // __CORE_CONTAINER_CHUNK_STACK_H__ diff --git a/cgogn/core/map/attribute_handler.h b/cgogn/core/map/attribute_handler.h index 191a71b3..f491d5d7 100644 --- a/cgogn/core/map/attribute_handler.h +++ b/cgogn/core/map/attribute_handler.h @@ -1,5 +1,5 @@ /******************************************************************************* -* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * * * +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * * Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France * * * * This library is free software; you can redistribute it and/or modify it * @@ -27,14 +27,14 @@ #include "core/map/map_base.h" #include "core/basic/cell.h" - ///TODO ajouter enregistrement dans la map de la carte. namespace cgogn { + /** * @brief Generic AttributeHandler class - * @TPARAM DATA_TRAITS stprage traits (for MapBase ptr) + * @TPARAM DATA_TRAITS storage traits (for MapBaseData ptr type) */ template class AttributeHandlerGen @@ -47,12 +47,13 @@ class AttributeHandlerGen bool valid_; public: + AttributeHandlerGen(bool v) : - map_(NULL),valid_(v) + map_(NULL), valid_(v) {} - virtual ~AttributeHandlerGen() {} - + virtual ~AttributeHandlerGen() + {} inline bool isValid() const { return valid_; } @@ -63,41 +64,44 @@ class AttributeHandlerGen inline void setInvalid() { valid_ = false ; } inline void setValid() { valid_ = true ; } -} ; - +}; /** * @brief Generic AttributeHandler class with orbit parameter - * @TPARAM ORBIT the orbit of attribute to handlde + * @TPARAM ORBIT the orbit of the attribute to handlde */ template class AttributeHandlerOrbit : public AttributeHandlerGen { protected: - ChunkArrayContainer* chunck_array_cont_; + + ChunkArrayContainer* chunk_array_cont_; public: + AttributeHandlerOrbit(MapBaseData* map) : AttributeHandlerGen(map) { - chunck_array_cont_ = &(map->getAttributeContainer(ORBIT)); + chunk_array_cont_ = &(map->getAttributeContainer(ORBIT)); } - unsigned int getOrbit() const { return ORBIT;} + unsigned int getOrbit() const { return ORBIT; } }; - - - - -template -class AttributeHandler: public AttributeHandlerOrbit +/** + * @brief AttributeHandler class + * @TPARAM T the data type of the attribute to handlde + */ +template +class AttributeHandler : public AttributeHandlerOrbit { protected: + ChunkArray* chunk_array_; public: + /** * @brief Default constructor * @@ -107,25 +111,24 @@ class AttributeHandler: public AttributeHandlerOrbit AttributeHandlerGen(false) {} - /** * @brief Constructor * @param m the map which belong attribute - * @param attribName name of attribute + * @param attributeName name of attribute */ - AttributeHandler(MapBaseData* m, const std::string& attribName): - AttributeHandlerOrbit(m) + AttributeHandler(MapBaseData* m, const std::string& attributeName): + AttributeHandlerOrbit(m) { - chunk_array_ = this->chunck_array_cont_->getAttribute(attribName); + chunk_array_ = this->chunk_array_cont_->getAttribute(attributeName); if (chunk_array_ == NULL) { this->setInvalid(); } } - AttributeHandler(MapBaseData* m, ChunkArray* ca): - AttributeHandlerOrbit(m),chunk_array_(ca) + AttributeHandlerOrbit(m), + chunk_array_(ca) { if (chunk_array_ == NULL) { @@ -138,7 +141,7 @@ class AttributeHandler: public AttributeHandlerOrbit * @param att */ AttributeHandler(const AttributeHandler& att): - AttributeHandlerOrbit(att.map_)/*, + AttributeHandlerOrbit(att.map_)/*, chunk_array_(att.chunk_array_)*/ { this->chunk_array_= att.chunk_array_; @@ -150,11 +153,11 @@ class AttributeHandler: public AttributeHandlerOrbit * @param att * @return */ - AttributeHandler& operator=(const AttributeHandler& att) + AttributeHandler& operator=(const AttributeHandler& att) { this->valid_ = att.valid_; this->map_ = att.map_; - this->chunck_array_cont_ = att.chunck_array_cont_; + this->chunk_array_cont_ = att.chunk_array_cont_; this->chunck_array_ = att.chunck_array_; } @@ -162,12 +165,11 @@ class AttributeHandler: public AttributeHandlerOrbit * @brief getDataVector * @return */ - ChunkArray* getDataVector() const + ChunkArray* getData() const { return chunk_array_; } - /** * @brief operator [] * @param c @@ -194,7 +196,7 @@ class AttributeHandler: public AttributeHandlerOrbit /** * @brief operator [] - * @param a + * @param i * @return */ T& operator[](unsigned int i) @@ -204,8 +206,8 @@ class AttributeHandler: public AttributeHandlerOrbit } /** - * @brief operator [] - * @param a + * @brief const operator [] + * @param i * @return */ const T& operator[](unsigned int i) const @@ -215,19 +217,19 @@ class AttributeHandler: public AttributeHandlerOrbit } - class const_iterator { public: const AttributeHandler* ah_ptr_; unsigned int index_; - inline const_iterator(const AttributeHandler* ah, unsigned int i): - ah_ptr_(ah),index_(i){} + inline const_iterator(const AttributeHandler* ah, unsigned int i) : + ah_ptr_(ah), index_(i) + {} inline const_iterator& operator++() { - ah_ptr_->chunck_array_cont_->next(index_); + ah_ptr_->chunk_array_cont_->next(index_); return *this; } @@ -245,12 +247,12 @@ class AttributeHandler: public AttributeHandlerOrbit inline const_iterator begin() const { - return const_iterator(this,this->chunck_array_cont_->begin()); + return const_iterator(this,this->chunk_array_cont_->begin()); } inline const_iterator end() const { - return const_iterator(this,this->chunck_array_cont_->end()); + return const_iterator(this,this->chunk_array_cont_->end()); } @@ -260,14 +262,13 @@ class AttributeHandler: public AttributeHandlerOrbit AttributeHandler* ah_ptr_; unsigned int index_; - inline iterator(AttributeHandler* ah, unsigned int i): - ah_ptr_(ah),index_(i){} - - + inline iterator(AttributeHandler* ah, unsigned int i) : + ah_ptr_(ah), index_(i) + {} inline iterator& operator++() { - ah_ptr_->chunck_array_cont_->next(index_); + ah_ptr_->chunk_array_cont_->next(index_); return *this; } @@ -285,17 +286,15 @@ class AttributeHandler: public AttributeHandlerOrbit inline iterator begin() { - return iterator(this,this->chunck_array_cont_->begin()); + return iterator(this,this->chunk_array_cont_->begin()); } inline iterator end() { - return iterator(this,this->chunck_array_cont_->end()); + return iterator(this,this->chunk_array_cont_->end()); } - - }; -} +} // namespace cgogn -#endif +#endif // __CORE_MAP_ATTRIBUTE_HANDLER_H__ diff --git a/cgogn/core/map/map1.h b/cgogn/core/map/map1.h index d4220196..afb4c70b 100644 --- a/cgogn/core/map/map1.h +++ b/cgogn/core/map/map1.h @@ -1,5 +1,5 @@ /******************************************************************************* -* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * * * +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * * Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France * * * * This library is free software; you can redistribute it and/or modify it * @@ -30,31 +30,79 @@ namespace cgogn { -class Topo_Traits_map1 +class Topo_Traits_Map1 { -// static const int CHUNK_SIZE=4096; - static const int PRIM_SIZE=1; + static const int PRIM_SIZE = 1; }; - template -class Map1: public MapBase +class Map1 : public MapBase { public: - static const unsigned int VERTEX = VERTEX2; - static const unsigned int EDGE = EDGE2; + static const unsigned int VERTEX = VERTEX1; + static const unsigned int EDGE = VERTEX1; static const unsigned int FACE = FACE2; template - using VertexAttributeHandler = AttributeHandler; + using VertexAttributeHandler = AttributeHandler; template - using EdgeAttributeHandler = AttributeHandler; + using EdgeAttributeHandler = AttributeHandler; template - using FaceAttributeHandler = AttributeHandler; + using FaceAttributeHandler = AttributeHandler; + +protected: + + void init() + { + ChunkArray* phi1 = this->topology_.template addAttribute("phi1"); + ChunkArray* phi_1 = this->topology_.template addAttribute("phi_1"); + this->topo_relations_.push_back(phi1); + this->topo_relations_.push_back(phi_1); + } + + //! Link the current dart to dart d with a permutation + /*! @param d the dart to which the current is linked + * - Before: d->f and e->g + * - After: d->g and e->f + * Join the permutations cycles of dart d and e + * - Starting from two cycles : d->f->...->d and e->g->...->e + * - It makes one cycle d->g->...->e->f->...->d + * If e = g then insert e in the cycle of d : d->e->f->...->d + */ + void phi1sew(Dart d, Dart e) + { + Dart f = phi1(d); + Dart g = phi1(e); + (*(this->topo_relations_[0]))[d.index] = g; + (*(this->topo_relations_[0]))[e.index] = f; + (*(this->topo_relations_[1]))[g.index] = d; + (*(this->topo_relations_[1]))[f.index] = e; + } + + //! Unlink the successor of a given dart in a permutation + /*! @param d a dart + * - Before: d->e->f + * - After: d->f and e->e + */ + void phi1unsew(Dart d) + { + Dart e = phi1(d); + Dart f = phi1(e); + (*(this->topo_relations_[0]))[d.index] = f; + (*(this->topo_relations_[0]))[e.index] = e; + (*(this->topo_relations_[1]))[f.index] = d; + (*(this->topo_relations_[1]))[e.index] = e; + } + +public: + Map1() + { + init(); + } /** * @brief phi1 @@ -63,7 +111,6 @@ class Map1: public MapBase */ Dart phi1(Dart d) const { - // phi1 first topo relation return (*(this->topo_relations_[0]))[d.index]; } @@ -74,11 +121,9 @@ class Map1: public MapBase */ Dart phi_1(Dart d) const { - // phi1 first topo relation return (*(this->topo_relations_[1]))[d.index]; } - /** * @brief add_cycle * @param nbEdges @@ -102,7 +147,6 @@ class Map1: public MapBase Dart e = this->newDart() ; // Create a new dart phi1sew(d, e) ; // Insert dart e between d and phi1(d) - // TODO: doit on traiter les marker de bord 2/3 dans Map1 if (this->template isBoundaryMarked<2>(d)) this->template boundaryMark<2>(e); @@ -125,50 +169,14 @@ class Map1: public MapBase this->deleteDart(d1) ; // Dart d1 is erased } - /** * @brief collapse_edge * @param d * @return */ Dart collapse_edge(Dart d); - - - -protected: - - void init() - { - ChunkArray* rel_phi1 = this->topology_.template addAttribute("phi1"); - ChunkArray* rel_phi_1 = this->topology_.template addAttribute("phi1"); - - this->topo_relations_.push_back(rel_phi1); - this->topo_relations_.push_back(rel_phi_1); - } - - - //! Link the current dart to dart d with a permutation - /*! @param d the dart to which the current is linked - * - Before: d->f and e->g - * - After: d->g and e->f - * Join the permutations cycles of dart d and e - * - Starting from two cycles : d->f->...->d and e->g->...->e - * - It makes one cycle d->g->...->e->f->...->d - * If e = g then insert e in the cycle of d : d->e->f->...->d - */ - void phi1sew(Dart d, Dart e); - - //! Unlink the successor of a given dart in a permutation - /*! @param d a dart - * - Before: d->e->f - * - After: d->f and e->e - */ - void phi1unsew(Dart d); - - }; +} // namespace cgogn - -} -#endif +#endif // __CORE_MAP_MAP1_H__ diff --git a/cgogn/core/map/map2.h b/cgogn/core/map/map2.h index a4c2e7ea..56fba9c8 100644 --- a/cgogn/core/map/map2.h +++ b/cgogn/core/map/map2.h @@ -1,5 +1,5 @@ /******************************************************************************* -* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * * * +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * * Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France * * * * This library is free software; you can redistribute it and/or modify it * @@ -26,14 +26,79 @@ #include "core/map/map1.h" -class Map2: public Map1 +namespace cgogn { +template +class Map2 : public Map1 +{ +public: + static const unsigned int VERTEX = VERTEX2; + static const unsigned int EDGE = EDGE2; + static const unsigned int FACE = FACE2; + template + using VertexAttributeHandler = AttributeHandler; -}; + template + using EdgeAttributeHandler = AttributeHandler; + + template + using FaceAttributeHandler = AttributeHandler; + +protected: + + void init() + { + ChunkArray* phi2 = this->topology_.template addAttribute("phi2"); + this->topo_relations_.push_back(phi2); + } + //! Link dart d with dart e by an involution + /* @param d,e the darts to link + * - Before: d->d and e->e + * - After: d->e and e->d + */ + void phi2sew(Dart d, Dart e) + { + assert(phi2(d) == d); + assert(phi2(e) == e); + (*(this->topo_relations_[2]))[d.index] = e; + (*(this->topo_relations_[2]))[e.index] = d; + } + + //! Unlink the current dart by an involution + /* @param d the dart to unlink + * - Before: d->e and e->d + * - After: d->d and e->e + */ + void phi2unsew(Dart d) + { + Dart e = phi2(d) ; + (*(this->topo_relations_[2]))[d.index] = d; + (*(this->topo_relations_[2]))[e.index] = e; + } + +public: + + Map2() : Map1() + { + init(); + } + + /** + * @brief phi2 + * @param d + * @return + */ + Dart phi2(Dart d) const + { + // phi2 first topo relation + return (*(this->topo_relations_[2]))[d.index]; + } +}; +} // namespace cgogn -#endif +#endif // __CORE_MAP_MAP2_H__ diff --git a/cgogn/core/map/map_base.h b/cgogn/core/map/map_base.h index d92600c2..8bfda9d1 100644 --- a/cgogn/core/map/map_base.h +++ b/cgogn/core/map/map_base.h @@ -1,5 +1,5 @@ /******************************************************************************* -* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * * * +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * * Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France * * * * This library is free software; you can redistribute it and/or modify it * @@ -27,34 +27,42 @@ #include "core/map/map_base_data.h" #include "core/map/attribute_handler.h" +#include + namespace cgogn { - - template -class MapBase: public MapBaseData +class MapBase : public MapBaseData { protected: - std::multimap*, AttributeHandlerGen*> attributeHandlers_ ; + + std::multimap*, AttributeHandlerGen*> attributeHandlers_; public: //TODO remonter dans map_base template - using AttributeHandler = AttributeHandler; - + using AttributeHandler = AttributeHandler; - MapBase() {} + MapBase() + {} template - inline AttributeHandler addAttribute(const std::string& nameAttr = "") + inline AttributeHandler addAttribute(const std::string& attributeName = "") { -// if(!this->template isOrbitEmbedded()) -// this->template addEmbedding() ; + if (this->embeddings_[ORBIT] == NULL) + { + std::ostringstream oss; + oss << "EMB_" << orbitName(ORBIT); + ChunkArray* idx = this->topology_.template addAttribute(oss.str()); + this->embeddings_[ORBIT] = idx; + for (unsigned int i = this->topology_.begin(); i != this->topology_.end(); this->topology_.next(i)) + (*idx)[i] = EMBNULL; + } - ChunkArray* ca = this->attributes_[ORBIT].template addAttribute(nameAttr) ; - return AttributeHandler(this, ca) ; + ChunkArray* ca = this->attributes_[ORBIT].template addAttribute(attributeName); + return AttributeHandler(this, ca); } /** @@ -63,21 +71,20 @@ class MapBase: public MapBaseData * @return true if remove succeed else false */ template - inline bool removeAttribute(AttributeHandler& attr_handl) + inline bool removeAttribute(AttributeHandler& ah) { - - ChunkArray* ca = attr_handl.getDataVector(); + ChunkArray* ca = ah.getData(); if (this->attributes_[ORBIT].removeAttribute(ca)) { - typedef typename std::multimap*, AttributeHandlerGen*>::iterator IT ; - std::pair bounds = attributeHandlers_.equal_range(ca) ; + typedef typename std::multimap*, AttributeHandlerGen*>::iterator IT; + std::pair bounds = attributeHandlers_.equal_range(ca); for(IT i = bounds.first; i != bounds.second; ++i) - (*i).second->setInvalid() ; - attributeHandlers_.erase(bounds.first, bounds.second) ; - return true ; + (*i).second->setInvalid(); + attributeHandlers_.erase(bounds.first, bounds.second); + return true; } - return false ; + return false; } /** @@ -88,33 +95,30 @@ class MapBase: public MapBaseData template inline AttributeHandler< T, ORBIT> getAttribute(const std::string& nameAttr) { - ChunkArray* ca = this->attribs_[ORBIT].template getAttribute(nameAttr) ; - return AttributeHandler(this, ca) ; + ChunkArray* ca = this->attributes_[ORBIT].template getAttribute(nameAttr); + return AttributeHandler(this, ca); } - inline Dart add_dart() { - unsigned int di = this->topology_.template insertLines<1>(); // insert a new dart line - this->topology_.initBooleansOfLine(di); + this->topology_.initBooleansOfLine(di); for(unsigned int i = 0; i < NB_ORBITS; ++i) { if (this->embeddings_[i]) // set all its embeddings - (*(this->embeddings_[i]))[di] = EMBNULL ; // to EMBNULL + (*(this->embeddings_[i]))[di] = EMBNULL; // to EMBNULL } - Dart d = Dart::create(di) ; + Dart d = Dart::create(di); for (auto relPtr: this->topo_relations_) (*relPtr)[di] = d; - return d ; + return d; } - }; -} +} // namespace cgogn -#endif +#endif // __CORE_MAP_MAP_BASE_H__ diff --git a/cgogn/core/map/map_base_data.h b/cgogn/core/map/map_base_data.h index f3cba132..34561c75 100644 --- a/cgogn/core/map/map_base_data.h +++ b/cgogn/core/map/map_base_data.h @@ -1,5 +1,5 @@ /******************************************************************************* -* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * * * +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * * Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France * * * * This library is free software; you can redistribute it and/or modify it * @@ -25,30 +25,33 @@ #define __CORE_MAP_MAP_BASE_DATA_H__ #include "core/container/chunk_array_container.h" +#include "core/basic/definitions.h" #include "core/basic/cell.h" +#include "utils/buffers.h" + +#include + namespace cgogn { - /** - * @brief Generic Map class for SCHNApps + * @brief Generic Map class (for SCHNApps) */ class MapGen { }; - /** * @brief The MapBase class */ template -class MapBaseData: public MapGen +class MapBaseData : public MapGen { protected: - /// topooly & embedding indices + /// topology & embedding indices ChunkArrayContainer topology_; /// embedding attributes @@ -64,25 +67,75 @@ class MapBaseData: public MapGen /// topo relations shortcuts std::vector*> topo_relations_; + /// buffers of pre-allocated vectors of dart or unsigned int + Buffers dart_buffers_[NB_THREADS]; + Buffers uint_buffers_[NB_THREADS]; + + /// vector of thread ids known by the map that can pretend to data such as mark vectors and buffers + std::vector thread_ids_; public: - MapBaseData() {} - ChunkArrayContainer& getAttributeContainer(unsigned int orbit) + MapBaseData() { - return attributes_[orbit]; + for (unsigned int i = 0; i < NB_ORBITS; ++i) + embeddings_[i] = NULL; + + thread_ids_.reserve(NB_THREADS + 1); + thread_ids_.push_back(std::this_thread::get_id()); } + inline ChunkArrayContainer& getAttributeContainer(unsigned int orbit) + { + return attributes_[orbit]; + } template - inline unsigned int getEmbedding(Cell c) const + inline unsigned int getEmbedding(const Cell& c) const + { + assert(embeddings_[ORBIT] != NULL || !"Invalid parameter: orbit not embedded"); + return (*embeddings_[ORBIT])[c.dart.index] ; + } + + inline std::vector* getDartBuffer() { -// assert(this->template isOrbitEmbedded() || !"Invalid parameter: orbit not embedded"); - return (*this->embeddings_[ORBIT])[c.dart.index] ; + unsigned int thread = getCurrentThreadIndex(); + return dart_buffers_[thread].getBuffer(); } + inline void releaseDartBuffer(std::vector* v) + { + unsigned int thread = getCurrentThreadIndex(); + dart_buffers_[thread].releaseBuffer(v); + } + + inline std::vector* getUIntBuffer() + { + unsigned int thread = getCurrentThreadIndex(); + return uint_buffers_[thread].getBuffer(); + } + + inline void releaseUIntBuffer(std::vector* v) + { + unsigned int thread = getCurrentThreadIndex(); + uint_buffers_[thread].releaseBuffer(v); + } + +protected: + + inline unsigned int getCurrentThreadIndex() const + { + std::thread::id id = std::this_thread::get_id(); + unsigned int i = 0; + while (id != thread_ids_[i]) + { + i++; + assert(i < thread_ids_.size()); + } + return i; + } }; -} +} // namespace cgogn -#endif +#endif // __CORE_MAP_MAP_BASE_DATA_H__ diff --git a/cgogn/core/map/map_tri.h b/cgogn/core/map/map_tri.h index 02b46dbb..2b6651f4 100644 --- a/cgogn/core/map/map_tri.h +++ b/cgogn/core/map/map_tri.h @@ -1,5 +1,5 @@ /******************************************************************************* -* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * * * +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * * Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France * * * * This library is free software; you can redistribute it and/or modify it * @@ -26,18 +26,21 @@ #include "core/map/map_base.h" +namespace cgogn +{ + class Traits_map_tri { - static const int CHUNK_SIZE=4096; static const int PRIM_SIZE=3; }; -class MapTri: public MapBase +class MapTri : public MapBase { }; +} // namespace cgogn -#endif +#endif // __CORE_MAP_MAP_TRI_H__ diff --git a/cgogn/utils/buffers.h b/cgogn/utils/buffers.h new file mode 100644 index 00000000..5610fc7f --- /dev/null +++ b/cgogn/utils/buffers.h @@ -0,0 +1,71 @@ +/******************************************************************************* +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * * * +* Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France * +* * +* This library is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by the * +* Free Software Foundation; either version 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: http://cgogn.unistra.fr/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ + +#ifndef __UTILS_BUFFERS_H__ +#define __UTILS_BUFFERS_H__ + +#include + +namespace cgogn +{ + +template +class Buffers +{ +protected: + + std::vector*> buffers_; + +public: + + inline std::vector* getBuffer() + { + if (buffers_.empty()) + { + std::vector* v = new std::vector; + v->reserve(128); + return v; + } + + std::vector* v = buffers_.back(); + buffers_.pop_back(); + return v; + } + + inline void releaseBuffer(std::vector* b) + { + if (b->capacity() > 1024) + { + std::vector v; + b->swap(v); + b->reserve(128); + } + + b->clear(); + buffers_.push_back(b); + } +}; + +} // namespace cgogn + +#endif // __UTILS_BUFFERS_H__ diff --git a/test/map/test_map.cpp b/test/map/test_map.cpp index 310274ae..b77c57a5 100644 --- a/test/map/test_map.cpp +++ b/test/map/test_map.cpp @@ -1,15 +1,16 @@ #include "core/map/map1.h" +#include "core/map/map2.h" using namespace cgogn; - struct My_Data_Traits { - static const int CHUNK_SIZE=64; + static const int CHUNK_SIZE = 64; }; + // typedef for short writing typedef Map1 MAP1; @@ -17,6 +18,12 @@ typedef Map1 MAP1; MAP1 map; +// typedef for short writing +typedef Map2 MAP2; + +// declare a map +MAP2 map2; + void fonc_const(const MAP1::VertexAttributeHandler& ah) { @@ -28,13 +35,10 @@ void fonc_const(const MAP1::VertexAttributeHandler& ah) // equivalent to for (MAP1::VertexAttributeHandler::const_iterator it = ah.begin(); it != ah.end(); ++it) std::cout << *it << std::endl; - - } void fonc_non_const(MAP1::VertexAttributeHandler& ah) { - for (float& f:ah) { f *= 2.0f; @@ -49,15 +53,13 @@ void fonc_non_const(MAP1::VertexAttributeHandler& ah) } - int test1() { - // add an attribute on vertex of map with - MAP1::VertexAttributeHandler ah = map.addAttribute("floats"); + MAP1::VertexAttributeHandler ah = map.addAttribute("floats"); // get ChunkArrayContainer -> get ChunkArray -> fill - ChunkArrayContainer& container = map.getAttributeContainer(VERTEX2); + ChunkArrayContainer& container = map.getAttributeContainer(VERTEX1); ChunkArray* att = container.getAttribute("floats"); for (int i=0;i<10;++i) container.insertLines<1>(); @@ -67,7 +69,6 @@ int test1() // access with index std::cout << ah[0] << std::endl; - fonc_non_const(ah); fonc_const(ah); @@ -76,16 +77,13 @@ int test1() // for (float f:ah) // std::cout << f << std::endl; - return 0; } - int main() { test1(); return 0; } - From 93c8c3c679ebe6da215a83cc87a690b4c75b0ef6 Mon Sep 17 00:00:00 2001 From: Lionel Untereiner Date: Wed, 4 Nov 2015 14:38:29 +0100 Subject: [PATCH 032/185] add new assert files in build system replaced old cassert with new assert in chunk_array_container --- cgogn/core/CMakeLists.txt | 2 ++ cgogn/core/container/chunk_array_container.h | 22 ++++++++++++++------ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/cgogn/core/CMakeLists.txt b/cgogn/core/CMakeLists.txt index e8e209bf..037895bb 100644 --- a/cgogn/core/CMakeLists.txt +++ b/cgogn/core/CMakeLists.txt @@ -6,6 +6,7 @@ set(HEADER_FILES basic/nameTypes.h basic/dart.h basic/cell.h + basic/assert.h container/chunk_array_container.h container/chunk_array_factory.h container/chunk_array_gen.h @@ -22,6 +23,7 @@ set(HEADER_FILES ) set(SOURCE_FILES + basic/assert.cpp container/chunk_array.cpp ) diff --git a/cgogn/core/container/chunk_array_container.h b/cgogn/core/container/chunk_array_container.h index ff64e5ba..81951d64 100644 --- a/cgogn/core/container/chunk_array_container.h +++ b/cgogn/core/container/chunk_array_container.h @@ -35,7 +35,7 @@ #include #include #include -#include +#include namespace cgogn { @@ -252,7 +252,8 @@ class ChunkArrayContainer template ChunkArray* addAttribute(const std::string& attribName) { - assert(attribName.size() != 0); + // assert(attribName.size() != 0); + cgogn_assert(attribName.size() != 0); // first check if attribute already exist unsigned int index = getArrayIndex(attribName) ; @@ -629,7 +630,9 @@ class ChunkArrayContainer { unsigned int beginPrimIdx = (index/PRIMSIZE) * PRIMSIZE; - assert(this->used(beginPrimIdx)|!" Error removing non existing index"); + // assert(this->used(beginPrimIdx)|!" Error removing non existing index"); + cgogn_message_assert(this->used(beginPrimIdx), "Error removing non existing index"); + holesStack_.push(beginPrimIdx); // mark lines as unused @@ -646,7 +649,9 @@ class ChunkArrayContainer */ void initLine(unsigned int index) { - assert( used(index) && "initLine only with allocated lines"); + // assert( used(index) && "initLine only with allocated lines"); + cgogn_message_assert(!used(index), "initLine only with allocated lines"); + for (auto ptrAtt: tableArrays_) // if (ptrAtt != nullptr) never null ! ptrAtt->initElt(index); @@ -654,7 +659,9 @@ class ChunkArrayContainer void initBooleansOfLine(unsigned int index) { - assert( used(index) && "initBooleansOfLine only with allocated lines"); + // assert( used(index) && "initBooleansOfLine only with allocated lines"); + cgogn_message_assert(!used(index), "initBooleansOfLine only with allocated lines"); + for (unsigned int i=0; iinitElt(index); } @@ -737,7 +744,10 @@ class ChunkArrayContainer return nullptr ; ChunkArray* atm = dynamic_cast*>(tableArrays_[index]); - assert((atm != nullptr) || !"getDataVector: wrong type"); + // assert((atm != nullptr) || !"getDataVector: wrong type"); + + cgogn_message_assert(atm != nullptr, "getDataVector: wrong type"); + return atm; } From 1ae7fb89671209025ba15ab48ba1765dc1bb3c73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Schmitt?= Date: Wed, 4 Nov 2015 17:27:17 +0100 Subject: [PATCH 033/185] attribute handlers : * added copy / move constructors * fixed some bugs * removed some useless temp variables * using nullptr instead of NULL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Étienne Schmitt --- cgogn/core/basic/definitions.h | 2 +- cgogn/core/map/attribute_handler.h | 100 ++++++++++++++++++++--------- 2 files changed, 69 insertions(+), 33 deletions(-) diff --git a/cgogn/core/basic/definitions.h b/cgogn/core/basic/definitions.h index 69cd5a68..9c65b9ce 100644 --- a/cgogn/core/basic/definitions.h +++ b/cgogn/core/basic/definitions.h @@ -46,7 +46,7 @@ namespace cgogn { -const unsigned int NB_THREADS = 8; +const unsigned int NB_THREADS = 8u; } // namespace cgogn diff --git a/cgogn/core/map/attribute_handler.h b/cgogn/core/map/attribute_handler.h index f491d5d7..ac233da5 100644 --- a/cgogn/core/map/attribute_handler.h +++ b/cgogn/core/map/attribute_handler.h @@ -39,19 +39,35 @@ namespace cgogn template class AttributeHandlerGen { +public: + typedef MapBaseData MapData; protected: - MapBaseData* map_; + MapData* map_; // boolean that states the validity of the handler bool valid_; public: - AttributeHandlerGen(bool v) : - map_(NULL), valid_(v) + inline AttributeHandlerGen(MapData * const map) : + map_(map) + ,valid_(false) {} + inline AttributeHandlerGen(const AttributeHandlerGen< DATA_TRAITS >& atthg) : + map_(atthg.map_) + ,valid_(atthg.valid_) + {} + + inline AttributeHandlerGen(AttributeHandlerGen< DATA_TRAITS >&& atthg) : + map_(atthg.map_) + ,valid_(atthg.valid_) + { + atthg.map_ = nullptr; + atthg.valid_ = false; + } + virtual ~AttributeHandlerGen() {} @@ -74,19 +90,33 @@ class AttributeHandlerGen template class AttributeHandlerOrbit : public AttributeHandlerGen { +public: + typedef AttributeHandlerGen Inherit; + typedef typename Inherit::MapData MapData; protected: ChunkArrayContainer* chunk_array_cont_; public: - AttributeHandlerOrbit(MapBaseData* map) : - AttributeHandlerGen(map) - { - chunk_array_cont_ = &(map->getAttributeContainer(ORBIT)); - } + inline AttributeHandlerOrbit(MapData* const map) : + Inherit(map) + ,chunk_array_cont_( &(map->getAttributeContainer(ORBIT)) ) + {} + + inline AttributeHandlerOrbit(const AttributeHandlerOrbit< DATA_TRAITS, ORBIT >& attho) : + Inherit(attho) + , chunk_array_cont_(attho.chunk_array_cont_) + {} + + inline AttributeHandlerOrbit(AttributeHandlerOrbit< DATA_TRAITS, ORBIT >&& attho) noexcept : + Inherit(std::move(attho)) + , chunk_array_cont_(attho.chunk_array_cont_) + { + attho.chunk_array_cont_ = nullptr; + } - unsigned int getOrbit() const { return ORBIT; } + virtual unsigned int getOrbit() const override { return ORBIT; } }; /** @@ -96,9 +126,13 @@ class AttributeHandlerOrbit : public AttributeHandlerGen template class AttributeHandler : public AttributeHandlerOrbit { +public: + typedef AttributeHandlerOrbit Inherit; + typedef ChunkArray ChunckArray; + typedef typename Inherit::MapData MapData; protected: - ChunkArray* chunk_array_; + ChunckArray* chunk_array_; public: @@ -108,7 +142,7 @@ class AttributeHandler : public AttributeHandlerOrbit * Construct a non-valid AttributeHandler (i.e. not linked to any attribute) */ AttributeHandler(): - AttributeHandlerGen(false) + Inherit(nullptr) {} /** @@ -116,21 +150,21 @@ class AttributeHandler : public AttributeHandlerOrbit * @param m the map which belong attribute * @param attributeName name of attribute */ - AttributeHandler(MapBaseData* m, const std::string& attributeName): - AttributeHandlerOrbit(m) + AttributeHandler(MapData* const m, const std::string& attributeName): + Inherit(m) { chunk_array_ = this->chunk_array_cont_->getAttribute(attributeName); - if (chunk_array_ == NULL) + if (chunk_array_ == nullptr) { this->setInvalid(); } } - AttributeHandler(MapBaseData* m, ChunkArray* ca): - AttributeHandlerOrbit(m), + AttributeHandler(MapData* const m, ChunckArray* const ca): + Inherit(m), chunk_array_(ca) { - if (chunk_array_ == NULL) + if (chunk_array_ == nullptr) { this->setInvalid(); } @@ -141,12 +175,16 @@ class AttributeHandler : public AttributeHandlerOrbit * @param att */ AttributeHandler(const AttributeHandler& att): - AttributeHandlerOrbit(att.map_)/*, - chunk_array_(att.chunk_array_)*/ - { - this->chunk_array_= att.chunk_array_; - this->valid_ = att.valid_; - } + Inherit(att) + ,chunk_array_(att.chunk_array_) + {} + + AttributeHandler(AttributeHandler&& att) noexcept : + Inherit(std::move(att)) + ,chunk_array_(att.chunk_array_) + { + att.chunk_array_ = nullptr; + } /** * @brief operator = @@ -165,7 +203,7 @@ class AttributeHandler : public AttributeHandlerOrbit * @brief getDataVector * @return */ - ChunkArray* getData() const + ChunckArray const * getData() const { return chunk_array_; } @@ -175,11 +213,10 @@ class AttributeHandler : public AttributeHandlerOrbit * @param c * @return */ - T& operator[](Cell c) + inline T& operator[](Cell c) { assert(this->valid || !"Invalid AttributeHandler") ; - unsigned int i = this->map_->getEmbedding(c) ; - return chunk_array_->operator[](i) ; + return chunk_array_->operator[]( this->map_->getEmbedding(c) ) ; } /** @@ -189,9 +226,8 @@ class AttributeHandler : public AttributeHandlerOrbit */ const T& operator[](Cell c) const { - assert(this->valid || !"Invalid AttributeHandler") ; - unsigned int i = this->map_->getEmbedding(c) ; - return chunk_array_->operator[](i) ; + assert(this->valid || !"Invalid AttributeHandler") ; + return chunk_array_->operator[]( this->map_->getEmbedding(c) ) ; } /** @@ -220,7 +256,7 @@ class AttributeHandler : public AttributeHandlerOrbit class const_iterator { public: - const AttributeHandler* ah_ptr_; + AttributeHandler const * const ah_ptr_; unsigned int index_; inline const_iterator(const AttributeHandler* ah, unsigned int i) : @@ -259,7 +295,7 @@ class AttributeHandler : public AttributeHandlerOrbit class iterator { public: - AttributeHandler* ah_ptr_; + AttributeHandler* const ah_ptr_; unsigned int index_; inline iterator(AttributeHandler* ah, unsigned int i) : From 01e2490ca96fd5a7ecea743104bef12002a7d994 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Schmitt?= Date: Wed, 4 Nov 2015 17:33:36 +0100 Subject: [PATCH 034/185] added a nullptr check in AttributeHandlerOrbit constructor. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Étienne Schmitt --- cgogn/core/map/attribute_handler.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/cgogn/core/map/attribute_handler.h b/cgogn/core/map/attribute_handler.h index ac233da5..039dceab 100644 --- a/cgogn/core/map/attribute_handler.h +++ b/cgogn/core/map/attribute_handler.h @@ -101,8 +101,13 @@ class AttributeHandlerOrbit : public AttributeHandlerGen inline AttributeHandlerOrbit(MapData* const map) : Inherit(map) - ,chunk_array_cont_( &(map->getAttributeContainer(ORBIT)) ) - {} + ,chunk_array_cont_(nullptr) + { + if (map != nullptr) + { + chunk_array_cont_ = &(map->getAttributeContainer(ORBIT)); + } + } inline AttributeHandlerOrbit(const AttributeHandlerOrbit< DATA_TRAITS, ORBIT >& attho) : Inherit(attho) From fd19144da5b4254e42483058f1e9511a274c3fbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Schmitt?= Date: Wed, 4 Nov 2015 17:50:52 +0100 Subject: [PATCH 035/185] using IGG great style. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Étienne Schmitt --- cgogn/core/map/attribute_handler.h | 136 ++++++++++++++--------------- 1 file changed, 68 insertions(+), 68 deletions(-) diff --git a/cgogn/core/map/attribute_handler.h b/cgogn/core/map/attribute_handler.h index 039dceab..8dbba777 100644 --- a/cgogn/core/map/attribute_handler.h +++ b/cgogn/core/map/attribute_handler.h @@ -40,33 +40,33 @@ template class AttributeHandlerGen { public: - typedef MapBaseData MapData; + typedef MapBaseData MapData; protected: - MapData* map_; + MapData* map_; // boolean that states the validity of the handler bool valid_; public: - inline AttributeHandlerGen(MapData * const map) : - map_(map) - ,valid_(false) + inline AttributeHandlerGen(MapData * const map) : + map_(map) + ,valid_(false) {} - inline AttributeHandlerGen(const AttributeHandlerGen< DATA_TRAITS >& atthg) : - map_(atthg.map_) - ,valid_(atthg.valid_) - {} + inline AttributeHandlerGen(const AttributeHandlerGen< DATA_TRAITS >& atthg) : + map_(atthg.map_) + ,valid_(atthg.valid_) + {} - inline AttributeHandlerGen(AttributeHandlerGen< DATA_TRAITS >&& atthg) : - map_(atthg.map_) - ,valid_(atthg.valid_) - { - atthg.map_ = nullptr; - atthg.valid_ = false; - } + inline AttributeHandlerGen(AttributeHandlerGen< DATA_TRAITS >&& atthg) : + map_(atthg.map_) + ,valid_(atthg.valid_) + { + atthg.map_ = nullptr; + atthg.valid_ = false; + } virtual ~AttributeHandlerGen() {} @@ -91,37 +91,37 @@ template class AttributeHandlerOrbit : public AttributeHandlerGen { public: - typedef AttributeHandlerGen Inherit; - typedef typename Inherit::MapData MapData; + typedef AttributeHandlerGen Inherit; + typedef typename Inherit::MapData MapData; protected: ChunkArrayContainer* chunk_array_cont_; public: - inline AttributeHandlerOrbit(MapData* const map) : - Inherit(map) - ,chunk_array_cont_(nullptr) - { - if (map != nullptr) - { - chunk_array_cont_ = &(map->getAttributeContainer(ORBIT)); - } - } - - inline AttributeHandlerOrbit(const AttributeHandlerOrbit< DATA_TRAITS, ORBIT >& attho) : - Inherit(attho) - , chunk_array_cont_(attho.chunk_array_cont_) - {} - - inline AttributeHandlerOrbit(AttributeHandlerOrbit< DATA_TRAITS, ORBIT >&& attho) noexcept : - Inherit(std::move(attho)) - , chunk_array_cont_(attho.chunk_array_cont_) - { - attho.chunk_array_cont_ = nullptr; - } - - virtual unsigned int getOrbit() const override { return ORBIT; } + inline AttributeHandlerOrbit(MapData* const map) : + Inherit(map) + ,chunk_array_cont_(nullptr) + { + if (map != nullptr) + { + chunk_array_cont_ = &(map->getAttributeContainer(ORBIT)); + } + } + + inline AttributeHandlerOrbit(const AttributeHandlerOrbit< DATA_TRAITS, ORBIT >& attho) : + Inherit(attho) + , chunk_array_cont_(attho.chunk_array_cont_) + {} + + inline AttributeHandlerOrbit(AttributeHandlerOrbit< DATA_TRAITS, ORBIT >&& attho) noexcept : + Inherit(std::move(attho)) + , chunk_array_cont_(attho.chunk_array_cont_) + { + attho.chunk_array_cont_ = nullptr; + } + + virtual unsigned int getOrbit() const override { return ORBIT; } }; /** @@ -132,12 +132,12 @@ template class AttributeHandler : public AttributeHandlerOrbit { public: - typedef AttributeHandlerOrbit Inherit; - typedef ChunkArray ChunckArray; - typedef typename Inherit::MapData MapData; + typedef AttributeHandlerOrbit Inherit; + typedef ChunkArray ChunckArray; + typedef typename Inherit::MapData MapData; protected: - ChunckArray* chunk_array_; + ChunckArray* chunk_array_; public: @@ -147,7 +147,7 @@ class AttributeHandler : public AttributeHandlerOrbit * Construct a non-valid AttributeHandler (i.e. not linked to any attribute) */ AttributeHandler(): - Inherit(nullptr) + Inherit(nullptr) {} /** @@ -155,21 +155,21 @@ class AttributeHandler : public AttributeHandlerOrbit * @param m the map which belong attribute * @param attributeName name of attribute */ - AttributeHandler(MapData* const m, const std::string& attributeName): - Inherit(m) + AttributeHandler(MapData* const m, const std::string& attributeName): + Inherit(m) { chunk_array_ = this->chunk_array_cont_->getAttribute(attributeName); - if (chunk_array_ == nullptr) + if (chunk_array_ == nullptr) { this->setInvalid(); } } - AttributeHandler(MapData* const m, ChunckArray* const ca): - Inherit(m), + AttributeHandler(MapData* const m, ChunckArray* const ca): + Inherit(m), chunk_array_(ca) { - if (chunk_array_ == nullptr) + if (chunk_array_ == nullptr) { this->setInvalid(); } @@ -180,16 +180,16 @@ class AttributeHandler : public AttributeHandlerOrbit * @param att */ AttributeHandler(const AttributeHandler& att): - Inherit(att) - ,chunk_array_(att.chunk_array_) - {} + Inherit(att) + ,chunk_array_(att.chunk_array_) + {} - AttributeHandler(AttributeHandler&& att) noexcept : - Inherit(std::move(att)) - ,chunk_array_(att.chunk_array_) - { - att.chunk_array_ = nullptr; - } + AttributeHandler(AttributeHandler&& att) noexcept : + Inherit(std::move(att)) + ,chunk_array_(att.chunk_array_) + { + att.chunk_array_ = nullptr; + } /** * @brief operator = @@ -208,7 +208,7 @@ class AttributeHandler : public AttributeHandlerOrbit * @brief getDataVector * @return */ - ChunckArray const * getData() const + ChunckArray const * getData() const { return chunk_array_; } @@ -218,10 +218,10 @@ class AttributeHandler : public AttributeHandlerOrbit * @param c * @return */ - inline T& operator[](Cell c) + inline T& operator[](Cell c) { assert(this->valid || !"Invalid AttributeHandler") ; - return chunk_array_->operator[]( this->map_->getEmbedding(c) ) ; + return chunk_array_->operator[]( this->map_->getEmbedding(c) ) ; } /** @@ -231,8 +231,8 @@ class AttributeHandler : public AttributeHandlerOrbit */ const T& operator[](Cell c) const { - assert(this->valid || !"Invalid AttributeHandler") ; - return chunk_array_->operator[]( this->map_->getEmbedding(c) ) ; + assert(this->valid || !"Invalid AttributeHandler") ; + return chunk_array_->operator[]( this->map_->getEmbedding(c) ) ; } /** @@ -261,7 +261,7 @@ class AttributeHandler : public AttributeHandlerOrbit class const_iterator { public: - AttributeHandler const * const ah_ptr_; + AttributeHandler const * const ah_ptr_; unsigned int index_; inline const_iterator(const AttributeHandler* ah, unsigned int i) : @@ -300,7 +300,7 @@ class AttributeHandler : public AttributeHandlerOrbit class iterator { public: - AttributeHandler* const ah_ptr_; + AttributeHandler* const ah_ptr_; unsigned int index_; inline iterator(AttributeHandler* ah, unsigned int i) : From d68c98b4a3e9e058b0e3fad9f386d29bfc5b7ca8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Schmitt?= Date: Wed, 4 Nov 2015 17:56:50 +0100 Subject: [PATCH 036/185] ChunkArray, not chunCK ! MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plus added some 'inline' keywords. Signed-off-by: Étienne Schmitt --- cgogn/core/map/attribute_handler.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/cgogn/core/map/attribute_handler.h b/cgogn/core/map/attribute_handler.h index 8dbba777..d5c30965 100644 --- a/cgogn/core/map/attribute_handler.h +++ b/cgogn/core/map/attribute_handler.h @@ -133,11 +133,11 @@ class AttributeHandler : public AttributeHandlerOrbit { public: typedef AttributeHandlerOrbit Inherit; - typedef ChunkArray ChunckArray; + typedef ChunkArray TChunkArray; typedef typename Inherit::MapData MapData; protected: - ChunckArray* chunk_array_; + TChunkArray* chunk_array_; public: @@ -165,7 +165,7 @@ class AttributeHandler : public AttributeHandlerOrbit } } - AttributeHandler(MapData* const m, ChunckArray* const ca): + AttributeHandler(MapData* const m, TChunkArray* const ca): Inherit(m), chunk_array_(ca) { @@ -208,7 +208,7 @@ class AttributeHandler : public AttributeHandlerOrbit * @brief getDataVector * @return */ - ChunckArray const * getData() const + TChunkArray const * getData() const { return chunk_array_; } @@ -229,7 +229,7 @@ class AttributeHandler : public AttributeHandlerOrbit * @param c * @return */ - const T& operator[](Cell c) const + inline const T& operator[](Cell c) const { assert(this->valid || !"Invalid AttributeHandler") ; return chunk_array_->operator[]( this->map_->getEmbedding(c) ) ; @@ -240,7 +240,7 @@ class AttributeHandler : public AttributeHandlerOrbit * @param i * @return */ - T& operator[](unsigned int i) + inline T& operator[](unsigned int i) { assert(this->valid_ || !"Invalid AttributeHandler") ; return chunk_array_->operator[](i) ; @@ -251,7 +251,7 @@ class AttributeHandler : public AttributeHandlerOrbit * @param i * @return */ - const T& operator[](unsigned int i) const + inline const T& operator[](unsigned int i) const { assert(this->valid_ || !"Invalid AttributeHandler") ; return chunk_array_->operator[](i) ; From 92ca7a32cb584c81cba2fdd2875c4aebd30b0a7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Schmitt?= Date: Wed, 4 Nov 2015 18:13:28 +0100 Subject: [PATCH 037/185] Modified some CMakeLists. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since cgogn core is no more header-only (because of assert.cpp) we need to use cmake's target_link_librarires. Signed-off-by: Étienne Schmitt --- test/chunk_array/CMakeLists.txt | 16 ++++++++-------- test/map/CMakeLists.txt | 12 ++++++------ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/test/chunk_array/CMakeLists.txt b/test/chunk_array/CMakeLists.txt index af7992cc..77e95182 100644 --- a/test/chunk_array/CMakeLists.txt +++ b/test/chunk_array/CMakeLists.txt @@ -2,18 +2,18 @@ project(${CGOGN_TEST_PREFIX}chunk_array LANGUAGES CXX ) -get_property(cgogn_core_includes - TARGET cgogn_core - PROPERTY INCLUDE_DIRECTORIES - ) +#get_property(cgogn_core_includes +# TARGET cgogn_core +# PROPERTY INCLUDE_DIRECTORIES +# ) add_executable(test_chunk_array test_chunk_array.cpp) -#target_link_libraries(test_chunk_array cgogn_core) -target_include_directories(test_chunk_array PRIVATE ${cgogn_core_includes}) +target_link_libraries(test_chunk_array cgogn_core) +#target_include_directories(test_chunk_array PRIVATE ${cgogn_core_includes}) add_executable(bench_chunk_array bench_chunk_array.cpp) -#target_link_libraries(bench_chunk_array cgogn_core) -target_include_directories(bench_chunk_array PRIVATE ${cgogn_core_includes}) +target_link_libraries(bench_chunk_array cgogn_core) +#target_include_directories(bench_chunk_array PRIVATE ${cgogn_core_includes}) install(TARGETS test_chunk_array EXPORT ${PROJECT_NAME}Targets diff --git a/test/map/CMakeLists.txt b/test/map/CMakeLists.txt index 101083a3..3c8e8614 100644 --- a/test/map/CMakeLists.txt +++ b/test/map/CMakeLists.txt @@ -3,9 +3,9 @@ project(${CGOGN_TEST_PREFIX}map ) add_executable(test_map test_map.cpp) -#target_link_libraries(test_map cgogn_core) -get_property(cgogn_core_includes - TARGET cgogn_core - PROPERTY INCLUDE_DIRECTORIES - ) -target_include_directories(test_map PRIVATE ${cgogn_core_includes}) \ No newline at end of file +target_link_libraries(test_map cgogn_core) +#get_property(cgogn_core_includes +# TARGET cgogn_core +# PROPERTY INCLUDE_DIRECTORIES +# ) +target_include_directories(test_map PRIVATE ${cgogn_core_includes}) From 72505177686a9c52830fdc42a0e4f085305cb268 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Schmitt?= Date: Wed, 4 Nov 2015 18:18:14 +0100 Subject: [PATCH 038/185] added CGoGN_CORE_API in assert.cpp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Étienne Schmitt --- cgogn/core/basic/assert.cpp | 31 ++++++++++++++++++------------- cgogn/core/basic/assert.h | 6 ++---- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/cgogn/core/basic/assert.cpp b/cgogn/core/basic/assert.cpp index dd06948d..ed3a82a4 100644 --- a/cgogn/core/basic/assert.cpp +++ b/cgogn/core/basic/assert.cpp @@ -21,23 +21,28 @@ * */ +#define CGoGN_CORE_DLL_EXPORT + #include +#include +#include +#include namespace cgogn { - void assertion_failed(const std::string& expression, const std::string& message, - const std::string& file_name, const std::string& function_name, int line_number ) - { - std::ostringstream os; - os << "Assertion failed: " << expression; - if(message.empty()) - os << ".\n"; - else - os<< " (" << message << ").\n"; - os << "file: " << file_name << ", function: " << function_name << ", line: " << line_number ; +void CGoGN_CORE_API assertion_failed(const std::string& expression, const std::string& message, + const std::string& file_name, const std::string& function_name, int line_number ) +{ + std::ostringstream os; + os << "Assertion failed: " << expression; + if(message.empty()) + os << ".\n"; + else + os<< " (" << message << ").\n"; + os << "file: " << file_name << ", function: " << function_name << ", line: " << line_number ; - std::cerr << os.str() << std::endl; - std::abort(); - } + std::cerr << os.str() << std::endl; + std::abort(); +} } diff --git a/cgogn/core/basic/assert.h b/cgogn/core/basic/assert.h index 49a5f5a8..14c9ce21 100644 --- a/cgogn/core/basic/assert.h +++ b/cgogn/core/basic/assert.h @@ -25,8 +25,6 @@ #define CORE_BASIC_ASSERT_ #include -#include -#include /** * \file cgogn/core/basic/assert.h @@ -100,7 +98,7 @@ namespace cgogn * \param[in] x the boolean expression of the condition * \see assertion_failed() */ -#define cgogn_invariant(x) \ +#define cgogn_invariant(x) \ (!(x)) ? cgogn::assertion_failed(#x, "", __FILE__, __func__, __LINE__) : (void)0 @@ -146,4 +144,4 @@ namespace cgogn #define parano_message_assert(x, msg) #endif -#endif \ No newline at end of file +#endif From a89f3ad417dc2891d605c6bab6f5bb8b4649a817 Mon Sep 17 00:00:00 2001 From: Etienne Schmitt Date: Wed, 4 Nov 2015 17:30:13 +0100 Subject: [PATCH 039/185] fixing compilation with VS 2013 Signed-off-by: Etienne Schmitt --- cgogn/core/basic/assert.cpp | 2 +- cgogn/core/basic/assert.h | 7 ++++++- cgogn/core/basic/definitions.h | 5 +++++ cgogn/core/map/attribute_handler.h | 4 ++-- cgogn/core/map/map2.h | 6 +++--- 5 files changed, 17 insertions(+), 7 deletions(-) diff --git a/cgogn/core/basic/assert.cpp b/cgogn/core/basic/assert.cpp index ed3a82a4..3ee4cff2 100644 --- a/cgogn/core/basic/assert.cpp +++ b/cgogn/core/basic/assert.cpp @@ -31,7 +31,7 @@ namespace cgogn { -void CGoGN_CORE_API assertion_failed(const std::string& expression, const std::string& message, +CGoGN_CORE_API void assertion_failed(const std::string& expression, const std::string& message, const std::string& file_name, const std::string& function_name, int line_number ) { std::ostringstream os; diff --git a/cgogn/core/basic/assert.h b/cgogn/core/basic/assert.h index 14c9ce21..46c810c9 100644 --- a/cgogn/core/basic/assert.h +++ b/cgogn/core/basic/assert.h @@ -25,6 +25,11 @@ #define CORE_BASIC_ASSERT_ #include +#include + +#if defined (WIN32) && !defined(__func__) +#define __func__ __FUNCTION__ +#endif /** * \file cgogn/core/basic/assert.h @@ -47,7 +52,7 @@ namespace cgogn * * \todo Add attribute [[noreturn]] when MSVC min version = 14 */ - void assertion_failed(const std::string& expression, const std::string& message, + CGoGN_CORE_API void assertion_failed(const std::string& expression, const std::string& message, const std::string& file_name, const std::string& function_name, int line_number ); } diff --git a/cgogn/core/basic/definitions.h b/cgogn/core/basic/definitions.h index 9c65b9ce..da858ddb 100644 --- a/cgogn/core/basic/definitions.h +++ b/cgogn/core/basic/definitions.h @@ -42,6 +42,11 @@ #define CGoGN_CORE_API #endif +#ifdef WIN32 +#define CGOGN_NOEXCEPT +#else +#define CGOGN_NOEXCEPT noexcept +#endif namespace cgogn { diff --git a/cgogn/core/map/attribute_handler.h b/cgogn/core/map/attribute_handler.h index d5c30965..db67b798 100644 --- a/cgogn/core/map/attribute_handler.h +++ b/cgogn/core/map/attribute_handler.h @@ -114,7 +114,7 @@ class AttributeHandlerOrbit : public AttributeHandlerGen , chunk_array_cont_(attho.chunk_array_cont_) {} - inline AttributeHandlerOrbit(AttributeHandlerOrbit< DATA_TRAITS, ORBIT >&& attho) noexcept : + inline AttributeHandlerOrbit(AttributeHandlerOrbit< DATA_TRAITS, ORBIT >&& attho) CGOGN_NOEXCEPT : Inherit(std::move(attho)) , chunk_array_cont_(attho.chunk_array_cont_) { @@ -184,7 +184,7 @@ class AttributeHandler : public AttributeHandlerOrbit ,chunk_array_(att.chunk_array_) {} - AttributeHandler(AttributeHandler&& att) noexcept : + AttributeHandler(AttributeHandler&& att) CGOGN_NOEXCEPT : Inherit(std::move(att)) ,chunk_array_(att.chunk_array_) { diff --git a/cgogn/core/map/map2.h b/cgogn/core/map/map2.h index 56fba9c8..9db3d466 100644 --- a/cgogn/core/map/map2.h +++ b/cgogn/core/map/map2.h @@ -39,13 +39,13 @@ class Map2 : public Map1 static const unsigned int FACE = FACE2; template - using VertexAttributeHandler = AttributeHandler; + using VertexAttributeHandler = cgogn::AttributeHandler; template - using EdgeAttributeHandler = AttributeHandler; + using EdgeAttributeHandler = cgogn::AttributeHandler; template - using FaceAttributeHandler = AttributeHandler; + using FaceAttributeHandler = cgogn::AttributeHandler; protected: From ab1532cde4fba2282b271c12d9c946411a75f742 Mon Sep 17 00:00:00 2001 From: Etienne Schmitt Date: Wed, 4 Nov 2015 17:37:49 +0100 Subject: [PATCH 040/185] removed unnecessary target_include_directories. Signed-off-by: Etienne Schmitt --- test/map/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/map/CMakeLists.txt b/test/map/CMakeLists.txt index 3c8e8614..71adbf78 100644 --- a/test/map/CMakeLists.txt +++ b/test/map/CMakeLists.txt @@ -8,4 +8,4 @@ target_link_libraries(test_map cgogn_core) # TARGET cgogn_core # PROPERTY INCLUDE_DIRECTORIES # ) -target_include_directories(test_map PRIVATE ${cgogn_core_includes}) +#target_include_directories(test_map PRIVATE ${cgogn_core_includes}) From 22b51918c7ce20d8e407be658d13e4211da36a97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Schmitt?= Date: Thu, 5 Nov 2015 12:24:11 +0100 Subject: [PATCH 041/185] More copy and move constructors, assignment op, move assignment op MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Étienne Schmitt --- cgogn/core/container/chunk_array.h | 77 ++++++++++++++++++++++- cgogn/core/container/chunk_stack.h | 26 ++++++++ cgogn/core/map/attribute_handler.h | 98 ++++++++++++++++++++++++++---- 3 files changed, 187 insertions(+), 14 deletions(-) diff --git a/cgogn/core/container/chunk_array.h b/cgogn/core/container/chunk_array.h index 51be440f..c961e443 100644 --- a/cgogn/core/container/chunk_array.h +++ b/cgogn/core/container/chunk_array.h @@ -56,6 +56,41 @@ class ChunkArray : public ChunkArrayGen tableData_.reserve(1024u); } + ChunkArray(const ChunkArray< CHUNKSIZE, T>& ca) + { + tableData_.reserve(1024u); + this->setNbChunks(ca.getNbChunks()); + for (std::size_t i = 0, end = tableData_.size() ; i < end ; ++i) + { + std::copy(ca.tableData_[i], ca.tableData_[i] + CHUNKSIZE, tableData_[i]); + } + } + + inline ChunkArray(ChunkArray< CHUNKSIZE, T>&& ca) : + tableData_(std::move(ca.tableData_)) + {} + + ChunkArray< CHUNKSIZE, T>& operator=(ChunkArray< CHUNKSIZE, T>&& ca) + { + // this != &ca because ca is a rvalue + this->clear(); + tableData_ = std::move(ca.tableData_); + return *this; + } + + ChunkArray< CHUNKSIZE, T>& operator=(const ChunkArray< CHUNKSIZE, T>& ca) + { + if (this != &ca) + { + this->setNbChunks(ca.getNbChunks()); + for (std::size_t i = 0, end = tableData_.size() ; i < end ; ++i) + { + std::copy(ca.tableData_[i], ca.tableData_[i] + CHUNKSIZE, tableData_[i]); + } + } + return *this; + } + /** * @brief Destructor of ChunkArray */ @@ -65,7 +100,7 @@ class ChunkArray : public ChunkArrayGen delete[] chunk; } - bool isBooleanArray() const + bool isBooleanArray() const override { return false; } @@ -338,7 +373,7 @@ class ChunkArray : public ChunkArrayGen public: - ChunkArray() : ChunkArrayGen() + inline ChunkArray() : ChunkArrayGen() { tableData_.reserve(1024u); } @@ -349,7 +384,43 @@ class ChunkArray : public ChunkArrayGen delete[] chunk; } - bool isBooleanArray() const + ChunkArray(const ChunkArray< CHUNKSIZE, bool>& ca) + { + tableData_.reserve(1024u); + this->setNbChunks(ca.getNbChunks()); + for (std::size_t i = 0, end = tableData_.size() ; i < end ; ++i) + { + std::copy(ca.tableData_[i], ca.tableData_[i] + CHUNKSIZE/32u, tableData_[i]); + } + } + + inline ChunkArray(ChunkArray< CHUNKSIZE, bool>&& ca) : + tableData_(std::move(ca.tableData_)) + {} + + ChunkArray< CHUNKSIZE, bool>& operator=(ChunkArray< CHUNKSIZE, bool>&& ca) + { + // this != &ca because ca is a rvalue + this->clear(); + tableData_ = std::move(ca.tableData_); + return *this; + } + + ChunkArray< CHUNKSIZE, bool>& operator=(const ChunkArray< CHUNKSIZE, bool>& ca) + { + if (this != &ca) + { + this->setNbChunks(ca.getNbChunks()); + for (std::size_t i = 0, end = tableData_.size() ; i < end ; ++i) + { + std::copy(ca.tableData_[i], ca.tableData_[i] + CHUNKSIZE/32u, tableData_[i]); + } + } + return *this; + } + + + bool isBooleanArray() const override { return true; } diff --git a/cgogn/core/container/chunk_stack.h b/cgogn/core/container/chunk_stack.h index c7afc31e..f7456f00 100644 --- a/cgogn/core/container/chunk_stack.h +++ b/cgogn/core/container/chunk_stack.h @@ -39,6 +39,8 @@ namespace cgogn template class ChunkStack : public ChunkArray { +public: + typedef ChunkArray Inherit; protected: unsigned int stackSize_; @@ -57,6 +59,30 @@ class ChunkStack : public ChunkArray inline ~ChunkStack() override {} + inline ChunkStack(const ChunkStack& cs) : + Inherit(cs) + ,stackSize_(cs.stackSize_) + {} + + inline ChunkStack(ChunkStack&& cs) : + Inherit(std::move(cs)) + ,stackSize_(cs.stackSize_) + {} + + inline ChunkStack& operator=(const ChunkStack& cs) + { + Inherit::operator =(cs); + stackSize_ = cs.stackSize_; + return *this; + } + + ChunkStack& operator=(ChunkStack&& cs) + { + Inherit::operator =(std::move(cs)); + stackSize_ = cs.stackSize_; + return *this; + } + /** * @brief push a value on top of heap * @param val diff --git a/cgogn/core/map/attribute_handler.h b/cgogn/core/map/attribute_handler.h index db67b798..60cef713 100644 --- a/cgogn/core/map/attribute_handler.h +++ b/cgogn/core/map/attribute_handler.h @@ -55,19 +55,49 @@ class AttributeHandlerGen ,valid_(false) {} + /** + * @brief copy constructor + * @param atthg + */ inline AttributeHandlerGen(const AttributeHandlerGen< DATA_TRAITS >& atthg) : map_(atthg.map_) ,valid_(atthg.valid_) {} - inline AttributeHandlerGen(AttributeHandlerGen< DATA_TRAITS >&& atthg) : + /** + * @brief move constructor + * @param atthg + */ + inline AttributeHandlerGen(AttributeHandlerGen< DATA_TRAITS >&& atthg) CGOGN_NOEXCEPT : map_(atthg.map_) ,valid_(atthg.valid_) + {} + + /** + * @brief operator = + * @param atthg + * @return + */ + inline AttributeHandlerGen& operator=(const AttributeHandlerGen< DATA_TRAITS >& atthg) + { + this->map_ = atthg.map_; + this->valid_ = atthg.valid_; + return *this; + } + + /** + * @brief move operator = + * @param atthg + * @return + */ + inline AttributeHandlerGen& operator=(AttributeHandlerGen< DATA_TRAITS >&& atthg) { - atthg.map_ = nullptr; - atthg.valid_ = false; + this->map_ = atthg.map_; + this->valid_ = atthg.valid_; + return *this; } + virtual ~AttributeHandlerGen() {} @@ -109,19 +139,49 @@ class AttributeHandlerOrbit : public AttributeHandlerGen } } + /** + * @brief copy constructor + * @param attho + */ inline AttributeHandlerOrbit(const AttributeHandlerOrbit< DATA_TRAITS, ORBIT >& attho) : Inherit(attho) , chunk_array_cont_(attho.chunk_array_cont_) {} + /** + * @brief move constructor + * @param attho + */ inline AttributeHandlerOrbit(AttributeHandlerOrbit< DATA_TRAITS, ORBIT >&& attho) CGOGN_NOEXCEPT : Inherit(std::move(attho)) , chunk_array_cont_(attho.chunk_array_cont_) + {} + + /** + * @brief operator = + * @param attho + * @return + */ + inline AttributeHandlerOrbit& operator=(const AttributeHandlerOrbit< DATA_TRAITS, ORBIT >& attho) { - attho.chunk_array_cont_ = nullptr; + Inherit::operator =(attho); + chunk_array_cont_ = attho.chunk_array_cont_; + return *this; + } + /** + * @brief move operator = + * @param attho + * @return + */ + inline AttributeHandlerOrbit& operator=(AttributeHandlerOrbit< DATA_TRAITS, ORBIT >&& attho) + { + Inherit::operator =(std::move(attho)); + chunk_array_cont_ = attho.chunk_array_cont_; + return *this; } virtual unsigned int getOrbit() const override { return ORBIT; } + virtual ~AttributeHandlerOrbit() override {} }; /** @@ -158,6 +218,7 @@ class AttributeHandler : public AttributeHandlerOrbit AttributeHandler(MapData* const m, const std::string& attributeName): Inherit(m) { + assert(this->chunk_array_cont_ != nullptr); chunk_array_ = this->chunk_array_cont_->getAttribute(attributeName); if (chunk_array_ == nullptr) { @@ -184,26 +245,40 @@ class AttributeHandler : public AttributeHandlerOrbit ,chunk_array_(att.chunk_array_) {} + /** + * @brief Move constructor + * @param att + */ AttributeHandler(AttributeHandler&& att) CGOGN_NOEXCEPT : Inherit(std::move(att)) ,chunk_array_(att.chunk_array_) + {} + + /** + * @brief operator = + * @param att + * @return + */ + AttributeHandler& operator=(const AttributeHandler& att) { - att.chunk_array_ = nullptr; + Inherit::operator=(att); + chunk_array_ = att.chunk_array_; + return *this; } /** - * @brief operator = + * @brief move operator = * @param att * @return */ - AttributeHandler& operator=(const AttributeHandler& att) + AttributeHandler& operator=(AttributeHandler&& att) { - this->valid_ = att.valid_; - this->map_ = att.map_; - this->chunk_array_cont_ = att.chunk_array_cont_; - this->chunck_array_ = att.chunck_array_; + Inherit::operator=(std::move(att)); + chunk_array_ = att.chunk_array_; + return *this; } + /** * @brief getDataVector * @return @@ -334,6 +409,7 @@ class AttributeHandler : public AttributeHandlerOrbit { return iterator(this,this->chunk_array_cont_->end()); } + virtual ~AttributeHandler() override {} }; } // namespace cgogn From e86be87ef6fb47bbac3d2688a86f58c7d89d9656 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Schmitt?= Date: Thu, 5 Nov 2015 12:48:26 +0100 Subject: [PATCH 042/185] improved ChunkArrayFactory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Étienne Schmitt --- cgogn/core/container/chunk_array_factory.h | 25 +++++++++------------- test/chunk_array/test_chunk_array.cpp | 9 +++----- 2 files changed, 13 insertions(+), 21 deletions(-) diff --git a/cgogn/core/container/chunk_array_factory.h b/cgogn/core/container/chunk_array_factory.h index 5558034e..a4059963 100644 --- a/cgogn/core/container/chunk_array_factory.h +++ b/cgogn/core/container/chunk_array_factory.h @@ -28,6 +28,7 @@ #include #include +#include namespace cgogn { @@ -36,18 +37,21 @@ template class ChunkArrayFactory { public: + typedef std::unique_ptr< ChunkArrayGen > ChunkArrayGenPtr; + typedef std::map Map; - static std::map*> mapCA_; + static Map mapCA_; /** * @brief register a type * @param keyType name of type * @param obj a ptr on object (new ChunkArray<32,int> for example) ptr will be deleted by clean method */ - static void registerCA(const std::string& keyType, ChunkArrayGen* obj) + template + static void registerCA(const std::string& keyType) { if(mapCA_.find(keyType) == mapCA_.end()) - mapCA_[keyType] = obj; + mapCA_[keyType] = ChunkArrayGenPtr(new ChunkArray()); } /** @@ -57,8 +61,8 @@ class ChunkArrayFactory */ static ChunkArrayGen* create(const std::string& keyType) { - ChunkArrayGen* tmp = NULL; - typename std::map*>::const_iterator it = mapCA_.find(keyType); + ChunkArrayGen* tmp = nullptr; + typename Map::const_iterator it = mapCA_.find(keyType); if(it != mapCA_.end()) { @@ -69,19 +73,10 @@ class ChunkArrayFactory return tmp; } - - /** - * @brief free allocated object stored in map - */ - static void clean() - { - for (auto it: mapCA_) - delete it.second; - } }; template -std::map*> ChunkArrayFactory::mapCA_= std::map*>(); +typename ChunkArrayFactory::Map ChunkArrayFactory::mapCA_= typename ChunkArrayFactory::Map(); } // namespace cgogn diff --git a/test/chunk_array/test_chunk_array.cpp b/test/chunk_array/test_chunk_array.cpp index e104dc30..e51b15b4 100644 --- a/test/chunk_array/test_chunk_array.cpp +++ b/test/chunk_array/test_chunk_array.cpp @@ -219,9 +219,9 @@ int test4() { std::cout << "=============== TEST 4 ===============" << std::endl; - ChunkArrayFactory::registerCA("float",new ChunkArray()); - ChunkArrayFactory::registerCA("int",new ChunkArray()); - ChunkArrayFactory::registerCA("bool",new ChunkArray()); + ChunkArrayFactory::registerCA("float"); + ChunkArrayFactory::registerCA("int"); + ChunkArrayFactory::registerCA("bool"); ChunkArrayContainer container; @@ -264,9 +264,6 @@ int test4() } std::cout << "----------------------------------------" << std::endl; - - ChunkArrayFactory::clean(); - return 0; } From 1c5e10eb96c3c9e9a85abe6a31be2467b39b7fce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Schmitt?= Date: Thu, 5 Nov 2015 16:39:55 +0100 Subject: [PATCH 043/185] removed useless chunk_array.cpp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Étienne Schmitt --- cgogn/core/CMakeLists.txt | 2 +- cgogn/core/container/chunk_array.cpp | 0 2 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 cgogn/core/container/chunk_array.cpp diff --git a/cgogn/core/CMakeLists.txt b/cgogn/core/CMakeLists.txt index 037895bb..2b22bb95 100644 --- a/cgogn/core/CMakeLists.txt +++ b/cgogn/core/CMakeLists.txt @@ -7,6 +7,7 @@ set(HEADER_FILES basic/dart.h basic/cell.h basic/assert.h + basic/serialization.h container/chunk_array_container.h container/chunk_array_factory.h container/chunk_array_gen.h @@ -24,7 +25,6 @@ set(HEADER_FILES set(SOURCE_FILES basic/assert.cpp - container/chunk_array.cpp ) add_library(${PROJECT_NAME} SHARED ${HEADER_FILES} ${SOURCE_FILES}) diff --git a/cgogn/core/container/chunk_array.cpp b/cgogn/core/container/chunk_array.cpp deleted file mode 100644 index e69de29b..00000000 From 37a804eb0a5b4ef005283103d35d50adf2d81d20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Schmitt?= Date: Thu, 5 Nov 2015 16:40:24 +0100 Subject: [PATCH 044/185] updated CGOGN_NOEXCEPT for VS 2015 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Étienne Schmitt --- cgogn/core/basic/definitions.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cgogn/core/basic/definitions.h b/cgogn/core/basic/definitions.h index da858ddb..825b1ee6 100644 --- a/cgogn/core/basic/definitions.h +++ b/cgogn/core/basic/definitions.h @@ -42,7 +42,7 @@ #define CGoGN_CORE_API #endif -#ifdef WIN32 +#if defined(_MSC_VER) && _MSC_VER < 1900 #define CGOGN_NOEXCEPT #else #define CGOGN_NOEXCEPT noexcept From bfa0df85e7af4655ab3061a52c13a2fccebfb8b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Schmitt?= Date: Thu, 5 Nov 2015 16:58:41 +0100 Subject: [PATCH 045/185] added serialization namespace, to ease saving and loading data. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Étienne Schmitt --- cgogn/core/basic/serialization.h | 79 ++++++++++++++++++++++++++ cgogn/core/container/chunk_array.h | 31 +++++----- cgogn/core/container/chunk_stack.h | 2 +- test/chunk_array/bench_chunk_array.cpp | 2 +- test/chunk_array/test_chunk_array.cpp | 13 ++++- 5 files changed, 106 insertions(+), 21 deletions(-) create mode 100644 cgogn/core/basic/serialization.h diff --git a/cgogn/core/basic/serialization.h b/cgogn/core/basic/serialization.h new file mode 100644 index 00000000..cba258a1 --- /dev/null +++ b/cgogn/core/basic/serialization.h @@ -0,0 +1,79 @@ +/******************************************************************************* +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * +* Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France * +* * +* This library is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by the * +* Free Software Foundation; either version 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: http://cgogn.unistra.fr/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ +#ifndef CORE_SERIALIZATION_H_ +#define CORE_SERIALIZATION_H_ +#include +#include + +namespace cgogn +{ +namespace serialization +{ + +template +void load(std::istream& istream, T * dest, std::size_t quantity) +{ + assert(dest != nullptr); + istream.read(reinterpret_cast(dest), quantity*sizeof(T)); +} + +template +void save(std::ostream& ostream, T const * src, std::size_t quantity) +{ + assert(src != nullptr); + ostream.write(reinterpret_cast(src),quantity*sizeof(T)); +} + +// loading n vectors +template +void load(std::istream& istream, std::vector* dest, std::size_t quantity) +{ + assert(dest != nullptr); + for (std::size_t i = 0; i < quantity ; ++i) + { + unsigned int vecSize; + istream.read(reinterpret_cast(&vecSize), sizeof(unsigned int)); + dest[i].resize(vecSize); + load(istream, &(dest[i][0]), vecSize); + } +} + +template +void save(std::ostream& ostream, std::vector const * src, std::size_t quantity) +{ + assert(src != nullptr); + for (std::size_t i = 0; i < quantity ; ++i) + { + const unsigned int size = src[i].size(); + ostream.write(reinterpret_cast(&size), sizeof(unsigned int)); + save(ostream, &(src[i][0]), size); + } + +} + + +} +} + +#endif // CORE_SERIALIZATION_H_ + diff --git a/cgogn/core/container/chunk_array.h b/cgogn/core/container/chunk_array.h index c961e443..d086b8f8 100644 --- a/cgogn/core/container/chunk_array.h +++ b/cgogn/core/container/chunk_array.h @@ -29,7 +29,7 @@ #include #include #include - +#include namespace cgogn { @@ -311,7 +311,7 @@ class ChunkArray : public ChunkArrayGen { assert(nbLines/CHUNKSIZE <= getNbChunks()); - fs.write(reinterpret_cast(&nbLines),sizeof(unsigned int)); + serialization::save(fs, &nbLines, 1); // no data -> finished if (nbLines == 0) @@ -322,19 +322,18 @@ class ChunkArray : public ChunkArrayGen // save data chunks except last for(unsigned int i=0; i(tableData_[i]),CHUNKSIZE*sizeof(T)); + serialization::save(fs, tableData_[i], CHUNKSIZE); } // save last incomplete chunk - unsigned nb = nbLines - nbc*CHUNKSIZE; - fs.write(reinterpret_cast(tableData_[nbc]),std::streamsize(nb*sizeof(T))); + const unsigned nb = nbLines - nbc*CHUNKSIZE; + serialization::save(fs, tableData_[nbc], nb); } bool load(std::istream& fs) override { unsigned int nbLines; - fs.read(reinterpret_cast(&nbLines), sizeof(unsigned int)); - + serialization::load(fs, &nbLines, 1); // no data -> finished if (nbLines == 0) return true; @@ -348,12 +347,12 @@ class ChunkArray : public ChunkArrayGen // load data chunks except last nbc--; - for(unsigned int i = 0; i < nbc; ++i) - fs.read(reinterpret_cast(tableData_[i]),CHUNKSIZE*sizeof(T)); + for(unsigned int i = 0u; i < nbc; ++i) + serialization::load(fs, tableData_[i], CHUNKSIZE); // load last incomplete chunk - unsigned int nb = nbLines - nbc*CHUNKSIZE; - fs.read(reinterpret_cast(tableData_[nbc]),std::streamsize(nb*sizeof(T))); + const unsigned int nb = nbLines - nbc*CHUNKSIZE; + serialization::load(fs, tableData_[nbc], nb); return true; } @@ -576,21 +575,21 @@ class ChunkArray : public ChunkArrayGen // TODO: if (nbLines==0) nbLines=CHUNKSIZE*tableData_.size(); ?? // save number of lines - fs.write(reinterpret_cast(&nbLines),sizeof(unsigned int)); + serialization::save(fs, &nbLines,1); // no data -> finished if (nbLines == 0u) return; - unsigned int nbc = getNbChunks()-1; + const unsigned int nbc = getNbChunks()-1u; // save data chunks except last for(unsigned int i=0u; i(tableData_[i]),CHUNKSIZE/8u);// /8 because bool = 1 bit & octet = 8 bit + fs.write(reinterpret_cast(tableData_[i]),CHUNKSIZE/8u); // /8 because bool = 1 bit & octet = 8 bit } // save last - unsigned int nb = nbLines - nbc*CHUNKSIZE; + const unsigned int nb = nbLines - nbc*CHUNKSIZE; fs.write(reinterpret_cast(tableData_[nbc]),nb/8u); } @@ -598,7 +597,7 @@ class ChunkArray : public ChunkArrayGen { // get number of lines to load unsigned int nbLines; - fs.read(reinterpret_cast(&nbLines), sizeof(unsigned int)); + serialization::load(fs, &nbLines, 1); // no data -> finished if (nbLines == 0) diff --git a/cgogn/core/container/chunk_stack.h b/cgogn/core/container/chunk_stack.h index f7456f00..d6de1e5e 100644 --- a/cgogn/core/container/chunk_stack.h +++ b/cgogn/core/container/chunk_stack.h @@ -76,7 +76,7 @@ class ChunkStack : public ChunkArray return *this; } - ChunkStack& operator=(ChunkStack&& cs) + inline ChunkStack& operator=(ChunkStack&& cs) { Inherit::operator =(std::move(cs)); stackSize_ = cs.stackSize_; diff --git a/test/chunk_array/bench_chunk_array.cpp b/test/chunk_array/bench_chunk_array.cpp index 15747e11..0b2d146e 100644 --- a/test/chunk_array/bench_chunk_array.cpp +++ b/test/chunk_array/bench_chunk_array.cpp @@ -1,6 +1,6 @@ #include - +#include #define BLK_SZ 4096 using namespace cgogn; diff --git a/test/chunk_array/test_chunk_array.cpp b/test/chunk_array/test_chunk_array.cpp index e51b15b4..c89e061d 100644 --- a/test/chunk_array/test_chunk_array.cpp +++ b/test/chunk_array/test_chunk_array.cpp @@ -218,17 +218,18 @@ int test3() int test4() { std::cout << "=============== TEST 4 ===============" << std::endl; - + typedef std::vector< std::vector< double > > vecvecdouble; ChunkArrayFactory::registerCA("float"); ChunkArrayFactory::registerCA("int"); ChunkArrayFactory::registerCA("bool"); + ChunkArrayFactory::registerCA("std::vector>"); ChunkArrayContainer container; ChunkArray* att1 = container.addAttribute("entier"); ChunkArray* att2 = container.addAttribute("reel"); ChunkArray* att3 = container.addAttribute("bools"); - + ChunkArray* att4 = container.addAttribute("vecvecdouble"); for (int i=0;i<7;++i) container.insertLines<3>(); @@ -239,6 +240,7 @@ int test4() (*att1)[i] = 1+int(i); (*att2)[i] = 3.0f + 0.1f*float(i); (*att3).setVal(i,i%2); + (*att4)[i] = {{3.0 + 0.1*double(i),15.0 + 0.1*double(i)}, {103.0 + 0.1*double(i), 203.0 + 0.1*double(i), 303.0 + 0.1*double(i)}}; } container.removeLines<3>(3); @@ -257,10 +259,15 @@ int test4() ChunkArray* load_att1 = cont2.getAttribute("entier"); ChunkArray* load_att2 = cont2.getAttribute("reel"); ChunkArray* load_att3 = cont2.getAttribute("bools"); + ChunkArray* load_att4 = cont2.getAttribute("vecvecdouble"); for(unsigned int i=cont2.begin(); i!=cont2.end(); cont2.next(i)) { - std::cout << i << ": "<< (*load_att1)[i] << " / " << (*load_att2)[i] << " / " << (*load_att3)[i] < Date: Thu, 5 Nov 2015 19:12:20 +0100 Subject: [PATCH 046/185] ChunkArrayFactory : the function registerCA() is now automatically called when adding an attribute. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Étienne Schmitt --- cgogn/core/container/chunk_array_container.h | 1 + cgogn/core/container/chunk_array_factory.h | 7 ++++--- test/chunk_array/test_chunk_array.cpp | 6 ------ 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/cgogn/core/container/chunk_array_container.h b/cgogn/core/container/chunk_array_container.h index dbde4c48..41d55f04 100644 --- a/cgogn/core/container/chunk_array_container.h +++ b/cgogn/core/container/chunk_array_container.h @@ -262,6 +262,7 @@ class ChunkArrayContainer // create the new attribute std::string typeName = nameOfType(T()) ; ChunkArray* carr = new ChunkArray() ; + ChunkArrayFactory::template registerCA(); // reserve memory carr->setNbChunks(refs_.getNbChunks()) ; diff --git a/cgogn/core/container/chunk_array_factory.h b/cgogn/core/container/chunk_array_factory.h index a4059963..14eb7008 100644 --- a/cgogn/core/container/chunk_array_factory.h +++ b/cgogn/core/container/chunk_array_factory.h @@ -24,8 +24,8 @@ #ifndef __CORE_CONTAINER_CHUNK_ARRAY_FACTORY_H__ #define __CORE_CONTAINER_CHUNK_ARRAY_FACTORY_H__ -#include "core/container/chunk_array.h" - +#include +#include #include #include #include @@ -48,8 +48,9 @@ class ChunkArrayFactory * @param obj a ptr on object (new ChunkArray<32,int> for example) ptr will be deleted by clean method */ template - static void registerCA(const std::string& keyType) + static void registerCA() { + const std::string& keyType(nameOfType(T())); if(mapCA_.find(keyType) == mapCA_.end()) mapCA_[keyType] = ChunkArrayGenPtr(new ChunkArray()); } diff --git a/test/chunk_array/test_chunk_array.cpp b/test/chunk_array/test_chunk_array.cpp index c89e061d..11a40b4d 100644 --- a/test/chunk_array/test_chunk_array.cpp +++ b/test/chunk_array/test_chunk_array.cpp @@ -214,16 +214,10 @@ int test3() return 0; } - int test4() { std::cout << "=============== TEST 4 ===============" << std::endl; typedef std::vector< std::vector< double > > vecvecdouble; - ChunkArrayFactory::registerCA("float"); - ChunkArrayFactory::registerCA("int"); - ChunkArrayFactory::registerCA("bool"); - ChunkArrayFactory::registerCA("std::vector>"); - ChunkArrayContainer container; ChunkArray* att1 = container.addAttribute("entier"); From 4a4f7d5d13a94bfee68aa5911ef42f470e7543c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Schmitt?= Date: Fri, 6 Nov 2015 13:58:07 +0100 Subject: [PATCH 047/185] overload serialization:: load and save for std::list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Étienne Schmitt --- cgogn/core/basic/nameTypes.h | 12 ++--- cgogn/core/basic/serialization.h | 48 +++++++++++++++++++- cgogn/core/container/chunk_array_container.h | 12 ++--- test/chunk_array/test_chunk_array.cpp | 11 ++++- 4 files changed, 67 insertions(+), 16 deletions(-) diff --git a/cgogn/core/basic/nameTypes.h b/cgogn/core/basic/nameTypes.h index 3f8759e6..b0d98782 100644 --- a/cgogn/core/basic/nameTypes.h +++ b/cgogn/core/basic/nameTypes.h @@ -40,6 +40,10 @@ std::string nameOfType(const T& /*v*/) return T::CGoGNnameOfType(); } +// first we need to declare some specializations +template inline std::string nameOfType(const std::list& /*v*/); +template inline std::string nameOfType(const std::vector& /*v*/); + template <> inline std::string nameOfType(const bool& /*v*/) { return "bool"; } template <> inline std::string nameOfType(const char& /*v*/) { return "char"; } @@ -86,14 +90,6 @@ class AddTypeName : public T static std::string CGoGNnameOfType() { return "UNKNOWN"; } }; -template -bool typeIsBool(T) -{ - return false; -} - -template <> bool typeIsBool(bool) { return true; } - } // namespace cgogn #endif // __CORE_BASIC_NAME_TYPES_H__ diff --git a/cgogn/core/basic/serialization.h b/cgogn/core/basic/serialization.h index cba258a1..1dd1c498 100644 --- a/cgogn/core/basic/serialization.h +++ b/cgogn/core/basic/serialization.h @@ -24,6 +24,7 @@ #define CORE_SERIALIZATION_H_ #include #include +#include namespace cgogn { @@ -44,6 +45,17 @@ void save(std::ostream& ostream, T const * src, std::size_t quantity) ostream.write(reinterpret_cast(src),quantity*sizeof(T)); } +// first step : declare all overrides of load and save +template +void load(std::istream& istream, std::vector* dest, std::size_t quantity); +template +void save(std::ostream& ostream, std::vector const * src, std::size_t quantity); +template +void load(std::istream& istream, std::list* dest, std::size_t quantity); +template +void save(std::ostream& ostream, std::list const * src, std::size_t quantity); + + // loading n vectors template void load(std::istream& istream, std::vector* dest, std::size_t quantity) @@ -58,19 +70,53 @@ void load(std::istream& istream, std::vector* dest, std::size_t quantity) } } +// saving n vectors template void save(std::ostream& ostream, std::vector const * src, std::size_t quantity) { assert(src != nullptr); for (std::size_t i = 0; i < quantity ; ++i) { - const unsigned int size = src[i].size(); + const unsigned int size = static_cast(src[i].size()); ostream.write(reinterpret_cast(&size), sizeof(unsigned int)); save(ostream, &(src[i][0]), size); } +} +// loading n lists +template +void load(std::istream& istream, std::list* dest, std::size_t quantity) +{ + assert(dest != nullptr); + for (std::size_t i = 0; i < quantity ; ++i) + { + unsigned int listSize; + istream.read(reinterpret_cast(&listSize), sizeof(unsigned int)); + std::vector temp; + temp.resize(listSize); + load(istream, &(temp[0]), listSize); + for(auto&& x : temp) + { + dest[i].emplace_back(std::move(x)); + } + + } } +// saving n lists +template +void save(std::ostream& ostream, std::list const * src, std::size_t quantity) +{ + assert(src != nullptr); + + for (std::size_t i = 0; i < quantity ; ++i) + { + const unsigned int size = static_cast(src[i].size()); + ostream.write(reinterpret_cast(&size), sizeof(unsigned int)); + for (const auto& elem : src[i]) + save(ostream, &elem, 1); + } +} } } diff --git a/cgogn/core/container/chunk_array_container.h b/cgogn/core/container/chunk_array_container.h index 41d55f04..249f8073 100644 --- a/cgogn/core/container/chunk_array_container.h +++ b/cgogn/core/container/chunk_array_container.h @@ -24,10 +24,10 @@ #ifndef __CORE_CONTAINER_CHUNK_ARRAY_CONTAINER_H__ #define __CORE_CONTAINER_CHUNK_ARRAY_CONTAINER_H__ -#include "core/container/chunk_array.h" -#include "core/container/chunk_stack.h" -#include "core/basic/nameTypes.h" -#include "core/container/chunk_array_factory.h" +#include +#include +#include +#include #include #include @@ -260,7 +260,7 @@ class ChunkArrayContainer } // create the new attribute - std::string typeName = nameOfType(T()) ; + const std::string& typeName = nameOfType(T()) ; ChunkArray* carr = new ChunkArray() ; ChunkArrayFactory::template registerCA(); @@ -273,7 +273,7 @@ class ChunkArrayContainer typeNames_.push_back(typeName); // move bool in front of others - if (typeIsBool(T())) + if (std::is_same::value) { if (tableArrays_.size() > nbBoolAttribs_) { diff --git a/test/chunk_array/test_chunk_array.cpp b/test/chunk_array/test_chunk_array.cpp index 11a40b4d..105a57c6 100644 --- a/test/chunk_array/test_chunk_array.cpp +++ b/test/chunk_array/test_chunk_array.cpp @@ -218,12 +218,13 @@ int test4() { std::cout << "=============== TEST 4 ===============" << std::endl; typedef std::vector< std::vector< double > > vecvecdouble; - + typedef std::vector< std::list< double > > veclistdouble; ChunkArrayContainer container; ChunkArray* att1 = container.addAttribute("entier"); ChunkArray* att2 = container.addAttribute("reel"); ChunkArray* att3 = container.addAttribute("bools"); ChunkArray* att4 = container.addAttribute("vecvecdouble"); + ChunkArray* att5 = container.addAttribute("veclistdouble"); for (int i=0;i<7;++i) container.insertLines<3>(); @@ -235,6 +236,7 @@ int test4() (*att2)[i] = 3.0f + 0.1f*float(i); (*att3).setVal(i,i%2); (*att4)[i] = {{3.0 + 0.1*double(i),15.0 + 0.1*double(i)}, {103.0 + 0.1*double(i), 203.0 + 0.1*double(i), 303.0 + 0.1*double(i)}}; + (*att5)[i] = {{3.0 + 0.1*double(i),15.0 + 0.1*double(i)}, {103.0 + 0.1*double(i), 203.0 + 0.1*double(i), 303.0 + 0.1*double(i)}}; } container.removeLines<3>(3); @@ -254,6 +256,7 @@ int test4() ChunkArray* load_att2 = cont2.getAttribute("reel"); ChunkArray* load_att3 = cont2.getAttribute("bools"); ChunkArray* load_att4 = cont2.getAttribute("vecvecdouble"); + ChunkArray* load_att5 = cont2.getAttribute("veclistdouble"); for(unsigned int i=cont2.begin(); i!=cont2.end(); cont2.next(i)) { @@ -261,7 +264,13 @@ int test4() for (const auto& v : (*load_att4)[i]) for (auto x : v) std::cout << x << " "; + + std::cout << " / "; + for (const auto& v : (*load_att5)[i]) + for (auto x : v) + std::cout << x << " "; std::cout << std::endl; + } std::cout << "----------------------------------------" << std::endl; From 0e972ad47a8300fb1453a508262fab59f159b8da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Schmitt?= Date: Fri, 6 Nov 2015 15:46:33 +0100 Subject: [PATCH 048/185] added nameOfType for signed chars MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Étienne Schmitt --- cgogn/core/basic/nameTypes.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cgogn/core/basic/nameTypes.h b/cgogn/core/basic/nameTypes.h index b0d98782..d5e853b9 100644 --- a/cgogn/core/basic/nameTypes.h +++ b/cgogn/core/basic/nameTypes.h @@ -55,6 +55,8 @@ template <> inline std::string nameOfType(const int& /*v*/) { return "int"; } template <> inline std::string nameOfType(const long& /*v*/) { return "long"; } template <> inline std::string nameOfType(const long long& /*v*/) { return "long long"; } +// because signed char != char +template <> inline std::string nameOfType(const signed char& /*v*/) { return "signed char"; } template <> inline std::string nameOfType(const unsigned char& /*v*/) { return "unsigned char"; } From 4e37e8fdc536cc275ef3c076da517b1e59807e13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Schmitt?= Date: Fri, 6 Nov 2015 15:47:25 +0100 Subject: [PATCH 049/185] Removed copy/move constructors and assignments operators for chunkarray and chunkarraygen MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Étienne Schmitt --- cgogn/core/container/chunk_array.h | 38 +++----------------------- cgogn/core/container/chunk_array_gen.h | 5 ++++ 2 files changed, 9 insertions(+), 34 deletions(-) diff --git a/cgogn/core/container/chunk_array.h b/cgogn/core/container/chunk_array.h index d086b8f8..06f268fd 100644 --- a/cgogn/core/container/chunk_array.h +++ b/cgogn/core/container/chunk_array.h @@ -56,40 +56,10 @@ class ChunkArray : public ChunkArrayGen tableData_.reserve(1024u); } - ChunkArray(const ChunkArray< CHUNKSIZE, T>& ca) - { - tableData_.reserve(1024u); - this->setNbChunks(ca.getNbChunks()); - for (std::size_t i = 0, end = tableData_.size() ; i < end ; ++i) - { - std::copy(ca.tableData_[i], ca.tableData_[i] + CHUNKSIZE, tableData_[i]); - } - } - - inline ChunkArray(ChunkArray< CHUNKSIZE, T>&& ca) : - tableData_(std::move(ca.tableData_)) - {} - - ChunkArray< CHUNKSIZE, T>& operator=(ChunkArray< CHUNKSIZE, T>&& ca) - { - // this != &ca because ca is a rvalue - this->clear(); - tableData_ = std::move(ca.tableData_); - return *this; - } - - ChunkArray< CHUNKSIZE, T>& operator=(const ChunkArray< CHUNKSIZE, T>& ca) - { - if (this != &ca) - { - this->setNbChunks(ca.getNbChunks()); - for (std::size_t i = 0, end = tableData_.size() ; i < end ; ++i) - { - std::copy(ca.tableData_[i], ca.tableData_[i] + CHUNKSIZE, tableData_[i]); - } - } - return *this; - } + ChunkArray(const ChunkArray< CHUNKSIZE, T>& ca) = delete; + ChunkArray(ChunkArray< CHUNKSIZE, T>&& ca) = delete; + ChunkArray< CHUNKSIZE, T>& operator=(ChunkArray< CHUNKSIZE, T>&& ca) = delete; + ChunkArray< CHUNKSIZE, T>& operator=(const ChunkArray< CHUNKSIZE, T>& ca) = delete; /** * @brief Destructor of ChunkArray diff --git a/cgogn/core/container/chunk_array_gen.h b/cgogn/core/container/chunk_array_gen.h index c5849a96..9660053a 100644 --- a/cgogn/core/container/chunk_array_gen.h +++ b/cgogn/core/container/chunk_array_gen.h @@ -37,6 +37,11 @@ template class ChunkArrayGen { public: + ChunkArrayGen() = default; + ChunkArrayGen(ChunkArrayGenconst& ) = delete; + ChunkArrayGen(ChunkArrayGen&& ) = delete; + ChunkArrayGen& operator=(ChunkArrayGenconst& ) = delete; + ChunkArrayGen& operator=(ChunkArrayGen&& ) = delete; /** * @brief virtual destructor From 92bb8cdefd62d80ead00f0057e2102956e061284 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Schmitt?= Date: Fri, 6 Nov 2015 15:48:59 +0100 Subject: [PATCH 050/185] fixed a memory leak in ChunkArrayContainer. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit *Added setCurrentBrowser and setStandardBrowser methods Signed-off-by: Étienne Schmitt --- cgogn/core/container/chunk_array_container.h | 27 +++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/cgogn/core/container/chunk_array_container.h b/cgogn/core/container/chunk_array_container.h index 249f8073..2ac5f154 100644 --- a/cgogn/core/container/chunk_array_container.h +++ b/cgogn/core/container/chunk_array_container.h @@ -34,6 +34,7 @@ #include #include #include +#include #include namespace cgogn @@ -126,7 +127,7 @@ class ChunkArrayContainer /** * Browser that allow special traversals */ - ContainerStandardBrowser< ChunkArrayContainer >* stdBrowser_; + std::unique_ptr< ContainerStandardBrowser< ChunkArrayContainer > > stdBrowser_; /** * @brief get array index from name @@ -211,8 +212,8 @@ class ChunkArrayContainer nbUsedLines_(0u), nbMaxLines_(0u) { - stdBrowser_ = new ContainerStandardBrowser< ChunkArrayContainer >(this); - currentBrowser_= stdBrowser_; + stdBrowser_.reset(new ContainerStandardBrowser< ChunkArrayContainer >(this)); + currentBrowser_= stdBrowser_.get(); } /** @@ -220,6 +221,8 @@ class ChunkArrayContainer */ ~ChunkArrayContainer() { + if (currentBrowser_ != stdBrowser_.get()) + delete currentBrowser_; for (auto ptr: tableArrays_) delete ptr; } @@ -368,6 +371,24 @@ class ChunkArrayContainer { return refs_[index] != 0; } + /** + * @brief setCurrentBrowser + * @param browser, pointer to a heap-allocated ContainerBrowser + */ + inline void setCurrentBrowser(ContainerBrowser* browser) + { + if (currentBrowser_ != stdBrowser_.get()) + delete currentBrowser_; + currentBrowser_ = browser; + } + + inline void setStandardBrowser() + { + if (currentBrowser_ != stdBrowser_.get()) + delete currentBrowser_; + currentBrowser_ = stdBrowser_; + } + /** * @brief begin From d828aaa5c7d757118712e0edc6b0e7533e6ccf18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Schmitt?= Date: Fri, 6 Nov 2015 16:23:14 +0100 Subject: [PATCH 051/185] Added MapGen and derived classes' destructors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Étienne Schmitt --- cgogn/core/map/map1.h | 2 ++ cgogn/core/map/map2.h | 1 + cgogn/core/map/map_base.h | 2 +- cgogn/core/map/map_base_data.h | 6 +++++- cgogn/core/map/map_tri.h | 5 ++--- 5 files changed, 11 insertions(+), 5 deletions(-) diff --git a/cgogn/core/map/map1.h b/cgogn/core/map/map1.h index 9dadcb48..7fb17ab7 100644 --- a/cgogn/core/map/map1.h +++ b/cgogn/core/map/map1.h @@ -104,6 +104,8 @@ class Map1 : public MapBase init(); } + virtual ~Map1() override {} + /** * @brief phi1 * @param d diff --git a/cgogn/core/map/map2.h b/cgogn/core/map/map2.h index 9db3d466..acf5b090 100644 --- a/cgogn/core/map/map2.h +++ b/cgogn/core/map/map2.h @@ -87,6 +87,7 @@ class Map2 : public Map1 init(); } + ~Map2() override {} /** * @brief phi2 * @param d diff --git a/cgogn/core/map/map_base.h b/cgogn/core/map/map_base.h index 8bfda9d1..9a0b7d9c 100644 --- a/cgogn/core/map/map_base.h +++ b/cgogn/core/map/map_base.h @@ -51,7 +51,7 @@ class MapBase : public MapBaseData template inline AttributeHandler addAttribute(const std::string& attributeName = "") { - if (this->embeddings_[ORBIT] == NULL) + if (this->embeddings_[ORBIT] == nullptr) { std::ostringstream oss; oss << "EMB_" << orbitName(ORBIT); diff --git a/cgogn/core/map/map_base_data.h b/cgogn/core/map/map_base_data.h index 34561c75..14d7b685 100644 --- a/cgogn/core/map/map_base_data.h +++ b/cgogn/core/map/map_base_data.h @@ -40,6 +40,8 @@ namespace cgogn */ class MapGen { +public: + virtual ~MapGen() {} }; @@ -79,12 +81,14 @@ class MapBaseData : public MapGen MapBaseData() { for (unsigned int i = 0; i < NB_ORBITS; ++i) - embeddings_[i] = NULL; + embeddings_[i] = nullptr; thread_ids_.reserve(NB_THREADS + 1); thread_ids_.push_back(std::this_thread::get_id()); } + ~MapBaseData() override {} + inline ChunkArrayContainer& getAttributeContainer(unsigned int orbit) { return attributes_[orbit]; diff --git a/cgogn/core/map/map_tri.h b/cgogn/core/map/map_tri.h index 2b6651f4..4405de96 100644 --- a/cgogn/core/map/map_tri.h +++ b/cgogn/core/map/map_tri.h @@ -36,9 +36,8 @@ class Traits_map_tri class MapTri : public MapBase { - - - +public: + ~MapTri() override {} }; } // namespace cgogn From d21275053454835cf3bc007c1c788a828b6dee8e Mon Sep 17 00:00:00 2001 From: Lionel Untereiner Date: Fri, 6 Nov 2015 20:53:41 +0100 Subject: [PATCH 052/185] correction of a cast between size_t and streamsize adding include of cassert --- cgogn/core/basic/serialization.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cgogn/core/basic/serialization.h b/cgogn/core/basic/serialization.h index 1dd1c498..3e7fe9f0 100644 --- a/cgogn/core/basic/serialization.h +++ b/cgogn/core/basic/serialization.h @@ -22,9 +22,11 @@ *******************************************************************************/ #ifndef CORE_SERIALIZATION_H_ #define CORE_SERIALIZATION_H_ + #include #include #include +#include namespace cgogn { @@ -35,14 +37,14 @@ template void load(std::istream& istream, T * dest, std::size_t quantity) { assert(dest != nullptr); - istream.read(reinterpret_cast(dest), quantity*sizeof(T)); + istream.read(reinterpret_cast(dest), static_cast(quantity*sizeof(T))); } template void save(std::ostream& ostream, T const * src, std::size_t quantity) { assert(src != nullptr); - ostream.write(reinterpret_cast(src),quantity*sizeof(T)); + ostream.write(reinterpret_cast(src), static_cast(quantity*sizeof(T))); } // first step : declare all overrides of load and save From edcebb375439fb7c96e7fa5d23fd6ea916e7dc6d Mon Sep 17 00:00:00 2001 From: Lionel Untereiner Date: Fri, 6 Nov 2015 20:54:45 +0100 Subject: [PATCH 053/185] changing the include gardes name to be C/C++ compliant (warnings with clang) --- cgogn/core/basic/assert.h | 2 +- cgogn/core/basic/cell.h | 6 +++--- cgogn/core/basic/dart.h | 6 +++--- cgogn/core/basic/definitions.h | 6 +++--- cgogn/core/basic/nameTypes.h | 6 +++--- cgogn/core/container/chunk_array.h | 12 +++++++----- cgogn/core/container/chunk_array_container.h | 9 +++++---- cgogn/core/container/chunk_array_factory.h | 9 +++++---- cgogn/core/container/chunk_array_gen.h | 6 +++--- cgogn/core/container/chunk_stack.h | 8 ++++---- cgogn/core/map/attribute_handler.h | 10 +++++----- cgogn/core/map/map1.h | 10 +++++----- cgogn/core/map/map2.h | 8 ++++---- cgogn/core/map/map_base.h | 10 +++++----- cgogn/core/map/map_base_data.h | 14 +++++++------- cgogn/core/map/map_tri.h | 8 ++++---- cgogn/utils/buffers.h | 6 +++--- test/map/test_map.cpp | 4 ++-- 18 files changed, 72 insertions(+), 68 deletions(-) diff --git a/cgogn/core/basic/assert.h b/cgogn/core/basic/assert.h index 46c810c9..7b1d8022 100644 --- a/cgogn/core/basic/assert.h +++ b/cgogn/core/basic/assert.h @@ -149,4 +149,4 @@ namespace cgogn #define parano_message_assert(x, msg) #endif -#endif +#endif // CORE_BASIC_ASSERT_ diff --git a/cgogn/core/basic/cell.h b/cgogn/core/basic/cell.h index c4cb32a3..c5f492a5 100644 --- a/cgogn/core/basic/cell.h +++ b/cgogn/core/basic/cell.h @@ -21,8 +21,8 @@ * * *******************************************************************************/ -#ifndef __CORE_BASIC_CELL_H__ -#define __CORE_BASIC_CELL_H__ +#ifndef CORE_BASIC_CELL_H_ +#define CORE_BASIC_CELL_H_ #include "core/basic/dart.h" @@ -91,4 +91,4 @@ class Cell } // namespace cgogn -#endif // __CORE_BASIC_CELL_H__ +#endif // CORE_BASIC_CELL_H_ diff --git a/cgogn/core/basic/dart.h b/cgogn/core/basic/dart.h index 6bde6daf..be93b6f5 100644 --- a/cgogn/core/basic/dart.h +++ b/cgogn/core/basic/dart.h @@ -21,8 +21,8 @@ * * *******************************************************************************/ -#ifndef __CORE_BASIC_DART_H__ -#define __CORE_BASIC_DART_H__ +#ifndef CORE_BASIC_DART_H_ +#define CORE_BASIC_DART_H_ namespace cgogn { @@ -66,4 +66,4 @@ const unsigned int EMBNULL = 0xffffffff; } // namespace cgogn -#endif // __CORE_BASIC_DART_H__ +#endif // CORE_BASIC_DART_H_ diff --git a/cgogn/core/basic/definitions.h b/cgogn/core/basic/definitions.h index 825b1ee6..e3edd0cf 100644 --- a/cgogn/core/basic/definitions.h +++ b/cgogn/core/basic/definitions.h @@ -21,8 +21,8 @@ * * *******************************************************************************/ -#ifndef __CORE_BASIC_DEFINITIONS_H__ -#define __CORE_BASIC_DEFINITIONS_H__ +#ifndef CORE_BASIC_DEFINITIONS_H_ +#define CORE_BASIC_DEFINITIONS_H_ /** * \file basic/definitions.h @@ -55,4 +55,4 @@ const unsigned int NB_THREADS = 8u; } // namespace cgogn -#endif // __CORE_BASIC_DEFINITIONS_H__ +#endif // CORE_BASIC_DEFINITIONS_H_ diff --git a/cgogn/core/basic/nameTypes.h b/cgogn/core/basic/nameTypes.h index d5e853b9..a0275d98 100644 --- a/cgogn/core/basic/nameTypes.h +++ b/cgogn/core/basic/nameTypes.h @@ -21,8 +21,8 @@ * * *******************************************************************************/ -#ifndef __CORE_BASIC_NAME_TYPES_H__ -#define __CORE_BASIC_NAME_TYPES_H__ +#ifndef CORE_BASIC_NAME_TYPES_H_ +#define CORE_BASIC_NAME_TYPES_H_ #include #include @@ -94,4 +94,4 @@ class AddTypeName : public T } // namespace cgogn -#endif // __CORE_BASIC_NAME_TYPES_H__ +#endif // CORE_BASIC_NAME_TYPES_H_ diff --git a/cgogn/core/container/chunk_array.h b/cgogn/core/container/chunk_array.h index 06f268fd..47ec65e2 100644 --- a/cgogn/core/container/chunk_array.h +++ b/cgogn/core/container/chunk_array.h @@ -21,15 +21,17 @@ * * *******************************************************************************/ -#ifndef __CORE_CONTAINER_CHUNK_ARRAY_H__ -#define __CORE_CONTAINER_CHUNK_ARRAY_H__ +#ifndef CORE_CONTAINER_CHUNK_ARRAY_H_ +#define CORE_CONTAINER_CHUNK_ARRAY_H_ + +#include +#include -#include "core/container/chunk_array_gen.h" #include #include #include #include -#include + namespace cgogn { @@ -595,4 +597,4 @@ class ChunkArray : public ChunkArrayGen } // namespace cgogn -#endif // __CORE_CONTAINER_CHUNK_ARRAY_H__ +#endif // CORE_CONTAINER_CHUNK_ARRAY_H_ diff --git a/cgogn/core/container/chunk_array_container.h b/cgogn/core/container/chunk_array_container.h index 2ac5f154..1cbc2b20 100644 --- a/cgogn/core/container/chunk_array_container.h +++ b/cgogn/core/container/chunk_array_container.h @@ -21,10 +21,12 @@ * * *******************************************************************************/ -#ifndef __CORE_CONTAINER_CHUNK_ARRAY_CONTAINER_H__ -#define __CORE_CONTAINER_CHUNK_ARRAY_CONTAINER_H__ +#ifndef CORE_CONTAINER_CHUNK_ARRAY_CONTAINER_H_ +#define CORE_CONTAINER_CHUNK_ARRAY_CONTAINER_H_ #include +#include + #include #include #include @@ -35,7 +37,6 @@ #include #include #include -#include namespace cgogn { @@ -845,4 +846,4 @@ class ChunkArrayContainer } // namespace cgogn -#endif // __CORE_CONTAINER_CHUNK_ARRAY_CONTAINER_H__ +#endif // CORE_CONTAINER_CHUNK_ARRAY_CONTAINER_H_ diff --git a/cgogn/core/container/chunk_array_factory.h b/cgogn/core/container/chunk_array_factory.h index 14eb7008..df49b422 100644 --- a/cgogn/core/container/chunk_array_factory.h +++ b/cgogn/core/container/chunk_array_factory.h @@ -21,11 +21,12 @@ * * *******************************************************************************/ -#ifndef __CORE_CONTAINER_CHUNK_ARRAY_FACTORY_H__ -#define __CORE_CONTAINER_CHUNK_ARRAY_FACTORY_H__ +#ifndef CORE_CONTAINER_CHUNK_ARRAY_FACTORY_H_ +#define CORE_CONTAINER_CHUNK_ARRAY_FACTORY_H_ -#include #include +#include + #include #include #include @@ -81,4 +82,4 @@ typename ChunkArrayFactory::Map ChunkArrayFactory::mapCA_= } // namespace cgogn -#endif // __CORE_CONTAINER_CHUNK_ARRAY_FACTORY_H__ +#endif // CORE_CONTAINER_CHUNK_ARRAY_FACTORY_H_ diff --git a/cgogn/core/container/chunk_array_gen.h b/cgogn/core/container/chunk_array_gen.h index 9660053a..da208f95 100644 --- a/cgogn/core/container/chunk_array_gen.h +++ b/cgogn/core/container/chunk_array_gen.h @@ -21,8 +21,8 @@ * * *******************************************************************************/ -#ifndef __CORE_CONTAINER_CHUNK_ARRAY_GEN_H__ -#define __CORE_CONTAINER_CHUNK_ARRAY_GEN_H__ +#ifndef CORE_CONTAINER_CHUNK_ARRAY_GEN_H_ +#define CORE_CONTAINER_CHUNK_ARRAY_GEN_H_ #include #include @@ -133,4 +133,4 @@ class ChunkArrayGen } // namespace cgogn -#endif // __CORE_CONTAINER_CHUNK_ARRAY_GEN_H__ +#endif // CORE_CONTAINER_CHUNK_ARRAY_GEN_H_ diff --git a/cgogn/core/container/chunk_stack.h b/cgogn/core/container/chunk_stack.h index d6de1e5e..2a20de3b 100644 --- a/cgogn/core/container/chunk_stack.h +++ b/cgogn/core/container/chunk_stack.h @@ -21,10 +21,10 @@ * * *******************************************************************************/ -#ifndef __CORE_CONTAINER_CHUNK_STACK_H__ -#define __CORE_CONTAINER_CHUNK_STACK_H__ +#ifndef CORE_CONTAINER_CHUNK_STACK_H_ +#define CORE_CONTAINER_CHUNK_STACK_H_ -#include "core/container/chunk_array.h" +#include #include @@ -162,4 +162,4 @@ class ChunkStack : public ChunkArray } // namespace cgogn -#endif // __CORE_CONTAINER_CHUNK_STACK_H__ +#endif // CORE_CONTAINER_CHUNK_STACK_H_ diff --git a/cgogn/core/map/attribute_handler.h b/cgogn/core/map/attribute_handler.h index 60cef713..89d3d46e 100644 --- a/cgogn/core/map/attribute_handler.h +++ b/cgogn/core/map/attribute_handler.h @@ -21,11 +21,11 @@ * * *******************************************************************************/ -#ifndef __CORE_MAP_ATTRIBUTE_HANDLER_H__ -#define __CORE_MAP_ATTRIBUTE_HANDLER_H__ +#ifndef CORE_MAP_ATTRIBUTE_HANDLER_H_ +#define CORE_MAP_ATTRIBUTE_HANDLER_H_ -#include "core/map/map_base.h" -#include "core/basic/cell.h" +#include +#include ///TODO ajouter enregistrement dans la map de la carte. @@ -414,4 +414,4 @@ class AttributeHandler : public AttributeHandlerOrbit } // namespace cgogn -#endif // __CORE_MAP_ATTRIBUTE_HANDLER_H__ +#endif // CORE_MAP_ATTRIBUTE_HANDLER_H_ diff --git a/cgogn/core/map/map1.h b/cgogn/core/map/map1.h index 9dadcb48..c13a51da 100644 --- a/cgogn/core/map/map1.h +++ b/cgogn/core/map/map1.h @@ -21,11 +21,11 @@ * * *******************************************************************************/ -#ifndef __CORE_MAP_MAP1_H__ -#define __CORE_MAP_MAP1_H__ +#ifndef CORE_MAP_MAP1_H_ +#define CORE_MAP_MAP1_H_ -#include "core/map/map_base.h" -#include "core/basic/dart.h" +#include +#include namespace cgogn { @@ -179,4 +179,4 @@ class Map1 : public MapBase } // namespace cgogn -#endif // __CORE_MAP_MAP1_H__ +#endif // CORE_MAP_MAP1_H_ diff --git a/cgogn/core/map/map2.h b/cgogn/core/map/map2.h index 9db3d466..956d8469 100644 --- a/cgogn/core/map/map2.h +++ b/cgogn/core/map/map2.h @@ -21,10 +21,10 @@ * * *******************************************************************************/ -#ifndef __CORE_MAP_MAP2_H__ -#define __CORE_MAP_MAP2_H__ +#ifndef CORE_MAP_MAP2_H_ +#define CORE_MAP_MAP2_H_ -#include "core/map/map1.h" +#include namespace cgogn { @@ -101,4 +101,4 @@ class Map2 : public Map1 } // namespace cgogn -#endif // __CORE_MAP_MAP2_H__ +#endif // CORE_MAP_MAP2_H_ diff --git a/cgogn/core/map/map_base.h b/cgogn/core/map/map_base.h index 8bfda9d1..66c5a804 100644 --- a/cgogn/core/map/map_base.h +++ b/cgogn/core/map/map_base.h @@ -21,11 +21,11 @@ * * *******************************************************************************/ -#ifndef __CORE_MAP_MAP_BASE_H__ -#define __CORE_MAP_MAP_BASE_H__ +#ifndef CORE_MAP_MAP_BASE_H_ +#define CORE_MAP_MAP_BASE_H_ -#include "core/map/map_base_data.h" -#include "core/map/attribute_handler.h" +#include +#include #include @@ -121,4 +121,4 @@ class MapBase : public MapBaseData } // namespace cgogn -#endif // __CORE_MAP_MAP_BASE_H__ +#endif // CORE_MAP_MAP_BASE_H_ diff --git a/cgogn/core/map/map_base_data.h b/cgogn/core/map/map_base_data.h index 34561c75..10344b0d 100644 --- a/cgogn/core/map/map_base_data.h +++ b/cgogn/core/map/map_base_data.h @@ -21,14 +21,14 @@ * * *******************************************************************************/ -#ifndef __CORE_MAP_MAP_BASE_DATA_H__ -#define __CORE_MAP_MAP_BASE_DATA_H__ +#ifndef CORE_MAP_MAP_BASE_DATA_H_ +#define CORE_MAP_MAP_BASE_DATA_H_ -#include "core/container/chunk_array_container.h" -#include "core/basic/definitions.h" -#include "core/basic/cell.h" +#include +#include +#include -#include "utils/buffers.h" +#include #include @@ -138,4 +138,4 @@ class MapBaseData : public MapGen } // namespace cgogn -#endif // __CORE_MAP_MAP_BASE_DATA_H__ +#endif // CORE_MAP_MAP_BASE_DATA_H_ diff --git a/cgogn/core/map/map_tri.h b/cgogn/core/map/map_tri.h index 2b6651f4..117308e3 100644 --- a/cgogn/core/map/map_tri.h +++ b/cgogn/core/map/map_tri.h @@ -21,10 +21,10 @@ * * *******************************************************************************/ -#ifndef __CORE_MAP_MAP_TRI_H__ -#define __CORE_MAP_MAP_TRI_H__ +#ifndef CORE_MAP_MAP_TRI_H_ +#define CORE_MAP_MAP_TRI_H_ -#include "core/map/map_base.h" +#include namespace cgogn { @@ -43,4 +43,4 @@ class MapTri : public MapBase } // namespace cgogn -#endif // __CORE_MAP_MAP_TRI_H__ +#endif // CORE_MAP_MAP_TRI_H_ diff --git a/cgogn/utils/buffers.h b/cgogn/utils/buffers.h index 5610fc7f..d914b60d 100644 --- a/cgogn/utils/buffers.h +++ b/cgogn/utils/buffers.h @@ -21,8 +21,8 @@ * * *******************************************************************************/ -#ifndef __UTILS_BUFFERS_H__ -#define __UTILS_BUFFERS_H__ +#ifndef UTILS_BUFFERS_H_ +#define UTILS_BUFFERS_H_ #include @@ -68,4 +68,4 @@ class Buffers } // namespace cgogn -#endif // __UTILS_BUFFERS_H__ +#endif // UTILS_BUFFERS_H_ diff --git a/test/map/test_map.cpp b/test/map/test_map.cpp index b77c57a5..48640816 100644 --- a/test/map/test_map.cpp +++ b/test/map/test_map.cpp @@ -1,6 +1,6 @@ -#include "core/map/map1.h" -#include "core/map/map2.h" +#include +#include using namespace cgogn; From bf4d56df7a8baf3e725d40231cd4de8099ce2675 Mon Sep 17 00:00:00 2001 From: Lionel Untereiner Date: Fri, 6 Nov 2015 20:58:56 +0100 Subject: [PATCH 054/185] correction of an old style cast --- cgogn/core/container/chunk_array_container.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cgogn/core/container/chunk_array_container.h b/cgogn/core/container/chunk_array_container.h index 1cbc2b20..fa5c7cd7 100644 --- a/cgogn/core/container/chunk_array_container.h +++ b/cgogn/core/container/chunk_array_container.h @@ -771,7 +771,7 @@ class ChunkArrayContainer // save info (size+used_lines+max_lines+sizeof names) std::vector buffer; buffer.reserve(1024); - buffer.push_back((unsigned int)(tableArrays_.size())); + buffer.push_back(static_cast(tableArrays_.size())); buffer.push_back(nbUsedLines_); buffer.push_back(nbMaxLines_); buffer.push_back(nbBoolAttribs_); From 9d0cc52836b90eca4c81b7a30d8345a1e642a3e7 Mon Sep 17 00:00:00 2001 From: Lionel Untereiner Date: Fri, 6 Nov 2015 21:18:53 +0100 Subject: [PATCH 055/185] adding a cpp file with ContainerBrowser dtor avoids the warning "-Wweak-vtables" (i.e. has no out-of-line virtual method definitions). It avoids a copy of the class in every translation unit. --- cgogn/core/CMakeLists.txt | 4 +++- cgogn/core/container/chunk_array_container.cpp | 10 ++++++++++ cgogn/core/container/chunk_array_container.h | 2 +- 3 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 cgogn/core/container/chunk_array_container.cpp diff --git a/cgogn/core/CMakeLists.txt b/cgogn/core/CMakeLists.txt index 2b22bb95..ef11314f 100644 --- a/cgogn/core/CMakeLists.txt +++ b/cgogn/core/CMakeLists.txt @@ -7,7 +7,7 @@ set(HEADER_FILES basic/dart.h basic/cell.h basic/assert.h - basic/serialization.h + basic/serialization.h container/chunk_array_container.h container/chunk_array_factory.h container/chunk_array_gen.h @@ -25,6 +25,8 @@ set(HEADER_FILES set(SOURCE_FILES basic/assert.cpp + + container/chunk_array_container.cpp ) add_library(${PROJECT_NAME} SHARED ${HEADER_FILES} ${SOURCE_FILES}) diff --git a/cgogn/core/container/chunk_array_container.cpp b/cgogn/core/container/chunk_array_container.cpp new file mode 100644 index 00000000..fae1a793 --- /dev/null +++ b/cgogn/core/container/chunk_array_container.cpp @@ -0,0 +1,10 @@ +#include + +namespace cgogn +{ + + ContainerBrowser::~ContainerBrowser() + { + + } +} diff --git a/cgogn/core/container/chunk_array_container.h b/cgogn/core/container/chunk_array_container.h index fa5c7cd7..5285251a 100644 --- a/cgogn/core/container/chunk_array_container.h +++ b/cgogn/core/container/chunk_array_container.h @@ -51,7 +51,7 @@ class ContainerBrowser virtual void nextPrimitive(unsigned int &it, unsigned int primSz) const = 0; virtual void enable() = 0; virtual void disable() = 0; - virtual ~ContainerBrowser() {} + virtual ~ContainerBrowser(); }; template From 3d5daae9f4612dd75609a58c70b54c8bcc723e92 Mon Sep 17 00:00:00 2001 From: Lionel Untereiner Date: Fri, 6 Nov 2015 21:21:32 +0100 Subject: [PATCH 056/185] ignoring clang pedantic warnings avout c++98 compatibility --- cmake/platforms/Darwin-clang.cmake | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cmake/platforms/Darwin-clang.cmake b/cmake/platforms/Darwin-clang.cmake index 395bb9f8..dbbe1bd1 100644 --- a/cmake/platforms/Darwin-clang.cmake +++ b/cmake/platforms/Darwin-clang.cmake @@ -24,6 +24,8 @@ set(FULL_WARNINGS #-Wno-sign- # Ignore warnings about C++98 compatibility -Wno-c++98-compat + # Ignore warnings about c++98 compat pedantic mode + -Wno-c++98-compat-pedantic # Ignore warnings about C++11 extensions (cgogn is promoting c++11 ) -Wno-c++11-extensions ) From 8e25e807b34fe5a10e3ebc4790e6868949734403 Mon Sep 17 00:00:00 2001 From: Lionel Untereiner Date: Fri, 6 Nov 2015 21:51:34 +0100 Subject: [PATCH 057/185] added a copy constructor to dart because of the c++11 rule: "The generation of the implicitly-defined copy constructor is deprecated if T has a user-defined destructor or user-defined copy assignment operator." --- cgogn/core/basic/dart.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cgogn/core/basic/dart.h b/cgogn/core/basic/dart.h index be93b6f5..86ecd3d8 100644 --- a/cgogn/core/basic/dart.h +++ b/cgogn/core/basic/dart.h @@ -33,6 +33,8 @@ struct Dart Dart(): index(0xffffffff) {} + Dart(const Dart& d) : index(d.index) {} + static Dart nil() { Dart d; d.index = 0xffffffff; return d; } static Dart create(unsigned int i) { Dart d; d.index = i; return d; } From 155e4b704ab9fa1c21dd787c657f3bec4ea9cfe2 Mon Sep 17 00:00:00 2001 From: Lionel Untereiner Date: Fri, 6 Nov 2015 22:05:54 +0100 Subject: [PATCH 058/185] removed warnings in test programs --- test/chunk_array/bench_chunk_array.cpp | 8 ++- test/chunk_array/test_chunk_array.cpp | 5 +- test/map/test_map.cpp | 67 ++++++++++++++------------ 3 files changed, 48 insertions(+), 32 deletions(-) diff --git a/test/chunk_array/bench_chunk_array.cpp b/test/chunk_array/bench_chunk_array.cpp index 0b2d146e..2dd891bc 100644 --- a/test/chunk_array/bench_chunk_array.cpp +++ b/test/chunk_array/bench_chunk_array.cpp @@ -5,6 +5,12 @@ using namespace cgogn; +int test1(); +int test2(); +int test3(); +int test4(); +int test5(); + /** * @brief The Vec3f class: just for the example @@ -175,7 +181,7 @@ int test5() std::cout << "= TEST 5 = Traversal" << std::endl; ChunkArrayContainer container; - ChunkArray* att1 = container.addAttribute("ints"); + ChunkArray* att1 = container.addAttribute("uints"); for (unsigned int i=0;i(); diff --git a/test/chunk_array/test_chunk_array.cpp b/test/chunk_array/test_chunk_array.cpp index 105a57c6..0ea4d390 100644 --- a/test/chunk_array/test_chunk_array.cpp +++ b/test/chunk_array/test_chunk_array.cpp @@ -7,7 +7,10 @@ using namespace cgogn; - +int test1(); +int test2(); +int test3(); +int test4(); int test1() { diff --git a/test/map/test_map.cpp b/test/map/test_map.cpp index 48640816..127114d3 100644 --- a/test/map/test_map.cpp +++ b/test/map/test_map.cpp @@ -14,47 +14,26 @@ struct My_Data_Traits // typedef for short writing typedef Map1 MAP1; -// declare a map -MAP1 map; - // typedef for short writing typedef Map2 MAP2; -// declare a map -MAP2 map2; - - -void fonc_const(const MAP1::VertexAttributeHandler& ah) -{ - for (const float& f:ah) - { - std::cout << f << std::endl; - } - // equivalent to - for (MAP1::VertexAttributeHandler::const_iterator it = ah.begin(); it != ah.end(); ++it) - std::cout << *it << std::endl; -} +void fonc_const(const MAP1::VertexAttributeHandler& ah); -void fonc_non_const(MAP1::VertexAttributeHandler& ah) -{ - for (float& f:ah) - { - f *= 2.0f; - std::cout << f << std::endl; - } +void fonc_non_const(MAP1::VertexAttributeHandler& ah); - // equivalent to - for (MAP1::VertexAttributeHandler::iterator it = ah.begin(); it != ah.end(); ++it) - { - *it /= 2.0f; - } -} +int test1(); int test1() { + // declare a map + MAP1 map; + + // declare a map + MAP2 map2; + // add an attribute on vertex of map with MAP1::VertexAttributeHandler ah = map.addAttribute("floats"); @@ -81,6 +60,34 @@ int test1() } +void fonc_const(const MAP1::VertexAttributeHandler& ah) +{ + for (const float& f:ah) + { + std::cout << f << std::endl; + } + + // equivalent to + for (MAP1::VertexAttributeHandler::const_iterator it = ah.begin(); it != ah.end(); ++it) + std::cout << *it << std::endl; +} + +void fonc_non_const(MAP1::VertexAttributeHandler& ah) +{ + for (float& f:ah) + { + f *= 2.0f; + std::cout << f << std::endl; + } + + // equivalent to + for (MAP1::VertexAttributeHandler::iterator it = ah.begin(); it != ah.end(); ++it) + { + *it /= 2.0f; + } +} + + int main() { From fb328978563ebd5d1a77003d5d2088ba0d121594 Mon Sep 17 00:00:00 2001 From: Lionel Untereiner Date: Fri, 6 Nov 2015 22:19:44 +0100 Subject: [PATCH 059/185] replacing cassert by cgogn_assert macro --- cgogn/core/basic/definitions.h | 15 +++++++++++++ cgogn/core/basic/serialization.h | 15 ++++++------- cgogn/core/container/chunk_array.h | 22 ++++++++++---------- cgogn/core/container/chunk_array_container.h | 7 +------ cgogn/core/container/chunk_stack.h | 4 ++-- cgogn/core/map/attribute_handler.h | 15 ++++++------- cgogn/core/map/map2.h | 4 ++-- cgogn/core/map/map_base_data.h | 4 ++-- 8 files changed, 49 insertions(+), 37 deletions(-) diff --git a/cgogn/core/basic/definitions.h b/cgogn/core/basic/definitions.h index e3edd0cf..cb937553 100644 --- a/cgogn/core/basic/definitions.h +++ b/cgogn/core/basic/definitions.h @@ -48,6 +48,21 @@ #define CGOGN_NOEXCEPT noexcept #endif +/** + * \def CGOGN_DEBUG + * \brief This macro is set when compiling in debug mode + * + * \def CGOGN_PARANO + * \brief This macro is set when compiling in debug mode + */ +#ifdef NDEBUG +#undef CGOGN_DEBUG +#undef CGOGN_PARANO +#else +#define CGOGN_DEBUG +#define CGOGN_PARANO +#endif + namespace cgogn { diff --git a/cgogn/core/basic/serialization.h b/cgogn/core/basic/serialization.h index 3e7fe9f0..dfa5de64 100644 --- a/cgogn/core/basic/serialization.h +++ b/cgogn/core/basic/serialization.h @@ -23,10 +23,11 @@ #ifndef CORE_SERIALIZATION_H_ #define CORE_SERIALIZATION_H_ +#include + #include #include #include -#include namespace cgogn { @@ -36,14 +37,14 @@ namespace serialization template void load(std::istream& istream, T * dest, std::size_t quantity) { - assert(dest != nullptr); + cgogn_assert(dest != nullptr); istream.read(reinterpret_cast(dest), static_cast(quantity*sizeof(T))); } template void save(std::ostream& ostream, T const * src, std::size_t quantity) { - assert(src != nullptr); + cgogn_assert(src != nullptr); ostream.write(reinterpret_cast(src), static_cast(quantity*sizeof(T))); } @@ -62,7 +63,7 @@ void save(std::ostream& ostream, std::list const * src, std::size_t quantity) template void load(std::istream& istream, std::vector* dest, std::size_t quantity) { - assert(dest != nullptr); + cgogn_assert(dest != nullptr); for (std::size_t i = 0; i < quantity ; ++i) { unsigned int vecSize; @@ -76,7 +77,7 @@ void load(std::istream& istream, std::vector* dest, std::size_t quantity) template void save(std::ostream& ostream, std::vector const * src, std::size_t quantity) { - assert(src != nullptr); + cgogn_assert(src != nullptr); for (std::size_t i = 0; i < quantity ; ++i) { const unsigned int size = static_cast(src[i].size()); @@ -89,7 +90,7 @@ void save(std::ostream& ostream, std::vector const * src, std::size_t quantit template void load(std::istream& istream, std::list* dest, std::size_t quantity) { - assert(dest != nullptr); + cgogn_assert(dest != nullptr); for (std::size_t i = 0; i < quantity ; ++i) { unsigned int listSize; @@ -109,7 +110,7 @@ void load(std::istream& istream, std::list* dest, std::size_t quantity) template void save(std::ostream& ostream, std::list const * src, std::size_t quantity) { - assert(src != nullptr); + cgogn_assert(src != nullptr); for (std::size_t i = 0; i < quantity ; ++i) { diff --git a/cgogn/core/container/chunk_array.h b/cgogn/core/container/chunk_array.h index 47ec65e2..8cd5884d 100644 --- a/cgogn/core/container/chunk_array.h +++ b/cgogn/core/container/chunk_array.h @@ -26,11 +26,11 @@ #include #include +#include #include #include #include -#include namespace cgogn { @@ -148,7 +148,7 @@ class ChunkArray : public ChunkArrayGen */ inline T& operator[](unsigned int i) { - assert(i/CHUNKSIZE < tableData_.size()); + cgogn_assert(i/CHUNKSIZE < tableData_.size()); return tableData_[i / CHUNKSIZE][i % CHUNKSIZE]; } @@ -159,7 +159,7 @@ class ChunkArray : public ChunkArrayGen */ inline const T& operator[](unsigned int i) const { - assert(i/CHUNKSIZE < tableData_.size()); + cgogn_assert(i/CHUNKSIZE < tableData_.size()); return tableData_[i / CHUNKSIZE][i % CHUNKSIZE]; } @@ -170,7 +170,7 @@ class ChunkArray : public ChunkArrayGen */ inline void setVal(unsigned int i, const T& v) { - assert(i/CHUNKSIZE < tableData_.size()); + cgogn_assert(i/CHUNKSIZE < tableData_.size()); tableData_[i / CHUNKSIZE][i % CHUNKSIZE] = v; } @@ -281,7 +281,7 @@ class ChunkArray : public ChunkArrayGen void save(std::ostream& fs, unsigned int nbLines) const override { - assert(nbLines/CHUNKSIZE <= getNbChunks()); + cgogn_assert(nbLines/CHUNKSIZE <= getNbChunks()); serialization::save(fs, &nbLines, 1); @@ -442,7 +442,7 @@ class ChunkArray : public ChunkArrayGen void setFalse(unsigned int i) { const unsigned int jj = i / CHUNKSIZE; - assert(jj < tableData_.size()); + cgogn_assert(jj < tableData_.size()); const unsigned int j = i % CHUNKSIZE; const unsigned int x = j/32u; const unsigned int y = j%32u; @@ -453,7 +453,7 @@ class ChunkArray : public ChunkArrayGen void setTrue(unsigned int i) { const unsigned int jj = i / CHUNKSIZE; - assert(jj < tableData_.size()); + cgogn_assert(jj < tableData_.size()); const unsigned int j = i % CHUNKSIZE; const unsigned int x = j/32u; const unsigned int y = j%32u; @@ -464,7 +464,7 @@ class ChunkArray : public ChunkArrayGen void setVal(unsigned int i, bool b) { const unsigned int jj = i / CHUNKSIZE; - assert(jj < tableData_.size()); + cgogn_assert(jj < tableData_.size()); const unsigned int j = i % CHUNKSIZE; const unsigned int x = j/32u; const unsigned int y = j%32u; @@ -487,7 +487,7 @@ class ChunkArray : public ChunkArrayGen void setFalseDirty(unsigned int i) { const unsigned int jj = i / CHUNKSIZE; - assert(jj < tableData_.size()); + cgogn_assert(jj < tableData_.size()); const unsigned int j = (i % CHUNKSIZE)/32u; tableData_[jj][j] = 0u; } @@ -495,7 +495,7 @@ class ChunkArray : public ChunkArrayGen bool operator[](unsigned int i) const { const unsigned int jj = i / CHUNKSIZE; - assert(jj < tableData_.size()); + cgogn_assert(jj < tableData_.size()); const unsigned int j = i % CHUNKSIZE; const unsigned int x = j/32u; const unsigned int y = j%32u; @@ -543,7 +543,7 @@ class ChunkArray : public ChunkArrayGen nbLines = ((nbLines/32u)+1u)*32u; - assert(nbLines/CHUNKSIZE <= tableData_.size()); + cgogn_assert(nbLines/CHUNKSIZE <= tableData_.size()); // TODO: if (nbLines==0) nbLines=CHUNKSIZE*tableData_.size(); ?? // save number of lines diff --git a/cgogn/core/container/chunk_array_container.h b/cgogn/core/container/chunk_array_container.h index 5285251a..da852ca2 100644 --- a/cgogn/core/container/chunk_array_container.h +++ b/cgogn/core/container/chunk_array_container.h @@ -252,7 +252,6 @@ class ChunkArrayContainer template ChunkArray* addAttribute(const std::string& attribName) { - // assert(attribName.size() != 0); cgogn_assert(attribName.size() != 0); // first check if attribute already exist @@ -636,7 +635,6 @@ class ChunkArrayContainer { unsigned int beginPrimIdx = (index/PRIMSIZE) * PRIMSIZE; - // assert(this->used(beginPrimIdx)|!" Error removing non existing index"); cgogn_message_assert(this->used(beginPrimIdx), "Error removing non existing index"); holesStack_.push(beginPrimIdx); @@ -654,7 +652,6 @@ class ChunkArrayContainer */ void initLine(unsigned int index) { - // assert( used(index) && "initLine only with allocated lines"); cgogn_message_assert(!used(index), "initLine only with allocated lines"); for (auto ptrAtt: tableArrays_) @@ -664,7 +661,6 @@ class ChunkArrayContainer void initBooleansOfLine(unsigned int index) { - // assert( used(index) && "initBooleansOfLine only with allocated lines"); cgogn_message_assert(!used(index), "initBooleansOfLine only with allocated lines"); for (unsigned int i=0; iinitElt(index); @@ -745,7 +741,6 @@ class ChunkArrayContainer return nullptr ; ChunkArray* atm = dynamic_cast*>(tableArrays_[index]); - // assert((atm != nullptr) || !"getDataVector: wrong type"); cgogn_message_assert(atm != nullptr, "getDataVector: wrong type"); diff --git a/cgogn/core/container/chunk_stack.h b/cgogn/core/container/chunk_stack.h index 2a20de3b..e78fd27c 100644 --- a/cgogn/core/container/chunk_stack.h +++ b/cgogn/core/container/chunk_stack.h @@ -25,8 +25,8 @@ #define CORE_CONTAINER_CHUNK_STACK_H_ #include +#include -#include namespace cgogn { @@ -121,7 +121,7 @@ class ChunkStack : public ChunkArray */ inline void pop() { - assert(stackSize_ > 0u); + cgogn_assert(stackSize_ > 0u); stackSize_--; } diff --git a/cgogn/core/map/attribute_handler.h b/cgogn/core/map/attribute_handler.h index 89d3d46e..69652ded 100644 --- a/cgogn/core/map/attribute_handler.h +++ b/cgogn/core/map/attribute_handler.h @@ -26,6 +26,7 @@ #include #include +#include ///TODO ajouter enregistrement dans la map de la carte. @@ -218,7 +219,7 @@ class AttributeHandler : public AttributeHandlerOrbit AttributeHandler(MapData* const m, const std::string& attributeName): Inherit(m) { - assert(this->chunk_array_cont_ != nullptr); + cgogn_assert(this->chunk_array_cont_ != nullptr); chunk_array_ = this->chunk_array_cont_->getAttribute(attributeName); if (chunk_array_ == nullptr) { @@ -295,7 +296,7 @@ class AttributeHandler : public AttributeHandlerOrbit */ inline T& operator[](Cell c) { - assert(this->valid || !"Invalid AttributeHandler") ; + cgogn_message_assert(this->valid_, "Invalid AttributeHandler") ; return chunk_array_->operator[]( this->map_->getEmbedding(c) ) ; } @@ -306,7 +307,7 @@ class AttributeHandler : public AttributeHandlerOrbit */ inline const T& operator[](Cell c) const { - assert(this->valid || !"Invalid AttributeHandler") ; + cgogn_message_assert(this->valid_, "Invalid AttributeHandler") ; return chunk_array_->operator[]( this->map_->getEmbedding(c) ) ; } @@ -317,7 +318,7 @@ class AttributeHandler : public AttributeHandlerOrbit */ inline T& operator[](unsigned int i) { - assert(this->valid_ || !"Invalid AttributeHandler") ; + cgogn_message_assert(this->valid_, "Invalid AttributeHandler") ; return chunk_array_->operator[](i) ; } @@ -328,7 +329,7 @@ class AttributeHandler : public AttributeHandlerOrbit */ inline const T& operator[](unsigned int i) const { - assert(this->valid_ || !"Invalid AttributeHandler") ; + cgogn_message_assert(this->valid_, "Invalid AttributeHandler") ; return chunk_array_->operator[](i) ; } @@ -356,7 +357,7 @@ class AttributeHandler : public AttributeHandlerOrbit inline bool operator!=(const_iterator it) const { - assert(ah_ptr_ == it.ah_ptr_); + cgogn_assert(ah_ptr_ == it.ah_ptr_); return index_ != it.index_; } }; @@ -395,7 +396,7 @@ class AttributeHandler : public AttributeHandlerOrbit inline bool operator!=(iterator it) const { - assert(ah_ptr_ == it.ah_ptr_); + cgogn_assert(ah_ptr_ == it.ah_ptr_); return index_ != it.index_; } }; diff --git a/cgogn/core/map/map2.h b/cgogn/core/map/map2.h index 956d8469..8e62efec 100644 --- a/cgogn/core/map/map2.h +++ b/cgogn/core/map/map2.h @@ -62,8 +62,8 @@ class Map2 : public Map1 */ void phi2sew(Dart d, Dart e) { - assert(phi2(d) == d); - assert(phi2(e) == e); + cgogn_assert(phi2(d) == d); + cgogn_assert(phi2(e) == e); (*(this->topo_relations_[2]))[d.index] = e; (*(this->topo_relations_[2]))[e.index] = d; } diff --git a/cgogn/core/map/map_base_data.h b/cgogn/core/map/map_base_data.h index 10344b0d..85a71581 100644 --- a/cgogn/core/map/map_base_data.h +++ b/cgogn/core/map/map_base_data.h @@ -93,7 +93,7 @@ class MapBaseData : public MapGen template inline unsigned int getEmbedding(const Cell& c) const { - assert(embeddings_[ORBIT] != NULL || !"Invalid parameter: orbit not embedded"); + cgogn_message_assert(embeddings_[ORBIT] != NULL, "Invalid parameter: orbit not embedded"); return (*embeddings_[ORBIT])[c.dart.index] ; } @@ -130,7 +130,7 @@ class MapBaseData : public MapGen while (id != thread_ids_[i]) { i++; - assert(i < thread_ids_.size()); + cgogn_assert(i < thread_ids_.size()); } return i; } From 126d738a403b24d30904b9094956d0e2006c34f1 Mon Sep 17 00:00:00 2001 From: Lionel Untereiner Date: Fri, 6 Nov 2015 22:35:40 +0100 Subject: [PATCH 060/185] adding c++11 [[noreturn]] attribute assert function --- cgogn/core/basic/assert.cpp | 4 ++-- cgogn/core/basic/assert.h | 4 ++-- cgogn/core/basic/definitions.h | 16 +++++++++++----- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/cgogn/core/basic/assert.cpp b/cgogn/core/basic/assert.cpp index 3ee4cff2..84b3a67c 100644 --- a/cgogn/core/basic/assert.cpp +++ b/cgogn/core/basic/assert.cpp @@ -21,7 +21,7 @@ * */ -#define CGoGN_CORE_DLL_EXPORT +#define CGOGN_CORE_DLL_EXPORT #include #include @@ -31,7 +31,7 @@ namespace cgogn { -CGoGN_CORE_API void assertion_failed(const std::string& expression, const std::string& message, +CGOGN_CORE_API void assertion_failed(const std::string& expression, const std::string& message, const std::string& file_name, const std::string& function_name, int line_number ) { std::ostringstream os; diff --git a/cgogn/core/basic/assert.h b/cgogn/core/basic/assert.h index 7b1d8022..bfee850a 100644 --- a/cgogn/core/basic/assert.h +++ b/cgogn/core/basic/assert.h @@ -31,6 +31,7 @@ #define __func__ __FUNCTION__ #endif + /** * \file cgogn/core/basic/assert.h * \brief Assertion checking mechanism. @@ -50,9 +51,8 @@ namespace cgogn * \param[in] function_name function where the assertion failed. * \param[in] line_number line where the assertion failed. * - * \todo Add attribute [[noreturn]] when MSVC min version = 14 */ - CGoGN_CORE_API void assertion_failed(const std::string& expression, const std::string& message, + CGOGN_CORE_API CGOGN_NORETURN void assertion_failed(const std::string& expression, const std::string& message, const std::string& file_name, const std::string& function_name, int line_number ); } diff --git a/cgogn/core/basic/definitions.h b/cgogn/core/basic/definitions.h index cb937553..4f8d8181 100644 --- a/cgogn/core/basic/definitions.h +++ b/cgogn/core/basic/definitions.h @@ -31,15 +31,15 @@ #ifdef WIN32 -#ifndef CGoGN_CORE_API -#if defined CGoGN_CORE_DLL_EXPORT -#define CGoGN_CORE_API __declspec(dllexport) +#ifndef CGOGN_CORE_API +#if defined CGOGN_CORE_DLL_EXPORT +#define CGOGN_CORE_API __declspec(dllexport) #else -#define CGoGN_CORE_API __declspec(dllimport) +#define CGOGN_CORE_API __declspec(dllimport) #endif #endif #else -#define CGoGN_CORE_API +#define CGOGN_CORE_API #endif #if defined(_MSC_VER) && _MSC_VER < 1900 @@ -48,6 +48,12 @@ #define CGOGN_NOEXCEPT noexcept #endif +#if defined (WIN32) +#define CGOGN_NORETURN __declspec(noreturn) +#else +#define CGOGN_NORETURN [[noreturn]] +#endif + /** * \def CGOGN_DEBUG * \brief This macro is set when compiling in debug mode From 32766eacd6b2f7ce60995a7a7d7854a031c7c7e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Schmitt?= Date: Tue, 10 Nov 2015 15:11:09 +0100 Subject: [PATCH 061/185] Several small things : MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * removed the openmp flag * added -Winline in order to produce a warning when a func can't be inlined * the c++11 flag is now set using target_compile_options for transitivity between target. (any target linking against cgogn will be build with the flag) * deleted ChunkArrayContainer and ChunkStack copy/assignment constructors/op * added some missing inline keywords Signed-off-by: Étienne Schmitt --- cgogn/core/CMakeLists.txt | 25 ++++-------------- cgogn/core/basic/assert.cpp | 1 + cgogn/core/basic/definitions.h | 14 +++++++++- cgogn/core/container/chunk_array_container.h | 5 ++++ cgogn/core/container/chunk_stack.h | 27 +++----------------- cgogn/core/map/attribute_handler.h | 16 ++++++------ cgogn/core/map/map1.h | 4 +-- cmake/platforms/Linux-gcc.cmake | 12 ++++----- 8 files changed, 43 insertions(+), 61 deletions(-) diff --git a/cgogn/core/CMakeLists.txt b/cgogn/core/CMakeLists.txt index 2b22bb95..5b89cc0f 100644 --- a/cgogn/core/CMakeLists.txt +++ b/cgogn/core/CMakeLists.txt @@ -19,7 +19,6 @@ set(HEADER_FILES map/map1.h map/map2.h map/map_tri.h - map/attribute_handler.h ) @@ -30,25 +29,11 @@ set(SOURCE_FILES add_library(${PROJECT_NAME} SHARED ${HEADER_FILES} ${SOURCE_FILES}) set_target_properties(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX "_d") -set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 11) -#target_compile_features(${PROJECT_NAME} PUBLIC -# cxx_nullptr -# cxx_range_for -# cxx_static_assert -# cxx_deleted_functions -# cxx_defaulted_functions -# cxx_auto_type -# cxx_alias_templates -# cxx_final -# cxx_defaulted_move_initializers -# cxx_default_function_template_args -# cxx_decltype -# cxx_lambdas -# cxx_override -# cxx_return_type_deduction -# cxx_strong_enums -# cxx_template_template_parameters -# ) + +#use of target_compile_options to have a transitive c++11 flag +if(NOT MSVC) + target_compile_options(${PROJECT_NAME} INTERFACE "-std=c++11") +endif() target_include_directories(${PROJECT_NAME} PUBLIC $ diff --git a/cgogn/core/basic/assert.cpp b/cgogn/core/basic/assert.cpp index 3ee4cff2..2ac55201 100644 --- a/cgogn/core/basic/assert.cpp +++ b/cgogn/core/basic/assert.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include namespace cgogn diff --git a/cgogn/core/basic/definitions.h b/cgogn/core/basic/definitions.h index 825b1ee6..5e961e9c 100644 --- a/cgogn/core/basic/definitions.h +++ b/cgogn/core/basic/definitions.h @@ -42,12 +42,24 @@ #define CGoGN_CORE_API #endif +/* + * for a given type T, std::vector will only use move constructor of T if it's marked noexcept. Same for std::swap. +*/ #if defined(_MSC_VER) && _MSC_VER < 1900 -#define CGOGN_NOEXCEPT +#define CGOGN_NOEXCEPT throw() #else #define CGOGN_NOEXCEPT noexcept #endif +/* + * Thread local storage. In VS <1900 it works only with POD types. +*/ +#if defined(_MSC_VER) && _MSC_VER < 1900 +#define CGOGN_TLS __declspec( thread ) +#else +#define CGOGN_TLS thread_local +#endif + namespace cgogn { diff --git a/cgogn/core/container/chunk_array_container.h b/cgogn/core/container/chunk_array_container.h index 2ac5f154..74e0f9bc 100644 --- a/cgogn/core/container/chunk_array_container.h +++ b/cgogn/core/container/chunk_array_container.h @@ -216,6 +216,11 @@ class ChunkArrayContainer currentBrowser_= stdBrowser_.get(); } + ChunkArrayContainer(ChunkArrayContainerconst& ) = delete; + ChunkArrayContainer(ChunkArrayContainer&& ) = delete; + ChunkArrayContainer& operator=(ChunkArrayContainerconst& ) = delete; + ChunkArrayContainer& operator=(ChunkArrayContainer&& ) = delete; + /** * @brief ChunkArrayContainer destructor */ diff --git a/cgogn/core/container/chunk_stack.h b/cgogn/core/container/chunk_stack.h index d6de1e5e..54ae1375 100644 --- a/cgogn/core/container/chunk_stack.h +++ b/cgogn/core/container/chunk_stack.h @@ -59,29 +59,10 @@ class ChunkStack : public ChunkArray inline ~ChunkStack() override {} - inline ChunkStack(const ChunkStack& cs) : - Inherit(cs) - ,stackSize_(cs.stackSize_) - {} - - inline ChunkStack(ChunkStack&& cs) : - Inherit(std::move(cs)) - ,stackSize_(cs.stackSize_) - {} - - inline ChunkStack& operator=(const ChunkStack& cs) - { - Inherit::operator =(cs); - stackSize_ = cs.stackSize_; - return *this; - } - - inline ChunkStack& operator=(ChunkStack&& cs) - { - Inherit::operator =(std::move(cs)); - stackSize_ = cs.stackSize_; - return *this; - } + inline ChunkStack(const ChunkStack& cs) = delete; + inline ChunkStack(ChunkStack&& cs) = delete; + inline ChunkStack& operator=(const ChunkStack& cs) = delete; + inline ChunkStack& operator=(ChunkStack&& cs) = delete; /** * @brief push a value on top of heap diff --git a/cgogn/core/map/attribute_handler.h b/cgogn/core/map/attribute_handler.h index 60cef713..8a8ac60f 100644 --- a/cgogn/core/map/attribute_handler.h +++ b/cgogn/core/map/attribute_handler.h @@ -206,7 +206,7 @@ class AttributeHandler : public AttributeHandlerOrbit * * Construct a non-valid AttributeHandler (i.e. not linked to any attribute) */ - AttributeHandler(): + inline AttributeHandler(): Inherit(nullptr) {} @@ -215,7 +215,7 @@ class AttributeHandler : public AttributeHandlerOrbit * @param m the map which belong attribute * @param attributeName name of attribute */ - AttributeHandler(MapData* const m, const std::string& attributeName): + inline AttributeHandler(MapData* const m, const std::string& attributeName): Inherit(m) { assert(this->chunk_array_cont_ != nullptr); @@ -226,7 +226,7 @@ class AttributeHandler : public AttributeHandlerOrbit } } - AttributeHandler(MapData* const m, TChunkArray* const ca): + inline AttributeHandler(MapData* const m, TChunkArray* const ca): Inherit(m), chunk_array_(ca) { @@ -240,7 +240,7 @@ class AttributeHandler : public AttributeHandlerOrbit * @brief Copy constructor * @param att */ - AttributeHandler(const AttributeHandler& att): + inline AttributeHandler(const AttributeHandler& att): Inherit(att) ,chunk_array_(att.chunk_array_) {} @@ -249,7 +249,7 @@ class AttributeHandler : public AttributeHandlerOrbit * @brief Move constructor * @param att */ - AttributeHandler(AttributeHandler&& att) CGOGN_NOEXCEPT : + inline AttributeHandler(AttributeHandler&& att) CGOGN_NOEXCEPT : Inherit(std::move(att)) ,chunk_array_(att.chunk_array_) {} @@ -259,7 +259,7 @@ class AttributeHandler : public AttributeHandlerOrbit * @param att * @return */ - AttributeHandler& operator=(const AttributeHandler& att) + inline AttributeHandler& operator=(const AttributeHandler& att) { Inherit::operator=(att); chunk_array_ = att.chunk_array_; @@ -271,7 +271,7 @@ class AttributeHandler : public AttributeHandlerOrbit * @param att * @return */ - AttributeHandler& operator=(AttributeHandler&& att) + inline AttributeHandler& operator=(AttributeHandler&& att) { Inherit::operator=(std::move(att)); chunk_array_ = att.chunk_array_; @@ -283,7 +283,7 @@ class AttributeHandler : public AttributeHandlerOrbit * @brief getDataVector * @return */ - TChunkArray const * getData() const + inline TChunkArray const * getData() const { return chunk_array_; } diff --git a/cgogn/core/map/map1.h b/cgogn/core/map/map1.h index 7fb17ab7..f70cbaa5 100644 --- a/cgogn/core/map/map1.h +++ b/cgogn/core/map/map1.h @@ -99,7 +99,7 @@ class Map1 : public MapBase public: - Map1() + inline Map1() { init(); } @@ -111,7 +111,7 @@ class Map1 : public MapBase * @param d * @return */ - Dart phi1(Dart d) const + inline Dart phi1(Dart d) const { return (*(this->topo_relations_[0]))[d.index]; } diff --git a/cmake/platforms/Linux-gcc.cmake b/cmake/platforms/Linux-gcc.cmake index 64ed9e1c..83f70d3e 100644 --- a/cmake/platforms/Linux-gcc.cmake +++ b/cmake/platforms/Linux-gcc.cmake @@ -11,6 +11,7 @@ set(FULL_WARNINGS -pedantic -Wno-long-long -Wconversion + -Winline ) # Determine gcc version and activate additional warnings available in latest versions @@ -64,10 +65,10 @@ string_append(CMAKE_C_FLAGS -msse3) # Compile and link with OpenMP -if (GCC_VERSION VERSION_GREATER 4.0) - string_append(CMAKE_CXX_FLAGS -fopenmp) - string_append(CMAKE_C_FLAGS -fopenmp) -endif() +#if (GCC_VERSION VERSION_GREATER 4.0) +# string_append(CMAKE_CXX_FLAGS -fopenmp) +# string_append(CMAKE_C_FLAGS -fopenmp) +#endif() # Always generate position independant code # (to allow linking with DLLs) @@ -75,9 +76,6 @@ string_append(CMAKE_CXX_FLAGS -fPIC) string_append(CMAKE_C_FLAGS -fPIC) -string_append(CMAKE_CXX_FLAGS -std=c++11) - - macro(m_add_executable) # Create a statically linked executable From 8657ed16c2fe9d157944ed2bd46bdd9933ab0c1b Mon Sep 17 00:00:00 2001 From: Lionel Untereiner Date: Wed, 11 Nov 2015 10:46:43 +0100 Subject: [PATCH 062/185] first version of documentation generation (full doc) --- CMakeLists.txt | 2 + doc/CMakeLists.txt | 33 ++++++ doc/full.dox | 260 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 295 insertions(+) create mode 100644 doc/CMakeLists.txt create mode 100644 doc/full.dox diff --git a/CMakeLists.txt b/CMakeLists.txt index fc3db95d..9503a6ca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,6 +45,8 @@ setBuildType() #### CGOGN sources # add each subdirectory with a CMakeList +add_subdirectory(doc) + add_subdirectory(${CGOGN_SOURCE_DIR}) add_subdirectory(test) diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt new file mode 100644 index 00000000..6a666f58 --- /dev/null +++ b/doc/CMakeLists.txt @@ -0,0 +1,33 @@ + +# the minimum version allowed for doxygen +set(DOXYGEN_MIN_VERSION 1.8.0) + +# check doxygen +find_package(Doxygen ${DOXYGEN_MIN_VERSION} QUIET) +if(NOT DOXYGEN_FOUND) + message(WARNING "Doxygen not found") + unset(DOXYGEN_EXECUTABLE CACHE) + return() +endif() + +#target for generating a full documentation + +set(DOC_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}) + +configure_file(full.dox full.dox @ONLY) + +add_custom_target( + doc-full + COMMAND ${CMAKE_COMMAND} -E remove_directory ${DOC_OUTPUT_DIR}/full + COMMAND ${DOXYGEN_EXECUTABLE} full.dox + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Generate full API documentation for ${PROJECT_NAME}" + ) + +set_property( + DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${DOC_OUTPUT_DIR}/full + ) + +#install documentation +install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/full/html DESTINATION doc/full COMPONENT doc-full OPTIONAL) diff --git a/doc/full.dox b/doc/full.dox new file mode 100644 index 00000000..2ba83e7e --- /dev/null +++ b/doc/full.dox @@ -0,0 +1,260 @@ +# This file describes the settings to be used by doxygen for a project +# This includes *header* files. + +#--------------------------------------------------------------------------- +# General configuration options +#--------------------------------------------------------------------------- + +# The PROJECT_NAME tag is a single word (or a sequence of word surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = "CGoGN" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = "Version" + +# The PROJECT_BRIEF tag can provide an optional one line description for +# a project. + +PROJECT_BRIEF = "n-dimensional meshes with combinatorial maps" + +# The WARN_LOGFILE tag can be used to specify a file to which warning and +# error messages should be written. + +WARN_LOGFILE = @DOC_OUTPUT_DIR@/full.log + +# If the FULL_PATH_NAMES tag is set to YES Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user defined part of the path. Stripping is +# only done if the specified string matches the left-hand part of the path. + +STRIP_FROM_PATH = @CMAKE_SOURCE_DIR@/ + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells the +# reader which header file to include in order to use a class. + +STRIP_FROM_INC_PATH = @CMAKE_SOURCE_DIR@/cgogn/ + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = @DOC_OUTPUT_DIR@/full + +# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities +# in documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless the +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES, all private members of a +# class will be included in the documentation. + +EXTRACT_PRIVATE = YES + +# If the EXTRACT_STATIC tag is set to YES, all static members of a +# file will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) +# defined locally in source files will be included in the documentation. + +EXTRACT_LOCAL_CLASSES = YES + +# If this flag is set to YES, the members of anonymous namespaces will +# be extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the +# base name of the file that contains the anonymous namespace. + +EXTRACT_ANON_NSPACES = YES + + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = @CMAKE_SOURCE_DIR@/cgogn @CMAKE_SOURCE_DIR@/doc/full @CMAKE_SOURCE_DIR@/doc/full + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +FILE_PATTERNS = *.h *.cpp *.dox + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. + +EXCLUDE_PATTERNS = */.git/* + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. + +TAB_SIZE = 8 + + +#--------------------------------------------------------------------------- +# Configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. + +SOURCE_BROWSER = YES + + +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output. + +GENERATE_HTML = YES + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated +# HTML page will contain the date and time when the page was generated. + +HTML_TIMESTAMP = YES + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. + +GENERATE_TREEVIEW = YES + +HTML_FILE_EXTENSION = .xtml + + +#--------------------------------------------------------------------------- +# Configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output. + +GENERATE_LATEX = NO + + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate +# all C-preprocessor directives found in the sources and include files. +ENABLE_PREPROCESSING = YES + +# If the SEARCH_INCLUDES tag is set to YES, the include files in the +# INCLUDE_PATH will be searched if a #include is found. + +SEARCH_INCLUDES = YES + + +#--------------------------------------------------------------------------- +# Configuration options related to external references +#--------------------------------------------------------------------------- + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = @DOC_OUTPUT_DIR@/full.tags + + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool +# is available from the path. + +HAVE_DOT = @DOXYGEN_DOT_FOUND@ + +# The DOT_PATH tag can be used to specify the path where the dot tool can +# be found. + +DOT_PATH = @DOXYGEN_DOT_PATH@ + +# If set to YES the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented or is not a +# class. +HIDE_UNDOC_RELATIONS = NO + +# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate +# a graph for each documented class showing the direct and indirect +# implementation dependencies (inheritance, containment, and class references +# variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and +# collaboration graphs will show the relations between templates and their +# instances. + +TEMPLATE_RELATIONS = YES + +# If the REFERENCES_RELATION tag is set to YES then for each documented +# function all documented entities called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the CALL_GRAPH tag is set to YES then doxygen will generate a call +# dependency graph for every global function or class method. + +CALL_GRAPH = YES + +# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller +# dependency graph for every global function or class method. + +CALLER_GRAPH = YES + +# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are +# set to YES then doxygen will generate a graph for each documented file +# showing the direct and indirect include dependencies of the file with other +# documented files. + +INCLUDE_GRAPH = YES + +# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags +# are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file +# with other documented files. + +INCLUDED_BY_GRAPH = YES + +# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to +# enable generation of interactive SVG images that allow zooming and panning. + +INTERACTIVE_SVG = YES + +# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple +# output files in one run (dot version > 1.8.10). + +DOT_MULTI_TARGETS = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the +# images generated by dot + +DOT_IMAGE_FORMAT = svg + + + From 23d56c7b767cb038657262e4e762ef31a3f15d73 Mon Sep 17 00:00:00 2001 From: Lionel Untereiner Date: Wed, 11 Nov 2015 10:49:09 +0100 Subject: [PATCH 063/185] changing code style to be more aesthetic in the doc --- cgogn/core/basic/assert.h | 53 ++++++++++++++++++++++++++++----------- 1 file changed, 39 insertions(+), 14 deletions(-) diff --git a/cgogn/core/basic/assert.h b/cgogn/core/basic/assert.h index bfee850a..0cb027ee 100644 --- a/cgogn/core/basic/assert.h +++ b/cgogn/core/basic/assert.h @@ -52,8 +52,9 @@ namespace cgogn * \param[in] line_number line where the assertion failed. * */ - CGOGN_CORE_API CGOGN_NORETURN void assertion_failed(const std::string& expression, const std::string& message, - const std::string& file_name, const std::string& function_name, int line_number ); + CGOGN_CORE_API CGOGN_NORETURN void assertion_failed(const std::string& expression, + const std::string& message, const std::string& file_name, + const std::string& function_name, int line_number ); } @@ -63,18 +64,28 @@ namespace cgogn * \param[in] x the boolean expression of the condition * \see assertion_failed() */ -#define cgogn_assert(x) \ - (!(x)) ? cgogn::assertion_failed(#x, "", __FILE__, __func__, __LINE__) : (void)0 +#define cgogn_assert(x) \ +{ \ + if(!(x)) \ + { \ + cgogn::assertion_failed(#x, "", __FILE__, __func__, __LINE__); \ + } \ +} /** * \brief Verifies that a condition is met and take a specific message. * \details * \param[in] x the boolean expression of the condition - * \parap[in] msg the specific message about the condition + * \param[in] msg the specific message about the condition * \see assertion_failed() */ -#define cgogn_message_assert(x, msg) \ - (!(x)) ? cgogn::assertion_failed(#x, msg, __FILE__, __func__, __LINE__) : (void)0 +#define cgogn_message_assert(x, msg) \ +{ \ + if(!(x)) \ + { \ + cgogn::assertion_failed(#x, msg, __FILE__, __func__, __LINE__); \ + } \ +} /** * \brief Verifies that the required contract condition is met. @@ -83,8 +94,13 @@ namespace cgogn * \param[in] x the boolean expression of the condition * \see assertion_failed() */ -#define cgogn_require(x) \ - (!(x)) ? cgogn::assertion_failed(#x, "", __FILE__, __func__, __LINE__) : (void)0 +#define cgogn_require(x) \ +{ \ + if(!(x)) \ + { \ + cgogn::assertion_failed(#x, "", __FILE__, __func__, __LINE__); \ + } \ +} /** * \brief Verifies that the ensured contract condition is met. @@ -93,8 +109,13 @@ namespace cgogn * \param[in] x the boolean expression of the condition * \see assertion_failed() */ -#define cgogn_ensure(x) \ - (!(x)) ? cgogn::assertion_failed(#x, "", __FILE__, __func__, __LINE__) : (void)0 +#define cgogn_ensure(x) \ +{ \ + if(!(x)) \ + { \ + cgogn::assertion_failed(#x, "", __FILE__, __func__, __LINE__); \ + } \ +} /** * \brief Verifies that the invariant contract condition is met. @@ -103,9 +124,13 @@ namespace cgogn * \param[in] x the boolean expression of the condition * \see assertion_failed() */ -#define cgogn_invariant(x) \ - (!(x)) ? cgogn::assertion_failed(#x, "", __FILE__, __func__, __LINE__) : (void)0 - +#define cgogn_invariant(x) \ +{ \ + if(!(x)) \ + { \ + cgogn::assertion_failed(#x, "", __FILE__, __func__, __LINE__); \ + } \ +} /** * \def debug_assert(x) From c064875129a01a5905d9012de84e9cf6de9baaa6 Mon Sep 17 00:00:00 2001 From: Lionel Untereiner Date: Wed, 11 Nov 2015 10:51:05 +0100 Subject: [PATCH 064/185] adding some comments --- cgogn/core/basic/cell.h | 23 +++++++++++++++----- cgogn/core/basic/definitions.h | 15 +++++++++++-- cgogn/core/container/chunk_array_container.h | 1 + 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/cgogn/core/basic/cell.h b/cgogn/core/basic/cell.h index c5f492a5..4ec4e726 100644 --- a/cgogn/core/basic/cell.h +++ b/cgogn/core/basic/cell.h @@ -24,7 +24,13 @@ #ifndef CORE_BASIC_CELL_H_ #define CORE_BASIC_CELL_H_ -#include "core/basic/dart.h" +#include + + +/** + * \file core/basic/cell.h + * \brief Orbit and cell definitions for CGOGN API + */ namespace cgogn { @@ -58,13 +64,13 @@ inline std::string orbitName(unsigned int orbit) /** - * class for cellular typing + * \brief Cellular typing * - * warning to automatic conversion + * \details warning to automatic conversion * cell -> Dart (or const Dart&) ok * Dart -> Cell (or const Cell&) ok + * \tparam ORBIT The type of the orbit used to create the Cell */ - template class Cell { @@ -72,10 +78,15 @@ class Cell Dart dart; - /// empty construtor + /** + * \brief Constructs a new empty Cell with NIL dart. + */ inline Cell(): dart() {} - /// constructor from Dart + /** + * \brief Constructs a new Cell with a dart. + * \param d dart to convert to a cell of a given orbit + */ inline Cell(Dart d): dart(d) {} /// copy constructor diff --git a/cgogn/core/basic/definitions.h b/cgogn/core/basic/definitions.h index 4f8d8181..fac84729 100644 --- a/cgogn/core/basic/definitions.h +++ b/cgogn/core/basic/definitions.h @@ -25,11 +25,13 @@ #define CORE_BASIC_DEFINITIONS_H_ /** - * \file basic/definitions.h + * \file core/basic/definitions.h * \brief Basic definitions for CGOGN API */ - +/** + * \brief Linkage declaration for CGOGN symbols. + */ #ifdef WIN32 #ifndef CGOGN_CORE_API #if defined CGOGN_CORE_DLL_EXPORT @@ -42,12 +44,18 @@ #define CGOGN_CORE_API #endif +/** + * \brief No execpt declaration for CGOGN symbols. + */ #if defined(_MSC_VER) && _MSC_VER < 1900 #define CGOGN_NOEXCEPT #else #define CGOGN_NOEXCEPT noexcept #endif +/** + * \brief No return declaration for CGOGN symbols. + */ #if defined (WIN32) #define CGOGN_NORETURN __declspec(noreturn) #else @@ -72,6 +80,9 @@ namespace cgogn { +/** + * \brief The maximum nunmber of threads created by the API. + */ const unsigned int NB_THREADS = 8u; } // namespace cgogn diff --git a/cgogn/core/container/chunk_array_container.h b/cgogn/core/container/chunk_array_container.h index da852ca2..c0626b20 100644 --- a/cgogn/core/container/chunk_array_container.h +++ b/cgogn/core/container/chunk_array_container.h @@ -667,6 +667,7 @@ class ChunkArrayContainer tableArrays_[i]->initElt(index); } + //TODO delete if useless void initBoolsOfLine(unsigned int index) { // cgogn_assert(!used(index), "initLine only with allocated lines"); From bf9579a963195ea96ce2a7aa5b2e2f38c04715c1 Mon Sep 17 00:00:00 2001 From: Lionel Untereiner Date: Wed, 11 Nov 2015 17:46:36 +0100 Subject: [PATCH 065/185] correction of assertion boolean test --- cgogn/core/map/attribute_handler.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cgogn/core/map/attribute_handler.h b/cgogn/core/map/attribute_handler.h index 69652ded..a98e7ea2 100644 --- a/cgogn/core/map/attribute_handler.h +++ b/cgogn/core/map/attribute_handler.h @@ -296,7 +296,7 @@ class AttributeHandler : public AttributeHandlerOrbit */ inline T& operator[](Cell c) { - cgogn_message_assert(this->valid_, "Invalid AttributeHandler") ; + cgogn_message_assert(!this->valid_, "Invalid AttributeHandler") ; return chunk_array_->operator[]( this->map_->getEmbedding(c) ) ; } @@ -307,7 +307,7 @@ class AttributeHandler : public AttributeHandlerOrbit */ inline const T& operator[](Cell c) const { - cgogn_message_assert(this->valid_, "Invalid AttributeHandler") ; + cgogn_message_assert(!this->valid_, "Invalid AttributeHandler") ; return chunk_array_->operator[]( this->map_->getEmbedding(c) ) ; } @@ -318,7 +318,7 @@ class AttributeHandler : public AttributeHandlerOrbit */ inline T& operator[](unsigned int i) { - cgogn_message_assert(this->valid_, "Invalid AttributeHandler") ; + cgogn_message_assert(!this->valid_, "Invalid AttributeHandler") ; return chunk_array_->operator[](i) ; } @@ -329,7 +329,7 @@ class AttributeHandler : public AttributeHandlerOrbit */ inline const T& operator[](unsigned int i) const { - cgogn_message_assert(this->valid_, "Invalid AttributeHandler") ; + cgogn_message_assert(!this->valid_, "Invalid AttributeHandler") ; return chunk_array_->operator[](i) ; } From 1fc15a5e16a21858d4068473f77bae894a1db21e Mon Sep 17 00:00:00 2001 From: Lionel Untereiner Date: Wed, 11 Nov 2015 20:11:01 +0100 Subject: [PATCH 066/185] comments for dart.h --- cgogn/core/basic/dart.h | 163 ++++++++++++++++++++++++++++++---------- 1 file changed, 125 insertions(+), 38 deletions(-) diff --git a/cgogn/core/basic/dart.h b/cgogn/core/basic/dart.h index 86ecd3d8..00ddb77e 100644 --- a/cgogn/core/basic/dart.h +++ b/cgogn/core/basic/dart.h @@ -24,47 +24,134 @@ #ifndef CORE_BASIC_DART_H_ #define CORE_BASIC_DART_H_ -namespace cgogn -{ +#include -struct Dart +/** + * \file cgogn/core/basic/dart.h + * \brief Dart definition. + */ +namespace cgogn { - unsigned int index; - - Dart(): index(0xffffffff) {} - - Dart(const Dart& d) : index(d.index) {} - - static Dart nil() { Dart d; d.index = 0xffffffff; return d; } - - static Dart create(unsigned int i) { Dart d; d.index = i; return d; } - - static std::string CGoGNnameOfType() { return "Dart"; } - - explicit Dart(unsigned int v): index(v) {} - - bool isNil() const { return index == 0xffffffff ; } - - Dart operator=(Dart d) { index = d.index; return *this; } - - bool operator==(Dart d) const { return d.index == index; } - - bool operator!=(Dart d) const { return d.index != index; } - - bool operator<(Dart d) const { return index < d.index; } - - - friend std::ostream& operator<<( std::ostream &out, const Dart& fa ); - friend std::istream& operator>>( std::istream &in, Dart& fa ); -}; - - -std::ostream& operator<<( std::ostream &out, const Dart& fa ) { return out << fa.index; } -std::istream& operator>>( std::istream &in, Dart& fa ) { in >> fa.index; return in; } - -const Dart NIL = Dart::nil(); -const unsigned int EMBNULL = 0xffffffff; + /** + * \brief Dart. + */ + struct Dart + { + /** + * \brief the value of a dart. + */ + unsigned int index; + + /** + * \brief Creates a new nil Dart + */ + Dart(): index(std::numeric_limits::max()) {} + + /** + * \brief Creates a new Dart with a value + * \details The explicit keyword specifies that this + * constructor is only considered for direct initialization. + * \code + * Dart d = 10 is forbidden + * \endcode + * + * \param[in] v the value of the new dart + */ + explicit Dart(unsigned int v): index(v) {} + + /** + * \brief Copy constructor. + * Creates a new Dart from an another one. + * \param[in] d a dart + */ + Dart(const Dart& d): index(d.index) {} + + //TODO why ???? puisque Dart d; -> d is nil + //utilise avec l'operateur de comparaison a la place de isNil ... + static Dart nil() { Dart d; d.index = std::numeric_limits::max(); return d; + } + + //TODO why ??? Dar d = Dart::create(10) instead of Dard d(10) + //utilise dans genericmap newDart() + static Dart create(unsigned int i) { Dart d; d.index = i; return d; } + + /** + * \brief Name of this CGoGN type + * \return a string representing the name of the class + * \todo un peu moche comme facon de faire... + */ + static std::string CGoGNnameOfType() { return "Dart"; } + + /** + * \brief Tests the nullity of the dart. + * \retval true if the dart is nil + * \retval false otherwise + */ + bool isNil() const { return index == std::numeric_limits::max() ; } + + /** + * \brief Assigns to the left hand side dart the value + * of the right hand side dart. + * \param[in] rhs the dart to assign + * \return The dart with the assigned value + */ + Dart operator=(Dart rhs) { index = rhs.index; return *this; } + + /** + * \brief Tests whether the left hand side dart is equal + * from the right hand side dart. + * \param[in] rhs the dart to compare with + * \retval true if \p lhs is equal than \p rhs + * \retval false otherwise + */ + bool operator==(Dart rhs) const { return index == rhs.index; } + + /** + * \brief Tests whether the left hand side dart is different + * from the right hand side dart. + * \param[in] rhs the dart to compare with + * \retval true if \p lhs is different than \p rhs + * \retval false otherwise + */ + bool operator!=(Dart rhs) const { return index != rhs.index; } + + /** + * \brief Tests whether the left hand side dart is less + * greather than the right hand side dart. + * \param[in] rhs the dart to compare with + * \retval true if \p lhs is less greather than \p rhs + * \retval false otherwise + */ + bool operator<(Dart rhs) const { return index < rhs.index; } + + /** + * \brief Prints a dart to a stream. + * \param[out] out the stream to print on + * \param[in] rhs the dart to print + */ + friend std::ostream& operator<<( std::ostream &out, const Dart& rhs ) { return out << rhs.index; } + + /** + * \brief Reads a dart from a stream. + * \param[in] in the stream to read from + * \param[out] rhs the dart read + */ + friend std::istream& operator>>( std::istream &in, Dart& rhs ) { in >> rhs.index; return in; } + + }; + + + /** + * \brief Definition of a nil dart + * \todo usefull .. Le constructeur vide creer un dart nil + */ + const Dart NIL = Dart::nil(); + + /** + * \brief Definition of null embedding + */ + const unsigned int EMBNULL = std::numeric_limits::max(); } // namespace cgogn From 51997016374a287beb96d44d6c9980c7b80f5961 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Schmitt?= Date: Thu, 12 Nov 2015 17:10:42 +0100 Subject: [PATCH 067/185] several things : * added make_unique * fixed test_map.cpp : a Map cannot be declared in global namespace because of static initialization issues in c++ : it's impossible to have control on the initialization order of those variables * added 2 missing setValid() methods calls in attribute_handler.h * added target cgogn_utils * doing some testing with a costum memory allocator (not usable yet !!) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Étienne Schmitt --- cgogn/CMakeLists.txt | 1 + cgogn/core/CMakeLists.txt | 10 +-- cgogn/core/container/chunk_array_factory.h | 6 +- cgogn/core/map/attribute_handler.h | 10 ++- cgogn/utils/CMakeLists.txt | 35 +++++++++ cgogn/utils/allocator.cpp | 7 ++ cgogn/utils/allocator.h | 82 ++++++++++++++++++++++ cgogn/utils/make_unique.h | 46 ++++++++++++ test/map/test_map.cpp | 14 ++-- 9 files changed, 190 insertions(+), 21 deletions(-) create mode 100644 cgogn/utils/CMakeLists.txt create mode 100644 cgogn/utils/allocator.cpp create mode 100644 cgogn/utils/allocator.h create mode 100644 cgogn/utils/make_unique.h diff --git a/cgogn/CMakeLists.txt b/cgogn/CMakeLists.txt index ad6d4787..4f3a3050 100644 --- a/cgogn/CMakeLists.txt +++ b/cgogn/CMakeLists.txt @@ -1 +1,2 @@ +add_subdirectory(utils) add_subdirectory(core) diff --git a/cgogn/core/CMakeLists.txt b/cgogn/core/CMakeLists.txt index 5b89cc0f..9f453c56 100644 --- a/cgogn/core/CMakeLists.txt +++ b/cgogn/core/CMakeLists.txt @@ -7,7 +7,7 @@ set(HEADER_FILES basic/dart.h basic/cell.h basic/assert.h - basic/serialization.h + basic/serialization.h container/chunk_array_container.h container/chunk_array_factory.h container/chunk_array_gen.h @@ -23,22 +23,18 @@ set(HEADER_FILES ) set(SOURCE_FILES - basic/assert.cpp + basic/assert.cpp ) add_library(${PROJECT_NAME} SHARED ${HEADER_FILES} ${SOURCE_FILES}) set_target_properties(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX "_d") -#use of target_compile_options to have a transitive c++11 flag -if(NOT MSVC) - target_compile_options(${PROJECT_NAME} INTERFACE "-std=c++11") -endif() - target_include_directories(${PROJECT_NAME} PUBLIC $ $ ) +target_link_libraries(${PROJECT_NAME} cgogn_utils) install(DIRECTORY basic container DESTINATION include/cgogn/cgogn_core diff --git a/cgogn/core/container/chunk_array_factory.h b/cgogn/core/container/chunk_array_factory.h index 14eb7008..d39962b6 100644 --- a/cgogn/core/container/chunk_array_factory.h +++ b/cgogn/core/container/chunk_array_factory.h @@ -29,7 +29,7 @@ #include #include #include - +#include namespace cgogn { @@ -50,9 +50,9 @@ class ChunkArrayFactory template static void registerCA() { - const std::string& keyType(nameOfType(T())); + std::string&& keyType(nameOfType(T())); if(mapCA_.find(keyType) == mapCA_.end()) - mapCA_[keyType] = ChunkArrayGenPtr(new ChunkArray()); + mapCA_[std::move(keyType)] = make_unique>(); } /** diff --git a/cgogn/core/map/attribute_handler.h b/cgogn/core/map/attribute_handler.h index 8a8ac60f..779e84dc 100644 --- a/cgogn/core/map/attribute_handler.h +++ b/cgogn/core/map/attribute_handler.h @@ -219,11 +219,13 @@ class AttributeHandler : public AttributeHandlerOrbit Inherit(m) { assert(this->chunk_array_cont_ != nullptr); - chunk_array_ = this->chunk_array_cont_->getAttribute(attributeName); + chunk_array_ = this->chunk_array_cont_->getAttribute(attributeName); if (chunk_array_ == nullptr) { this->setInvalid(); - } + } else { + this->setValid(); + } } inline AttributeHandler(MapData* const m, TChunkArray* const ca): @@ -233,7 +235,9 @@ class AttributeHandler : public AttributeHandlerOrbit if (chunk_array_ == nullptr) { this->setInvalid(); - } + } else { + this->setValid(); + } } /** diff --git a/cgogn/utils/CMakeLists.txt b/cgogn/utils/CMakeLists.txt new file mode 100644 index 00000000..04bb9366 --- /dev/null +++ b/cgogn/utils/CMakeLists.txt @@ -0,0 +1,35 @@ +project(cgogn_utils + LANGUAGES CXX) + +set(HEADER_FILES + allocator.h + buffers.h + make_unique.h + ) + +set(SOURCE_FILES + allocator.cpp +) + +add_library(${PROJECT_NAME} SHARED ${HEADER_FILES} ${SOURCE_FILES}) +#use of target_compile_options to have a transitive c++11 flag +if(NOT MSVC) + target_compile_options(${PROJECT_NAME} PUBLIC "-std=c++11") +endif() +set_target_properties(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX "_d") + +target_include_directories(${PROJECT_NAME} PUBLIC + $ + $ + ) +install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + DESTINATION include/cgogn/utils + FILES_MATCHING PATTERN "*.h" +) + +install(TARGETS ${PROJECT_NAME} + EXPORT ${PROJECT_NAME}Targets + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib + ) diff --git a/cgogn/utils/allocator.cpp b/cgogn/utils/allocator.cpp new file mode 100644 index 00000000..408c6ddc --- /dev/null +++ b/cgogn/utils/allocator.cpp @@ -0,0 +1,7 @@ +#include "allocator.h" + +namespace cgogn +{ + + +} diff --git a/cgogn/utils/allocator.h b/cgogn/utils/allocator.h new file mode 100644 index 00000000..bfbedd24 --- /dev/null +++ b/cgogn/utils/allocator.h @@ -0,0 +1,82 @@ +#ifndef UTILS_ALLOCATOR_H +#define UTILS_ALLOCATOR_H +#include +#include +namespace cgogn { + +struct Chunk +{ + typedef unsigned char uchar; + void init(std::size_t blockSize, uchar blocks) + { + assert(blocks > 0); + // Overflow check + const ::std::size_t allocSize = blockSize * blocks; + assert( allocSize / blockSize == blocks); + _pData = new uchar[blockSize * blocks]; + _firstAvailableBlock = 0; + _blocksAvailable = blocks; + uchar i{0}; + uchar* p = _pData; + for(; i != blocks ; p+=blockSize) + { + *p = ++i; + } + } + + inline bool isFilled() const + { + return _blocksAvailable == uchar(0); + } + + inline bool hasAvailable( unsigned char numBlocks ) const + { + return ( _blocksAvailable == numBlocks ); + } + + void* allocate(std::size_t blockSize) + { + if (isFilled()) + return nullptr; + + uchar* result = _pData + (_firstAvailableBlock * blockSize); + //update firstavailableblock to point to the next block + _firstAvailableBlock = *result; + --_blocksAvailable; + return result; + } + + void deallocate(void* p, std::size_t blockSize) + { + assert( p >= _pData ); + uchar* toRelease = static_cast(p); + // Alignment check + assert((toRelease - _pData) % blockSize == 0); + const unsigned char index = static_cast< unsigned char >(( toRelease - _pData ) / blockSize); +#if defined(DEBUG) || defined(_DEBUG) + // Check if block was already deleted. Attempting to delete the same + // block more than once causes Chunk's linked-list of stealth indexes to + // become corrupt. And causes count of blocksAvailable_ to be wrong. + if ( 0 < _blocksAvailable ) + assert( _firstAvailableBlock != index ); +#endif + *toRelease = _firstAvailableBlock; + _firstAvailableBlock = static_cast( index ); + ++_blocksAvailable; + } + + void release() + { + assert( _pData != nullptr); + delete[] _pData; + + } + + unsigned char* _pData; + unsigned char _firstAvailableBlock; + unsigned char _blocksAvailable; +}; +} + +#endif // UTILS_ALLOCATOR_H + diff --git a/cgogn/utils/make_unique.h b/cgogn/utils/make_unique.h new file mode 100644 index 00000000..d125779c --- /dev/null +++ b/cgogn/utils/make_unique.h @@ -0,0 +1,46 @@ +#ifndef UTILS_MAKE_UNIQUE_H +#define UTILS_MAKE_UNIQUE_H +#include +#include +#include +#include + +/* + * std::make_unique is c++14 but std::make_shared is c++11 + * bellow you can find the iso implementation of make_unique + * see https://isocpp.org/files/papers/N3656.txt + */ + +namespace cgogn { + template struct _Unique_if { + typedef std::unique_ptr _Single_object; + }; + + template struct _Unique_if { + typedef std::unique_ptr _Unknown_bound; + }; + + template struct _Unique_if { + typedef void _Known_bound; + }; + + template + typename _Unique_if::_Single_object + make_unique(Args&&... args) { + return std::unique_ptr(new T(std::forward(args)...)); + } + + template + typename _Unique_if::_Unknown_bound + make_unique(size_t n) { + typedef typename std::remove_extent::type U; + return std::unique_ptr(new U[n]()); + } + + template + typename _Unique_if::_Known_bound + make_unique(Args&&...) = delete; +} + +#endif // UTILS_MAKE_UNIQUE_H + diff --git a/test/map/test_map.cpp b/test/map/test_map.cpp index b77c57a5..c2737c13 100644 --- a/test/map/test_map.cpp +++ b/test/map/test_map.cpp @@ -14,15 +14,10 @@ struct My_Data_Traits // typedef for short writing typedef Map1 MAP1; -// declare a map -MAP1 map; - - // typedef for short writing typedef Map2 MAP2; -// declare a map -MAP2 map2; + void fonc_const(const MAP1::VertexAttributeHandler& ah) @@ -53,7 +48,7 @@ void fonc_non_const(MAP1::VertexAttributeHandler& ah) } -int test1() +int test1(MAP1& map) { // add an attribute on vertex of map with MAP1::VertexAttributeHandler ah = map.addAttribute("floats"); @@ -84,6 +79,9 @@ int test1() int main() { - test1(); + // declare a map + MAP1 map; + MAP2 map2; + test1(map); return 0; } From d4f929b9b956ffe47949ffb69d7ec4d2c6d9eb13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Schmitt?= Date: Thu, 12 Nov 2015 17:20:50 +0100 Subject: [PATCH 068/185] using make_unique in chunck array container MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Étienne Schmitt --- cgogn/core/container/chunk_array_container.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cgogn/core/container/chunk_array_container.h b/cgogn/core/container/chunk_array_container.h index 74e0f9bc..5849bea2 100644 --- a/cgogn/core/container/chunk_array_container.h +++ b/cgogn/core/container/chunk_array_container.h @@ -36,6 +36,7 @@ #include #include #include +#include namespace cgogn { @@ -209,10 +210,10 @@ class ChunkArrayContainer * @brief ChunkArrayContainer constructor */ ChunkArrayContainer(): - nbUsedLines_(0u), - nbMaxLines_(0u) + nbUsedLines_(0u) + ,nbMaxLines_(0u) + ,stdBrowser_(make_unique< ContainerStandardBrowser> >(this)) { - stdBrowser_.reset(new ContainerStandardBrowser< ChunkArrayContainer >(this)); currentBrowser_= stdBrowser_.get(); } From 11bcfe16e8bad14065eb378345675a405e71c89a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Schmitt?= Date: Fri, 13 Nov 2015 11:45:18 +0100 Subject: [PATCH 069/185] moved assert to utils/ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Étienne Schmitt --- cgogn/utils/CMakeLists.txt | 4 ++-- cgogn/{core/basic => utils}/assert.cpp | 0 cgogn/{core/basic => utils}/assert.h | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename cgogn/{core/basic => utils}/assert.cpp (100%) rename cgogn/{core/basic => utils}/assert.h (100%) diff --git a/cgogn/utils/CMakeLists.txt b/cgogn/utils/CMakeLists.txt index 04bb9366..089fd359 100644 --- a/cgogn/utils/CMakeLists.txt +++ b/cgogn/utils/CMakeLists.txt @@ -2,13 +2,13 @@ project(cgogn_utils LANGUAGES CXX) set(HEADER_FILES - allocator.h + assert.h buffers.h make_unique.h ) set(SOURCE_FILES - allocator.cpp + assert.cpp ) add_library(${PROJECT_NAME} SHARED ${HEADER_FILES} ${SOURCE_FILES}) diff --git a/cgogn/core/basic/assert.cpp b/cgogn/utils/assert.cpp similarity index 100% rename from cgogn/core/basic/assert.cpp rename to cgogn/utils/assert.cpp diff --git a/cgogn/core/basic/assert.h b/cgogn/utils/assert.h similarity index 100% rename from cgogn/core/basic/assert.h rename to cgogn/utils/assert.h From cd6e2ee639d71c38421d7c19c1da0cc01adc44b0 Mon Sep 17 00:00:00 2001 From: Lionel Untereiner Date: Fri, 6 Nov 2015 21:18:53 +0100 Subject: [PATCH 070/185] adding a cpp file with ContainerBrowser dtor avoids the warning "-Wweak-vtables" (i.e. has no out-of-line virtual method definitions). It avoids a copy of the class in every translation unit. --- cgogn/core/CMakeLists.txt | 1 + cgogn/core/container/chunk_array_container.cpp | 10 ++++++++++ cgogn/core/container/chunk_array_container.h | 2 +- 3 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 cgogn/core/container/chunk_array_container.cpp diff --git a/cgogn/core/CMakeLists.txt b/cgogn/core/CMakeLists.txt index 9f453c56..91ab0c0d 100644 --- a/cgogn/core/CMakeLists.txt +++ b/cgogn/core/CMakeLists.txt @@ -19,6 +19,7 @@ set(HEADER_FILES map/map1.h map/map2.h map/map_tri.h + map/attribute_handler.h ) diff --git a/cgogn/core/container/chunk_array_container.cpp b/cgogn/core/container/chunk_array_container.cpp new file mode 100644 index 00000000..fae1a793 --- /dev/null +++ b/cgogn/core/container/chunk_array_container.cpp @@ -0,0 +1,10 @@ +#include + +namespace cgogn +{ + + ContainerBrowser::~ContainerBrowser() + { + + } +} diff --git a/cgogn/core/container/chunk_array_container.h b/cgogn/core/container/chunk_array_container.h index 5849bea2..c9adc19f 100644 --- a/cgogn/core/container/chunk_array_container.h +++ b/cgogn/core/container/chunk_array_container.h @@ -51,7 +51,7 @@ class ContainerBrowser virtual void nextPrimitive(unsigned int &it, unsigned int primSz) const = 0; virtual void enable() = 0; virtual void disable() = 0; - virtual ~ContainerBrowser() {} + virtual ~ContainerBrowser(); }; template From be5807d8478991c176f9f07df57283cc60a7e778 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Schmitt?= Date: Fri, 13 Nov 2015 11:58:41 +0100 Subject: [PATCH 071/185] fixed compilation. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Étienne Schmitt --- cgogn/core/CMakeLists.txt | 3 +-- cgogn/core/container/chunk_array_container.h | 2 +- cgogn/utils/assert.cpp | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/cgogn/core/CMakeLists.txt b/cgogn/core/CMakeLists.txt index 91ab0c0d..b3e16182 100644 --- a/cgogn/core/CMakeLists.txt +++ b/cgogn/core/CMakeLists.txt @@ -6,7 +6,6 @@ set(HEADER_FILES basic/nameTypes.h basic/dart.h basic/cell.h - basic/assert.h basic/serialization.h container/chunk_array_container.h container/chunk_array_factory.h @@ -24,7 +23,7 @@ set(HEADER_FILES ) set(SOURCE_FILES - basic/assert.cpp + container/chunk_array_container.cpp ) add_library(${PROJECT_NAME} SHARED ${HEADER_FILES} ${SOURCE_FILES}) diff --git a/cgogn/core/container/chunk_array_container.h b/cgogn/core/container/chunk_array_container.h index c9adc19f..7b1dc9bd 100644 --- a/cgogn/core/container/chunk_array_container.h +++ b/cgogn/core/container/chunk_array_container.h @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include namespace cgogn diff --git a/cgogn/utils/assert.cpp b/cgogn/utils/assert.cpp index 2ac55201..56c377de 100644 --- a/cgogn/utils/assert.cpp +++ b/cgogn/utils/assert.cpp @@ -23,7 +23,7 @@ #define CGoGN_CORE_DLL_EXPORT -#include +#include #include #include #include From 85f12dd9616f174de56a602ecbdc730c719f8cb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Schmitt?= Date: Fri, 13 Nov 2015 12:12:12 +0100 Subject: [PATCH 072/185] fixed compilation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Étienne Schmitt --- cgogn/core/basic/serialization.h | 2 +- cgogn/core/container/chunk_array.h | 2 +- cgogn/core/container/chunk_stack.h | 2 +- cgogn/core/map/attribute_handler.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cgogn/core/basic/serialization.h b/cgogn/core/basic/serialization.h index dfa5de64..17e8228a 100644 --- a/cgogn/core/basic/serialization.h +++ b/cgogn/core/basic/serialization.h @@ -23,7 +23,7 @@ #ifndef CORE_SERIALIZATION_H_ #define CORE_SERIALIZATION_H_ -#include +#include #include #include diff --git a/cgogn/core/container/chunk_array.h b/cgogn/core/container/chunk_array.h index 8cd5884d..baed68e1 100644 --- a/cgogn/core/container/chunk_array.h +++ b/cgogn/core/container/chunk_array.h @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include diff --git a/cgogn/core/container/chunk_stack.h b/cgogn/core/container/chunk_stack.h index 60f14e24..c38f20ea 100644 --- a/cgogn/core/container/chunk_stack.h +++ b/cgogn/core/container/chunk_stack.h @@ -25,7 +25,7 @@ #define CORE_CONTAINER_CHUNK_STACK_H_ #include -#include +#include namespace cgogn diff --git a/cgogn/core/map/attribute_handler.h b/cgogn/core/map/attribute_handler.h index 6530502e..c5efc199 100644 --- a/cgogn/core/map/attribute_handler.h +++ b/cgogn/core/map/attribute_handler.h @@ -400,7 +400,7 @@ class AttributeHandler : public AttributeHandlerOrbit inline bool operator!=(iterator it) const { - assert(ah_ptr_ == it.ah_ptr_); + cgogn_assert(ah_ptr_ == it.ah_ptr_); return index_ != it.index_; } }; From c8b7cbb7b984b0fb068662844d05667119a405cf Mon Sep 17 00:00:00 2001 From: Etienne Schmitt Date: Fri, 13 Nov 2015 12:20:39 +0100 Subject: [PATCH 073/185] fixed compilation under MSVC 2013 Signed-off-by: Etienne Schmitt --- cgogn/core/CMakeLists.txt | 2 +- cgogn/core/basic/dart.h | 26 +++--------- cgogn/core/basic/dll.h | 40 +++++++++++++++++++ .../core/container/chunk_array_container.cpp | 24 +++++++++++ cgogn/core/container/chunk_array_container.h | 4 +- cgogn/core/map/attribute_handler.h | 8 ++-- cgogn/core/map/map_base_data.h | 2 +- cgogn/utils/CMakeLists.txt | 2 + cgogn/utils/assert.cpp | 7 ++-- cgogn/utils/assert.h | 11 ++--- cgogn/{core/basic => utils}/definitions.h | 8 ++-- cgogn/utils/dll.h | 40 +++++++++++++++++++ test/chunk_array/test_chunk_array.cpp | 2 +- 13 files changed, 136 insertions(+), 40 deletions(-) create mode 100644 cgogn/core/basic/dll.h rename cgogn/{core/basic => utils}/definitions.h (95%) create mode 100644 cgogn/utils/dll.h diff --git a/cgogn/core/CMakeLists.txt b/cgogn/core/CMakeLists.txt index b3e16182..1ea3bec6 100644 --- a/cgogn/core/CMakeLists.txt +++ b/cgogn/core/CMakeLists.txt @@ -2,7 +2,7 @@ project(cgogn_core LANGUAGES CXX) set(HEADER_FILES - basic/definitions.h + basic/dll.h basic/nameTypes.h basic/dart.h basic/cell.h diff --git a/cgogn/core/basic/dart.h b/cgogn/core/basic/dart.h index 00ddb77e..3f082474 100644 --- a/cgogn/core/basic/dart.h +++ b/cgogn/core/basic/dart.h @@ -25,6 +25,7 @@ #define CORE_BASIC_DART_H_ #include +#include /** * \file cgogn/core/basic/dart.h @@ -38,6 +39,8 @@ namespace cgogn */ struct Dart { + // MSVC doesn't support std::numeric_limits::max() when declaring static const variables + const static unsigned int INVALID_INDEX = UINT32_MAX; /** * \brief the value of a dart. */ @@ -46,7 +49,7 @@ namespace cgogn /** * \brief Creates a new nil Dart */ - Dart(): index(std::numeric_limits::max()) {} + Dart() : index(INVALID_INDEX) {} /** * \brief Creates a new Dart with a value @@ -67,19 +70,9 @@ namespace cgogn */ Dart(const Dart& d): index(d.index) {} - //TODO why ???? puisque Dart d; -> d is nil - //utilise avec l'operateur de comparaison a la place de isNil ... - static Dart nil() { Dart d; d.index = std::numeric_limits::max(); return d; - } - - //TODO why ??? Dar d = Dart::create(10) instead of Dard d(10) - //utilise dans genericmap newDart() - static Dart create(unsigned int i) { Dart d; d.index = i; return d; } - /** * \brief Name of this CGoGN type * \return a string representing the name of the class - * \todo un peu moche comme facon de faire... */ static std::string CGoGNnameOfType() { return "Dart"; } @@ -88,7 +81,7 @@ namespace cgogn * \retval true if the dart is nil * \retval false otherwise */ - bool isNil() const { return index == std::numeric_limits::max() ; } + bool isNil() const { return index == INVALID_INDEX ; } /** * \brief Assigns to the left hand side dart the value @@ -141,17 +134,10 @@ namespace cgogn }; - - /** - * \brief Definition of a nil dart - * \todo usefull .. Le constructeur vide creer un dart nil - */ - const Dart NIL = Dart::nil(); - /** * \brief Definition of null embedding */ - const unsigned int EMBNULL = std::numeric_limits::max(); + const unsigned int EMBNULL = Dart::INVALID_INDEX; } // namespace cgogn diff --git a/cgogn/core/basic/dll.h b/cgogn/core/basic/dll.h new file mode 100644 index 00000000..d324d846 --- /dev/null +++ b/cgogn/core/basic/dll.h @@ -0,0 +1,40 @@ +/******************************************************************************* +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * +* Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France * +* * +* This library is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by the * +* Free Software Foundation; either version 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: http://cgogn.unistra.fr/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ +#ifndef CORE_DLL_H_ +#define CORE_DLL_H_ +/** +* \brief Linkage declaration for CGOGN symbols. +*/ +#ifdef WIN32 +#ifndef CGOGN_CORE_API +#if defined CGOGN_CORE_DLL_EXPORT +#define CGOGN_CORE_API __declspec(dllexport) +#else +#define CGOGN_CORE_API __declspec(dllimport) +#endif +#endif +#else +#define CGOGN_CORE_API +#endif + +#endif // CORE_DLL_H_ \ No newline at end of file diff --git a/cgogn/core/container/chunk_array_container.cpp b/cgogn/core/container/chunk_array_container.cpp index fae1a793..0bf49fb9 100644 --- a/cgogn/core/container/chunk_array_container.cpp +++ b/cgogn/core/container/chunk_array_container.cpp @@ -1,3 +1,27 @@ +/******************************************************************************* +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * +* Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France * +* * +* This library is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by the * +* Free Software Foundation; either version 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: http://cgogn.unistra.fr/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ + +#define CGOGN_CORE_DLL_EXPORT #include namespace cgogn diff --git a/cgogn/core/container/chunk_array_container.h b/cgogn/core/container/chunk_array_container.h index 3d4500e8..bdcd00f4 100644 --- a/cgogn/core/container/chunk_array_container.h +++ b/cgogn/core/container/chunk_array_container.h @@ -26,6 +26,7 @@ #include #include +#include #include #include @@ -43,7 +44,7 @@ namespace cgogn { -class ContainerBrowser +class CGOGN_CORE_API ContainerBrowser { public: @@ -70,6 +71,7 @@ class ContainerStandardBrowser:public ContainerBrowser virtual void nextPrimitive(unsigned int &it, unsigned int primSz) const { cac_->realNextPrimitive(it,primSz); } virtual void enable() {} virtual void disable() {} + virtual ~ContainerStandardBrowser() {} }; diff --git a/cgogn/core/map/attribute_handler.h b/cgogn/core/map/attribute_handler.h index c5efc199..015d5558 100644 --- a/cgogn/core/map/attribute_handler.h +++ b/cgogn/core/map/attribute_handler.h @@ -300,7 +300,7 @@ class AttributeHandler : public AttributeHandlerOrbit */ inline T& operator[](Cell c) { - cgogn_message_assert(!this->valid_, "Invalid AttributeHandler") ; + cgogn_message_assert(this->valid_, "Invalid AttributeHandler") ; return chunk_array_->operator[]( this->map_->getEmbedding(c) ) ; } @@ -311,7 +311,7 @@ class AttributeHandler : public AttributeHandlerOrbit */ inline const T& operator[](Cell c) const { - cgogn_message_assert(!this->valid_, "Invalid AttributeHandler") ; + cgogn_message_assert(this->valid_, "Invalid AttributeHandler") ; return chunk_array_->operator[]( this->map_->getEmbedding(c) ) ; } @@ -322,7 +322,7 @@ class AttributeHandler : public AttributeHandlerOrbit */ inline T& operator[](unsigned int i) { - cgogn_message_assert(!this->valid_, "Invalid AttributeHandler") ; + cgogn_message_assert(this->valid_, "Invalid AttributeHandler") ; return chunk_array_->operator[](i) ; } @@ -333,7 +333,7 @@ class AttributeHandler : public AttributeHandlerOrbit */ inline const T& operator[](unsigned int i) const { - cgogn_message_assert(!this->valid_, "Invalid AttributeHandler") ; + cgogn_message_assert(this->valid_, "Invalid AttributeHandler") ; return chunk_array_->operator[](i) ; } diff --git a/cgogn/core/map/map_base_data.h b/cgogn/core/map/map_base_data.h index d669fe16..d6fde626 100644 --- a/cgogn/core/map/map_base_data.h +++ b/cgogn/core/map/map_base_data.h @@ -25,7 +25,7 @@ #define CORE_MAP_MAP_BASE_DATA_H_ #include -#include +#include #include #include diff --git a/cgogn/utils/CMakeLists.txt b/cgogn/utils/CMakeLists.txt index 089fd359..f8fb0d40 100644 --- a/cgogn/utils/CMakeLists.txt +++ b/cgogn/utils/CMakeLists.txt @@ -2,6 +2,8 @@ project(cgogn_utils LANGUAGES CXX) set(HEADER_FILES + dll.h + definitions.h assert.h buffers.h make_unique.h diff --git a/cgogn/utils/assert.cpp b/cgogn/utils/assert.cpp index b6a65052..dcfca66b 100644 --- a/cgogn/utils/assert.cpp +++ b/cgogn/utils/assert.cpp @@ -21,18 +21,17 @@ * */ -#define CGOGN_CORE_DLL_EXPORT - +#define CGOGN_UTILS_DLL_EXPORT +#include #include #include #include #include -#include namespace cgogn { -CGOGN_CORE_API void assertion_failed(const std::string& expression, const std::string& message, + CGOGN_UTILS_API CGOGN_NORETURN void assertion_failed(const std::string& expression, const std::string& message, const std::string& file_name, const std::string& function_name, int line_number ) { std::ostringstream os; diff --git a/cgogn/utils/assert.h b/cgogn/utils/assert.h index 0cb027ee..328e9e8a 100644 --- a/cgogn/utils/assert.h +++ b/cgogn/utils/assert.h @@ -21,11 +21,12 @@ * */ -#ifndef CORE_BASIC_ASSERT_ -#define CORE_BASIC_ASSERT_ +#ifndef UTILS_BASIC_ASSERT_ +#define UTILS_BASIC_ASSERT_ #include -#include +#include +#include #if defined (WIN32) && !defined(__func__) #define __func__ __FUNCTION__ @@ -52,7 +53,7 @@ namespace cgogn * \param[in] line_number line where the assertion failed. * */ - CGOGN_CORE_API CGOGN_NORETURN void assertion_failed(const std::string& expression, + CGOGN_UTILS_API CGOGN_NORETURN void assertion_failed(const std::string& expression, const std::string& message, const std::string& file_name, const std::string& function_name, int line_number ); @@ -174,4 +175,4 @@ namespace cgogn #define parano_message_assert(x, msg) #endif -#endif // CORE_BASIC_ASSERT_ +#endif // UTILS_BASIC_ASSERT_ diff --git a/cgogn/core/basic/definitions.h b/cgogn/utils/definitions.h similarity index 95% rename from cgogn/core/basic/definitions.h rename to cgogn/utils/definitions.h index 90bcc216..b3808b4b 100644 --- a/cgogn/core/basic/definitions.h +++ b/cgogn/utils/definitions.h @@ -21,8 +21,8 @@ * * *******************************************************************************/ -#ifndef CORE_BASIC_DEFINITIONS_H_ -#define CORE_BASIC_DEFINITIONS_H_ +#ifndef UTILS_BASIC_DEFINITIONS_H_ +#define UTILS_BASIC_DEFINITIONS_H_ /** * \file core/basic/definitions.h @@ -65,11 +65,13 @@ /** * \brief No return declaration for CGOGN symbols. */ +#ifndef CGOGN_NORETURN #if defined (WIN32) #define CGOGN_NORETURN __declspec(noreturn) #else #define CGOGN_NORETURN [[noreturn]] #endif +#endif /** * \def CGOGN_DEBUG @@ -96,4 +98,4 @@ const unsigned int NB_THREADS = 8u; } // namespace cgogn -#endif // CORE_BASIC_DEFINITIONS_H_ +#endif // UTILS_BASIC_DEFINITIONS_H_ diff --git a/cgogn/utils/dll.h b/cgogn/utils/dll.h new file mode 100644 index 00000000..4c922408 --- /dev/null +++ b/cgogn/utils/dll.h @@ -0,0 +1,40 @@ +/******************************************************************************* +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * +* Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France * +* * +* This library is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by the * +* Free Software Foundation; either version 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: http://cgogn.unistra.fr/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ +#ifndef UTILS_DLL_H_ +#define UTILS_DLL_H_ +/** +* \brief Linkage declaration for CGOGN symbols. +*/ +#ifdef WIN32 +#ifndef CGOGN_UTILS_API +#if defined CGOGN_UTILS_DLL_EXPORT +#define CGOGN_UTILS_API __declspec(dllexport) +#else +#define CGOGN_UTILS_API __declspec(dllimport) +#endif +#endif +#else +#define CGOGN_UTILS_API +#endif + +#endif // UTILS_DLL_H_ \ No newline at end of file diff --git a/test/chunk_array/test_chunk_array.cpp b/test/chunk_array/test_chunk_array.cpp index 0ea4d390..5b09cf06 100644 --- a/test/chunk_array/test_chunk_array.cpp +++ b/test/chunk_array/test_chunk_array.cpp @@ -237,7 +237,7 @@ int test4() { (*att1)[i] = 1+int(i); (*att2)[i] = 3.0f + 0.1f*float(i); - (*att3).setVal(i,i%2); + (*att3).setVal(i,static_cast(i%2)); (*att4)[i] = {{3.0 + 0.1*double(i),15.0 + 0.1*double(i)}, {103.0 + 0.1*double(i), 203.0 + 0.1*double(i), 303.0 + 0.1*double(i)}}; (*att5)[i] = {{3.0 + 0.1*double(i),15.0 + 0.1*double(i)}, {103.0 + 0.1*double(i), 203.0 + 0.1*double(i), 303.0 + 0.1*double(i)}}; } From 537817b03568d422f1ae922ec684f2f4dff71eaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Schmitt?= Date: Fri, 13 Nov 2015 14:20:14 +0100 Subject: [PATCH 074/185] fixed a compilation issue MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Étienne Schmitt --- cgogn/core/map/map_base.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cgogn/core/map/map_base.h b/cgogn/core/map/map_base.h index a96617fd..53566b36 100644 --- a/cgogn/core/map/map_base.h +++ b/cgogn/core/map/map_base.h @@ -110,7 +110,7 @@ class MapBase : public MapBaseData (*(this->embeddings_[i]))[di] = EMBNULL; // to EMBNULL } - Dart d = Dart::create(di); + Dart d(di); for (auto relPtr: this->topo_relations_) (*relPtr)[di] = d; From 709804deb50729f42716d4e4b4f1fc8062bd3859 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Schmitt?= Date: Fri, 13 Nov 2015 14:49:56 +0100 Subject: [PATCH 075/185] using UINT_MAX instead of UINT32_MAX MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Étienne Schmitt --- cgogn/core/basic/dart.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cgogn/core/basic/dart.h b/cgogn/core/basic/dart.h index 3f082474..c885a0d9 100644 --- a/cgogn/core/basic/dart.h +++ b/cgogn/core/basic/dart.h @@ -24,7 +24,6 @@ #ifndef CORE_BASIC_DART_H_ #define CORE_BASIC_DART_H_ -#include #include /** @@ -40,7 +39,7 @@ namespace cgogn struct Dart { // MSVC doesn't support std::numeric_limits::max() when declaring static const variables - const static unsigned int INVALID_INDEX = UINT32_MAX; + const static unsigned int INVALID_INDEX = UINT_MAX; /** * \brief the value of a dart. */ From 51fb9ae4bdc7981eb8c1de30a27c3d7ad5b1661d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Schmitt?= Date: Fri, 13 Nov 2015 15:38:35 +0100 Subject: [PATCH 076/185] using IGG style. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Étienne Schmitt --- cgogn/core/basic/cell.h | 4 +- cgogn/core/basic/dart.h | 86 +++++++++---------- .../core/container/chunk_array_container.cpp | 8 +- cgogn/core/container/chunk_array_container.h | 32 +++---- cgogn/core/container/chunk_array_factory.h | 4 +- cgogn/core/container/chunk_stack.h | 8 +- cgogn/core/map/attribute_handler.h | 14 +-- cgogn/core/map/map1.h | 4 +- cgogn/core/map/map_base.h | 2 +- cgogn/utils/buffers.h | 44 +++++----- cgogn/utils/definitions.h | 20 ----- cgogn/utils/make_unique.h | 56 ++++++------ test/map/test_map.cpp | 14 +-- 13 files changed, 138 insertions(+), 158 deletions(-) diff --git a/cgogn/core/basic/cell.h b/cgogn/core/basic/cell.h index 4ec4e726..f2a703fc 100644 --- a/cgogn/core/basic/cell.h +++ b/cgogn/core/basic/cell.h @@ -29,7 +29,7 @@ /** * \file core/basic/cell.h - * \brief Orbit and cell definitions for CGOGN API + * \brief Orbit and cell definitions for CGOGN API */ namespace cgogn @@ -84,7 +84,7 @@ class Cell inline Cell(): dart() {} /** - * \brief Constructs a new Cell with a dart. + * \brief Constructs a new Cell with a dart. * \param d dart to convert to a cell of a given orbit */ inline Cell(Dart d): dart(d) {} diff --git a/cgogn/core/basic/dart.h b/cgogn/core/basic/dart.h index c885a0d9..41f8921e 100644 --- a/cgogn/core/basic/dart.h +++ b/cgogn/core/basic/dart.h @@ -33,110 +33,110 @@ namespace cgogn { - /** - * \brief Dart. - */ - struct Dart - { - // MSVC doesn't support std::numeric_limits::max() when declaring static const variables - const static unsigned int INVALID_INDEX = UINT_MAX; - /** +/** + * \brief Dart. + */ +struct Dart +{ + // MSVC doesn't support std::numeric_limits::max() when declaring static const variables + const static unsigned int INVALID_INDEX = UINT_MAX; + /** * \brief the value of a dart. */ - unsigned int index; + unsigned int index; - /** - * \brief Creates a new nil Dart + /** + * \brief Creates a new nil Dart */ - Dart() : index(INVALID_INDEX) {} + Dart() : index(INVALID_INDEX) {} - /** + /** * \brief Creates a new Dart with a value - * \details The explicit keyword specifies that this + * \details The explicit keyword specifies that this * constructor is only considered for direct initialization. - * \code + * \code * Dart d = 10 is forbidden * \endcode - * + * * \param[in] v the value of the new dart */ - explicit Dart(unsigned int v): index(v) {} + explicit Dart(unsigned int v): index(v) {} - /** + /** * \brief Copy constructor. * Creates a new Dart from an another one. * \param[in] d a dart */ - Dart(const Dart& d): index(d.index) {} + Dart(const Dart& d): index(d.index) {} - /** + /** * \brief Name of this CGoGN type * \return a string representing the name of the class */ - static std::string CGoGNnameOfType() { return "Dart"; } + static std::string CGoGNnameOfType() { return "Dart"; } - /** + /** * \brief Tests the nullity of the dart. * \retval true if the dart is nil * \retval false otherwise */ - bool isNil() const { return index == INVALID_INDEX ; } + bool isNil() const { return index == INVALID_INDEX ; } - /** - * \brief Assigns to the left hand side dart the value + /** + * \brief Assigns to the left hand side dart the value * of the right hand side dart. * \param[in] rhs the dart to assign * \return The dart with the assigned value */ - Dart operator=(Dart rhs) { index = rhs.index; return *this; } + Dart operator=(Dart rhs) { index = rhs.index; return *this; } - /** - * \brief Tests whether the left hand side dart is equal + /** + * \brief Tests whether the left hand side dart is equal * from the right hand side dart. * \param[in] rhs the dart to compare with * \retval true if \p lhs is equal than \p rhs * \retval false otherwise */ - bool operator==(Dart rhs) const { return index == rhs.index; } + bool operator==(Dart rhs) const { return index == rhs.index; } - /** - * \brief Tests whether the left hand side dart is different + /** + * \brief Tests whether the left hand side dart is different * from the right hand side dart. * \param[in] rhs the dart to compare with * \retval true if \p lhs is different than \p rhs * \retval false otherwise */ - bool operator!=(Dart rhs) const { return index != rhs.index; } + bool operator!=(Dart rhs) const { return index != rhs.index; } - /** - * \brief Tests whether the left hand side dart is less + /** + * \brief Tests whether the left hand side dart is less * greather than the right hand side dart. * \param[in] rhs the dart to compare with * \retval true if \p lhs is less greather than \p rhs * \retval false otherwise */ - bool operator<(Dart rhs) const { return index < rhs.index; } + bool operator<(Dart rhs) const { return index < rhs.index; } - /** + /** * \brief Prints a dart to a stream. * \param[out] out the stream to print on * \param[in] rhs the dart to print */ - friend std::ostream& operator<<( std::ostream &out, const Dart& rhs ) { return out << rhs.index; } - - /** + friend std::ostream& operator<<( std::ostream &out, const Dart& rhs ) { return out << rhs.index; } + + /** * \brief Reads a dart from a stream. * \param[in] in the stream to read from * \param[out] rhs the dart read */ - friend std::istream& operator>>( std::istream &in, Dart& rhs ) { in >> rhs.index; return in; } + friend std::istream& operator>>( std::istream &in, Dart& rhs ) { in >> rhs.index; return in; } - }; +}; - /** +/** * \brief Definition of null embedding */ - const unsigned int EMBNULL = Dart::INVALID_INDEX; +const unsigned int EMBNULL = Dart::INVALID_INDEX; } // namespace cgogn diff --git a/cgogn/core/container/chunk_array_container.cpp b/cgogn/core/container/chunk_array_container.cpp index 0bf49fb9..2c53d062 100644 --- a/cgogn/core/container/chunk_array_container.cpp +++ b/cgogn/core/container/chunk_array_container.cpp @@ -26,9 +26,9 @@ namespace cgogn { - - ContainerBrowser::~ContainerBrowser() - { - } +ContainerBrowser::~ContainerBrowser() +{ + +} } diff --git a/cgogn/core/container/chunk_array_container.h b/cgogn/core/container/chunk_array_container.h index bdcd00f4..08c7e781 100644 --- a/cgogn/core/container/chunk_array_container.h +++ b/cgogn/core/container/chunk_array_container.h @@ -214,17 +214,17 @@ class ChunkArrayContainer * @brief ChunkArrayContainer constructor */ ChunkArrayContainer(): - nbUsedLines_(0u) - ,nbMaxLines_(0u) - ,stdBrowser_(make_unique< ContainerStandardBrowser> >(this)) + nbUsedLines_(0u) + ,nbMaxLines_(0u) + ,stdBrowser_(make_unique< ContainerStandardBrowser> >(this)) { currentBrowser_= stdBrowser_.get(); } - ChunkArrayContainer(ChunkArrayContainerconst& ) = delete; - ChunkArrayContainer(ChunkArrayContainer&& ) = delete; - ChunkArrayContainer& operator=(ChunkArrayContainerconst& ) = delete; - ChunkArrayContainer& operator=(ChunkArrayContainer&& ) = delete; + ChunkArrayContainer(ChunkArrayContainerconst& ) = delete; + ChunkArrayContainer(ChunkArrayContainer&& ) = delete; + ChunkArrayContainer& operator=(ChunkArrayContainerconst& ) = delete; + ChunkArrayContainer& operator=(ChunkArrayContainer&& ) = delete; /** * @brief ChunkArrayContainer destructor @@ -664,8 +664,8 @@ class ChunkArrayContainer cgogn_message_assert(!used(index), "initLine only with allocated lines"); for (auto ptrAtt: tableArrays_) -// if (ptrAtt != nullptr) never null ! - ptrAtt->initElt(index); + // if (ptrAtt != nullptr) never null ! + ptrAtt->initElt(index); } void initBooleansOfLine(unsigned int index) @@ -678,10 +678,10 @@ class ChunkArrayContainer void initBoolsOfLine(unsigned int index) { -// assert( used(index) && "initLine only with allocated lines"); -// for (auto ptrAtt: tableArrays_) -// if (ptrAtt != NULL) -// ptrAtt->initElt(index); + // assert( used(index) && "initLine only with allocated lines"); + // for (auto ptrAtt: tableArrays_) + // if (ptrAtt != NULL) + // ptrAtt->initElt(index); } /** @@ -703,7 +703,7 @@ class ChunkArrayContainer */ void refLine(unsigned int index) { -// static_assert(PRIMSIZE == 1u, "refLine with container where PRIMSIZE!=1"); + // static_assert(PRIMSIZE == 1u, "refLine with container where PRIMSIZE!=1"); refs_[index]++; } @@ -714,7 +714,7 @@ class ChunkArrayContainer */ bool unrefLine(unsigned int index) { -// static_assert(PRIMSIZE == 1u, "unrefLine with container where PRIMSIZE!=1"); + // static_assert(PRIMSIZE == 1u, "unrefLine with container where PRIMSIZE!=1"); refs_[index]--; if (refs_[index] == 1u) { @@ -733,7 +733,7 @@ class ChunkArrayContainer */ T_REF getNbRefs(unsigned int index) const { -// static_assert(PRIMSIZE == 1u, "getNbRefs with container where PRIMSIZE!=1"); + // static_assert(PRIMSIZE == 1u, "getNbRefs with container where PRIMSIZE!=1"); return refs_[index]; } diff --git a/cgogn/core/container/chunk_array_factory.h b/cgogn/core/container/chunk_array_factory.h index 9309e86c..16b25773 100644 --- a/cgogn/core/container/chunk_array_factory.h +++ b/cgogn/core/container/chunk_array_factory.h @@ -51,9 +51,9 @@ class ChunkArrayFactory template static void registerCA() { - std::string&& keyType(nameOfType(T())); + std::string&& keyType(nameOfType(T())); if(mapCA_.find(keyType) == mapCA_.end()) - mapCA_[std::move(keyType)] = make_unique>(); + mapCA_[std::move(keyType)] = make_unique>(); } /** diff --git a/cgogn/core/container/chunk_stack.h b/cgogn/core/container/chunk_stack.h index c38f20ea..5e2b4c6e 100644 --- a/cgogn/core/container/chunk_stack.h +++ b/cgogn/core/container/chunk_stack.h @@ -59,10 +59,10 @@ class ChunkStack : public ChunkArray inline ~ChunkStack() override {} - inline ChunkStack(const ChunkStack& cs) = delete; - inline ChunkStack(ChunkStack&& cs) = delete; - inline ChunkStack& operator=(const ChunkStack& cs) = delete; - inline ChunkStack& operator=(ChunkStack&& cs) = delete; + inline ChunkStack(const ChunkStack& cs) = delete; + inline ChunkStack(ChunkStack&& cs) = delete; + inline ChunkStack& operator=(const ChunkStack& cs) = delete; + inline ChunkStack& operator=(ChunkStack&& cs) = delete; /** * @brief push a value on top of heap diff --git a/cgogn/core/map/attribute_handler.h b/cgogn/core/map/attribute_handler.h index 015d5558..ffaf970d 100644 --- a/cgogn/core/map/attribute_handler.h +++ b/cgogn/core/map/attribute_handler.h @@ -224,9 +224,9 @@ class AttributeHandler : public AttributeHandlerOrbit if (chunk_array_ == nullptr) { this->setInvalid(); - } else { - this->setValid(); - } + } else { + this->setValid(); + } } AttributeHandler(MapData* const m, TChunkArray* const ca): @@ -236,9 +236,9 @@ class AttributeHandler : public AttributeHandlerOrbit if (chunk_array_ == nullptr) { this->setInvalid(); - } else { - this->setValid(); - } + } else { + this->setValid(); + } } /** @@ -400,7 +400,7 @@ class AttributeHandler : public AttributeHandlerOrbit inline bool operator!=(iterator it) const { - cgogn_assert(ah_ptr_ == it.ah_ptr_); + cgogn_assert(ah_ptr_ == it.ah_ptr_); return index_ != it.index_; } }; diff --git a/cgogn/core/map/map1.h b/cgogn/core/map/map1.h index 4a939486..20ead0d3 100644 --- a/cgogn/core/map/map1.h +++ b/cgogn/core/map/map1.h @@ -99,7 +99,7 @@ class Map1 : public MapBase public: - inline Map1() + inline Map1() { init(); } @@ -111,7 +111,7 @@ class Map1 : public MapBase * @param d * @return */ - inline Dart phi1(Dart d) const + inline Dart phi1(Dart d) const { return (*(this->topo_relations_[0]))[d.index]; } diff --git a/cgogn/core/map/map_base.h b/cgogn/core/map/map_base.h index 53566b36..37118496 100644 --- a/cgogn/core/map/map_base.h +++ b/cgogn/core/map/map_base.h @@ -110,7 +110,7 @@ class MapBase : public MapBaseData (*(this->embeddings_[i]))[di] = EMBNULL; // to EMBNULL } - Dart d(di); + Dart d(di); for (auto relPtr: this->topo_relations_) (*relPtr)[di] = d; diff --git a/cgogn/utils/buffers.h b/cgogn/utils/buffers.h index d914b60d..ee4f58c4 100644 --- a/cgogn/utils/buffers.h +++ b/cgogn/utils/buffers.h @@ -34,36 +34,36 @@ class Buffers { protected: - std::vector*> buffers_; + std::vector*> buffers_; public: - inline std::vector* getBuffer() - { - if (buffers_.empty()) + inline std::vector* getBuffer() { - std::vector* v = new std::vector; - v->reserve(128); - return v; - } + if (buffers_.empty()) + { + std::vector* v = new std::vector; + v->reserve(128); + return v; + } - std::vector* v = buffers_.back(); - buffers_.pop_back(); - return v; - } + std::vector* v = buffers_.back(); + buffers_.pop_back(); + return v; + } - inline void releaseBuffer(std::vector* b) - { - if (b->capacity() > 1024) + inline void releaseBuffer(std::vector* b) { - std::vector v; - b->swap(v); - b->reserve(128); - } + if (b->capacity() > 1024) + { + std::vector v; + b->swap(v); + b->reserve(128); + } - b->clear(); - buffers_.push_back(b); - } + b->clear(); + buffers_.push_back(b); + } }; } // namespace cgogn diff --git a/cgogn/utils/definitions.h b/cgogn/utils/definitions.h index b3808b4b..77289653 100644 --- a/cgogn/utils/definitions.h +++ b/cgogn/utils/definitions.h @@ -24,26 +24,6 @@ #ifndef UTILS_BASIC_DEFINITIONS_H_ #define UTILS_BASIC_DEFINITIONS_H_ -/** - * \file core/basic/definitions.h - * \brief Basic definitions for CGOGN API - */ - -/** - * \brief Linkage declaration for CGOGN symbols. - */ -#ifdef WIN32 -#ifndef CGOGN_CORE_API -#if defined CGOGN_CORE_DLL_EXPORT -#define CGOGN_CORE_API __declspec(dllexport) -#else -#define CGOGN_CORE_API __declspec(dllimport) -#endif -#endif -#else -#define CGOGN_CORE_API -#endif - /** * \brief No execpt declaration for CGOGN symbols. */ diff --git a/cgogn/utils/make_unique.h b/cgogn/utils/make_unique.h index d125779c..2bc5b9e4 100644 --- a/cgogn/utils/make_unique.h +++ b/cgogn/utils/make_unique.h @@ -12,34 +12,34 @@ */ namespace cgogn { - template struct _Unique_if { - typedef std::unique_ptr _Single_object; - }; - - template struct _Unique_if { - typedef std::unique_ptr _Unknown_bound; - }; - - template struct _Unique_if { - typedef void _Known_bound; - }; - - template - typename _Unique_if::_Single_object - make_unique(Args&&... args) { - return std::unique_ptr(new T(std::forward(args)...)); - } - - template - typename _Unique_if::_Unknown_bound - make_unique(size_t n) { - typedef typename std::remove_extent::type U; - return std::unique_ptr(new U[n]()); - } - - template - typename _Unique_if::_Known_bound - make_unique(Args&&...) = delete; +template struct _Unique_if { + typedef std::unique_ptr _Single_object; +}; + +template struct _Unique_if { + typedef std::unique_ptr _Unknown_bound; +}; + +template struct _Unique_if { + typedef void _Known_bound; +}; + +template +typename _Unique_if::_Single_object +make_unique(Args&&... args) { + return std::unique_ptr(new T(std::forward(args)...)); +} + +template +typename _Unique_if::_Unknown_bound +make_unique(size_t n) { + typedef typename std::remove_extent::type U; + return std::unique_ptr(new U[n]()); +} + +template +typename _Unique_if::_Known_bound +make_unique(Args&&...) = delete; } #endif // UTILS_MAKE_UNIQUE_H diff --git a/test/map/test_map.cpp b/test/map/test_map.cpp index 2cdc3cf8..c3a5a473 100644 --- a/test/map/test_map.cpp +++ b/test/map/test_map.cpp @@ -27,7 +27,7 @@ void fonc_const(const MAP1::VertexAttributeHandler& ah) // equivalent to for (MAP1::VertexAttributeHandler::const_iterator it = ah.begin(); it != ah.end(); ++it) - std::cout << *it << std::endl; + std::cout << *it << std::endl; } void fonc_non_const(MAP1::VertexAttributeHandler& ah) @@ -66,9 +66,9 @@ int test1(MAP1& map) fonc_const(ah); -// // traverse container with for range -// for (float f:ah) -// std::cout << f << std::endl; + // // traverse container with for range + // for (float f:ah) + // std::cout << f << std::endl; return 0; } @@ -77,8 +77,8 @@ int test1(MAP1& map) int main() { - MAP1 map; - MAP2 map2; - test1(map); + MAP1 map; + MAP2 map2; + test1(map); return 0; } From cc129ef5846d0ca493ac170d0ccd742c6252c07a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Schmitt?= Date: Fri, 13 Nov 2015 15:51:03 +0100 Subject: [PATCH 077/185] replaced WIN32 by _MSC_VER. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Étienne Schmitt --- cgogn/utils/definitions.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cgogn/utils/definitions.h b/cgogn/utils/definitions.h index 77289653..16aa0dc2 100644 --- a/cgogn/utils/definitions.h +++ b/cgogn/utils/definitions.h @@ -46,7 +46,7 @@ * \brief No return declaration for CGOGN symbols. */ #ifndef CGOGN_NORETURN -#if defined (WIN32) +#if defined (_MSC_VER) #define CGOGN_NORETURN __declspec(noreturn) #else #define CGOGN_NORETURN [[noreturn]] From bb2c21a96127f7da222654809f733f3d3a5d9107 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Schmitt?= Date: Fri, 13 Nov 2015 16:31:12 +0100 Subject: [PATCH 078/185] added doc about CGOGN_NOEXCEPT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Étienne Schmitt --- cgogn/utils/definitions.h | 1 + 1 file changed, 1 insertion(+) diff --git a/cgogn/utils/definitions.h b/cgogn/utils/definitions.h index 16aa0dc2..4f44c33c 100644 --- a/cgogn/utils/definitions.h +++ b/cgogn/utils/definitions.h @@ -26,6 +26,7 @@ /** * \brief No execpt declaration for CGOGN symbols. + * For a given type T, std::vector will only use move constructor of T if it's marked noexcept. Same for std::swap. */ #if defined(_MSC_VER) && _MSC_VER < 1900 #define CGOGN_NOEXCEPT throw() From 1027359cdc3f45bb65403347a7f812609d175703 Mon Sep 17 00:00:00 2001 From: Sylvain Thery Date: Tue, 17 Nov 2015 08:53:57 +0100 Subject: [PATCH 079/185] addMarkerAttributes & inline warnings --- cgogn/core/basic/nameTypes.h | 38 ++++++------ cgogn/core/container/chunk_array_container.h | 62 +++++++++++--------- cgogn/core/map/map_base.h | 3 + 3 files changed, 56 insertions(+), 47 deletions(-) diff --git a/cgogn/core/basic/nameTypes.h b/cgogn/core/basic/nameTypes.h index a0275d98..bc21cd7f 100644 --- a/cgogn/core/basic/nameTypes.h +++ b/cgogn/core/basic/nameTypes.h @@ -41,41 +41,41 @@ std::string nameOfType(const T& /*v*/) } // first we need to declare some specializations -template inline std::string nameOfType(const std::list& /*v*/); -template inline std::string nameOfType(const std::vector& /*v*/); +template /*inline*/ std::string nameOfType(const std::list& /*v*/); +template /*inline*/ std::string nameOfType(const std::vector& /*v*/); -template <> inline std::string nameOfType(const bool& /*v*/) { return "bool"; } +template <> /*inline*/ std::string nameOfType(const bool& /*v*/) { return "bool"; } -template <> inline std::string nameOfType(const char& /*v*/) { return "char"; } +template <> /*inline*/ std::string nameOfType(const char& /*v*/) { return "char"; } -template <> inline std::string nameOfType(const short& /*v*/) { return "short"; } +template <> /*inline*/ std::string nameOfType(const short& /*v*/) { return "short"; } -template <> inline std::string nameOfType(const int& /*v*/) { return "int"; } +template <> /*inline*/ std::string nameOfType(const int& /*v*/) { return "int"; } -template <> inline std::string nameOfType(const long& /*v*/) { return "long"; } +template <> /*inline*/ std::string nameOfType(const long& /*v*/) { return "long"; } -template <> inline std::string nameOfType(const long long& /*v*/) { return "long long"; } +template <> /*inline*/ std::string nameOfType(const long long& /*v*/) { return "long long"; } // because signed char != char -template <> inline std::string nameOfType(const signed char& /*v*/) { return "signed char"; } +template <> /*inline*/ std::string nameOfType(const signed char& /*v*/) { return "signed char"; } -template <> inline std::string nameOfType(const unsigned char& /*v*/) { return "unsigned char"; } +template <> /*inline*/ std::string nameOfType(const unsigned char& /*v*/) { return "unsigned char"; } -template <> inline std::string nameOfType(const unsigned short& /*v*/) { return "unsigned short"; } +template <> /*inline*/ std::string nameOfType(const unsigned short& /*v*/) { return "unsigned short"; } -template <> inline std::string nameOfType(const unsigned int& /*v*/) { return "unsigned int"; } +template <> /*inline*/ std::string nameOfType(const unsigned int& /*v*/) { return "unsigned int"; } -template <> inline std::string nameOfType(const unsigned long& /*v*/) { return "unsigned long"; } +template <> /*inline*/ std::string nameOfType(const unsigned long& /*v*/) { return "unsigned long"; } -template <> inline std::string nameOfType(const unsigned long long& /*v*/) { return "unsigned long long"; } +template <> /*inline*/ std::string nameOfType(const unsigned long long& /*v*/) { return "unsigned long long"; } -template <> inline std::string nameOfType(const float& /*v*/) { return "float"; } +template <> /*inline*/ std::string nameOfType(const float& /*v*/) { return "float"; } -template <> inline std::string nameOfType(const double& /*v*/) { return "double"; } +template <> /*inline*/ std::string nameOfType(const double& /*v*/) { return "double"; } -template <> inline std::string nameOfType(const std::string& /*v*/) { return "std::string"; } +template <> /*inline*/ std::string nameOfType(const std::string& /*v*/) { return "std::string"; } -template inline std::string nameOfType(const std::vector& /*v*/) { return std::string("std::vector<") + nameOfType(T()) + std::string(">"); } -template inline std::string nameOfType(const std::list& /*v*/) { return "std::list<"+ nameOfType(T()) + std::string(">"); } +template /*inline*/ std::string nameOfType(const std::vector& /*v*/) { return std::string("std::vector<") + nameOfType(T()) + std::string(">"); } +template /*inline*/ std::string nameOfType(const std::list& /*v*/) { return "std::list<"+ nameOfType(T()) + std::string(">"); } /** diff --git a/cgogn/core/container/chunk_array_container.h b/cgogn/core/container/chunk_array_container.h index 08c7e781..3b0b7112 100644 --- a/cgogn/core/container/chunk_array_container.h +++ b/cgogn/core/container/chunk_array_container.h @@ -122,7 +122,7 @@ class ChunkArrayContainer /** * @brief number of bool attribs (which are alway in front of all others) */ - unsigned int nbBoolAttribs_; + unsigned int nbMarkerAttribs_; /** * Browser that allow special traversals @@ -176,19 +176,19 @@ class ChunkArrayContainer // store ptr for using it before delete ChunkArrayGen* ptrToDel = tableArrays_[index]; - // in case of bool, keep booleans first ! - if (tableArrays_[index]->isBooleanArray()) + // in case of Markers, keep Markers first ! + if (index < nbMarkerAttribs_) { - nbBoolAttribs_--; + nbMarkerAttribs_--; - if (index < nbBoolAttribs_) // if attribute is not last of boolean + if (index < nbMarkerAttribs_) // if attribute is not last of Markers { - tableArrays_[index] = tableArrays_[nbBoolAttribs_]; // copy last of boolean on index - names_[index] = names_[nbBoolAttribs_]; - typeNames_[index] = typeNames_[nbBoolAttribs_]; + tableArrays_[index] = tableArrays_[nbMarkerAttribs_]; // copy last of boolean on index + names_[index] = names_[nbMarkerAttribs_]; + typeNames_[index] = typeNames_[nbMarkerAttribs_]; } // now overwrite last of bool with last - index = nbBoolAttribs_; + index = nbMarkerAttribs_; } if (index != tableArrays_.size()- std::size_t(1u)) @@ -204,7 +204,6 @@ class ChunkArrayContainer delete ptrToDel ; - return true ; } @@ -284,24 +283,31 @@ class ChunkArrayContainer names_.push_back(attribName); typeNames_.push_back(typeName); - // move bool in front of others - if (std::is_same::value) - { - if (tableArrays_.size() > nbBoolAttribs_) - { - // swap ptrs - auto tmp = tableArrays_.back(); - tableArrays_.back() = tableArrays_[nbBoolAttribs_]; - tableArrays_[nbBoolAttribs_] = tmp; - // swap names & typenames - names_.back().swap(names_[nbBoolAttribs_]); - typeNames_.back().swap(typeNames_[nbBoolAttribs_]); - } - nbBoolAttribs_++; + return carr ; + } + /** + * @brief add an Marker attribute + * @param attribName name of marker attribute + * @return pointer on created ChunkArray + */ + ChunkArray* addMarkerAttribute(const std::string& attribName) + { + ChunkArray* ptr = this->template addMarkerAttribute(attribName); + + if (tableArrays_.size() > nbMarkerAttribs_) + { + // swap ptrs + auto tmp = tableArrays_.back(); + tableArrays_.back() = tableArrays_[nbMarkerAttribs_]; + tableArrays_[nbMarkerAttribs_] = tmp; + // swap names & typenames + names_.back().swap(names_[nbMarkerAttribs_]); + typeNames_.back().swap(typeNames_[nbMarkerAttribs_]); } + nbMarkerAttribs_++; - return carr ; + return ptr; } /** @@ -672,7 +678,7 @@ class ChunkArrayContainer { cgogn_message_assert(!used(index), "initBooleansOfLine only with allocated lines"); - for (unsigned int i=0; iinitElt(index); } @@ -778,7 +784,7 @@ class ChunkArrayContainer buffer.push_back(static_cast(tableArrays_.size())); buffer.push_back(nbUsedLines_); buffer.push_back(nbMaxLines_); - buffer.push_back(nbBoolAttribs_); + buffer.push_back(nbMarkerAttribs_); for(unsigned int i=0u; i(names_[i].size()+1)); @@ -815,7 +821,7 @@ class ChunkArrayContainer nbUsedLines_ = buff1[1]; nbMaxLines_ = buff1[2]; - nbBoolAttribs_ = buff1[3]; + nbMarkerAttribs_ = buff1[3]; std::vector buff2(2u*buff1[0]); fs.read(reinterpret_cast(&(buff2[0])),std::streamsize(2u*buff1[0]*sizeof(unsigned int))); diff --git a/cgogn/core/map/map_base.h b/cgogn/core/map/map_base.h index 37118496..82655ff4 100644 --- a/cgogn/core/map/map_base.h +++ b/cgogn/core/map/map_base.h @@ -48,6 +48,9 @@ class MapBase : public MapBaseData MapBase() {} + ~MapBase() + {} + template inline AttributeHandler addAttribute(const std::string& attributeName = "") { From 10efc5eab0f648f4b61c77dc9619546c6441fce0 Mon Sep 17 00:00:00 2001 From: david-cazier Date: Tue, 17 Nov 2015 17:22:06 +0100 Subject: [PATCH 080/185] Fix compil Windows --- cgogn/core/map/map_base.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cgogn/core/map/map_base.h b/cgogn/core/map/map_base.h index 8bfda9d1..2cc3c4aa 100644 --- a/cgogn/core/map/map_base.h +++ b/cgogn/core/map/map_base.h @@ -43,7 +43,7 @@ class MapBase : public MapBaseData //TODO remonter dans map_base template - using AttributeHandler = AttributeHandler; + using AttributeHandler = cgogn::AttributeHandler; MapBase() {} From 855252bef51fba1a5ee96b5e2c1b37c995c6585b Mon Sep 17 00:00:00 2001 From: Sylvain Thery Date: Tue, 17 Nov 2015 17:25:35 +0100 Subject: [PATCH 081/185] restore inline --- cgogn/core/basic/nameTypes.h | 38 ++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/cgogn/core/basic/nameTypes.h b/cgogn/core/basic/nameTypes.h index bc21cd7f..a0275d98 100644 --- a/cgogn/core/basic/nameTypes.h +++ b/cgogn/core/basic/nameTypes.h @@ -41,41 +41,41 @@ std::string nameOfType(const T& /*v*/) } // first we need to declare some specializations -template /*inline*/ std::string nameOfType(const std::list& /*v*/); -template /*inline*/ std::string nameOfType(const std::vector& /*v*/); +template inline std::string nameOfType(const std::list& /*v*/); +template inline std::string nameOfType(const std::vector& /*v*/); -template <> /*inline*/ std::string nameOfType(const bool& /*v*/) { return "bool"; } +template <> inline std::string nameOfType(const bool& /*v*/) { return "bool"; } -template <> /*inline*/ std::string nameOfType(const char& /*v*/) { return "char"; } +template <> inline std::string nameOfType(const char& /*v*/) { return "char"; } -template <> /*inline*/ std::string nameOfType(const short& /*v*/) { return "short"; } +template <> inline std::string nameOfType(const short& /*v*/) { return "short"; } -template <> /*inline*/ std::string nameOfType(const int& /*v*/) { return "int"; } +template <> inline std::string nameOfType(const int& /*v*/) { return "int"; } -template <> /*inline*/ std::string nameOfType(const long& /*v*/) { return "long"; } +template <> inline std::string nameOfType(const long& /*v*/) { return "long"; } -template <> /*inline*/ std::string nameOfType(const long long& /*v*/) { return "long long"; } +template <> inline std::string nameOfType(const long long& /*v*/) { return "long long"; } // because signed char != char -template <> /*inline*/ std::string nameOfType(const signed char& /*v*/) { return "signed char"; } +template <> inline std::string nameOfType(const signed char& /*v*/) { return "signed char"; } -template <> /*inline*/ std::string nameOfType(const unsigned char& /*v*/) { return "unsigned char"; } +template <> inline std::string nameOfType(const unsigned char& /*v*/) { return "unsigned char"; } -template <> /*inline*/ std::string nameOfType(const unsigned short& /*v*/) { return "unsigned short"; } +template <> inline std::string nameOfType(const unsigned short& /*v*/) { return "unsigned short"; } -template <> /*inline*/ std::string nameOfType(const unsigned int& /*v*/) { return "unsigned int"; } +template <> inline std::string nameOfType(const unsigned int& /*v*/) { return "unsigned int"; } -template <> /*inline*/ std::string nameOfType(const unsigned long& /*v*/) { return "unsigned long"; } +template <> inline std::string nameOfType(const unsigned long& /*v*/) { return "unsigned long"; } -template <> /*inline*/ std::string nameOfType(const unsigned long long& /*v*/) { return "unsigned long long"; } +template <> inline std::string nameOfType(const unsigned long long& /*v*/) { return "unsigned long long"; } -template <> /*inline*/ std::string nameOfType(const float& /*v*/) { return "float"; } +template <> inline std::string nameOfType(const float& /*v*/) { return "float"; } -template <> /*inline*/ std::string nameOfType(const double& /*v*/) { return "double"; } +template <> inline std::string nameOfType(const double& /*v*/) { return "double"; } -template <> /*inline*/ std::string nameOfType(const std::string& /*v*/) { return "std::string"; } +template <> inline std::string nameOfType(const std::string& /*v*/) { return "std::string"; } -template /*inline*/ std::string nameOfType(const std::vector& /*v*/) { return std::string("std::vector<") + nameOfType(T()) + std::string(">"); } -template /*inline*/ std::string nameOfType(const std::list& /*v*/) { return "std::list<"+ nameOfType(T()) + std::string(">"); } +template inline std::string nameOfType(const std::vector& /*v*/) { return std::string("std::vector<") + nameOfType(T()) + std::string(">"); } +template inline std::string nameOfType(const std::list& /*v*/) { return "std::list<"+ nameOfType(T()) + std::string(">"); } /** From a1402533b76e2bd76b2bbc0f4944300684a8f7d5 Mon Sep 17 00:00:00 2001 From: Pierre Kraemer Date: Tue, 17 Nov 2015 17:34:31 +0100 Subject: [PATCH 082/185] add dart & cell marker classes + extern TLS Dart & uint buffers --- cgogn/core/CMakeLists.txt | 40 +++--- cgogn/core/basic/cell_marker.h | 124 ++++++++++++++++ cgogn/core/basic/dart_marker.h | 144 +++++++++++++++++++ cgogn/core/container/chunk_array.h | 47 ++++-- cgogn/core/container/chunk_array_container.h | 48 +++---- cgogn/core/map/map1.h | 22 +-- cgogn/core/map/map2.h | 10 +- cgogn/core/map/map_base.h | 5 +- cgogn/core/map/map_base_data.cpp | 51 +++++++ cgogn/core/map/map_base_data.h | 115 ++++++++++++--- cgogn/core/traversal/traversor_cell.h | 38 +++++ cgogn/utils/CMakeLists.txt | 32 +++-- cgogn/utils/buffers.h | 10 +- cgogn/utils/make_unique.h | 47 +++++- test/map/test_map.cpp | 16 ++- 15 files changed, 634 insertions(+), 115 deletions(-) create mode 100644 cgogn/core/basic/cell_marker.h create mode 100644 cgogn/core/basic/dart_marker.h create mode 100644 cgogn/core/map/map_base_data.cpp create mode 100644 cgogn/core/traversal/traversor_cell.h diff --git a/cgogn/core/CMakeLists.txt b/cgogn/core/CMakeLists.txt index 1ea3bec6..910f018f 100644 --- a/cgogn/core/CMakeLists.txt +++ b/cgogn/core/CMakeLists.txt @@ -1,12 +1,16 @@ project(cgogn_core - LANGUAGES CXX) + LANGUAGES CXX +) set(HEADER_FILES basic/dll.h basic/nameTypes.h basic/dart.h + basic/dart_marker.h basic/cell.h + basic/cell_marker.h basic/serialization.h + container/chunk_array_container.h container/chunk_array_factory.h container/chunk_array_gen.h @@ -18,36 +22,36 @@ set(HEADER_FILES map/map1.h map/map2.h map/map_tri.h - map/attribute_handler.h - ) + + traversal/traversor_cell.h +) set(SOURCE_FILES container/chunk_array_container.cpp - ) + + map/map_base_data.cpp +) add_library(${PROJECT_NAME} SHARED ${HEADER_FILES} ${SOURCE_FILES}) set_target_properties(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX "_d") target_include_directories(${PROJECT_NAME} PUBLIC - $ - $ - ) + $ + $ +) + target_link_libraries(${PROJECT_NAME} cgogn_utils) install(DIRECTORY basic container - DESTINATION include/cgogn/cgogn_core - FILES_MATCHING PATTERN "*.h" + DESTINATION include/cgogn/cgogn_core + FILES_MATCHING PATTERN "*.h" ) install(TARGETS ${PROJECT_NAME} - EXPORT ${PROJECT_NAME}Targets - RUNTIME DESTINATION bin - LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib - ) - - - - + EXPORT ${PROJECT_NAME}Targets + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib +) diff --git a/cgogn/core/basic/cell_marker.h b/cgogn/core/basic/cell_marker.h new file mode 100644 index 00000000..62c94cd9 --- /dev/null +++ b/cgogn/core/basic/cell_marker.h @@ -0,0 +1,124 @@ +/******************************************************************************* +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * +* Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France * +* * +* This library is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by the * +* Free Software Foundation; either version 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: http://cgogn.unistra.fr/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ + +#ifndef CORE_BASIC_CELL_MARKER_H_ +#define CORE_BASIC_CELL_MARKER_H_ + +#include +#include + +namespace cgogn +{ + +class CellMarkerGen +{ +public: + + CellMarkerGen() + {} + + virtual ~CellMarkerGen() + {} + + CellMarkerGen(const CellMarkerGen& dm) = delete; + CellMarkerGen(CellMarkerGen&& dm) = delete; + CellMarkerGen& operator=(CellMarkerGen&& dm) = delete; + CellMarkerGen& operator=(const CellMarkerGen& dm) = delete; +}; + +template +class CellMarkerT : public CellMarkerGen +{ +protected: + + MAP& map_; + ChunkArray* mark_attribute_; + +public: + + CellMarkerT(MAP& map) : + CellMarkerGen(), + map_(map) + { + mark_attribute_ = map_.template getMarkAttribute(); + } + + ~CellMarkerT() override + { + if (MapGen::isAlive(&map_)) + map_.template releaseMarkAttribute(mark_attribute_); + } + + CellMarkerT(const CellMarkerT& dm) = delete; + CellMarkerT(CellMarkerT&& dm) = delete; + CellMarkerT& operator=(CellMarkerT&& dm) = delete; + CellMarkerT& operator=(const CellMarkerT& dm) = delete; + + inline void mark(Dart d) + { + cgogn_message_assert(mark_attribute_ != nullptr, "CellMarker has null mark attribute"); + mark_attribute_->setTrue(d.index); + } + + inline void unmark(Dart d) + { + cgogn_message_assert(mark_attribute_ != nullptr, "CellMarker has null mark attribute"); + mark_attribute_->setFalse(d.index); + } + + inline void isMarked(Dart d) const + { + cgogn_message_assert(mark_attribute_ != nullptr, "CellMarker has null mark attribute"); + return (*mark_attribute_)[d.index]; + } +}; + +template +class CellMarker : public CellMarkerT +{ +public: + + CellMarker(MAP& map) : + CellMarkerT(map) + {} + + ~CellMarker() override + { + unmarkAll() ; + } + + CellMarker(const CellMarker& dm) = delete; + CellMarker(CellMarker&& dm) = delete; + CellMarker& operator=(CellMarker&& dm) = delete; + CellMarker& operator=(const CellMarker& dm) = delete; + + void unmarkAll() + { + cgogn_message_assert(this->mark_attribute_ != nullptr, "CellMarker has null mark attribute"); + this->mark_attribute_->allFalse(); + } +}; + +} // namespace cgogn + +#endif // CORE_BASIC_CELL_MARKER_H_ diff --git a/cgogn/core/basic/dart_marker.h b/cgogn/core/basic/dart_marker.h new file mode 100644 index 00000000..d9f3d483 --- /dev/null +++ b/cgogn/core/basic/dart_marker.h @@ -0,0 +1,144 @@ +/******************************************************************************* +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * +* Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France * +* * +* This library is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by the * +* Free Software Foundation; either version 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: http://cgogn.unistra.fr/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ + +#ifndef CORE_BASIC_DART_MARKER_H_ +#define CORE_BASIC_DART_MARKER_H_ + +#include +#include + +namespace cgogn +{ + +class DartMarkerGen +{ +public: + + DartMarkerGen() + {} + + virtual ~DartMarkerGen() + {} + + DartMarkerGen(const DartMarkerGen& dm) = delete; + DartMarkerGen(DartMarkerGen&& dm) = delete; + DartMarkerGen& operator=(DartMarkerGen&& dm) = delete; + DartMarkerGen& operator=(const DartMarkerGen& dm) = delete; +}; + +template +class DartMarkerT : public DartMarkerGen +{ +protected: + + MAP& map_; + ChunkArray* mark_attribute_; + +public: + + DartMarkerT(MAP& map) : + DartMarkerGen(), + map_(map) + { + mark_attribute_ = map_.template getTopologyMarkAttribute(); + } + + ~DartMarkerT() override + { + if (MapGen::isAlive(&map_)) + map_.template releaseTopologyMarkAttribute(mark_attribute_); + } + + DartMarkerT(const DartMarkerT& dm) = delete; + DartMarkerT(DartMarkerT&& dm) = delete; + DartMarkerT& operator=(DartMarkerT&& dm) = delete; + DartMarkerT& operator=(const DartMarkerT& dm) = delete; + + inline void mark(Dart d) + { + cgogn_message_assert(mark_attribute_ != nullptr, "DartMarker has null mark attribute"); + mark_attribute_->setTrue(d.index); + } + + inline void unmark(Dart d) + { + cgogn_message_assert(mark_attribute_ != nullptr, "DartMarker has null mark attribute"); + mark_attribute_->setFalse(d.index); + } + + inline void isMarked(Dart d) const + { + cgogn_message_assert(mark_attribute_ != nullptr, "DartMarker has null mark attribute"); + return (*mark_attribute_)[d.index]; + } + +// template +// inline void markOrbit(Cell c) +// { +// cgogn_message_assert(mark_attribute_ != nullptr, "DartMarker has null mark attribute"); +// map_.foreach_dart_of_orbit(c, [&] (Dart d) +// { +// mark_attribute_->setTrue(d.index); +// }) ; +// } + +// template +// inline void unmarkOrbit(Cell c) +// { +// cgogn_message_assert(mark_attribute_ != nullptr, "DartMarker has null mark attribute"); +// map_.foreach_dart_of_orbit(c, [&] (Dart d) +// { +// mark_attribute_->setFalse(d.index); +// }) ; +// } +}; + +template +class DartMarker : public DartMarkerT +{ +public: + + DartMarker(MAP& map) : + DartMarkerT(map) + {} + + ~DartMarker() override + { + unmarkAll() ; + } + + DartMarker(const DartMarker& dm) = delete; + DartMarker(DartMarker&& dm) = delete; + DartMarker& operator=(DartMarker&& dm) = delete; + DartMarker& operator=(const DartMarker& dm) = delete; + + void unmarkAll() + { + cgogn_message_assert(this->mark_attribute_ != nullptr, "DartMarker has null mark attribute"); + this->mark_attribute_->allFalse(); + } +}; + +} // namespace cgogn + +#endif // CORE_BASIC_DART_MARKER_H_ diff --git a/cgogn/core/container/chunk_array.h b/cgogn/core/container/chunk_array.h index baed68e1..0105a9fc 100644 --- a/cgogn/core/container/chunk_array.h +++ b/cgogn/core/container/chunk_array.h @@ -355,7 +355,7 @@ class ChunkArray : public ChunkArrayGen delete[] chunk; } - ChunkArray(const ChunkArray< CHUNKSIZE, bool>& ca) + ChunkArray(const ChunkArray& ca) { tableData_.reserve(1024u); this->setNbChunks(ca.getNbChunks()); @@ -369,7 +369,7 @@ class ChunkArray : public ChunkArrayGen tableData_(std::move(ca.tableData_)) {} - ChunkArray< CHUNKSIZE, bool>& operator=(ChunkArray< CHUNKSIZE, bool>&& ca) + ChunkArray& operator=(ChunkArray< CHUNKSIZE, bool>&& ca) { // this != &ca because ca is a rvalue this->clear(); @@ -377,7 +377,7 @@ class ChunkArray : public ChunkArrayGen return *this; } - ChunkArray< CHUNKSIZE, bool>& operator=(const ChunkArray< CHUNKSIZE, bool>& ca) + ChunkArray& operator=(const ChunkArray& ca) { if (this != &ca) { @@ -411,7 +411,7 @@ class ChunkArray : public ChunkArrayGen { if (nbc >= tableData_.size()) { - for (std::size_t i= tableData_.size(); i : public ChunkArrayGen tableData_.clear(); } - void setFalse(unsigned int i) + inline void setFalse(unsigned int i) { const unsigned int jj = i / CHUNKSIZE; cgogn_assert(jj < tableData_.size()); @@ -450,7 +450,7 @@ class ChunkArray : public ChunkArrayGen tableData_[jj][x] &= ~mask; } - void setTrue(unsigned int i) + inline void setTrue(unsigned int i) { const unsigned int jj = i / CHUNKSIZE; cgogn_assert(jj < tableData_.size()); @@ -461,7 +461,7 @@ class ChunkArray : public ChunkArrayGen tableData_[jj][x] |= mask; } - void setVal(unsigned int i, bool b) + inline void setVal(unsigned int i, bool b) { const unsigned int jj = i / CHUNKSIZE; cgogn_assert(jj < tableData_.size()); @@ -484,7 +484,7 @@ class ChunkArray : public ChunkArrayGen * Use only if final goal is to set all array to 0 (MarkerStore) * @todo find another name for the method! */ - void setFalseDirty(unsigned int i) + inline void setFalseDirty(unsigned int i) { const unsigned int jj = i / CHUNKSIZE; cgogn_assert(jj < tableData_.size()); @@ -492,7 +492,7 @@ class ChunkArray : public ChunkArrayGen tableData_[jj][j] = 0u; } - bool operator[](unsigned int i) const + inline bool operator[](unsigned int i) const { const unsigned int jj = i / CHUNKSIZE; cgogn_assert(jj < tableData_.size()); @@ -505,7 +505,27 @@ class ChunkArray : public ChunkArrayGen return (tableData_[jj][x] & mask) != 0u; } - unsigned int getChunksPointers(std::vector& addr, unsigned int& byteBlockSize) const override + inline void allFalse() + { + for (std::size_t i = 0, end = tableData_.size() ; i < end ; ++i) + { + unsigned int* ptr = tableData_[i]; + for (unsigned int j = 0; j < CHUNKSIZE/32u; ++j) + *ptr++ = 0; + } + } + + inline void allTrue() + { + for (std::size_t i = 0, end = tableData_.size() ; i < end ; ++i) + { + unsigned int* ptr = tableData_[i]; + for (unsigned int j = 0; j < CHUNKSIZE/32u; ++j) + *ptr++ = 0xffffffff; + } + } + + inline unsigned int getChunksPointers(std::vector& addr, unsigned int& byteBlockSize) const override { byteBlockSize = CHUNKSIZE / 8u; @@ -518,18 +538,18 @@ class ChunkArray : public ChunkArrayGen return static_cast(addr.size()); } - void initElt(unsigned int id) override + inline void initElt(unsigned int id) override { setFalse(id); } - void copyElt(unsigned int dst, unsigned int src) override + inline void copyElt(unsigned int dst, unsigned int src) override { setVal(dst,this->operator [](src)); } - void swapElt(unsigned int id1, unsigned int id2) override + inline void swapElt(unsigned int id1, unsigned int id2) override { bool data = this->operator [](id1); setVal(id1,this->operator [](id2)); @@ -542,7 +562,6 @@ class ChunkArray : public ChunkArrayGen if (nbLines%32u) nbLines = ((nbLines/32u)+1u)*32u; - cgogn_assert(nbLines/CHUNKSIZE <= tableData_.size()); // TODO: if (nbLines==0) nbLines=CHUNKSIZE*tableData_.size(); ?? diff --git a/cgogn/core/container/chunk_array_container.h b/cgogn/core/container/chunk_array_container.h index 08c7e781..3af13a16 100644 --- a/cgogn/core/container/chunk_array_container.h +++ b/cgogn/core/container/chunk_array_container.h @@ -58,7 +58,7 @@ class CGOGN_CORE_API ContainerBrowser }; template -class ContainerStandardBrowser:public ContainerBrowser +class ContainerStandardBrowser : public ContainerBrowser { const CONTAINER* cac_; @@ -202,10 +202,10 @@ class ChunkArrayContainer names_.pop_back(); typeNames_.pop_back(); - delete ptrToDel ; + delete ptrToDel; - return true ; + return true; } public: @@ -242,11 +242,11 @@ class ChunkArrayContainer { // first check if attribute already exist - unsigned int index = getArrayIndex(attribName) ; + unsigned int index = getArrayIndex(attribName); if (index == UNKNOWN) { - std::cerr << "attribute " << attribName << " not found." << std::endl ; - return nullptr ; + std::cerr << "attribute " << attribName << " not found." << std::endl; + return nullptr; } return static_cast*>(tableArrays_[index]); @@ -264,23 +264,23 @@ class ChunkArrayContainer cgogn_assert(attribName.size() != 0); // first check if attribute already exist - unsigned int index = getArrayIndex(attribName) ; + unsigned int index = getArrayIndex(attribName); if (index != UNKNOWN) { - std::cerr << "attribute " << attribName << " already found.." << std::endl ; - return nullptr ; + std::cerr << "attribute " << attribName << " already found.." << std::endl; + return nullptr; } // create the new attribute - const std::string& typeName = nameOfType(T()) ; - ChunkArray* carr = new ChunkArray() ; + const std::string& typeName = nameOfType(T()); + ChunkArray* carr = new ChunkArray(); ChunkArrayFactory::template registerCA(); // reserve memory - carr->setNbChunks(refs_.getNbChunks()) ; + carr->setNbChunks(refs_.getNbChunks()); // store pointer, name & typename. - tableArrays_.push_back(carr) ; + tableArrays_.push_back(carr); names_.push_back(attribName); typeNames_.push_back(typeName); @@ -301,7 +301,7 @@ class ChunkArrayContainer } - return carr ; + return carr; } /** @@ -311,12 +311,12 @@ class ChunkArrayContainer */ bool removeAttribute(const std::string& attribName) { - unsigned int index = getArrayIndex(attribName) ; + unsigned int index = getArrayIndex(attribName); if (index == UNKNOWN) { - std::cerr << "removeAttribute by name: attribute not found (" << attribName << ")"<< std::endl ; - return false ; + std::cerr << "removeAttribute by name: attribute not found (" << attribName << ")"<< std::endl; + return false; } removeAttribute(index); @@ -331,12 +331,12 @@ class ChunkArrayContainer */ bool removeAttribute(const ChunkArrayGen* ptr) { - unsigned int index = getArrayIndex(ptr) ; + unsigned int index = getArrayIndex(ptr); if (index == UNKNOWN) { - std::cerr << "removeAttribute by ptr: attribute not found (" << std::endl ; - return false ; + std::cerr << "removeAttribute by ptr: attribute not found (" << std::endl; + return false; } removeAttribute(index); @@ -745,9 +745,9 @@ class ChunkArrayContainer template ChunkArray* getDataArray(const std::string& attribName) { - unsigned int index = getArrayIndex(attribName) ; + unsigned int index = getArrayIndex(attribName); if(index == UNKNOWN) - return nullptr ; + return nullptr; ChunkArray* atm = dynamic_cast*>(tableArrays_[index]); @@ -763,9 +763,9 @@ class ChunkArrayContainer */ ChunkArrayGen* getVirtualDataArray(const std::string& attribName) { - unsigned int index = getArrayIndex(attribName) ; + unsigned int index = getArrayIndex(attribName); if(index == UNKNOWN) - return nullptr ; + return nullptr; return tableArrays_[index]; } diff --git a/cgogn/core/map/map1.h b/cgogn/core/map/map1.h index 20ead0d3..6859b19c 100644 --- a/cgogn/core/map/map1.h +++ b/cgogn/core/map/map1.h @@ -40,9 +40,9 @@ class Map1 : public MapBase { public: - static const unsigned int VERTEX = VERTEX1; - static const unsigned int EDGE = VERTEX1; - static const unsigned int FACE = FACE2; + static const unsigned int VERTEX = VERTEX1; + static const unsigned int EDGE = VERTEX1; + static const unsigned int FACE = FACE2; template using VertexAttributeHandler = cgogn::AttributeHandler; @@ -131,13 +131,13 @@ class Map1 : public MapBase * @param nbEdges * @return */ - Dart add_cycle(unsigned int nbEdges) ; + Dart add_cycle(unsigned int nbEdges); /** * @brief remove_cycle * @param d */ - void remove_cycle(Dart d) ; + void remove_cycle(Dart d); /** * @brief cut_edge @@ -146,8 +146,8 @@ class Map1 : public MapBase */ Dart cut_edge(Dart d) { - Dart e = this->newDart() ; // Create a new dart - phi1sew(d, e) ; // Insert dart e between d and phi1(d) + Dart e = this->newDart(); // Create a new dart + phi1sew(d, e); // Insert dart e between d and phi1(d) // TODO: doit on traiter les marker de bord 2/3 dans Map1 if (this->template isBoundaryMarked<2>(d)) @@ -156,7 +156,7 @@ class Map1 : public MapBase if (this->template isBoundaryMarked<3>(d)) this->template boundaryMark<3>(e); - return e ; + return e; } /** @@ -166,9 +166,9 @@ class Map1 : public MapBase */ void uncut_edge(Dart d) { - Dart d1 = phi1(d) ; - phi1unsew(d) ; // Dart d is linked to the successor of its successor - this->deleteDart(d1) ; // Dart d1 is erased + Dart d1 = phi1(d); + phi1unsew(d); // Dart d is linked to the successor of its successor + this->deleteDart(d1); // Dart d1 is erased } /** diff --git a/cgogn/core/map/map2.h b/cgogn/core/map/map2.h index 8de97c46..acef1ecb 100644 --- a/cgogn/core/map/map2.h +++ b/cgogn/core/map/map2.h @@ -34,9 +34,9 @@ class Map2 : public Map1 { public: - static const unsigned int VERTEX = VERTEX2; - static const unsigned int EDGE = EDGE2; - static const unsigned int FACE = FACE2; + static const unsigned int VERTEX = VERTEX2; + static const unsigned int EDGE = EDGE2; + static const unsigned int FACE = FACE2; template using VertexAttributeHandler = cgogn::AttributeHandler; @@ -87,7 +87,9 @@ class Map2 : public Map1 init(); } - ~Map2() override {} + ~Map2() override + {} + /** * @brief phi2 * @param d diff --git a/cgogn/core/map/map_base.h b/cgogn/core/map/map_base.h index 37118496..f7ef8906 100644 --- a/cgogn/core/map/map_base.h +++ b/cgogn/core/map/map_base.h @@ -41,7 +41,6 @@ class MapBase : public MapBaseData public: - //TODO remonter dans map_base template using AttributeHandler = AttributeHandler; @@ -99,6 +98,10 @@ class MapBase : public MapBaseData return AttributeHandler(this, ca); } + /** + * add a Dart in the map + * @return the new Dart + */ inline Dart add_dart() { unsigned int di = this->topology_.template insertLines<1>(); // insert a new dart line diff --git a/cgogn/core/map/map_base_data.cpp b/cgogn/core/map/map_base_data.cpp new file mode 100644 index 00000000..ecb9f3dd --- /dev/null +++ b/cgogn/core/map/map_base_data.cpp @@ -0,0 +1,51 @@ +/******************************************************************************* +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * +* Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France * +* * +* This library is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by the * +* Free Software Foundation; either version 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: http://cgogn.unistra.fr/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ + +#include + +namespace cgogn +{ + +std::vector* MapGen::instances_ = nullptr; + +CGOGN_TLS Buffers dart_buffers_thread = Buffers(); +CGOGN_TLS Buffers uint_buffers_thread = Buffers(); + +MapGen::MapGen() +{ + if (instances_ == nullptr) + instances_ = new std::vector; + + // register the map in the vector of instances + instances_->push_back(this); +} + +MapGen::~MapGen() +{ + // remove the map from the vector of instances + auto it = std::find(instances_->begin(), instances_->end(), this); + *it = instances_->back(); + instances_->pop_back(); +} + +} // namespace cgogn diff --git a/cgogn/core/map/map_base_data.h b/cgogn/core/map/map_base_data.h index d6fde626..cc9fa948 100644 --- a/cgogn/core/map/map_base_data.h +++ b/cgogn/core/map/map_base_data.h @@ -31,22 +31,41 @@ #include #include +#include +#include namespace cgogn { +/// buffers of pre-allocated vectors of dart or unsigned int +extern CGOGN_TLS Buffers dart_buffers_thread; +extern CGOGN_TLS Buffers uint_buffers_thread; + /** - * @brief Generic Map class (for SCHNApps) + * @brief Generic Map class */ class MapGen { +private: + + /// vector of Map instances + static std::vector* instances_; + public: - virtual ~MapGen() {} + + MapGen(); + + virtual ~MapGen(); + + static inline bool isAlive(MapGen* map) + { + return std::find(instances_->begin(), instances_->end(), map) != instances_->end(); + } }; /** - * @brief The MapBase class + * @brief The MapBaseData class */ template class MapBaseData : public MapGen @@ -60,28 +79,43 @@ class MapBaseData : public MapGen ChunkArrayContainer attributes_[NB_ORBITS]; /// embedding indices shortcuts - ChunkArray* embeddings_[NB_ORBITS]; + ChunkArray* embeddings_[NB_ORBITS]; /// boundary markers shortcuts - ChunkArray* boundaryMarkers_[2]; + ChunkArray* boundary_markers_[2]; // TODO: ?? store in a std::vector ? /// topo relations shortcuts - std::vector*> topo_relations_; + std::vector*> topo_relations_; - /// buffers of pre-allocated vectors of dart or unsigned int - Buffers dart_buffers_[NB_THREADS]; - Buffers uint_buffers_[NB_THREADS]; + /// vector of available mark attributes per orbit per thread + std::vector*> mark_attributes_[NB_ORBITS][NB_THREADS]; + unsigned int mark_attribute_id_[NB_ORBITS]; + std::mutex mark_attributes_mutex_[NB_ORBITS]; - /// vector of thread ids known by the map that can pretend to data such as mark vectors and buffers + /// vector of available mark attributes per thread on the topology container + std::vector*> mark_attributes_topology_[NB_THREADS]; + unsigned int mark_attribute_topology_id_; + std::mutex mark_attributes_topology_mutex_; + + /// vector of thread ids known by the map that can pretend to data such as mark vectors std::vector thread_ids_; public: + static const unsigned int CHUNK_SIZE = DATA_TRAITS::CHUNK_SIZE; + MapBaseData() { for (unsigned int i = 0; i < NB_ORBITS; ++i) + { embeddings_[i] = nullptr; + mark_attribute_id_[i] = 0; + for (unsigned int j = 0; j < NB_THREADS; ++j) + { + mark_attributes_[i][j].reserve(8); + } + } thread_ids_.reserve(NB_THREADS + 1); thread_ids_.push_back(std::this_thread::get_id()); @@ -98,31 +132,76 @@ class MapBaseData : public MapGen inline unsigned int getEmbedding(const Cell& c) const { cgogn_message_assert(embeddings_[ORBIT] != NULL, "Invalid parameter: orbit not embedded"); + return (*embeddings_[ORBIT])[c.dart.index] ; } - inline std::vector* getDartBuffer() + inline ChunkArray* getTopologyMarkAttribute() { unsigned int thread = getCurrentThreadIndex(); - return dart_buffers_[thread].getBuffer(); + if (!mark_attributes_topology_[thread].empty()) + { + ChunkArray* ca = mark_attributes_topology_[thread].back(); + mark_attributes_topology_[thread].pop_back(); + return ca; + } + else + { + std::lock_guard lock(mark_attributes_topology_mutex_); + + unsigned int x = mark_attribute_topology_id_++; + std::string number("___"); + number[2] = '0'+char(x%10u); x /= 10u; + number[1] = '0'+char(x%10u); x /= 10u; + number[0] = '0'+char(x%10u); + +// ChunkArray* ca = topology_.addMarkerAttribute("marker_" + number); +// return ca; + return nullptr; + } } - inline void releaseDartBuffer(std::vector* v) + inline void releaseTopologyMarkAttribute(ChunkArray* ca) { unsigned int thread = getCurrentThreadIndex(); - dart_buffers_[thread].releaseBuffer(v); + mark_attributes_topology_[thread].push_back(ca); } - inline std::vector* getUIntBuffer() + template + inline ChunkArray* getMarkAttribute() { + cgogn_message_assert(embeddings_[ORBIT] != NULL, "Invalid parameter: orbit not embedded"); + unsigned int thread = getCurrentThreadIndex(); - return uint_buffers_[thread].getBuffer(); + if (!mark_attributes_[ORBIT][thread].empty()) + { + ChunkArray* ca = mark_attributes_[ORBIT][thread].back(); + mark_attributes_[ORBIT][thread].pop_back(); + return ca; + } + else + { + std::lock_guard lock(mark_attributes_mutex_[ORBIT]); + + unsigned int x = mark_attribute_id_[ORBIT]++; + std::string number("___"); + number[2] = '0'+char(x%10u); x /= 10u; + number[1] = '0'+char(x%10u); x /= 10u; + number[0] = '0'+char(x%10u); + +// ChunkArray* ca = attributes_[ORBIT].addMarkerAttribute("marker_" + orbitName(ORBIT) + number); +// return ca; + return nullptr; + } } - inline void releaseUIntBuffer(std::vector* v) + template + inline void releaseMarkAttribute(ChunkArray* ca) { + cgogn_message_assert(embeddings_[ORBIT] != NULL, "Invalid parameter: orbit not embedded"); + unsigned int thread = getCurrentThreadIndex(); - uint_buffers_[thread].releaseBuffer(v); + mark_attributes_[ORBIT][thread].push_back(ca); } protected: diff --git a/cgogn/core/traversal/traversor_cell.h b/cgogn/core/traversal/traversor_cell.h new file mode 100644 index 00000000..c9ea711b --- /dev/null +++ b/cgogn/core/traversal/traversor_cell.h @@ -0,0 +1,38 @@ +/******************************************************************************* +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * +* Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France * +* * +* This library is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by the * +* Free Software Foundation; either version 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: http://cgogn.unistra.fr/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ + +#ifndef CORE_TRAVERSAL_TRAVERSORCELL_H_ +#define CORE_TRAVERSAL_TRAVERSORCELL_H_ + +namespace cgogn +{ + +template +class TraversorCell +{ + +}; + +} // namespace cgogn + +#endif // CORE_TRAVERSAL_TRAVERSORCELL_H_ diff --git a/cgogn/utils/CMakeLists.txt b/cgogn/utils/CMakeLists.txt index f8fb0d40..6cb92a9c 100644 --- a/cgogn/utils/CMakeLists.txt +++ b/cgogn/utils/CMakeLists.txt @@ -1,16 +1,17 @@ project(cgogn_utils - LANGUAGES CXX) + LANGUAGES CXX +) set(HEADER_FILES dll.h definitions.h assert.h - buffers.h - make_unique.h - ) + buffers.h + make_unique.h +) set(SOURCE_FILES - assert.cpp + assert.cpp ) add_library(${PROJECT_NAME} SHARED ${HEADER_FILES} ${SOURCE_FILES}) @@ -21,17 +22,18 @@ endif() set_target_properties(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX "_d") target_include_directories(${PROJECT_NAME} PUBLIC - $ - $ - ) + $ + $ +) + install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} - DESTINATION include/cgogn/utils - FILES_MATCHING PATTERN "*.h" + DESTINATION include/cgogn/utils + FILES_MATCHING PATTERN "*.h" ) install(TARGETS ${PROJECT_NAME} - EXPORT ${PROJECT_NAME}Targets - RUNTIME DESTINATION bin - LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib - ) + EXPORT ${PROJECT_NAME}Targets + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib +) diff --git a/cgogn/utils/buffers.h b/cgogn/utils/buffers.h index ee4f58c4..72347a31 100644 --- a/cgogn/utils/buffers.h +++ b/cgogn/utils/buffers.h @@ -38,6 +38,14 @@ class Buffers public: + ~Buffers() + { + for (auto i : buffers_) + { + delete i; + } + } + inline std::vector* getBuffer() { if (buffers_.empty()) @@ -56,7 +64,7 @@ class Buffers { if (b->capacity() > 1024) { - std::vector v; + std::vector v; b->swap(v); b->reserve(128); } diff --git a/cgogn/utils/make_unique.h b/cgogn/utils/make_unique.h index 2bc5b9e4..dd9937ee 100644 --- a/cgogn/utils/make_unique.h +++ b/cgogn/utils/make_unique.h @@ -1,5 +1,29 @@ +/******************************************************************************* +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * * * +* Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France * +* * +* This library is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by the * +* Free Software Foundation; either version 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: http://cgogn.unistra.fr/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ + #ifndef UTILS_MAKE_UNIQUE_H #define UTILS_MAKE_UNIQUE_H + #include #include #include @@ -11,28 +35,38 @@ * see https://isocpp.org/files/papers/N3656.txt */ -namespace cgogn { -template struct _Unique_if { +namespace cgogn +{ + +template +struct _Unique_if +{ typedef std::unique_ptr _Single_object; }; -template struct _Unique_if { +template +struct _Unique_if +{ typedef std::unique_ptr _Unknown_bound; }; -template struct _Unique_if { +template +struct _Unique_if +{ typedef void _Known_bound; }; template typename _Unique_if::_Single_object -make_unique(Args&&... args) { +make_unique(Args&&... args) +{ return std::unique_ptr(new T(std::forward(args)...)); } template typename _Unique_if::_Unknown_bound -make_unique(size_t n) { +make_unique(size_t n) +{ typedef typename std::remove_extent::type U; return std::unique_ptr(new U[n]()); } @@ -40,6 +74,7 @@ make_unique(size_t n) { template typename _Unique_if::_Known_bound make_unique(Args&&...) = delete; + } #endif // UTILS_MAKE_UNIQUE_H diff --git a/test/map/test_map.cpp b/test/map/test_map.cpp index c3a5a473..fac2e363 100644 --- a/test/map/test_map.cpp +++ b/test/map/test_map.cpp @@ -2,12 +2,15 @@ #include #include +#include +#include + using namespace cgogn; struct My_Data_Traits { - static const int CHUNK_SIZE = 64; + static const unsigned int CHUNK_SIZE = 64; }; @@ -51,6 +54,13 @@ int test1(MAP1& map) // add an attribute on vertex of map with MAP1::VertexAttributeHandler ah = map.addAttribute("floats"); + std::vector* uib = cgogn::uint_buffers_thread.getBuffer(); + uib->push_back(3); + cgogn::uint_buffers_thread.releaseBuffer(uib); + + DartMarker dm(map); + CellMarker cm(map); + // get ChunkArrayContainer -> get ChunkArray -> fill ChunkArrayContainer& container = map.getAttributeContainer(VERTEX1); ChunkArray* att = container.getAttribute("floats"); @@ -77,8 +87,8 @@ int test1(MAP1& map) int main() { - MAP1 map; + MAP1 map1; MAP2 map2; - test1(map); + test1(map1); return 0; } From d4a0ddc2726ace87802cfb1ed3d84e16d7f40437 Mon Sep 17 00:00:00 2001 From: Pierre Kraemer Date: Tue, 17 Nov 2015 17:44:54 +0100 Subject: [PATCH 083/185] use Cell instead of Dart in CellMarker methods --- cgogn/core/basic/cell_marker.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cgogn/core/basic/cell_marker.h b/cgogn/core/basic/cell_marker.h index 62c94cd9..aab0d98e 100644 --- a/cgogn/core/basic/cell_marker.h +++ b/cgogn/core/basic/cell_marker.h @@ -74,22 +74,22 @@ class CellMarkerT : public CellMarkerGen CellMarkerT& operator=(CellMarkerT&& dm) = delete; CellMarkerT& operator=(const CellMarkerT& dm) = delete; - inline void mark(Dart d) + inline void mark(Cell c) { cgogn_message_assert(mark_attribute_ != nullptr, "CellMarker has null mark attribute"); - mark_attribute_->setTrue(d.index); + mark_attribute_->setTrue(map_.getEmbedding(c)); } - inline void unmark(Dart d) + inline void unmark(Cell c) { cgogn_message_assert(mark_attribute_ != nullptr, "CellMarker has null mark attribute"); - mark_attribute_->setFalse(d.index); + mark_attribute_->setFalse(map_.getEmbedding(c)); } - inline void isMarked(Dart d) const + inline void isMarked(Cell c) const { cgogn_message_assert(mark_attribute_ != nullptr, "CellMarker has null mark attribute"); - return (*mark_attribute_)[d.index]; + return (*mark_attribute_)[map_.getEmbedding(c)]; } }; From 29f595ec62ba1dc3feea41d03f20655bc89db45f Mon Sep 17 00:00:00 2001 From: Pierre Kraemer Date: Tue, 17 Nov 2015 19:48:15 +0100 Subject: [PATCH 084/185] create mark attributes in addMarkAttribute methods --- cgogn/core/container/chunk_array.h | 6 ++---- cgogn/core/container/chunk_array_container.h | 6 +++--- cgogn/core/map/map_base.h | 2 +- cgogn/core/map/map_base_data.h | 10 ++++------ test/map/test_map.cpp | 4 ++++ 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/cgogn/core/container/chunk_array.h b/cgogn/core/container/chunk_array.h index 0105a9fc..0d4ba9e5 100644 --- a/cgogn/core/container/chunk_array.h +++ b/cgogn/core/container/chunk_array.h @@ -507,9 +507,8 @@ class ChunkArray : public ChunkArrayGen inline void allFalse() { - for (std::size_t i = 0, end = tableData_.size() ; i < end ; ++i) + for (auto ptr : tableData_) { - unsigned int* ptr = tableData_[i]; for (unsigned int j = 0; j < CHUNKSIZE/32u; ++j) *ptr++ = 0; } @@ -517,9 +516,8 @@ class ChunkArray : public ChunkArrayGen inline void allTrue() { - for (std::size_t i = 0, end = tableData_.size() ; i < end ; ++i) + for (auto ptr : tableData_) { - unsigned int* ptr = tableData_[i]; for (unsigned int j = 0; j < CHUNKSIZE/32u; ++j) *ptr++ = 0xffffffff; } diff --git a/cgogn/core/container/chunk_array_container.h b/cgogn/core/container/chunk_array_container.h index ed5dbd9c..f2e76c8d 100644 --- a/cgogn/core/container/chunk_array_container.h +++ b/cgogn/core/container/chunk_array_container.h @@ -258,7 +258,7 @@ class ChunkArrayContainer * @return pointer on created ChunkArray */ template - ChunkArray* addAttribute(const std::string& attribName) + ChunkArray* addAttribute(const std::string& attribName) { cgogn_assert(attribName.size() != 0); @@ -291,9 +291,9 @@ class ChunkArrayContainer * @param attribName name of marker attribute * @return pointer on created ChunkArray */ - ChunkArray* addMarkerAttribute(const std::string& attribName) + ChunkArray* addMarkerAttribute(const std::string& attribName) { - ChunkArray* ptr = this->template addMarkerAttribute(attribName); + ChunkArray* ptr = addAttribute(attribName); if (tableArrays_.size() > nbMarkerAttribs_) { diff --git a/cgogn/core/map/map_base.h b/cgogn/core/map/map_base.h index 9079f51e..79c9e0da 100644 --- a/cgogn/core/map/map_base.h +++ b/cgogn/core/map/map_base.h @@ -105,7 +105,7 @@ class MapBase : public MapBaseData * add a Dart in the map * @return the new Dart */ - inline Dart add_dart() + inline Dart addDart() { unsigned int di = this->topology_.template insertLines<1>(); // insert a new dart line this->topology_.initBooleansOfLine(di); diff --git a/cgogn/core/map/map_base_data.h b/cgogn/core/map/map_base_data.h index cc9fa948..51fd4ae4 100644 --- a/cgogn/core/map/map_base_data.h +++ b/cgogn/core/map/map_base_data.h @@ -155,9 +155,8 @@ class MapBaseData : public MapGen number[1] = '0'+char(x%10u); x /= 10u; number[0] = '0'+char(x%10u); -// ChunkArray* ca = topology_.addMarkerAttribute("marker_" + number); -// return ca; - return nullptr; + ChunkArray* ca = topology_.addMarkerAttribute("marker_" + number); + return ca; } } @@ -189,9 +188,8 @@ class MapBaseData : public MapGen number[1] = '0'+char(x%10u); x /= 10u; number[0] = '0'+char(x%10u); -// ChunkArray* ca = attributes_[ORBIT].addMarkerAttribute("marker_" + orbitName(ORBIT) + number); -// return ca; - return nullptr; + ChunkArray* ca = attributes_[ORBIT].addMarkerAttribute("marker_" + orbitName(ORBIT) + number); + return ca; } } diff --git a/test/map/test_map.cpp b/test/map/test_map.cpp index fac2e363..874e5996 100644 --- a/test/map/test_map.cpp +++ b/test/map/test_map.cpp @@ -58,9 +58,13 @@ int test1(MAP1& map) uib->push_back(3); cgogn::uint_buffers_thread.releaseBuffer(uib); + Dart d = map.addDart(); + DartMarker dm(map); CellMarker cm(map); + dm.mark(d); + // get ChunkArrayContainer -> get ChunkArray -> fill ChunkArrayContainer& container = map.getAttributeContainer(VERTEX1); ChunkArray* att = container.getAttribute("floats"); From 15e6fb73418fb1407e2eaf6d23884aba14fafe26 Mon Sep 17 00:00:00 2001 From: Pierre Kraemer Date: Wed, 18 Nov 2015 10:41:29 +0100 Subject: [PATCH 085/185] delete copy constructors of bool ChunkArray + other minor updates --- cgogn/core/basic/serialization.h | 17 +- cgogn/core/container/chunk_array.h | 555 ++++++++++--------- cgogn/core/container/chunk_array_container.h | 449 ++++++++------- cgogn/core/container/chunk_array_gen.h | 42 +- cgogn/core/container/chunk_stack.h | 38 +- cgogn/core/map/map_base.h | 16 +- test/chunk_array/bench_chunk_array.cpp | 26 +- test/chunk_array/test_chunk_array.cpp | 9 +- 8 files changed, 579 insertions(+), 573 deletions(-) diff --git a/cgogn/core/basic/serialization.h b/cgogn/core/basic/serialization.h index 17e8228a..4d15118d 100644 --- a/cgogn/core/basic/serialization.h +++ b/cgogn/core/basic/serialization.h @@ -20,6 +20,7 @@ * Contact information: cgogn@unistra.fr * * * *******************************************************************************/ + #ifndef CORE_SERIALIZATION_H_ #define CORE_SERIALIZATION_H_ @@ -31,18 +32,19 @@ namespace cgogn { + namespace serialization { template -void load(std::istream& istream, T * dest, std::size_t quantity) +void load(std::istream& istream, T* dest, std::size_t quantity) { cgogn_assert(dest != nullptr); istream.read(reinterpret_cast(dest), static_cast(quantity*sizeof(T))); } template -void save(std::ostream& ostream, T const * src, std::size_t quantity) +void save(std::ostream& ostream, T const* src, std::size_t quantity) { cgogn_assert(src != nullptr); ostream.write(reinterpret_cast(src), static_cast(quantity*sizeof(T))); @@ -58,7 +60,6 @@ void load(std::istream& istream, std::list* dest, std::size_t quantity); template void save(std::ostream& ostream, std::list const * src, std::size_t quantity); - // loading n vectors template void load(std::istream& istream, std::vector* dest, std::size_t quantity) @@ -75,7 +76,7 @@ void load(std::istream& istream, std::vector* dest, std::size_t quantity) // saving n vectors template -void save(std::ostream& ostream, std::vector const * src, std::size_t quantity) +void save(std::ostream& ostream, std::vector const* src, std::size_t quantity) { cgogn_assert(src != nullptr); for (std::size_t i = 0; i < quantity ; ++i) @@ -108,7 +109,7 @@ void load(std::istream& istream, std::list* dest, std::size_t quantity) // saving n lists template -void save(std::ostream& ostream, std::list const * src, std::size_t quantity) +void save(std::ostream& ostream, std::list const* src, std::size_t quantity) { cgogn_assert(src != nullptr); @@ -121,8 +122,8 @@ void save(std::ostream& ostream, std::list const * src, std::size_t quantity) } } -} -} +} // namespace serialization -#endif // CORE_SERIALIZATION_H_ +} // namespace cgogn +#endif // CORE_SERIALIZATION_H_ diff --git a/cgogn/core/container/chunk_array.h b/cgogn/core/container/chunk_array.h index 0d4ba9e5..5b6331a4 100644 --- a/cgogn/core/container/chunk_array.h +++ b/cgogn/core/container/chunk_array.h @@ -46,7 +46,7 @@ class ChunkArray : public ChunkArrayGen protected: /// vector of block pointers - std::vector tableData_; + std::vector table_data_; public: @@ -55,28 +55,20 @@ class ChunkArray : public ChunkArrayGen */ inline ChunkArray() : ChunkArrayGen() { - tableData_.reserve(1024u); + table_data_.reserve(1024u); } - ChunkArray(const ChunkArray< CHUNKSIZE, T>& ca) = delete; - ChunkArray(ChunkArray< CHUNKSIZE, T>&& ca) = delete; - ChunkArray< CHUNKSIZE, T>& operator=(ChunkArray< CHUNKSIZE, T>&& ca) = delete; - ChunkArray< CHUNKSIZE, T>& operator=(const ChunkArray< CHUNKSIZE, T>& ca) = delete; + ChunkArray(const ChunkArray& ca) = delete; + ChunkArray(ChunkArray&& ca) = delete; + ChunkArray& operator=(ChunkArray&& ca) = delete; + ChunkArray& operator=(const ChunkArray& ca) = delete; - /** - * @brief Destructor of ChunkArray - */ ~ChunkArray() override { - for(auto chunk: tableData_) + for(auto chunk : table_data_) delete[] chunk; } - bool isBooleanArray() const override - { - return false; - } - /** * @brief create a ChunkArray * @return generic pointer @@ -86,12 +78,17 @@ class ChunkArray : public ChunkArrayGen return new ChunkArray(); } + bool isBooleanArray() const override + { + return false; + } + /** * @brief add a chunk (T[CHUNKSIZE]) */ void addChunk() override { - tableData_.emplace_back(new T[CHUNKSIZE]()); + table_data_.emplace_back(new T[CHUNKSIZE]()); } /** @@ -100,16 +97,16 @@ class ChunkArray : public ChunkArrayGen */ void setNbChunks(unsigned int nbc) override { - if (nbc >= tableData_.size()) + if (nbc >= table_data_.size()) { - for (std::size_t i= tableData_.size(); i */ unsigned int getNbChunks() const override { - return static_cast(tableData_.size()); + return static_cast(table_data_.size()); } /** - * @brief number of allocated elements - * @return allocated lines + * @brief get the capacity of the array + * @return number of allocated lines */ unsigned int capacity() const override { - return static_cast(tableData_.size())*CHUNKSIZE; + return static_cast(table_data_.size())*CHUNKSIZE; } /** - * @brief clear + * @brief clear the array */ void clear() override { - for(auto chunk: tableData_) + for(auto chunk : table_data_) delete[] chunk; - tableData_.clear(); - } - - /** - * @brief ref operator [] - * @param i index of element to access - * @return ref of element - */ - inline T& operator[](unsigned int i) - { - cgogn_assert(i/CHUNKSIZE < tableData_.size()); - return tableData_[i / CHUNKSIZE][i % CHUNKSIZE]; - } - - /** - * @brief const ref operator [] - * @param i index of element to access - * @return const ref of element - */ - inline const T& operator[](unsigned int i) const - { - cgogn_assert(i/CHUNKSIZE < tableData_.size()); - return tableData_[i / CHUNKSIZE][i % CHUNKSIZE]; - } - - /** - * @brief set the value of an element (works also with bool) - * @param i index of element to set - * @param v value - */ - inline void setVal(unsigned int i, const T& v) - { - cgogn_assert(i/CHUNKSIZE < tableData_.size()); - tableData_[i / CHUNKSIZE][i % CHUNKSIZE] = v; + table_data_.clear(); } /** - * @brief get pointer on all chunks data + * @brief fill a vector with pointers to all chunks * @param addr vector to fill - * @param byteBlockSize filled with CHUNKSIZE*sizeof(T) + * @param byte_block_size filled with CHUNKSIZE*sizeof(T) * @return addr.size() */ - unsigned int getChunksPointers(std::vector& addr, unsigned int& byteBlockSize) const override + unsigned int getChunksPointers(std::vector& addr, unsigned int& byte_block_size) const override { - byteBlockSize = CHUNKSIZE * sizeof(T); + byte_block_size = CHUNKSIZE * sizeof(T); - addr.reserve(tableData_.size()); + addr.reserve(table_data_.size()); addr.clear(); - for (typename std::vector::const_iterator it = tableData_.begin(); it != tableData_.end(); ++it) + for (typename std::vector::const_iterator it = table_data_.begin(); it != table_data_.end(); ++it) addr.push_back(*it); return static_cast(addr.size()); } /** - * @brief init an element (overwrite with T()) - * @param id index of element + * @brief initialize an element (overwrite with T()) + * @param id index of the element */ - void initElt(unsigned int id) override + void initElement(unsigned int id) override { - tableData_[id / CHUNKSIZE][id % CHUNKSIZE] = T(); + table_data_[id / CHUNKSIZE][id % CHUNKSIZE] = T(); } /** - * @brief copy element - * @param dst destination - * @param src source + * @brief copy an element to another one + * @param dst destination index + * @param src source index */ - void copyElt(unsigned int dst, unsigned int src) override + void copyElement(unsigned int dst, unsigned int src) override { - tableData_[dst / CHUNKSIZE][dst % CHUNKSIZE] = tableData_[src / CHUNKSIZE][src % CHUNKSIZE]; + table_data_[dst / CHUNKSIZE][dst % CHUNKSIZE] = table_data_[src / CHUNKSIZE][src % CHUNKSIZE]; } /** * @brief swap two elements - * @param id1 idx first - * @param id2 idx second + * @param idx1 first element index + * @param idx2 second element index */ - void swapElt(unsigned int id1, unsigned int id2) override + void swapElements(unsigned int idx1, unsigned int idx2) override { - std::swap(tableData_[id1 / CHUNKSIZE][id1 % CHUNKSIZE], tableData_[id2 / CHUNKSIZE][id2 % CHUNKSIZE] ); + std::swap(table_data_[idx1 / CHUNKSIZE][idx1 % CHUNKSIZE], table_data_[idx2 / CHUNKSIZE][idx2 % CHUNKSIZE] ); } -// void save(std::ostream& fs, unsigned int nbLines) const +// void save(std::ostream& fs, unsigned int nb_lines) const // { // unsigned int nbs[3]; -// nbs[0] = (unsigned int)(tableData_.size()); -// nbs[1] = nbLines; +// nbs[0] = (unsigned int)(table_data_.size()); +// nbs[1] = nb_lines; // nbs[2] = CHUNKSIZE*sizeof(T); -// assert(nbLines/CHUNKSIZE <= tableData_.size()); -// // TODO: if (nbLines==0) nbLines=CHUNKSIZE*tableData_.size(); ?? +// assert(nb_lines/CHUNKSIZE <= table_data_.size()); +// // TODO: if (nb_lines == 0) nb_lines = CHUNKSIZE*table_data_.size(); ?? // fs.write(reinterpret_cast(nbs),3*sizeof(unsigned int)); @@ -242,12 +206,12 @@ class ChunkArray : public ChunkArrayGen // // save data chunks except last // for(unsigned int i=0; i(tableData_[i]),CHUNKSIZE*sizeof(T)); +// fs.write(reinterpret_cast(table_data_[i]),CHUNKSIZE*sizeof(T)); // } // // save last -// unsigned nbl = nbLines - nbca*CHUNKSIZE; -// fs.write(reinterpret_cast(tableData_[nbca]),std::streamsize(nbl*sizeof(T))); +// unsigned nbl = nb_lines - nbca*CHUNKSIZE; +// fs.write(reinterpret_cast(table_data_[nbca]),std::streamsize(nbl*sizeof(T))); // } // bool load(std::istream& fs) @@ -270,49 +234,49 @@ class ChunkArray : public ChunkArrayGen // // load data chunks except last // unsigned int nbca = nbs[0]-1; // for(unsigned int i = 0; i < nbca; ++i) -// fs.read(reinterpret_cast(tableData_[i]),CHUNKSIZE*sizeof(T)); +// fs.read(reinterpret_cast(table_data_[i]),CHUNKSIZE*sizeof(T)); // // load last chunk // unsigned int nbl = nbs[1] - CHUNKSIZE*nbca; -// fs.read(reinterpret_cast(tableData_[nbca]),std::streamsize(nbl*sizeof(T))); +// fs.read(reinterpret_cast(table_data_[nbca]),std::streamsize(nbl*sizeof(T))); // return true; // } - void save(std::ostream& fs, unsigned int nbLines) const override + void save(std::ostream& fs, unsigned int nb_lines) const override { - cgogn_assert(nbLines/CHUNKSIZE <= getNbChunks()); + cgogn_assert(nb_lines / CHUNKSIZE <= getNbChunks()); - serialization::save(fs, &nbLines, 1); + serialization::save(fs, &nb_lines, 1); // no data -> finished - if (nbLines == 0) + if (nb_lines == 0) return; - unsigned int nbc = getNbChunks() - 1; + unsigned int nbc = getNbChunks() - 1u; // save data chunks except last - for(unsigned int i=0; i finished - if (nbLines == 0) + if (nb_lines == 0) return true; // compute number of chunks - unsigned int nbc = nbLines / CHUNKSIZE; - if (nbLines % CHUNKSIZE != 0) + unsigned int nbc = nb_lines / CHUNKSIZE; + if (nb_lines % CHUNKSIZE != 0) nbc++; this->setNbChunks(nbc); @@ -320,16 +284,48 @@ class ChunkArray : public ChunkArrayGen // load data chunks except last nbc--; for(unsigned int i = 0u; i < nbc; ++i) - serialization::load(fs, tableData_[i], CHUNKSIZE); + serialization::load(fs, table_data_[i], CHUNKSIZE); // load last incomplete chunk - const unsigned int nb = nbLines - nbc*CHUNKSIZE; - serialization::load(fs, tableData_[nbc], nb); + const unsigned int nb = nb_lines - nbc*CHUNKSIZE; + serialization::load(fs, table_data_[nbc], nb); return true; } -}; + /** + * @brief ref operator [] + * @param i index of element to access + * @return ref to the element + */ + inline T& operator[](unsigned int i) + { + cgogn_assert(i / CHUNKSIZE < table_data_.size()); + return table_data_[i / CHUNKSIZE][i % CHUNKSIZE]; + } + + /** + * @brief const ref operator [] + * @param i index of element to access + * @return const ref to the element + */ + inline const T& operator[](unsigned int i) const + { + cgogn_assert(i / CHUNKSIZE < table_data_.size()); + return table_data_[i / CHUNKSIZE][i % CHUNKSIZE]; + } + + /** + * @brief set the value of an element (works also with bool) + * @param i index of element to set + * @param v value + */ + inline void setValue(unsigned int i, const T& v) + { + cgogn_assert(i / CHUNKSIZE < table_data_.size()); + table_data_[i / CHUNKSIZE][i % CHUNKSIZE] = v; + } +}; /** * @brief specialized version of ChunkArray for bool data. One bit per bool @@ -340,261 +336,187 @@ class ChunkArray : public ChunkArrayGen protected: /// vector of block pointers - std::vector tableData_; + std::vector table_data_; public: inline ChunkArray() : ChunkArrayGen() { - tableData_.reserve(1024u); + table_data_.reserve(1024u); } + ChunkArray(const ChunkArray& ca) = delete; + ChunkArray(ChunkArray&& ca) = delete; + ChunkArray& operator=(ChunkArray&& ca) = delete; + ChunkArray& operator=(const ChunkArray& ca) = delete; + ~ChunkArray() override { - for(auto chunk: tableData_) + for(auto chunk : table_data_) delete[] chunk; } - ChunkArray(const ChunkArray& ca) - { - tableData_.reserve(1024u); - this->setNbChunks(ca.getNbChunks()); - for (std::size_t i = 0, end = tableData_.size() ; i < end ; ++i) - { - std::copy(ca.tableData_[i], ca.tableData_[i] + CHUNKSIZE/32u, tableData_[i]); - } - } - - inline ChunkArray(ChunkArray< CHUNKSIZE, bool>&& ca) : - tableData_(std::move(ca.tableData_)) - {} - - ChunkArray& operator=(ChunkArray< CHUNKSIZE, bool>&& ca) - { - // this != &ca because ca is a rvalue - this->clear(); - tableData_ = std::move(ca.tableData_); - return *this; - } - - ChunkArray& operator=(const ChunkArray& ca) + /** + * @brief create a ChunkArray + * @return generic pointer + */ + ChunkArrayGen* clone() const override { - if (this != &ca) - { - this->setNbChunks(ca.getNbChunks()); - for (std::size_t i = 0, end = tableData_.size() ; i < end ; ++i) - { - std::copy(ca.tableData_[i], ca.tableData_[i] + CHUNKSIZE/32u, tableData_[i]); - } - } - return *this; + return new ChunkArray(); } - bool isBooleanArray() const override { return true; } - ChunkArrayGen* clone() const override - { - return new ChunkArray(); - } - + /** + * @brief add a chunk (T[CHUNKSIZE/32]) + */ void addChunk() override { // adding the empty parentheses for default-initialization - tableData_.push_back(new unsigned int[CHUNKSIZE/32u]()); + table_data_.push_back(new unsigned int[CHUNKSIZE/32u]()); } + /** + * @brief set number of chunks + * @param nbc number of chunks + */ void setNbChunks(unsigned int nbc) override { - if (nbc >= tableData_.size()) + if (nbc >= table_data_.size()) { - for (std::size_t i = tableData_.size(); i < nbc; ++i) + for (std::size_t i = table_data_.size(); i < nbc; ++i) addChunk(); } else { - for (std::size_t i = nbc; i < tableData_.size(); ++i) - delete[] tableData_[i]; - tableData_.resize(nbc); + for (std::size_t i = nbc; i < table_data_.size(); ++i) + delete[] table_data_[i]; + table_data_.resize(nbc); } } + /** + * @brief get the number of chunks of the array + * @return the number of chunks + */ unsigned int getNbChunks() const override { - return static_cast(tableData_.size()); + return static_cast(table_data_.size()); } + /** + * @brief get the capacity of the array + * @return number of allocated lines + */ unsigned int capacity() const override { - return static_cast(tableData_.size())*CHUNKSIZE/32u; + return static_cast(table_data_.size())*CHUNKSIZE/32u; } + /** + * @brief clear the array + */ void clear() override { - for(auto chunk: tableData_) + for(auto chunk : table_data_) delete[] chunk; - tableData_.clear(); - } - - inline void setFalse(unsigned int i) - { - const unsigned int jj = i / CHUNKSIZE; - cgogn_assert(jj < tableData_.size()); - const unsigned int j = i % CHUNKSIZE; - const unsigned int x = j/32u; - const unsigned int y = j%32u; - const unsigned int mask = 1u << y; - tableData_[jj][x] &= ~mask; - } - - inline void setTrue(unsigned int i) - { - const unsigned int jj = i / CHUNKSIZE; - cgogn_assert(jj < tableData_.size()); - const unsigned int j = i % CHUNKSIZE; - const unsigned int x = j/32u; - const unsigned int y = j%32u; - const unsigned int mask = 1u << y; - tableData_[jj][x] |= mask; - } - - inline void setVal(unsigned int i, bool b) - { - const unsigned int jj = i / CHUNKSIZE; - cgogn_assert(jj < tableData_.size()); - const unsigned int j = i % CHUNKSIZE; - const unsigned int x = j/32u; - const unsigned int y = j%32u; - const unsigned int mask = 1u << y; - - if (b) - tableData_[jj][x] |= mask; - else - tableData_[jj][x] &= ~mask; + table_data_.clear(); } /** - * @brief special optimized version of setFalse when goal is to set all to false; - * @param i index of element to set to false - * - * This version overwrites element AND SOME OF HIS NEIGHBOURS with 0 - * Use only if final goal is to set all array to 0 (MarkerStore) - * @todo find another name for the method! + * @brief fill a vector with pointers to all chunks + * @param addr vector to fill + * @param byte_block_size filled with CHUNKSIZE*sizeof(T) + * @return addr.size() */ - inline void setFalseDirty(unsigned int i) - { - const unsigned int jj = i / CHUNKSIZE; - cgogn_assert(jj < tableData_.size()); - const unsigned int j = (i % CHUNKSIZE)/32u; - tableData_[jj][j] = 0u; - } - - inline bool operator[](unsigned int i) const - { - const unsigned int jj = i / CHUNKSIZE; - cgogn_assert(jj < tableData_.size()); - const unsigned int j = i % CHUNKSIZE; - const unsigned int x = j/32u; - const unsigned int y = j%32u; - - const unsigned int mask = 1u << y; - - return (tableData_[jj][x] & mask) != 0u; - } - - inline void allFalse() + inline unsigned int getChunksPointers(std::vector& addr, unsigned int& byte_block_size) const override { - for (auto ptr : tableData_) - { - for (unsigned int j = 0; j < CHUNKSIZE/32u; ++j) - *ptr++ = 0; - } - } + byte_block_size = CHUNKSIZE / 8u; - inline void allTrue() - { - for (auto ptr : tableData_) - { - for (unsigned int j = 0; j < CHUNKSIZE/32u; ++j) - *ptr++ = 0xffffffff; - } - } - - inline unsigned int getChunksPointers(std::vector& addr, unsigned int& byteBlockSize) const override - { - byteBlockSize = CHUNKSIZE / 8u; - - addr.reserve(tableData_.size()); + addr.reserve(table_data_.size()); addr.clear(); - for (typename std::vector::const_iterator it = tableData_.begin(); it != tableData_.end(); ++it) + for (typename std::vector::const_iterator it = table_data_.begin(); it != table_data_.end(); ++it) addr.push_back(*it); return static_cast(addr.size()); } - inline void initElt(unsigned int id) override + /** + * @brief initialize an element (overwrite with T()) + * @param id index of the element + */ + inline void initElement(unsigned int id) override { setFalse(id); } - inline void copyElt(unsigned int dst, unsigned int src) override + /** + * @brief copy an element to another one + * @param dst destination index + * @param src source index + */ + inline void copyElement(unsigned int dst, unsigned int src) override { - setVal(dst,this->operator [](src)); + setValue(dst, this->operator[](src)); } - - inline void swapElt(unsigned int id1, unsigned int id2) override + /** + * @brief swap two elements + * @param idx1 first element index + * @param idx2 second element index + */ + inline void swapElements(unsigned int idx1, unsigned int idx2) override { - bool data = this->operator [](id1); - setVal(id1,this->operator [](id2)); - setVal(id2,data); + bool data = this->operator[](idx1); + setValue(idx1, this->operator[](idx2)); + setValue(idx2, data); } - void save(std::ostream& fs, unsigned int nbLines) const override + void save(std::ostream& fs, unsigned int nb_lines) const override { // round nbLines to 32 multiple - if (nbLines%32u) - nbLines = ((nbLines/32u)+1u)*32u; + if (nb_lines % 32u) + nb_lines = ((nb_lines / 32u) + 1u) * 32u; - cgogn_assert(nbLines/CHUNKSIZE <= tableData_.size()); - // TODO: if (nbLines==0) nbLines=CHUNKSIZE*tableData_.size(); ?? + cgogn_assert(nb_lines / CHUNKSIZE <= table_data_.size()); + // TODO: if (nb_lines==0) nb_lines = CHUNKSIZE*table_data_.size(); ?? // save number of lines - serialization::save(fs, &nbLines,1); + serialization::save(fs, &nb_lines, 1); // no data -> finished - if (nbLines == 0u) + if (nb_lines == 0u) return; - const unsigned int nbc = getNbChunks()-1u; + const unsigned int nbc = getNbChunks() - 1u; // save data chunks except last - for(unsigned int i=0u; i(tableData_[i]),CHUNKSIZE/8u); // /8 because bool = 1 bit & octet = 8 bit + fs.write(reinterpret_cast(table_data_[i]), CHUNKSIZE / 8u); // /8 because bool = 1 bit & octet = 8 bit } // save last - const unsigned int nb = nbLines - nbc*CHUNKSIZE; - fs.write(reinterpret_cast(tableData_[nbc]),nb/8u); + const unsigned int nb = nb_lines - nbc*CHUNKSIZE; + fs.write(reinterpret_cast(table_data_[nbc]), nb / 8u); } bool load(std::istream& fs) override { // get number of lines to load - unsigned int nbLines; - serialization::load(fs, &nbLines, 1); + unsigned int nb_lines; + serialization::load(fs, &nb_lines, 1); // no data -> finished - if (nbLines == 0) + if (nb_lines == 0) return true; // compute number of chunks - unsigned int nbc = nbLines / CHUNKSIZE; - if (nbLines % CHUNKSIZE != 0u) + unsigned int nbc = nb_lines / CHUNKSIZE; + if (nb_lines % CHUNKSIZE != 0u) nbc++; this->setNbChunks(nbc); @@ -602,14 +524,101 @@ class ChunkArray : public ChunkArrayGen // load data chunks except last nbc--; for(unsigned int i = 0u; i < nbc; ++i) - fs.read(reinterpret_cast(tableData_[i]),CHUNKSIZE/8u);// /8 because bool = 1 bit & octet = 8 bit + fs.read(reinterpret_cast(table_data_[i]), CHUNKSIZE / 8u);// /8 because bool = 1 bit & octet = 8 bit // load last chunk - unsigned int nb = nbLines - nbc*CHUNKSIZE; - fs.read(reinterpret_cast(tableData_[nbc]),nb/8u); + unsigned int nb = nb_lines - nbc*CHUNKSIZE; + fs.read(reinterpret_cast(table_data_[nbc]), nb / 8u); return true; } + + /** + * @brief ref operator [] + * @param i index of element to access + * @return value of the element + */ + inline bool operator[](unsigned int i) const + { + const unsigned int jj = i / CHUNKSIZE; + cgogn_assert(jj < table_data_.size()); + const unsigned int j = i % CHUNKSIZE; + const unsigned int x = j/32u; + const unsigned int y = j%32u; + + const unsigned int mask = 1u << y; + + return (table_data_[jj][x] & mask) != 0u; + } + + inline void setFalse(unsigned int i) + { + const unsigned int jj = i / CHUNKSIZE; + cgogn_assert(jj < table_data_.size()); + const unsigned int j = i % CHUNKSIZE; + const unsigned int x = j / 32u; + const unsigned int y = j % 32u; + const unsigned int mask = 1u << y; + table_data_[jj][x] &= ~mask; + } + + inline void setTrue(unsigned int i) + { + const unsigned int jj = i / CHUNKSIZE; + cgogn_assert(jj < table_data_.size()); + const unsigned int j = i % CHUNKSIZE; + const unsigned int x = j / 32u; + const unsigned int y = j % 32u; + const unsigned int mask = 1u << y; + table_data_[jj][x] |= mask; + } + + inline void setValue(unsigned int i, bool b) + { + const unsigned int jj = i / CHUNKSIZE; + cgogn_assert(jj < table_data_.size()); + const unsigned int j = i % CHUNKSIZE; + const unsigned int x = j / 32u; + const unsigned int y = j % 32u; + const unsigned int mask = 1u << y; + if (b) + table_data_[jj][x] |= mask; + else + table_data_[jj][x] &= ~mask; + } + + /** + * @brief special optimized version of setFalse when goal is to set all to false; + * @param i index of element to set to false + * + * This version overwrites element AND SOME OF HIS NEIGHBOURS with 0 + * Use only if final goal is to set all array to 0 (MarkerStore) + */ + inline void setFalse_byte(unsigned int i) + { + const unsigned int jj = i / CHUNKSIZE; + cgogn_assert(jj < table_data_.size()); + const unsigned int j = (i % CHUNKSIZE)/32u; + table_data_[jj][j] = 0u; + } + + inline void allFalse() + { + for (auto ptr : table_data_) + { + for (unsigned int j = 0u; j < CHUNKSIZE/32u; ++j) + *ptr++ = 0u; + } + } + +// inline void allTrue() +// { +// for (auto ptr : table_data_) +// { +// for (unsigned int j = 0u; j < CHUNKSIZE/32u; ++j) +// *ptr++ = 0xffffffff; +// } +// } }; } // namespace cgogn diff --git a/cgogn/core/container/chunk_array_container.h b/cgogn/core/container/chunk_array_container.h index f2e76c8d..d1597027 100644 --- a/cgogn/core/container/chunk_array_container.h +++ b/cgogn/core/container/chunk_array_container.h @@ -96,43 +96,43 @@ class ChunkArrayContainer /** * vector of pointers to ChunkVector */ - std::vector*> tableArrays_; + std::vector*> table_arrays_; std::vector names_; - std::vector typeNames_; + std::vector type_names_; ChunkArray refs_; /** * stack of holes */ - ChunkStack holesStack_; + ChunkStack holes_stack_; /** * size (number of elts) of the container */ - unsigned int nbUsedLines_; + unsigned int nb_used_lines_; /** * size of the container with holes (also index of next inserted line if no holes) */ - unsigned int nbMaxLines_; + unsigned int nb_max_lines_; /** * @brief number of bool attribs (which are alway in front of all others) */ - unsigned int nbMarkerAttribs_; + unsigned int nb_marker_attribs_; /** * Browser that allow special traversals */ - ContainerBrowser* currentBrowser_; + ContainerBrowser* current_browser_; /** * Browser that allow special traversals */ - std::unique_ptr< ContainerStandardBrowser< ChunkArrayContainer > > stdBrowser_; + std::unique_ptr< ContainerStandardBrowser< ChunkArrayContainer > > std_browser_; /** * @brief get array index from name @@ -140,11 +140,11 @@ class ChunkArrayContainer * @param attribName name of ChunkArray * @return the index in table */ - unsigned int getArrayIndex(const std::string& attribName) const + unsigned int getArrayIndex(const std::string& attribute_name) const { - for (unsigned int i=0; i != names_.size(); ++i) + for (unsigned int i = 0; i != names_.size(); ++i) { - if (names_[i] == attribName) + if (names_[i] == attribute_name) return i; } return UNKNOWN; @@ -158,9 +158,9 @@ class ChunkArrayContainer */ unsigned int getArrayIndex(const ChunkArrayGen* ptr) const { - for (unsigned int i=0u; i != tableArrays_.size(); ++i) + for (unsigned int i = 0u; i != table_arrays_.size(); ++i) { - if (tableArrays_[i] == ptr) + if (table_arrays_[i] == ptr) return i; } return UNKNOWN; @@ -174,33 +174,33 @@ class ChunkArrayContainer bool removeAttribute(unsigned int index) { // store ptr for using it before delete - ChunkArrayGen* ptrToDel = tableArrays_[index]; + ChunkArrayGen* ptrToDel = table_arrays_[index]; - // in case of Markers, keep Markers first ! - if (index < nbMarkerAttribs_) + // in case of Marker attribute, keep Marker attributes first ! + if (index < nb_marker_attribs_) { - nbMarkerAttribs_--; + nb_marker_attribs_--; - if (index < nbMarkerAttribs_) // if attribute is not last of Markers + if (index < nb_marker_attribs_) // if attribute is not last of Markers { - tableArrays_[index] = tableArrays_[nbMarkerAttribs_]; // copy last of boolean on index - names_[index] = names_[nbMarkerAttribs_]; - typeNames_[index] = typeNames_[nbMarkerAttribs_]; + table_arrays_[index] = table_arrays_[nb_marker_attribs_]; // copy last of boolean on index + names_[index] = names_[nb_marker_attribs_]; + type_names_[index] = type_names_[nb_marker_attribs_]; } // now overwrite last of bool with last - index = nbMarkerAttribs_; + index = nb_marker_attribs_; } - if (index != tableArrays_.size()- std::size_t(1u)) + if (index != table_arrays_.size() - std::size_t(1u)) { - tableArrays_[index] = tableArrays_.back(); - names_[index] = names_.back(); - typeNames_[index] = typeNames_.back(); + table_arrays_[index] = table_arrays_.back(); + names_[index] = names_.back(); + type_names_[index] = type_names_.back(); } - tableArrays_.pop_back(); + table_arrays_.pop_back(); names_.pop_back(); - typeNames_.pop_back(); + type_names_.pop_back(); delete ptrToDel; @@ -213,11 +213,11 @@ class ChunkArrayContainer * @brief ChunkArrayContainer constructor */ ChunkArrayContainer(): - nbUsedLines_(0u) - ,nbMaxLines_(0u) - ,stdBrowser_(make_unique< ContainerStandardBrowser> >(this)) + nb_used_lines_(0u) + ,nb_max_lines_(0u) + ,std_browser_(make_unique< ContainerStandardBrowser> >(this)) { - currentBrowser_= stdBrowser_.get(); + current_browser_= std_browser_.get(); } ChunkArrayContainer(ChunkArrayContainerconst& ) = delete; @@ -230,43 +230,49 @@ class ChunkArrayContainer */ ~ChunkArrayContainer() { - if (currentBrowser_ != stdBrowser_.get()) - delete currentBrowser_; - for (auto ptr: tableArrays_) + if (current_browser_ != std_browser_.get()) + delete current_browser_; + for (auto ptr: table_arrays_) delete ptr; } + /** + * @brief get an attribute + * @param attribute_name name of attribute + * @tparam T type of attribute + * @return pointer on attribute ChunkArray + */ template - ChunkArray* getAttribute(const std::string& attribName) + ChunkArray* getAttribute(const std::string& attribute_name) { // first check if attribute already exist - unsigned int index = getArrayIndex(attribName); + unsigned int index = getArrayIndex(attribute_name); if (index == UNKNOWN) { - std::cerr << "attribute " << attribName << " not found." << std::endl; + std::cerr << "attribute " << attribute_name << " not found." << std::endl; return nullptr; } - return static_cast*>(tableArrays_[index]); + return static_cast*>(table_arrays_[index]); } /** * @brief add an attribute - * @param attribName name of attribute + * @param attribute_name name of attribute * @tparam T type of attribute - * @return pointer on created ChunkArray + * @return pointer on created attribute ChunkArray */ template - ChunkArray* addAttribute(const std::string& attribName) + ChunkArray* addAttribute(const std::string& attribute_name) { - cgogn_assert(attribName.size() != 0); + cgogn_assert(attribute_name.size() != 0); // first check if attribute already exist - unsigned int index = getArrayIndex(attribName); + unsigned int index = getArrayIndex(attribute_name); if (index != UNKNOWN) { - std::cerr << "attribute " << attribName << " already found.." << std::endl; + std::cerr << "attribute " << attribute_name << " already exists.." << std::endl; return nullptr; } @@ -279,49 +285,49 @@ class ChunkArrayContainer carr->setNbChunks(refs_.getNbChunks()); // store pointer, name & typename. - tableArrays_.push_back(carr); - names_.push_back(attribName); - typeNames_.push_back(typeName); + table_arrays_.push_back(carr); + names_.push_back(attribute_name); + type_names_.push_back(typeName); return carr ; } /** - * @brief add an Marker attribute - * @param attribName name of marker attribute + * @brief add a Marker attribute + * @param attribute_name name of marker attribute * @return pointer on created ChunkArray */ - ChunkArray* addMarkerAttribute(const std::string& attribName) + ChunkArray* addMarkerAttribute(const std::string& attribute_name) { - ChunkArray* ptr = addAttribute(attribName); + ChunkArray* ptr = addAttribute(attribute_name); - if (tableArrays_.size() > nbMarkerAttribs_) + if (table_arrays_.size() > nb_marker_attribs_) { // swap ptrs - auto tmp = tableArrays_.back(); - tableArrays_.back() = tableArrays_[nbMarkerAttribs_]; - tableArrays_[nbMarkerAttribs_] = tmp; + auto tmp = table_arrays_.back(); + table_arrays_.back() = table_arrays_[nb_marker_attribs_]; + table_arrays_[nb_marker_attribs_] = tmp; // swap names & typenames - names_.back().swap(names_[nbMarkerAttribs_]); - typeNames_.back().swap(typeNames_[nbMarkerAttribs_]); + names_.back().swap(names_[nb_marker_attribs_]); + type_names_.back().swap(type_names_[nb_marker_attribs_]); } - nbMarkerAttribs_++; + nb_marker_attribs_++; return ptr; } /** * @brief remove an attribute by its name - * @param attribName name of attribute to remove - * @return true if attribute exist and has been removed + * @param attribute_name name of attribute to remove + * @return true if attribute exists and has been removed */ - bool removeAttribute(const std::string& attribName) + bool removeAttribute(const std::string& attribute_name) { - unsigned int index = getArrayIndex(attribName); + unsigned int index = getArrayIndex(attribute_name); if (index == UNKNOWN) { - std::cerr << "removeAttribute by name: attribute not found (" << attribName << ")" << std::endl; + std::cerr << "removeAttribute by name: attribute not found (" << attribute_name << ")" << std::endl; return false; } @@ -331,9 +337,9 @@ class ChunkArrayContainer } /** - * @brief remove an attribute by its name - * @param attribName name of attribute to remove - * @return true if attribute exist and has been removed + * @brief remove an attribute by its ChunkArray pointer + * @param ptr ChunkArray pointer to the attribute to remove + * @return true if attribute exists and has been removed */ bool removeAttribute(const ChunkArrayGen* ptr) { @@ -341,7 +347,7 @@ class ChunkArrayContainer if (index == UNKNOWN) { - std::cerr << "removeAttribute by ptr: attribute not found (" << std::endl; + std::cerr << "removeAttribute by ptr: attribute not found" << std::endl; return false; } @@ -356,7 +362,40 @@ class ChunkArrayContainer */ unsigned int getNbAttributes() const { - return tableArrays_.size(); + return table_arrays_.size(); + } + + /** + * @brief get a chunk_array + * @param attribName name of the array + * @return pointer on typed chunk_array + */ + template + ChunkArray* getDataArray(const std::string& attribute_name) + { + unsigned int index = getArrayIndex(attribute_name); + if(index == UNKNOWN) + return nullptr; + + ChunkArray* atm = dynamic_cast*>(table_arrays_[index]); + + cgogn_message_assert(atm != nullptr, "getDataArray: wrong type"); + + return atm; + } + + /** + * @brief get a chunk_array + * @param attribName name of the array + * @return pointer on virtual chunk_array + */ + ChunkArrayGen* getVirtualDataArray(const std::string& attribute_name) + { + unsigned int index = getArrayIndex(attribute_name); + if(index == UNKNOWN) + return nullptr; + + return table_arrays_[index]; } /** @@ -365,7 +404,7 @@ class ChunkArrayContainer */ unsigned int size() const { - return nbUsedLines_; + return nb_used_lines_; } /** @@ -377,32 +416,22 @@ class ChunkArrayContainer return refs_.capacity(); } - /** - * @brief is a line used - * @param index index of line - * @return true if used - */ - bool used(unsigned int index) const - { - return refs_[index] != 0; - } - /** * @brief setCurrentBrowser * @param browser, pointer to a heap-allocated ContainerBrowser */ inline void setCurrentBrowser(ContainerBrowser* browser) { - if (currentBrowser_ != stdBrowser_.get()) - delete currentBrowser_; - currentBrowser_ = browser; + if (current_browser_ != std_browser_.get()) + delete current_browser_; + current_browser_ = browser; } inline void setStandardBrowser() { - if (currentBrowser_ != stdBrowser_.get()) - delete currentBrowser_; - currentBrowser_ = stdBrowser_; + if (current_browser_ != std_browser_.get()) + delete current_browser_; + current_browser_ = std_browser_; } /** @@ -411,7 +440,7 @@ class ChunkArrayContainer */ inline unsigned int begin() const { - return currentBrowser_->begin(); + return current_browser_->begin(); } /** @@ -420,90 +449,87 @@ class ChunkArrayContainer */ inline unsigned int end() const { - return currentBrowser_->end(); + return current_browser_->end(); } /** * @brief next it <- next used index in the container * @param it index to "increment" */ - inline void next(unsigned int &it) const + inline void next(unsigned int& it) const { - currentBrowser_->next(it); + current_browser_->next(it); } /** * @brief next primitive: it <- next primitive used index in the container (eq to PRIMSIZE next) * @param it index to "increment" */ - inline void nextPrimitive(unsigned int &it, unsigned int primSz) const + inline void nextPrimitive(unsigned int& it, unsigned int prim_size) const { - currentBrowser_->nextPrimitive(it, primSz); + current_browser_->nextPrimitive(it, prim_size); } /** * @brief begin of container without browser - * @return + * @return the real index of the first used line of the container */ inline unsigned int realBegin() const { unsigned int it = 0u; - while ((it < nbMaxLines_) && (!used(it))) + while ((it < nb_max_lines_) && (!used(it))) ++it; return it; } /** * @brief end of container without browser - * @return + * @return the real index after the last used line of the container */ inline unsigned int realEnd() const { - return nbMaxLines_; + return nb_max_lines_; } /** * @brief next without browser * @param it */ - inline void realNext(unsigned int &it) const + inline void realNext(unsigned int& it) const { do { ++it; - } while ((it < nbMaxLines_) && (!used(it))); + } while ((it < nb_max_lines_) && (!used(it))); } /** * @brief next primitive without browser * @param it */ - inline void realNextPrimitive(unsigned int &it, unsigned int primSz) const + inline void realNextPrimitive(unsigned int &it, unsigned int prim_size) const { do { - it+=primSz; - } while ((it < nbMaxLines_) && (!used(it))); + it += prim_size; + } while ((it < nb_max_lines_) && (!used(it))); } /** - * @brief real reverse begin - * @return rbegin() + * @brief reverse begin of container without browser + * @return the real index of the first used line of the container in reverse order */ unsigned int realRBegin() const { - unsigned int it = nbMaxLines_-1u; + unsigned int it = nb_max_lines_- 1u; while ((it != 0xffffffff) && (!used(it))) --it; return it; } /** - * return the index before the first line of the container - */ - /** - * @brief real reverse end - * @return rend() + * @brief reverse end of container without browser + * @return the real index before the last used line of the container in reverse order */ unsigned int realREnd() const { @@ -511,48 +537,48 @@ class ChunkArrayContainer } /** - * @brief real next of reverse index - * @param it reverse index + * @brief reverse next without browser + * @param it */ void realRNext(unsigned int &it) const { do { --it; - } while ((it !=0xffffffff) && (!used(it))); + } while ((it != 0xffffffff) && (!used(it))); } /** * @brief clear the container - * @param removeAttrib remove the attributes (not only their data) + * @param remove_attributes remove the attributes (not only their data) */ - void clear(bool removeAttrib = false) + void clear(bool remove_attributes = false) { - nbUsedLines_ = 0u; - nbMaxLines_ = 0u; + nb_used_lines_ = 0u; + nb_max_lines_ = 0u; // clear CA of refs refs_.clear(); // clear holes - holesStack_.clear(); + holes_stack_.clear(); - //clear data - for (auto arr: tableArrays_) + // clear data + for (auto arr : table_arrays_) arr->clear(); // remove CA ? - if (removeAttrib) + if (remove_attributes) { - for (auto arr: tableArrays_) + for (auto arr : table_arrays_) delete arr; - tableArrays_.clear(); + table_arrays_.clear(); } } /** * @brief fragmentation of container (size/index of last lines): 100% = no holes - * @return 1 if full filled - 0 is lots of holes + * @return 1 is full filled - 0 is lots of holes */ float fragmentation() const { @@ -561,13 +587,13 @@ class ChunkArrayContainer /** * @brief container compacting - * @param mapOldNew table that contains a map from old indices to new indices (holes -> 0xffffffff) + * @param map_old_new vector that contains a map from old indices to new indices (holes -> 0xffffffff) */ template - void compact(std::vector& mapOldNew) + void compact(std::vector& map_old_new) { - mapOldNew.clear(); - mapOldNew.resize(realEnd(), 0xffffffff); + map_old_new.clear(); + map_old_new.resize(realEnd(), 0xffffffff); unsigned int up = realRBegin(); unsigned int down = 0u; @@ -579,7 +605,7 @@ class ChunkArrayContainer for(unsigned int i = 0u; i < PRIMSIZE; ++i) { unsigned rdown = down + PRIMSIZE-1u - i; - mapOldNew[up] = rdown; + map_old_new[up] = rdown; copyLine(rdown, up); realRNext(up); } @@ -589,22 +615,32 @@ class ChunkArrayContainer down++; } - nbMaxLines_ = nbUsedLines_; + nb_max_lines_ = nb_used_lines_; // free unused memory blocks - unsigned int newNbBlocks = nbMaxLines_/CHUNKSIZE + 1u; - for (auto arr : tableArrays_) - arr->setNbChunks(newNbBlocks); - refs_.setNbChunks(newNbBlocks); + unsigned int new_nb_blocks = nb_max_lines_/CHUNKSIZE + 1u; + for (auto arr : table_arrays_) + arr->setNbChunks(new_nb_blocks); + refs_.setNbChunks(new_nb_blocks); // clear holes - holesStack_.clear(); + holes_stack_.clear(); } /************************************** * LINES MANAGEMENT * **************************************/ + /** + * @brief is a line used + * @param index index of line + * @return true if used + */ + bool used(unsigned int index) const + { + return refs_[index] != 0; + } + /** * @brief insert a group of PRIMSIZE consecutive lines in the container * @return index of the first line of group @@ -614,29 +650,29 @@ class ChunkArrayContainer { unsigned int index; - if (holesStack_.empty()) // no holes -> insert at the end + if (holes_stack_.empty()) // no holes -> insert at the end { - index = nbMaxLines_; - nbMaxLines_ += PRIMSIZE; + index = nb_max_lines_; + nb_max_lines_ += PRIMSIZE; - if (nbMaxLines_%CHUNKSIZE <= PRIMSIZE) // prim on next block ? -> add block to C.A. + if (nb_max_lines_%CHUNKSIZE <= PRIMSIZE) // prim on next block ? -> add block to C.A. { - for (auto arr: tableArrays_) + for (auto arr: table_arrays_) arr->addChunk(); refs_.addChunk(); } } else { - index = holesStack_.head(); - holesStack_.pop(); + index = holes_stack_.head(); + holes_stack_.pop(); } // mark lines as used for(unsigned int i = 0u; i < PRIMSIZE; ++i) - refs_.setVal(index+i, 1u); // do not used [] in case of refs_ is bool + refs_.setValue(index+i, 1u); // do not use [] in case of refs_ is bool - nbUsedLines_ += PRIMSIZE; + nb_used_lines_ += PRIMSIZE; return index; } @@ -648,17 +684,17 @@ class ChunkArrayContainer template void removeLines(unsigned int index) { - unsigned int beginPrimIdx = (index/PRIMSIZE) * PRIMSIZE; + unsigned int begin_prim_idx = (index/PRIMSIZE) * PRIMSIZE; - cgogn_message_assert(this->used(beginPrimIdx), "Error removing non existing index"); + cgogn_message_assert(this->used(begin_prim_idx), "Error removing non existing index"); - holesStack_.push(beginPrimIdx); + holes_stack_.push(begin_prim_idx); // mark lines as unused for(unsigned int i = 0u; i < PRIMSIZE; ++i) - refs_.setVal(beginPrimIdx++, 0u);// do not used [] in case of refs_ is bool + refs_.setValue(begin_prim_idx++, 0u); // do not use [] in case of refs_ is bool - nbUsedLines_ -= PRIMSIZE; + nb_used_lines_ -= PRIMSIZE; } /** @@ -669,25 +705,17 @@ class ChunkArrayContainer { cgogn_message_assert(!used(index), "initLine only with allocated lines"); - for (auto ptrAtt : tableArrays_) - // if (ptrAtt != nullptr) never null ! - ptrAtt->initElt(index); + for (auto ptrAtt : table_arrays_) + // if (ptrAtt != nullptr) never null ! + ptrAtt->initElement(index); } - void initBooleansOfLine(unsigned int index) + void initMarkersOfLine(unsigned int index) { - cgogn_message_assert(!used(index), "initBooleansOfLine only with allocated lines"); + cgogn_message_assert(!used(index), "initMarkersOfLine only with allocated lines"); - for (unsigned int i = 0u; i < nbMarkerAttribs_; ++i) - tableArrays_[i]->initElt(index); - } - - void initBoolsOfLine(unsigned int index) - { - // assert( used(index) && "initLine only with allocated lines"); - // for (auto ptrAtt: tableArrays_) - // if (ptrAtt != NULL) - // ptrAtt->initElt(index); + for (unsigned int i = 0u; i < nb_marker_attribs_; ++i) + table_arrays_[i]->initElement(index); } /** @@ -695,12 +723,12 @@ class ChunkArrayContainer * @param dstIndex destination * @param srcIndex source */ - void copyLine(unsigned int dstIndex, unsigned int srcIndex) + void copyLine(unsigned int dst, unsigned int src) { - for (auto ptrAtt : tableArrays_) + for (auto ptrAtt : table_arrays_) if (ptrAtt != nullptr) - ptrAtt->copyElt(dstIndex, srcIndex); - refs_[dstIndex] = refs_[srcIndex]; + ptrAtt->copyElement(dst, src); + refs_[dst] = refs_[src]; } /** @@ -709,7 +737,7 @@ class ChunkArrayContainer */ void refLine(unsigned int index) { - // static_assert(PRIMSIZE == 1u, "refLine with container where PRIMSIZE!=1"); + // static_assert(PRIMSIZE == 1u, "refLine with container where PRIMSIZE!=1"); refs_[index]++; } @@ -720,13 +748,13 @@ class ChunkArrayContainer */ bool unrefLine(unsigned int index) { - // static_assert(PRIMSIZE == 1u, "unrefLine with container where PRIMSIZE!=1"); + // static_assert(PRIMSIZE == 1u, "unrefLine with container where PRIMSIZE!=1"); refs_[index]--; if (refs_[index] == 1u) { - holesStack_.push(index); - refs_[index] = 0u; // same as removeLine without the "if" - --nbUsedLines_; + holes_stack_.push(index); + refs_[index] = 0u; + --nb_used_lines_; return true; } return false; @@ -739,78 +767,45 @@ class ChunkArrayContainer */ T_REF getNbRefs(unsigned int index) const { - // static_assert(PRIMSIZE == 1u, "getNbRefs with container where PRIMSIZE!=1"); + // static_assert(PRIMSIZE == 1u, "getNbRefs with container where PRIMSIZE!=1"); return refs_[index]; } - /** - * @brief get a chunk_array - * @param attribName name of the array - * @return pointer on typed chunk_array - */ - template - ChunkArray* getDataArray(const std::string& attribName) - { - unsigned int index = getArrayIndex(attribName); - if(index == UNKNOWN) - return nullptr; - - ChunkArray* atm = dynamic_cast*>(tableArrays_[index]); - - cgogn_message_assert(atm != nullptr, "getDataArray: wrong type"); - - return atm; - } - - /** - * @brief get a chunk_array - * @param attribName name of the array - * @return pointer on virtual chunk_array - */ - ChunkArrayGen* getVirtualDataArray(const std::string& attribName) - { - unsigned int index = getArrayIndex(attribName); - if(index == UNKNOWN) - return nullptr; - - return tableArrays_[index]; - } - void save(std::ofstream& fs) { // save info (size+used_lines+max_lines+sizeof names) std::vector buffer; buffer.reserve(1024); - buffer.push_back(static_cast(tableArrays_.size())); - buffer.push_back(nbUsedLines_); - buffer.push_back(nbMaxLines_); - buffer.push_back(nbMarkerAttribs_); - for(unsigned int i = 0u; i < tableArrays_.size(); ++i) + buffer.push_back(static_cast(table_arrays_.size())); + buffer.push_back(nb_used_lines_); + buffer.push_back(nb_max_lines_); + buffer.push_back(nb_marker_attribs_); + for(unsigned int i = 0u; i < table_arrays_.size(); ++i) { buffer.push_back(static_cast(names_[i].size()+1)); - buffer.push_back(static_cast(typeNames_[i].size()+1)); + buffer.push_back(static_cast(type_names_[i].size()+1)); } fs.write(reinterpret_cast(&(buffer[0])),std::streamsize(buffer.size()*sizeof(unsigned int))); // save names - for(unsigned int i = 0; i < tableArrays_.size(); ++i) + for(unsigned int i = 0; i < table_arrays_.size(); ++i) { const char* s1 = names_[i].c_str(); - const char* s2 = typeNames_[i].c_str(); + const char* s2 = type_names_[i].c_str(); fs.write(s1, std::streamsize((names_[i].size()+1u)*sizeof(char))); - fs.write(s2, std::streamsize((typeNames_[i].size()+1u)*sizeof(char))); + fs.write(s2, std::streamsize((type_names_[i].size()+1u)*sizeof(char))); } // save chunk arrays - for(unsigned int i = 0u; i < tableArrays_.size(); ++i) + for(unsigned int i = 0u; i < table_arrays_.size(); ++i) { - tableArrays_[i]->save(fs, nbMaxLines_); + table_arrays_[i]->save(fs, nb_max_lines_); } // save uses/refs - refs_.save(fs, nbMaxLines_); + refs_.save(fs, nb_max_lines_); // save stack - holesStack_.save(fs, holesStack_.size()); + holes_stack_.save(fs, holes_stack_.size()); } bool load(std::ifstream& fs) @@ -819,15 +814,15 @@ class ChunkArrayContainer unsigned int buff1[4]; fs.read(reinterpret_cast(buff1), 4u*sizeof(unsigned int)); - nbUsedLines_ = buff1[1]; - nbMaxLines_ = buff1[2]; - nbMarkerAttribs_ = buff1[3]; + nb_used_lines_ = buff1[1]; + nb_max_lines_ = buff1[2]; + nb_marker_attribs_ = buff1[3]; std::vector buff2(2u*buff1[0]); fs.read(reinterpret_cast(&(buff2[0])), std::streamsize(2u*buff1[0]*sizeof(unsigned int))); names_.resize(buff1[0]); - typeNames_.resize(buff1[0]); + type_names_.resize(buff1[0]); // read name char buff3[256]; @@ -837,16 +832,16 @@ class ChunkArrayContainer names_[i] = std::string(buff3); fs.read(buff3, std::streamsize(buff2[2u*i+1u]*sizeof(char))); - typeNames_[i] = std::string(buff3); + type_names_[i] = std::string(buff3); } // read chunk array - tableArrays_.resize(buff1[0]); + table_arrays_.resize(buff1[0]); bool ok=true; for (unsigned int i = 0u; i < buff1[0]; ++i) { - tableArrays_[i] = ChunkArrayFactory::create(typeNames_[i]); - ok &= tableArrays_[i]->load(fs); + table_arrays_[i] = ChunkArrayFactory::create(type_names_[i]); + ok &= table_arrays_[i]->load(fs); } ok &= refs_.load(fs); diff --git a/cgogn/core/container/chunk_array_gen.h b/cgogn/core/container/chunk_array_gen.h index da208f95..b6d43eac 100644 --- a/cgogn/core/container/chunk_array_gen.h +++ b/cgogn/core/container/chunk_array_gen.h @@ -37,7 +37,9 @@ template class ChunkArrayGen { public: + ChunkArrayGen() = default; + ChunkArrayGen(ChunkArrayGenconst& ) = delete; ChunkArrayGen(ChunkArrayGen&& ) = delete; ChunkArrayGen& operator=(ChunkArrayGenconst& ) = delete; @@ -54,6 +56,8 @@ class ChunkArrayGen */ virtual ChunkArrayGen* clone() const = 0; + virtual bool isBooleanArray() const = 0; + /** * @brief add a chunk (T[CHUNKSIZE]) */ @@ -72,52 +76,50 @@ class ChunkArrayGen virtual unsigned int getNbChunks() const = 0; /** - * @brief number of allocated elements - * @return allocated lines + * @brief get the capacity of the array + * @return number of allocated lines */ virtual unsigned int capacity() const = 0; /** - * @brief clear + * @brief clear the array */ virtual void clear() = 0; - virtual bool isBooleanArray() const = 0; - /** - * @brief get pointer on all chunks data + * @brief fill a vector with pointers to all chunks * @param addr vector to fill - * @param byteBlockSize filled with CHUNKSIZE*sizeof(T) + * @param byte_block_size filled with CHUNKSIZE*sizeof(T) * @return addr.size() */ - virtual unsigned int getChunksPointers(std::vector& addr, unsigned int& byteBlockSize) const = 0; + virtual unsigned int getChunksPointers(std::vector& addr, unsigned int& byte_block_size) const = 0; /** - * @brief init an element (overwrite with T()) - * @param id index of element + * @brief initialize an element of the array (overwrite with T()) + * @param id index of the element */ - virtual void initElt(unsigned int id) = 0; + virtual void initElement(unsigned int id) = 0; /** - * @brief copy element - * @param dst destination - * @param src source + * @brief copy an element to another one + * @param dst destination element index + * @param src source element index */ - virtual void copyElt(unsigned int dst, unsigned int src) = 0; + virtual void copyElement(unsigned int dst, unsigned int src) = 0; /** * @brief swap two elements - * @param id1 idx first - * @param id2 idx second + * @param idx1 first element index + * @param idx2 second element index */ - virtual void swapElt(unsigned int id1, unsigned int id2) = 0; + virtual void swapElements(unsigned int idx1, unsigned int idx2) = 0; /** * @brief save * @param fs file stream - * @param nbLines number of line to save + * @param nb_lines number of line to save */ - virtual void save(std::ostream& fs, unsigned int nbLines) const = 0; + virtual void save(std::ostream& fs, unsigned int nb_lines) const = 0; /** * @brief load diff --git a/cgogn/core/container/chunk_stack.h b/cgogn/core/container/chunk_stack.h index 5e2b4c6e..daa7ae45 100644 --- a/cgogn/core/container/chunk_stack.h +++ b/cgogn/core/container/chunk_stack.h @@ -43,14 +43,14 @@ class ChunkStack : public ChunkArray typedef ChunkArray Inherit; protected: - unsigned int stackSize_; + unsigned int stack_size_; public: /** * @brief ChunkStack constructor */ ChunkStack(): - stackSize_(0u) + stack_size_(0u) {} /** @@ -70,14 +70,14 @@ class ChunkStack : public ChunkArray */ void push(const T& val) { - stackSize_++; - unsigned int offset = stackSize_ % CHUNKSIZE; - unsigned int blkId = stackSize_ / CHUNKSIZE; + stack_size_++; + unsigned int offset = stack_size_ % CHUNKSIZE; + unsigned int blkId = stack_size_ / CHUNKSIZE; - if (blkId >= this->tableData_.size()) + if (blkId >= this->table_data_.size()) this->addChunk(); - this->tableData_[blkId][offset] = val; + this->table_data_[blkId][offset] = val; } /** @@ -86,7 +86,7 @@ class ChunkStack : public ChunkArray */ inline bool empty() const { - return stackSize_ == 0u; + return stack_size_ == 0u; } /** @@ -94,7 +94,7 @@ class ChunkStack : public ChunkArray */ unsigned int size() const { - return stackSize_; + return stack_size_; } /** @@ -102,8 +102,8 @@ class ChunkStack : public ChunkArray */ inline void pop() { - cgogn_assert(stackSize_ > 0u); - stackSize_--; + cgogn_assert(stack_size_ > 0u); + stack_size_--; } /** @@ -112,10 +112,10 @@ class ChunkStack : public ChunkArray */ inline T head() const { - const unsigned int offset = stackSize_ % CHUNKSIZE; - const unsigned int blkId = stackSize_ / CHUNKSIZE; + const unsigned int offset = stack_size_ % CHUNKSIZE; + const unsigned int blkId = stack_size_ / CHUNKSIZE; - return this->tableData_[blkId][offset]; + return this->table_data_[blkId][offset]; } /** @@ -123,11 +123,11 @@ class ChunkStack : public ChunkArray */ void compact() { - const unsigned int keep = (stackSize_+CHUNKSIZE-1u) / CHUNKSIZE; - while (this->tableData_.size() > keep) + const unsigned int keep = (stack_size_+CHUNKSIZE-1u) / CHUNKSIZE; + while (this->table_data_.size() > keep) { - delete[] this->tableData_.back(); - this->tableData_.pop_back(); + delete[] this->table_data_.back(); + this->table_data_.pop_back(); } } @@ -136,7 +136,7 @@ class ChunkStack : public ChunkArray */ void clear() override { - stackSize_ = 0u; + stack_size_ = 0u; ChunkArray::clear(); } }; diff --git a/cgogn/core/map/map_base.h b/cgogn/core/map/map_base.h index 79c9e0da..a82054e5 100644 --- a/cgogn/core/map/map_base.h +++ b/cgogn/core/map/map_base.h @@ -37,7 +37,7 @@ class MapBase : public MapBaseData { protected: - std::multimap*, AttributeHandlerGen*> attributeHandlers_; + std::multimap*, AttributeHandlerGen*> attribute_handlers_; public: @@ -51,7 +51,7 @@ class MapBase : public MapBaseData {} template - inline AttributeHandler addAttribute(const std::string& attributeName = "") + inline AttributeHandler addAttribute(const std::string& attribute_name = "") { if (this->embeddings_[ORBIT] == nullptr) { @@ -63,7 +63,7 @@ class MapBase : public MapBaseData (*idx)[i] = EMBNULL; } - ChunkArray* ca = this->attributes_[ORBIT].template addAttribute(attributeName); + ChunkArray* ca = this->attributes_[ORBIT].template addAttribute(attribute_name); return AttributeHandler(this, ca); } @@ -80,10 +80,10 @@ class MapBase : public MapBaseData if (this->attributes_[ORBIT].removeAttribute(ca)) { typedef typename std::multimap*, AttributeHandlerGen*>::iterator IT; - std::pair bounds = attributeHandlers_.equal_range(ca); + std::pair bounds = attribute_handlers_.equal_range(ca); for(IT i = bounds.first; i != bounds.second; ++i) (*i).second->setInvalid(); - attributeHandlers_.erase(bounds.first, bounds.second); + attribute_handlers_.erase(bounds.first, bounds.second); return true; } return false; @@ -95,9 +95,9 @@ class MapBase : public MapBaseData * @return an AttributeHandler */ template - inline AttributeHandler< T, ORBIT> getAttribute(const std::string& nameAttr) + inline AttributeHandler< T, ORBIT> getAttribute(const std::string& attribute_name) { - ChunkArray* ca = this->attributes_[ORBIT].template getAttribute(nameAttr); + ChunkArray* ca = this->attributes_[ORBIT].template getAttribute(attribute_name); return AttributeHandler(this, ca); } @@ -108,7 +108,7 @@ class MapBase : public MapBaseData inline Dart addDart() { unsigned int di = this->topology_.template insertLines<1>(); // insert a new dart line - this->topology_.initBooleansOfLine(di); + this->topology_.initMarkersOfLine(di); for(unsigned int i = 0; i < NB_ORBITS; ++i) { diff --git a/test/chunk_array/bench_chunk_array.cpp b/test/chunk_array/bench_chunk_array.cpp index 2dd891bc..c30810e5 100644 --- a/test/chunk_array/bench_chunk_array.cpp +++ b/test/chunk_array/bench_chunk_array.cpp @@ -124,17 +124,17 @@ int test3() ChunkArrayContainer container; ChunkArray* att1 = container.addAttribute("bools"); - for (unsigned int i=0;i(); - for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) + for(unsigned int i = container.begin(); i != container.end(); container.next(i)) { - att1->setVal(i,true); + att1->setValue(i, true); } - for (unsigned int j=0; j<100; ++j) + for (unsigned int j = 0; j < 100; ++j) { - for (unsigned int i=0;isetFalse(i); att1->setFalse(NB_LINES-1-i); @@ -148,25 +148,25 @@ int test3() int test4() { - std::cout << "= TEST 4 = random bool cleaning with setFalseDirty" << std::endl; + std::cout << "= TEST 4 = random bool cleaning with setFalse_byte" << std::endl; ChunkArrayContainer container; ChunkArray* att1 = container.addAttribute("bools"); - for (unsigned int i=0;i(); - for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) + for(unsigned int i = container.begin(); i != container.end(); container.next(i)) { - att1->setVal(i,true); + att1->setValue(i, true); } - for (unsigned int j=0; j<100; ++j) + for (unsigned int j = 0; j < 100; ++j) { - for (unsigned int i=0;isetFalseDirty(i); - att1->setFalseDirty(NB_LINES-1-i); + att1->setFalse_byte(i); + att1->setFalse_byte(NB_LINES-1-i); } } diff --git a/test/chunk_array/test_chunk_array.cpp b/test/chunk_array/test_chunk_array.cpp index 5b09cf06..57536d9a 100644 --- a/test/chunk_array/test_chunk_array.cpp +++ b/test/chunk_array/test_chunk_array.cpp @@ -229,15 +229,15 @@ int test4() ChunkArray* att4 = container.addAttribute("vecvecdouble"); ChunkArray* att5 = container.addAttribute("veclistdouble"); - for (int i=0;i<7;++i) + for (unsigned int i = 0u; i < 7u; ++i) container.insertLines<3>(); - for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) + for(unsigned int i = container.begin(); i != container.end(); container.next(i)) { (*att1)[i] = 1+int(i); (*att2)[i] = 3.0f + 0.1f*float(i); - (*att3).setVal(i,static_cast(i%2)); + (*att3).setValue(i, static_cast(i%2)); (*att4)[i] = {{3.0 + 0.1*double(i),15.0 + 0.1*double(i)}, {103.0 + 0.1*double(i), 203.0 + 0.1*double(i), 303.0 + 0.1*double(i)}}; (*att5)[i] = {{3.0 + 0.1*double(i),15.0 + 0.1*double(i)}, {103.0 + 0.1*double(i), 203.0 + 0.1*double(i), 303.0 + 0.1*double(i)}}; } @@ -245,7 +245,6 @@ int test4() container.removeLines<3>(3); container.removeLines<3>(13); - std::ofstream of("pipo.map"); container.save(of); of.close(); @@ -261,7 +260,7 @@ int test4() ChunkArray* load_att4 = cont2.getAttribute("vecvecdouble"); ChunkArray* load_att5 = cont2.getAttribute("veclistdouble"); - for(unsigned int i=cont2.begin(); i!=cont2.end(); cont2.next(i)) + for(unsigned int i = cont2.begin(); i != cont2.end(); cont2.next(i)) { std::cout << i << ": "<< (*load_att1)[i] << " / " << (*load_att2)[i] << " / " << (*load_att3)[i] << " / "; for (const auto& v : (*load_att4)[i]) From 9e99302c80db014ea28c7fec0f20c7849c5b8b59 Mon Sep 17 00:00:00 2001 From: Pierre Kraemer Date: Wed, 18 Nov 2015 16:01:38 +0100 Subject: [PATCH 086/185] thread_start & thread_end method for TLS variables initialization + add_dart in Map1 + Map iterators --- cgogn/core/basic/dart.h | 125 ++++++++------- cgogn/core/container/chunk_array_container.h | 25 +-- cgogn/core/map/attribute_handler.h | 113 ++++++------- cgogn/core/map/map1.h | 23 +++ cgogn/core/map/map_base.h | 159 ++++++++++++++++--- cgogn/core/map/map_base_data.cpp | 10 +- cgogn/core/map/map_base_data.h | 6 +- cgogn/utils/CMakeLists.txt | 2 + cgogn/utils/assert.cpp | 54 ++++--- cgogn/utils/buffers.cpp | 32 ++++ cgogn/utils/buffers.h | 9 +- cgogn/utils/definitions.h | 2 +- cgogn/utils/make_unique.h | 2 +- cgogn/utils/thread.h | 49 ++++++ test/map/test_map.cpp | 12 +- 15 files changed, 442 insertions(+), 181 deletions(-) create mode 100644 cgogn/utils/buffers.cpp create mode 100644 cgogn/utils/thread.h diff --git a/cgogn/core/basic/dart.h b/cgogn/core/basic/dart.h index 41f8921e..a88d938c 100644 --- a/cgogn/core/basic/dart.h +++ b/cgogn/core/basic/dart.h @@ -25,117 +25,122 @@ #define CORE_BASIC_DART_H_ #include +#include +#include /** * \file cgogn/core/basic/dart.h * \brief Dart definition. */ + namespace cgogn { /** - * \brief Dart. - */ + * \brief Dart. + */ struct Dart { // MSVC doesn't support std::numeric_limits::max() when declaring static const variables const static unsigned int INVALID_INDEX = UINT_MAX; + /** - * \brief the value of a dart. - */ + * \brief the value of a dart. + */ unsigned int index; /** - * \brief Creates a new nil Dart - */ - Dart() : index(INVALID_INDEX) {} + * \brief Creates a new nil Dart + */ + Dart() : index(INVALID_INDEX) + {} /** - * \brief Creates a new Dart with a value - * \details The explicit keyword specifies that this - * constructor is only considered for direct initialization. - * \code - * Dart d = 10 is forbidden - * \endcode - * - * \param[in] v the value of the new dart - */ + * \brief Creates a new Dart with a value + * \details The explicit keyword specifies that this + * constructor is only considered for direct initialization. + * \code + * Dart d = 10 is forbidden + * \endcode + * + * \param[in] v the value of the new dart + */ explicit Dart(unsigned int v): index(v) {} /** - * \brief Copy constructor. - * Creates a new Dart from an another one. - * \param[in] d a dart - */ + * \brief Copy constructor. + * Creates a new Dart from an another one. + * \param[in] d a dart + */ Dart(const Dart& d): index(d.index) {} /** - * \brief Name of this CGoGN type - * \return a string representing the name of the class - */ + * \brief Name of this CGoGN type + * \return a string representing the name of the class + */ static std::string CGoGNnameOfType() { return "Dart"; } /** - * \brief Tests the nullity of the dart. - * \retval true if the dart is nil - * \retval false otherwise - */ + * \brief Tests the nullity of the dart. + * \retval true if the dart is nil + * \retval false otherwise + */ bool isNil() const { return index == INVALID_INDEX ; } /** - * \brief Assigns to the left hand side dart the value - * of the right hand side dart. - * \param[in] rhs the dart to assign - * \return The dart with the assigned value - */ + * \brief Assigns to the left hand side dart the value + * of the right hand side dart. + * \param[in] rhs the dart to assign + * \return The dart with the assigned value + */ Dart operator=(Dart rhs) { index = rhs.index; return *this; } /** - * \brief Tests whether the left hand side dart is equal - * from the right hand side dart. - * \param[in] rhs the dart to compare with - * \retval true if \p lhs is equal than \p rhs - * \retval false otherwise - */ + * \brief Tests whether the left hand side dart is equal + * from the right hand side dart. + * \param[in] rhs the dart to compare with + * \retval true if \p lhs is equal than \p rhs + * \retval false otherwise + */ bool operator==(Dart rhs) const { return index == rhs.index; } /** - * \brief Tests whether the left hand side dart is different - * from the right hand side dart. - * \param[in] rhs the dart to compare with - * \retval true if \p lhs is different than \p rhs - * \retval false otherwise - */ + * \brief Tests whether the left hand side dart is different + * from the right hand side dart. + * \param[in] rhs the dart to compare with + * \retval true if \p lhs is different than \p rhs + * \retval false otherwise + */ bool operator!=(Dart rhs) const { return index != rhs.index; } /** - * \brief Tests whether the left hand side dart is less - * greather than the right hand side dart. - * \param[in] rhs the dart to compare with - * \retval true if \p lhs is less greather than \p rhs - * \retval false otherwise - */ + * \brief Tests whether the left hand side dart is less + * greather than the right hand side dart. + * \param[in] rhs the dart to compare with + * \retval true if \p lhs is less greather than \p rhs + * \retval false otherwise + */ bool operator<(Dart rhs) const { return index < rhs.index; } /** - * \brief Prints a dart to a stream. - * \param[out] out the stream to print on - * \param[in] rhs the dart to print - */ + * \brief Prints a dart to a stream. + * \param[out] out the stream to print on + * \param[in] rhs the dart to print + */ friend std::ostream& operator<<( std::ostream &out, const Dart& rhs ) { return out << rhs.index; } /** - * \brief Reads a dart from a stream. - * \param[in] in the stream to read from - * \param[out] rhs the dart read - */ + * \brief Reads a dart from a stream. + * \param[in] in the stream to read from + * \param[out] rhs the dart read + */ friend std::istream& operator>>( std::istream &in, Dart& rhs ) { in >> rhs.index; return in; } }; /** - * \brief Definition of null embedding - */ + * \brief Definition of null embedding + */ const unsigned int EMBNULL = Dart::INVALID_INDEX; } // namespace cgogn diff --git a/cgogn/core/container/chunk_array_container.h b/cgogn/core/container/chunk_array_container.h index d1597027..e4a30aca 100644 --- a/cgogn/core/container/chunk_array_container.h +++ b/cgogn/core/container/chunk_array_container.h @@ -213,9 +213,10 @@ class ChunkArrayContainer * @brief ChunkArrayContainer constructor */ ChunkArrayContainer(): - nb_used_lines_(0u) - ,nb_max_lines_(0u) - ,std_browser_(make_unique< ContainerStandardBrowser> >(this)) + nb_used_lines_(0u), + nb_max_lines_(0u), + nb_marker_attribs_(0), + std_browser_(make_unique< ContainerStandardBrowser> >(this)) { current_browser_= std_browser_.get(); } @@ -377,7 +378,7 @@ class ChunkArrayContainer if(index == UNKNOWN) return nullptr; - ChunkArray* atm = dynamic_cast*>(table_arrays_[index]); + ChunkArray* atm = dynamic_cast*>(table_arrays_[index]); cgogn_message_assert(atm != nullptr, "getDataArray: wrong type"); @@ -632,9 +633,9 @@ class ChunkArrayContainer **************************************/ /** - * @brief is a line used - * @param index index of line - * @return true if used + * @brief get if the index is used + * @param index index to test + * @return true if the index is used, false otherwise */ bool used(unsigned int index) const { @@ -657,7 +658,7 @@ class ChunkArrayContainer if (nb_max_lines_%CHUNKSIZE <= PRIMSIZE) // prim on next block ? -> add block to C.A. { - for (auto arr: table_arrays_) + for (auto arr : table_arrays_) arr->addChunk(); refs_.addChunk(); } @@ -670,7 +671,7 @@ class ChunkArrayContainer // mark lines as used for(unsigned int i = 0u; i < PRIMSIZE; ++i) - refs_.setValue(index+i, 1u); // do not use [] in case of refs_ is bool + refs_.setValue(index + i, 1u); // do not use [] in case of refs_ is bool nb_used_lines_ += PRIMSIZE; @@ -686,7 +687,7 @@ class ChunkArrayContainer { unsigned int begin_prim_idx = (index/PRIMSIZE) * PRIMSIZE; - cgogn_message_assert(this->used(begin_prim_idx), "Error removing non existing index"); + cgogn_message_assert(used(begin_prim_idx), "Error removing non existing index"); holes_stack_.push(begin_prim_idx); @@ -703,7 +704,7 @@ class ChunkArrayContainer */ void initLine(unsigned int index) { - cgogn_message_assert(!used(index), "initLine only with allocated lines"); + cgogn_message_assert(used(index), "initLine only with allocated lines"); for (auto ptrAtt : table_arrays_) // if (ptrAtt != nullptr) never null ! @@ -712,7 +713,7 @@ class ChunkArrayContainer void initMarkersOfLine(unsigned int index) { - cgogn_message_assert(!used(index), "initMarkersOfLine only with allocated lines"); + cgogn_message_assert(used(index), "initMarkersOfLine only with allocated lines"); for (unsigned int i = 0u; i < nb_marker_attribs_; ++i) table_arrays_[i]->initElement(index); diff --git a/cgogn/core/map/attribute_handler.h b/cgogn/core/map/attribute_handler.h index ffaf970d..362e1c3b 100644 --- a/cgogn/core/map/attribute_handler.h +++ b/cgogn/core/map/attribute_handler.h @@ -34,14 +34,16 @@ namespace cgogn { /** - * @brief Generic AttributeHandler class + * \brief Generic AttributeHandler class * @TPARAM DATA_TRAITS storage traits (for MapBaseData ptr type) */ template class AttributeHandlerGen { public: + typedef MapBaseData MapData; + protected: MapData* map_; @@ -51,35 +53,35 @@ class AttributeHandlerGen public: - inline AttributeHandlerGen(MapData * const map) : + inline AttributeHandlerGen(MapData* const map) : map_(map) - ,valid_(false) + ,valid_(false) {} /** - * @brief copy constructor + * \brief copy constructor * @param atthg */ - inline AttributeHandlerGen(const AttributeHandlerGen< DATA_TRAITS >& atthg) : + inline AttributeHandlerGen(const AttributeHandlerGen& atthg) : map_(atthg.map_) - ,valid_(atthg.valid_) + ,valid_(atthg.valid_) {} /** - * @brief move constructor + * \brief move constructor * @param atthg */ - inline AttributeHandlerGen(AttributeHandlerGen< DATA_TRAITS >&& atthg) CGOGN_NOEXCEPT : + inline AttributeHandlerGen(AttributeHandlerGen&& atthg) CGOGN_NOEXCEPT : map_(atthg.map_) - ,valid_(atthg.valid_) + ,valid_(atthg.valid_) {} /** - * @brief operator = + * \brief operator = * @param atthg * @return */ - inline AttributeHandlerGen& operator=(const AttributeHandlerGen< DATA_TRAITS >& atthg) + inline AttributeHandlerGen& operator=(const AttributeHandlerGen& atthg) { this->map_ = atthg.map_; this->valid_ = atthg.valid_; @@ -87,18 +89,17 @@ class AttributeHandlerGen } /** - * @brief move operator = + * \brief move operator = * @param atthg * @return */ - inline AttributeHandlerGen& operator=(AttributeHandlerGen< DATA_TRAITS >&& atthg) + inline AttributeHandlerGen& operator=(AttributeHandlerGen&& atthg) { this->map_ = atthg.map_; this->valid_ = atthg.valid_; return *this; } - virtual ~AttributeHandlerGen() {} @@ -115,15 +116,17 @@ class AttributeHandlerGen /** - * @brief Generic AttributeHandler class with orbit parameter + * \brief Generic AttributeHandler class with orbit parameter * @TPARAM ORBIT the orbit of the attribute to handlde */ template class AttributeHandlerOrbit : public AttributeHandlerGen { public: + typedef AttributeHandlerGen Inherit; typedef typename Inherit::MapData MapData; + protected: ChunkArrayContainer* chunk_array_cont_; @@ -132,7 +135,7 @@ class AttributeHandlerOrbit : public AttributeHandlerGen inline AttributeHandlerOrbit(MapData* const map) : Inherit(map) - ,chunk_array_cont_(nullptr) + ,chunk_array_cont_(nullptr) { if (map != nullptr) { @@ -141,25 +144,25 @@ class AttributeHandlerOrbit : public AttributeHandlerGen } /** - * @brief copy constructor + * \brief copy constructor * @param attho */ - inline AttributeHandlerOrbit(const AttributeHandlerOrbit< DATA_TRAITS, ORBIT >& attho) : + inline AttributeHandlerOrbit(const AttributeHandlerOrbit< DATA_TRAITS, ORBIT >& attho) : Inherit(attho) - , chunk_array_cont_(attho.chunk_array_cont_) + ,chunk_array_cont_(attho.chunk_array_cont_) {} /** - * @brief move constructor + * \brief move constructor * @param attho */ inline AttributeHandlerOrbit(AttributeHandlerOrbit< DATA_TRAITS, ORBIT >&& attho) CGOGN_NOEXCEPT : Inherit(std::move(attho)) - , chunk_array_cont_(attho.chunk_array_cont_) + ,chunk_array_cont_(attho.chunk_array_cont_) {} /** - * @brief operator = + * \brief operator = * @param attho * @return */ @@ -170,7 +173,7 @@ class AttributeHandlerOrbit : public AttributeHandlerGen return *this; } /** - * @brief move operator = + * \brief move operator = * @param attho * @return */ @@ -186,16 +189,18 @@ class AttributeHandlerOrbit : public AttributeHandlerGen }; /** - * @brief AttributeHandler class + * \brief AttributeHandler class * @TPARAM T the data type of the attribute to handlde */ template class AttributeHandler : public AttributeHandlerOrbit { public: - typedef AttributeHandlerOrbit Inherit; - typedef ChunkArray TChunkArray; - typedef typename Inherit::MapData MapData; + + typedef AttributeHandlerOrbit Inherit; + typedef ChunkArray TChunkArray; + typedef typename Inherit::MapData MapData; + protected: TChunkArray* chunk_array_; @@ -203,7 +208,7 @@ class AttributeHandler : public AttributeHandlerOrbit public: /** - * @brief Default constructor + * \brief Default constructor * * Construct a non-valid AttributeHandler (i.e. not linked to any attribute) */ @@ -212,11 +217,11 @@ class AttributeHandler : public AttributeHandlerOrbit {} /** - * @brief Constructor + * \brief Constructor * @param m the map which belong attribute * @param attributeName name of attribute */ - AttributeHandler(MapData* const m, const std::string& attributeName): + AttributeHandler(MapData* const m, const std::string& attributeName) : Inherit(m) { cgogn_assert(this->chunk_array_cont_ != nullptr); @@ -229,9 +234,9 @@ class AttributeHandler : public AttributeHandlerOrbit } } - AttributeHandler(MapData* const m, TChunkArray* const ca): - Inherit(m), - chunk_array_(ca) + AttributeHandler(MapData* const m, TChunkArray* const ca) : + Inherit(m) + ,chunk_array_(ca) { if (chunk_array_ == nullptr) { @@ -242,25 +247,25 @@ class AttributeHandler : public AttributeHandlerOrbit } /** - * @brief Copy constructor + * \brief Copy constructor * @param att */ - AttributeHandler(const AttributeHandler& att): + AttributeHandler(const AttributeHandler& att) : Inherit(att) - ,chunk_array_(att.chunk_array_) + ,chunk_array_(att.chunk_array_) {} /** - * @brief Move constructor + * \brief Move constructor * @param att */ AttributeHandler(AttributeHandler&& att) CGOGN_NOEXCEPT : Inherit(std::move(att)) - ,chunk_array_(att.chunk_array_) + ,chunk_array_(att.chunk_array_) {} /** - * @brief operator = + * \brief operator = * @param att * @return */ @@ -272,7 +277,7 @@ class AttributeHandler : public AttributeHandlerOrbit } /** - * @brief move operator = + * \brief move operator = * @param att * @return */ @@ -283,9 +288,11 @@ class AttributeHandler : public AttributeHandlerOrbit return *this; } + virtual ~AttributeHandler() override + {} /** - * @brief getDataVector + * \brief getDataVector * @return */ TChunkArray const * getData() const @@ -294,7 +301,7 @@ class AttributeHandler : public AttributeHandlerOrbit } /** - * @brief operator [] + * \brief operator [] * @param c * @return */ @@ -305,7 +312,7 @@ class AttributeHandler : public AttributeHandlerOrbit } /** - * @brief operator [] + * \brief operator [] * @param c * @return */ @@ -316,7 +323,7 @@ class AttributeHandler : public AttributeHandlerOrbit } /** - * @brief operator [] + * \brief operator [] * @param i * @return */ @@ -327,7 +334,7 @@ class AttributeHandler : public AttributeHandlerOrbit } /** - * @brief const operator [] + * \brief const operator [] * @param i * @return */ @@ -341,11 +348,12 @@ class AttributeHandler : public AttributeHandlerOrbit class const_iterator { public: - AttributeHandler const * const ah_ptr_; + const AttributeHandler* const ah_ptr_; unsigned int index_; inline const_iterator(const AttributeHandler* ah, unsigned int i) : - ah_ptr_(ah), index_(i) + ah_ptr_(ah), + index_(i) {} inline const_iterator& operator++() @@ -368,19 +376,19 @@ class AttributeHandler : public AttributeHandlerOrbit inline const_iterator begin() const { - return const_iterator(this,this->chunk_array_cont_->begin()); + return const_iterator(this, this->chunk_array_cont_->begin()); } inline const_iterator end() const { - return const_iterator(this,this->chunk_array_cont_->end()); + return const_iterator(this, this->chunk_array_cont_->end()); } class iterator { public: - AttributeHandler* const ah_ptr_; + AttributeHandler* const ah_ptr_; unsigned int index_; inline iterator(AttributeHandler* ah, unsigned int i) : @@ -407,14 +415,13 @@ class AttributeHandler : public AttributeHandlerOrbit inline iterator begin() { - return iterator(this,this->chunk_array_cont_->begin()); + return iterator(this, this->chunk_array_cont_->begin()); } inline iterator end() { - return iterator(this,this->chunk_array_cont_->end()); + return iterator(this, this->chunk_array_cont_->end()); } - virtual ~AttributeHandler() override {} }; } // namespace cgogn diff --git a/cgogn/core/map/map1.h b/cgogn/core/map/map1.h index 6859b19c..58541dd8 100644 --- a/cgogn/core/map/map1.h +++ b/cgogn/core/map/map1.h @@ -126,6 +126,29 @@ class Map1 : public MapBase return (*(this->topo_relations_[1]))[d.index]; } + /** + * \brief add a Dart in the map + * @return the new Dart + */ + inline Dart addDart() + { + unsigned int di = this->topology_.template insertLines<1>(); // insert a new dart line + this->topology_.initMarkersOfLine(di); + + for(unsigned int i = 0; i < NB_ORBITS; ++i) + { + if (this->embeddings_[i]) // set all its embeddings + (*(this->embeddings_[i]))[di] = EMBNULL; // to EMBNULL + } + + Dart d(di); + + for (auto relPtr : this->topo_relations_) + (*relPtr)[di] = d; + + return d; + } + /** * @brief add_cycle * @param nbEdges diff --git a/cgogn/core/map/map_base.h b/cgogn/core/map/map_base.h index a82054e5..2aab859d 100644 --- a/cgogn/core/map/map_base.h +++ b/cgogn/core/map/map_base.h @@ -50,6 +50,15 @@ class MapBase : public MapBaseData ~MapBase() {} + /******************************************************************************* + * Attributes management + *******************************************************************************/ + + /** + * \brief add an attribute + * @param attribute_name the name of the attribute to create + * @return a handler to the created attribute + */ template inline AttributeHandler addAttribute(const std::string& attribute_name = "") { @@ -68,12 +77,12 @@ class MapBase : public MapBaseData } /** - * remove an attribute - * @param attr a handler to the attribute to remove + * \brief remove an attribute + * @param ah a handler to the attribute to remove * @return true if remove succeed else false */ template - inline bool removeAttribute(AttributeHandler& ah) + inline bool removeAttribute(AttributeHandler& ah) { ChunkArray* ca = ah.getData(); @@ -90,7 +99,7 @@ class MapBase : public MapBaseData } /** - * search an attribute for a given orbit + * \brief search an attribute for a given orbit * @param nameAttr attribute name * @return an AttributeHandler */ @@ -101,27 +110,141 @@ class MapBase : public MapBaseData return AttributeHandler(this, ca); } - /** - * add a Dart in the map - * @return the new Dart - */ - inline Dart addDart() + /******************************************************************************* + * Basic traversals + *******************************************************************************/ + +//private: + +// /** +// * \brief Map begin +// * @return the first dart of the map +// */ +// inline Dart begin() const +// { +// return Dart(this->topology_.begin()); +// } + +// /** +// * \brief Map end +// * @return the dart after the last dart of the map +// */ +// inline Dart end() const +// { +// return Dart(this->topology_.end()); +// } + +// /** +// * \brief next dart in the map +// * @param d reference to the dart to be modified +// */ +// inline void next(Dart& d) const +// { +// this->topology_.next(d.index); +// } + +//public: + + class iterator + { + public: + MapBase* const map_; + Dart dart_; + + inline iterator(MapBase* map, Dart d) : + map_(map), + dart_(d) + {} + + inline iterator& operator++() + { + map_->topology_.next(dart_.index); + return *this; + } + + inline Dart& operator*() + { + return dart_; + } + + inline bool operator!=(iterator it) const + { + cgogn_assert(map_ == it.map_); + return dart_ != it.dart_; + } + }; + + inline iterator begin() + { + return iterator(this, Dart(this->topology_.begin())); + } + + inline iterator end() + { + return iterator(this, Dart(this->topology_.end())); + } + + class const_iterator { - unsigned int di = this->topology_.template insertLines<1>(); // insert a new dart line - this->topology_.initMarkersOfLine(di); + public: + const MapBase* const map_; + Dart dart_; + + inline const_iterator(const MapBase* map, Dart d) : + map_(map), + dart_(d) + {} - for(unsigned int i = 0; i < NB_ORBITS; ++i) + inline const_iterator& operator++() { - if (this->embeddings_[i]) // set all its embeddings - (*(this->embeddings_[i]))[di] = EMBNULL; // to EMBNULL + map_->topology_.next(dart_.index); + return *this; } - Dart d(di); + inline const Dart& operator*() const + { + return dart_; + } - for (auto relPtr: this->topo_relations_) - (*relPtr)[di] = d; + inline bool operator!=(iterator it) const + { + cgogn_assert(map_ == it.map_); + return dart_ != it.dart_; + } + }; - return d; + inline const_iterator begin() const + { + return const_iterator(this, Dart(this->topology_.begin())); + } + + inline const_iterator end() const + { + return const_iterator(this, Dart(this->topology_.end())); + } + + /** + * \brief apply a function on each dart of the map + * @tparam FUNC type of the callable + * @param f a callable + */ + template + inline void foreach_dart(FUNC f) + { + for (Dart d : *this) + f(d); + } + + /** + * \brief apply a function on each dart of the map + * @tparam FUNC type of the callable + * @param f a callable + */ + template + inline void foreach_dart(FUNC& f) + { + for (Dart d : *this) + f(d); } }; diff --git a/cgogn/core/map/map_base_data.cpp b/cgogn/core/map/map_base_data.cpp index ecb9f3dd..f7c63d20 100644 --- a/cgogn/core/map/map_base_data.cpp +++ b/cgogn/core/map/map_base_data.cpp @@ -28,8 +28,8 @@ namespace cgogn std::vector* MapGen::instances_ = nullptr; -CGOGN_TLS Buffers dart_buffers_thread = Buffers(); -CGOGN_TLS Buffers uint_buffers_thread = Buffers(); +CGOGN_TLS Buffers* dart_buffers_thread = nullptr; +CGOGN_TLS Buffers* uint_buffers_thread = nullptr; MapGen::MapGen() { @@ -46,6 +46,12 @@ MapGen::~MapGen() auto it = std::find(instances_->begin(), instances_->end(), this); *it = instances_->back(); instances_->pop_back(); + + if (instances_->empty()) + { + delete instances_; + instances_ = nullptr; + } } } // namespace cgogn diff --git a/cgogn/core/map/map_base_data.h b/cgogn/core/map/map_base_data.h index 51fd4ae4..98907cd7 100644 --- a/cgogn/core/map/map_base_data.h +++ b/cgogn/core/map/map_base_data.h @@ -28,7 +28,7 @@ #include #include -#include +#include #include #include @@ -37,10 +37,6 @@ namespace cgogn { -/// buffers of pre-allocated vectors of dart or unsigned int -extern CGOGN_TLS Buffers dart_buffers_thread; -extern CGOGN_TLS Buffers uint_buffers_thread; - /** * @brief Generic Map class */ diff --git a/cgogn/utils/CMakeLists.txt b/cgogn/utils/CMakeLists.txt index 6cb92a9c..0fc76ffd 100644 --- a/cgogn/utils/CMakeLists.txt +++ b/cgogn/utils/CMakeLists.txt @@ -8,10 +8,12 @@ set(HEADER_FILES assert.h buffers.h make_unique.h + thread.h ) set(SOURCE_FILES assert.cpp + buffers.cpp ) add_library(${PROJECT_NAME} SHARED ${HEADER_FILES} ${SOURCE_FILES}) diff --git a/cgogn/utils/assert.cpp b/cgogn/utils/assert.cpp index dcfca66b..3e20ba0c 100644 --- a/cgogn/utils/assert.cpp +++ b/cgogn/utils/assert.cpp @@ -1,38 +1,39 @@ -/* - * CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps - * Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation; either version 2.1 of the License, or (at your - * option) any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Web site: http://cgogn.unistra.fr/ - * Contact information: cgogn@unistra.fr - * - */ +/******************************************************************************* +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * +* Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France * +* * +* This library is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by the * +* Free Software Foundation; either version 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: http://cgogn.unistra.fr/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ #define CGOGN_UTILS_DLL_EXPORT + #include #include #include #include #include -namespace cgogn +namespace cgogn { - CGOGN_UTILS_API CGOGN_NORETURN void assertion_failed(const std::string& expression, const std::string& message, - const std::string& file_name, const std::string& function_name, int line_number ) +CGOGN_UTILS_API CGOGN_NORETURN void assertion_failed(const std::string& expression, const std::string& message, + const std::string& file_name, const std::string& function_name, int line_number ) { std::ostringstream os; os << "Assertion failed: " << expression; @@ -45,4 +46,5 @@ namespace cgogn std::cerr << os.str() << std::endl; std::abort(); } -} + +} // namespace cgogn diff --git a/cgogn/utils/buffers.cpp b/cgogn/utils/buffers.cpp new file mode 100644 index 00000000..8756c20a --- /dev/null +++ b/cgogn/utils/buffers.cpp @@ -0,0 +1,32 @@ +/******************************************************************************* +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * +* Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France * +* * +* This library is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by the * +* Free Software Foundation; either version 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: http://cgogn.unistra.fr/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ + +#include + +namespace cgogn +{ + +CGOGN_TLS Buffers* dart_buffers_thread = nullptr; +CGOGN_TLS Buffers* uint_buffers_thread = nullptr; + +} // namespace cgogn diff --git a/cgogn/utils/buffers.h b/cgogn/utils/buffers.h index 72347a31..c47576e9 100644 --- a/cgogn/utils/buffers.h +++ b/cgogn/utils/buffers.h @@ -1,5 +1,5 @@ /******************************************************************************* -* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * * * +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * * Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France * * * * This library is free software; you can redistribute it and/or modify it * @@ -24,6 +24,9 @@ #ifndef UTILS_BUFFERS_H_ #define UTILS_BUFFERS_H_ +#include +#include + #include namespace cgogn @@ -74,6 +77,10 @@ class Buffers } }; +/// buffers of pre-allocated vectors of dart or unsigned int +extern CGOGN_TLS Buffers* dart_buffers_thread; +extern CGOGN_TLS Buffers* uint_buffers_thread; + } // namespace cgogn #endif // UTILS_BUFFERS_H_ diff --git a/cgogn/utils/definitions.h b/cgogn/utils/definitions.h index 4f44c33c..128e3afc 100644 --- a/cgogn/utils/definitions.h +++ b/cgogn/utils/definitions.h @@ -40,7 +40,7 @@ #if defined(_MSC_VER) && _MSC_VER < 1900 #define CGOGN_TLS __declspec( thread ) #else -#define CGOGN_TLS thread_local +#define CGOGN_TLS __thread #endif /** diff --git a/cgogn/utils/make_unique.h b/cgogn/utils/make_unique.h index dd9937ee..d95247a8 100644 --- a/cgogn/utils/make_unique.h +++ b/cgogn/utils/make_unique.h @@ -75,7 +75,7 @@ template typename _Unique_if::_Known_bound make_unique(Args&&...) = delete; -} +} // namespace cgogn #endif // UTILS_MAKE_UNIQUE_H diff --git a/cgogn/utils/thread.h b/cgogn/utils/thread.h new file mode 100644 index 00000000..924e82c5 --- /dev/null +++ b/cgogn/utils/thread.h @@ -0,0 +1,49 @@ +/******************************************************************************* +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * +* Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France * +* * +* This library is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by the * +* Free Software Foundation; either version 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: http://cgogn.unistra.fr/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ + +#ifndef UTILS_THREAD_H_ +#define UTILS_THREAD_H_ + +#include + +namespace cgogn +{ + +inline void thread_start() +{ + if (dart_buffers_thread == nullptr) + dart_buffers_thread = new Buffers(); + + if (uint_buffers_thread == nullptr) + uint_buffers_thread = new Buffers(); +} + +inline void thread_end() +{ + delete dart_buffers_thread; + delete uint_buffers_thread; +} + +} // namespace cgogn + +#endif // UTILS_THREAD_H_ diff --git a/test/map/test_map.cpp b/test/map/test_map.cpp index 874e5996..b8ff207a 100644 --- a/test/map/test_map.cpp +++ b/test/map/test_map.cpp @@ -54,9 +54,9 @@ int test1(MAP1& map) // add an attribute on vertex of map with MAP1::VertexAttributeHandler ah = map.addAttribute("floats"); - std::vector* uib = cgogn::uint_buffers_thread.getBuffer(); + std::vector* uib = cgogn::uint_buffers_thread->getBuffer(); uib->push_back(3); - cgogn::uint_buffers_thread.releaseBuffer(uib); + cgogn::uint_buffers_thread->releaseBuffer(uib); Dart d = map.addDart(); @@ -65,6 +65,12 @@ int test1(MAP1& map) dm.mark(d); + std::cout << "Darts :" << std::endl; + for (Dart d : map) + { + std::cout << d << std::endl; + } + // get ChunkArrayContainer -> get ChunkArray -> fill ChunkArrayContainer& container = map.getAttributeContainer(VERTEX1); ChunkArray* att = container.getAttribute("floats"); @@ -91,8 +97,10 @@ int test1(MAP1& map) int main() { + cgogn::thread_start(); MAP1 map1; MAP2 map2; test1(map1); + cgogn::thread_end(); return 0; } From 41255ad560010e2b2f3b19d3c23e900116c0ec36 Mon Sep 17 00:00:00 2001 From: Pierre Kraemer Date: Wed, 18 Nov 2015 16:41:09 +0100 Subject: [PATCH 087/185] first traversals and foreach_dart... --- cgogn/core/basic/dart_marker.h | 96 +++++++++++++++++++++++------ cgogn/core/map/map1.h | 86 +++++++++++++++++++++----- cgogn/core/map/map2.h | 107 ++++++++++++++++++++++++++++++--- cgogn/core/map/map_base_data.h | 28 ++++++--- cgogn/utils/assert.h | 76 ++++++++++++----------- 5 files changed, 303 insertions(+), 90 deletions(-) diff --git a/cgogn/core/basic/dart_marker.h b/cgogn/core/basic/dart_marker.h index d9f3d483..b5df2bb5 100644 --- a/cgogn/core/basic/dart_marker.h +++ b/cgogn/core/basic/dart_marker.h @@ -92,25 +92,25 @@ class DartMarkerT : public DartMarkerGen return (*mark_attribute_)[d.index]; } -// template -// inline void markOrbit(Cell c) -// { -// cgogn_message_assert(mark_attribute_ != nullptr, "DartMarker has null mark attribute"); -// map_.foreach_dart_of_orbit(c, [&] (Dart d) -// { -// mark_attribute_->setTrue(d.index); -// }) ; -// } - -// template -// inline void unmarkOrbit(Cell c) -// { -// cgogn_message_assert(mark_attribute_ != nullptr, "DartMarker has null mark attribute"); -// map_.foreach_dart_of_orbit(c, [&] (Dart d) -// { -// mark_attribute_->setFalse(d.index); -// }) ; -// } + template + inline void markOrbit(Cell c) + { + cgogn_message_assert(mark_attribute_ != nullptr, "DartMarker has null mark attribute"); + map_.foreach_dart_of_orbit(c, [&] (Dart d) + { + mark_attribute_->setTrue(d.index); + }); + } + + template + inline void unmarkOrbit(Cell c) + { + cgogn_message_assert(mark_attribute_ != nullptr, "DartMarker has null mark attribute"); + map_.foreach_dart_of_orbit(c, [&] (Dart d) + { + mark_attribute_->setFalse(d.index); + }); + } }; template @@ -118,8 +118,10 @@ class DartMarker : public DartMarkerT { public: + typedef DartMarkerT Inherit; + DartMarker(MAP& map) : - DartMarkerT(map) + Inherit(map) {} ~DartMarker() override @@ -139,6 +141,60 @@ class DartMarker : public DartMarkerT } }; +template +class DartMarkerStore : public DartMarkerT +{ +protected: + + std::vector* marked_darts_; + +public: + + typedef DartMarkerT Inherit; + + DartMarkerStore(MAP& map) : + Inherit(map) + { + marked_darts_ = dart_buffers_thread->getBuffer(); + } + + ~DartMarkerStore() override + { + unmarkAll(); + dart_buffers_thread->releaseBuffer(marked_darts_); + } + + DartMarkerStore(const DartMarkerStore& dm) = delete; + DartMarkerStore(DartMarkerStore&& dm) = delete; + DartMarkerStore& operator=(DartMarkerStore&& dm) = delete; + DartMarkerStore& operator=(const DartMarkerStore& dm) = delete; + + inline void mark(Dart d) + { + Inherit::mark(d); + marked_darts_->push_back(d); + } + + template + inline void markOrbit(Cell c) + { + this->map_.foreach_dart_of_orbit(c, [&] (Dart d) + { + Inherit::mark(d); + marked_darts_->push_back(d); + }); + } + + void unmarkAll() + { + cgogn_message_assert(this->mark_attribute_ != nullptr, "DartMarker has null mark attribute"); + for (Dart d : marked_darts_) + { + Inherit::unmark(d); + } + } +}; + } // namespace cgogn #endif // CORE_BASIC_DART_MARKER_H_ diff --git a/cgogn/core/map/map1.h b/cgogn/core/map/map1.h index 58541dd8..7c17c28e 100644 --- a/cgogn/core/map/map1.h +++ b/cgogn/core/map/map1.h @@ -63,10 +63,15 @@ class Map1 : public MapBase this->topo_relations_.push_back(phi_1); } - //! Link the current dart to dart d with a permutation - /*! @param d the dart to which the current is linked - * - Before: d->f and e->g - * - After: d->g and e->f + /******************************************************************************* + * Low-level topological operations + *******************************************************************************/ + + /** + * \brief Link the current dart to dart d with a permutation + * @param d the dart to which the current is linked + * - Before: d->f and e->g + * - After: d->g and e->f * Join the permutations cycles of dart d and e * - Starting from two cycles : d->f->...->d and e->g->...->e * - It makes one cycle d->g->...->e->f->...->d @@ -82,10 +87,11 @@ class Map1 : public MapBase (*(this->topo_relations_[1]))[f.index] = e; } - //! Unlink the successor of a given dart in a permutation - /*! @param d a dart - * - Before: d->e->f - * - After: d->f and e->e + /** + * \brief Unlink the successor of a given dart in a permutation + * @param d a dart + * - Before: d->e->f + * - After: d->f and e->e */ void phi1unsew(Dart d) { @@ -104,10 +110,15 @@ class Map1 : public MapBase init(); } - virtual ~Map1() override {} + virtual ~Map1() override + {} + + /******************************************************************************* + * Basic topological operations + *******************************************************************************/ /** - * @brief phi1 + * \brief phi1 * @param d * @return */ @@ -117,7 +128,7 @@ class Map1 : public MapBase } /** - * @brief phi_1 + * \brief phi_1 * @param d * @return */ @@ -149,21 +160,25 @@ class Map1 : public MapBase return d; } + /******************************************************************************* + * High-level topological operations + *******************************************************************************/ + /** - * @brief add_cycle + * \brief add_cycle * @param nbEdges * @return */ Dart add_cycle(unsigned int nbEdges); /** - * @brief remove_cycle + * \brief remove_cycle * @param d */ void remove_cycle(Dart d); /** - * @brief cut_edge + * \brief cut_edge * @param d * @return */ @@ -183,7 +198,7 @@ class Map1 : public MapBase } /** - * @brief uncut_edge + * \brief uncut_edge * @param d * @return */ @@ -195,11 +210,50 @@ class Map1 : public MapBase } /** - * @brief collapse_edge + * \brief collapse_edge * @param d * @return */ Dart collapse_edge(Dart d); + + /******************************************************************************* + * Orbits traversal + *******************************************************************************/ + + template + inline void foreach_dart_of_vertex(Dart d, const FUNC& f) const + { + f(d); + } + + template + inline void foreach_dart_of_edge(Dart d, const FUNC& f) const + { + f(d); + } + + template + inline void foreach_dart_of_face(Dart d, const FUNC& f) const + { + Dart it = d; + do + { + f(it); + it = phi1(it); + } while (it != d); + } + + template + void foreach_dart_of_orbit(Cell c, const FUNC& f) const + { + switch(ORBIT) + { + case Map1::VERTEX: f(c); break; + case Map1::EDGE: foreach_dart_of_edge(c, f); break; + case Map1::FACE: foreach_dart_of_face(c, f); break; + default: cgogn_message_assert(false, "Cells of this dimension are not handled"); break; + } + } }; } // namespace cgogn diff --git a/cgogn/core/map/map2.h b/cgogn/core/map/map2.h index acef1ecb..f6c876f8 100644 --- a/cgogn/core/map/map2.h +++ b/cgogn/core/map/map2.h @@ -25,6 +25,7 @@ #define CORE_MAP_MAP2_H_ #include +#include namespace cgogn { @@ -34,9 +35,12 @@ class Map2 : public Map1 { public: + typedef Map1 Inherit; + static const unsigned int VERTEX = VERTEX2; static const unsigned int EDGE = EDGE2; static const unsigned int FACE = FACE2; + static const unsigned int VOLUME = VOLUME3; template using VertexAttributeHandler = cgogn::AttributeHandler; @@ -55,10 +59,15 @@ class Map2 : public Map1 this->topo_relations_.push_back(phi2); } - //! Link dart d with dart e by an involution - /* @param d,e the darts to link - * - Before: d->d and e->e - * - After: d->e and e->d + /******************************************************************************* + * Low-level topological operations + *******************************************************************************/ + + /** + * \brief Link dart d with dart e by an involution + * @param d,e the darts to link + * - Before: d->d and e->e + * - After: d->e and e->d */ void phi2sew(Dart d, Dart e) { @@ -68,10 +77,11 @@ class Map2 : public Map1 (*(this->topo_relations_[2]))[e.index] = d; } - //! Unlink the current dart by an involution - /* @param d the dart to unlink - * - Before: d->e and e->d - * - After: d->d and e->e + /** + * \brief Unlink the current dart by an involution + * @param d the dart to unlink + * - Before: d->e and e->d + * - After: d->d and e->e */ void phi2unsew(Dart d) { @@ -82,7 +92,7 @@ class Map2 : public Map1 public: - Map2() : Map1() + Map2() : Inherit() { init(); } @@ -90,8 +100,12 @@ class Map2 : public Map1 ~Map2() override {} + /******************************************************************************* + * Basic topological operations + *******************************************************************************/ + /** - * @brief phi2 + * \brief phi2 * @param d * @return */ @@ -100,6 +114,79 @@ class Map2 : public Map1 // phi2 first topo relation return (*(this->topo_relations_[2]))[d.index]; } + + /******************************************************************************* + * Orbits traversal + *******************************************************************************/ + + template + inline void foreach_dart_of_vertex(Dart d, const FUNC& f) const + { + Dart dNext = d; + do + { + f(dNext); + dNext = phi2(this->phi_1(dNext)); + } while (dNext != d); + } + + template + inline void foreach_dart_of_edge(Dart d, const FUNC& f) const + { + f(d); + f(phi2(d)); + } + + template + inline void foreach_dart_of_face(Dart d, const FUNC& f) const + { + Inherit::foreach_dart_of_face(d, f); + } + template + void foreach_dart_of_volume(Dart d, const FUNC& f) const + { + DartMarkerStore marker(*this); // get a marker + + std::vector* visited_faces = dart_buffers_thread->getBuffer(); + + visited_faces->push_back(d); // Start with the face of d + + // For every face added to the list + for(unsigned int i = 0; i < visited_faces->size(); ++i) + { + if (!marker.isMarked((*visited_faces)[i])) // Face has not been visited yet + { + // Apply functor to the darts of the face + Map2::foreach_dart_of_face((*visited_faces)[i], f); + + // mark visited darts (current face) + // and add non visited adjacent faces to the list of face + Dart e = (*visited_faces)[i] ; + do + { + marker.mark(e); // Mark + Dart adj = phi2(e); // Get adjacent face + if (!marker.isMarked(adj)) + visited_faces->push_back(adj); // Add it + e = this->phi1(e); + } while(e != (*visited_faces)[i]); + } + } + + dart_buffers_thread->releaseBuffer(visited_faces); + } + + template + void foreach_dart_of_orbit(Cell c, const FUNC& f) const + { + switch(ORBIT) + { + case VERTEX: f(c); break; + case EDGE: foreach_dart_of_edge(c, f); break; + case FACE: foreach_dart_of_face(c, f); break; + default: cgogn_message_assert(false, "Cells of this dimension are not handled"); break; + } + } }; } // namespace cgogn diff --git a/cgogn/core/map/map_base_data.h b/cgogn/core/map/map_base_data.h index 98907cd7..243bc0fa 100644 --- a/cgogn/core/map/map_base_data.h +++ b/cgogn/core/map/map_base_data.h @@ -119,19 +119,15 @@ class MapBaseData : public MapGen ~MapBaseData() override {} + /******************************************************************************* + * Containers management + *******************************************************************************/ + inline ChunkArrayContainer& getAttributeContainer(unsigned int orbit) { return attributes_[orbit]; } - template - inline unsigned int getEmbedding(const Cell& c) const - { - cgogn_message_assert(embeddings_[ORBIT] != NULL, "Invalid parameter: orbit not embedded"); - - return (*embeddings_[ORBIT])[c.dart.index] ; - } - inline ChunkArray* getTopologyMarkAttribute() { unsigned int thread = getCurrentThreadIndex(); @@ -198,8 +194,24 @@ class MapBaseData : public MapGen mark_attributes_[ORBIT][thread].push_back(ca); } + /******************************************************************************* + * Embedding management + *******************************************************************************/ + + template + inline unsigned int getEmbedding(const Cell& c) const + { + cgogn_message_assert(embeddings_[ORBIT] != NULL, "Invalid parameter: orbit not embedded"); + + return (*embeddings_[ORBIT])[c.dart.index] ; + } + protected: + /******************************************************************************* + * Thread management + *******************************************************************************/ + inline unsigned int getCurrentThreadIndex() const { std::thread::id id = std::this_thread::get_id(); diff --git a/cgogn/utils/assert.h b/cgogn/utils/assert.h index 328e9e8a..46f98a7c 100644 --- a/cgogn/utils/assert.h +++ b/cgogn/utils/assert.h @@ -1,25 +1,25 @@ -/* - * CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps - * Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation; either version 2.1 of the License, or (at your - * option) any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Web site: http://cgogn.unistra.fr/ - * Contact information: cgogn@unistra.fr - * - */ +/******************************************************************************* +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * +* Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France * +* * +* This library is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by the * +* Free Software Foundation; either version 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: http://cgogn.unistra.fr/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ #ifndef UTILS_BASIC_ASSERT_ #define UTILS_BASIC_ASSERT_ @@ -42,20 +42,24 @@ namespace cgogn { - /** - * Prints an assertion failure. - * This function is called when a boolean condition is not met. - * It prints an error message and terminates the program. - * \param[in] expression string representation of the condition. - * \param[in] message string information message to print out. - * \param[in] file_name file where the assertion failed. - * \param[in] function_name function where the assertion failed. - * \param[in] line_number line where the assertion failed. - * - */ - CGOGN_UTILS_API CGOGN_NORETURN void assertion_failed(const std::string& expression, - const std::string& message, const std::string& file_name, - const std::string& function_name, int line_number ); +/** + * Prints an assertion failure. + * This function is called when a boolean condition is not met. + * It prints an error message and terminates the program. + * \param[in] expression string representation of the condition. + * \param[in] message string information message to print out. + * \param[in] file_name file where the assertion failed. + * \param[in] function_name function where the assertion failed. + * \param[in] line_number line where the assertion failed. + * + */ +CGOGN_UTILS_API CGOGN_NORETURN void assertion_failed( + const std::string& expression, + const std::string& message, + const std::string& file_name, + const std::string& function_name, + int line_number +); } From d46ac0aaebc216d97d98ffec06e7a18844109ec0 Mon Sep 17 00:00:00 2001 From: Pierre Kraemer Date: Wed, 18 Nov 2015 17:04:27 +0100 Subject: [PATCH 088/185] CellMarkerStore --- cgogn/core/basic/cell_marker.h | 51 ++++++++++++++++++++++++++++-- cgogn/core/basic/dart_marker.h | 6 ++-- cgogn/core/map/attribute_handler.h | 12 +++---- cgogn/core/map/map1.h | 6 ++-- cgogn/core/map/map2.h | 10 +++--- cgogn/core/map/map_base.h | 4 ++- cgogn/core/map/map_base_data.h | 7 ++-- 7 files changed, 77 insertions(+), 19 deletions(-) diff --git a/cgogn/core/basic/cell_marker.h b/cgogn/core/basic/cell_marker.h index aab0d98e..0e6e7cf5 100644 --- a/cgogn/core/basic/cell_marker.h +++ b/cgogn/core/basic/cell_marker.h @@ -98,8 +98,10 @@ class CellMarker : public CellMarkerT { public: + typedef CellMarkerT Inherit; + CellMarker(MAP& map) : - CellMarkerT(map) + Inherit(map) {} ~CellMarker() override @@ -112,13 +114,58 @@ class CellMarker : public CellMarkerT CellMarker& operator=(CellMarker&& dm) = delete; CellMarker& operator=(const CellMarker& dm) = delete; - void unmarkAll() + inline void unmarkAll() { cgogn_message_assert(this->mark_attribute_ != nullptr, "CellMarker has null mark attribute"); this->mark_attribute_->allFalse(); } }; +template +class CellMarkerStore : public CellMarkerT +{ +protected: + + std::vector* marked_cells_; + +public: + + typedef CellMarkerT Inherit; + + CellMarkerStore(MAP& map) : + Inherit(map) + { + marked_cells_ = uint_buffers_thread->getBuffer(); + } + + ~CellMarkerStore() override + { + unmarkAll(); + uint_buffers_thread->releaseBuffer(marked_cells_); + } + + CellMarkerStore(const CellMarkerStore& dm) = delete; + CellMarkerStore(CellMarkerStore&& dm) = delete; + CellMarkerStore& operator=(CellMarkerStore&& dm) = delete; + CellMarkerStore& operator=(const CellMarkerStore& dm) = delete; + + inline void mark(Cell c) + { + cgogn_message_assert(this->mark_attribute_ != nullptr, "CellMarker has null mark attribute"); + Inherit::mark(c); + marked_cells_->push_back(this->map_.getEmbedding(c)); + } + + inline void unmarkAll() + { + cgogn_message_assert(this->mark_attribute_ != nullptr, "CellMarker has null mark attribute"); + for (unsigned int i : marked_cells_) + { + this->mark_attribute_->setFalse(i); + } + } +}; + } // namespace cgogn #endif // CORE_BASIC_CELL_MARKER_H_ diff --git a/cgogn/core/basic/dart_marker.h b/cgogn/core/basic/dart_marker.h index b5df2bb5..bb5c48c8 100644 --- a/cgogn/core/basic/dart_marker.h +++ b/cgogn/core/basic/dart_marker.h @@ -134,7 +134,7 @@ class DartMarker : public DartMarkerT DartMarker& operator=(DartMarker&& dm) = delete; DartMarker& operator=(const DartMarker& dm) = delete; - void unmarkAll() + inline void unmarkAll() { cgogn_message_assert(this->mark_attribute_ != nullptr, "DartMarker has null mark attribute"); this->mark_attribute_->allFalse(); @@ -171,6 +171,7 @@ class DartMarkerStore : public DartMarkerT inline void mark(Dart d) { + cgogn_message_assert(this->mark_attribute_ != nullptr, "DartMarker has null mark attribute"); Inherit::mark(d); marked_darts_->push_back(d); } @@ -178,6 +179,7 @@ class DartMarkerStore : public DartMarkerT template inline void markOrbit(Cell c) { + cgogn_message_assert(this->mark_attribute_ != nullptr, "DartMarker has null mark attribute"); this->map_.foreach_dart_of_orbit(c, [&] (Dart d) { Inherit::mark(d); @@ -185,7 +187,7 @@ class DartMarkerStore : public DartMarkerT }); } - void unmarkAll() + inline void unmarkAll() { cgogn_message_assert(this->mark_attribute_ != nullptr, "DartMarker has null mark attribute"); for (Dart d : marked_darts_) diff --git a/cgogn/core/map/attribute_handler.h b/cgogn/core/map/attribute_handler.h index 362e1c3b..5e9deebf 100644 --- a/cgogn/core/map/attribute_handler.h +++ b/cgogn/core/map/attribute_handler.h @@ -235,8 +235,8 @@ class AttributeHandler : public AttributeHandlerOrbit } AttributeHandler(MapData* const m, TChunkArray* const ca) : - Inherit(m) - ,chunk_array_(ca) + Inherit(m), + chunk_array_(ca) { if (chunk_array_ == nullptr) { @@ -251,8 +251,8 @@ class AttributeHandler : public AttributeHandlerOrbit * @param att */ AttributeHandler(const AttributeHandler& att) : - Inherit(att) - ,chunk_array_(att.chunk_array_) + Inherit(att), + chunk_array_(att.chunk_array_) {} /** @@ -260,8 +260,8 @@ class AttributeHandler : public AttributeHandlerOrbit * @param att */ AttributeHandler(AttributeHandler&& att) CGOGN_NOEXCEPT : - Inherit(std::move(att)) - ,chunk_array_(att.chunk_array_) + Inherit(std::move(att)), + chunk_array_(att.chunk_array_) {} /** diff --git a/cgogn/core/map/map1.h b/cgogn/core/map/map1.h index 7c17c28e..ff740c75 100644 --- a/cgogn/core/map/map1.h +++ b/cgogn/core/map/map1.h @@ -40,6 +40,8 @@ class Map1 : public MapBase { public: + typedef MapBase Inherit; + static const unsigned int VERTEX = VERTEX1; static const unsigned int EDGE = VERTEX1; static const unsigned int FACE = FACE2; @@ -105,7 +107,7 @@ class Map1 : public MapBase public: - inline Map1() + Map1() : Inherit() { init(); } @@ -251,7 +253,7 @@ class Map1 : public MapBase case Map1::VERTEX: f(c); break; case Map1::EDGE: foreach_dart_of_edge(c, f); break; case Map1::FACE: foreach_dart_of_face(c, f); break; - default: cgogn_message_assert(false, "Cells of this dimension are not handled"); break; + default: cgogn_message_assert(false, "Cells of this dimension are not handled"); break; } } }; diff --git a/cgogn/core/map/map2.h b/cgogn/core/map/map2.h index f6c876f8..355d75d2 100644 --- a/cgogn/core/map/map2.h +++ b/cgogn/core/map/map2.h @@ -142,6 +142,7 @@ class Map2 : public Map1 { Inherit::foreach_dart_of_face(d, f); } + template void foreach_dart_of_volume(Dart d, const FUNC& f) const { @@ -181,10 +182,11 @@ class Map2 : public Map1 { switch(ORBIT) { - case VERTEX: f(c); break; - case EDGE: foreach_dart_of_edge(c, f); break; - case FACE: foreach_dart_of_face(c, f); break; - default: cgogn_message_assert(false, "Cells of this dimension are not handled"); break; + case Map2::VERTEX: f(c); break; + case Map2::EDGE: foreach_dart_of_edge(c, f); break; + case Map2::FACE: foreach_dart_of_face(c, f); break; + case Map2::VOLUME: foreach_dart_of_volume(c, f); break; + default: cgogn_message_assert(false, "Cells of this dimension are not handled"); break; } } }; diff --git a/cgogn/core/map/map_base.h b/cgogn/core/map/map_base.h index 2aab859d..57aba92e 100644 --- a/cgogn/core/map/map_base.h +++ b/cgogn/core/map/map_base.h @@ -41,10 +41,12 @@ class MapBase : public MapBaseData public: + typedef MapBaseData Inherit; + template using AttributeHandler = cgogn::AttributeHandler; - MapBase() + MapBase() : Inherit() {} ~MapBase() diff --git a/cgogn/core/map/map_base_data.h b/cgogn/core/map/map_base_data.h index 243bc0fa..f67a34a1 100644 --- a/cgogn/core/map/map_base_data.h +++ b/cgogn/core/map/map_base_data.h @@ -99,9 +99,11 @@ class MapBaseData : public MapGen public: + typedef MapGen Inherit; + static const unsigned int CHUNK_SIZE = DATA_TRAITS::CHUNK_SIZE; - MapBaseData() + MapBaseData() : Inherit() { for (unsigned int i = 0; i < NB_ORBITS; ++i) { @@ -117,7 +119,8 @@ class MapBaseData : public MapGen thread_ids_.push_back(std::this_thread::get_id()); } - ~MapBaseData() override {} + ~MapBaseData() override + {} /******************************************************************************* * Containers management From 37fdf1a83916b477d1a4ef833af0dbcd1e830c38 Mon Sep 17 00:00:00 2001 From: David Cazier/develop Date: Wed, 18 Nov 2015 18:23:14 +0100 Subject: [PATCH 089/185] =?UTF-8?q?Changements=20cosm=C3=A9tiques=20dans?= =?UTF-8?q?=20thread.h=20et=20d=C3=A9placement=20des=20buffers=20dans=20th?= =?UTF-8?q?read.cpp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cgogn/utils/CMakeLists.txt | 4 +-- cgogn/utils/assert.h | 47 ++++++++++++------------- cgogn/utils/buffers.h | 9 ++--- cgogn/utils/definitions.h | 16 ++------- cgogn/utils/{buffers.cpp => thread.cpp} | 2 +- cgogn/utils/thread.h | 9 +++++ 6 files changed, 40 insertions(+), 47 deletions(-) rename cgogn/utils/{buffers.cpp => thread.cpp} (98%) diff --git a/cgogn/utils/CMakeLists.txt b/cgogn/utils/CMakeLists.txt index 0fc76ffd..75791c96 100644 --- a/cgogn/utils/CMakeLists.txt +++ b/cgogn/utils/CMakeLists.txt @@ -13,13 +13,13 @@ set(HEADER_FILES set(SOURCE_FILES assert.cpp - buffers.cpp + thread.cpp ) add_library(${PROJECT_NAME} SHARED ${HEADER_FILES} ${SOURCE_FILES}) #use of target_compile_options to have a transitive c++11 flag if(NOT MSVC) - target_compile_options(${PROJECT_NAME} PUBLIC "-std=c++11") + target_compile_options(${PROJECT_NAME} PUBLIC "-std=c++11") endif() set_target_properties(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX "_d") diff --git a/cgogn/utils/assert.h b/cgogn/utils/assert.h index 46f98a7c..6b33ef64 100644 --- a/cgogn/utils/assert.h +++ b/cgogn/utils/assert.h @@ -21,8 +21,8 @@ * * *******************************************************************************/ -#ifndef UTILS_BASIC_ASSERT_ -#define UTILS_BASIC_ASSERT_ +#ifndef UTILS_ASSERT_ +#define UTILS_ASSERT_ #include #include @@ -32,14 +32,13 @@ #define __func__ __FUNCTION__ #endif - /** * \file cgogn/core/basic/assert.h * \brief Assertion checking mechanism. * * Allows the user to add a specific message to output */ -namespace cgogn +namespace cgogn { /** @@ -75,7 +74,7 @@ CGOGN_UTILS_API CGOGN_NORETURN void assertion_failed( { \ cgogn::assertion_failed(#x, "", __FILE__, __func__, __LINE__); \ } \ -} +} /** * \brief Verifies that a condition is met and take a specific message. @@ -95,7 +94,7 @@ CGOGN_UTILS_API CGOGN_NORETURN void assertion_failed( /** * \brief Verifies that the required contract condition is met. * \details - * + * * \param[in] x the boolean expression of the condition * \see assertion_failed() */ @@ -105,12 +104,12 @@ CGOGN_UTILS_API CGOGN_NORETURN void assertion_failed( { \ cgogn::assertion_failed(#x, "", __FILE__, __func__, __LINE__); \ } \ -} +} /** * \brief Verifies that the ensured contract condition is met. * \details - * + * * \param[in] x the boolean expression of the condition * \see assertion_failed() */ @@ -120,12 +119,12 @@ CGOGN_UTILS_API CGOGN_NORETURN void assertion_failed( { \ cgogn::assertion_failed(#x, "", __FILE__, __func__, __LINE__); \ } \ -} +} /** * \brief Verifies that the invariant contract condition is met. * \details - * + * * \param[in] x the boolean expression of the condition * \see assertion_failed() */ @@ -135,7 +134,7 @@ CGOGN_UTILS_API CGOGN_NORETURN void assertion_failed( { \ cgogn::assertion_failed(#x, "", __FILE__, __func__, __LINE__); \ } \ -} +} /** * \def debug_assert(x) @@ -148,17 +147,17 @@ CGOGN_UTILS_API CGOGN_NORETURN void assertion_failed( * \note This assertion check is only active in debug mode. */ #ifdef CGOGN_DEBUG - #define debug_assert(x) cgogn_assert(x) + #define debug_assert(x) cgogn_assert(x) #define debug_message_assert(x, msg) cgogn_message_assert(x, msg) - #define debug_require(x) cgogn_require(x) - #define debug_ensure(x) cgogn_ensure(x) - #define debug_invariant(x) cgogn_invariant(x) + #define debug_require(x) cgogn_require(x) + #define debug_ensure(x) cgogn_ensure(x) + #define debug_invariant(x) cgogn_invariant(x) #else - #define debug_assert(x) + #define debug_assert(x) #define debug_message_assert(x, msg) - #define debug_require(x) - #define debug_ensure(x) - #define debug_invariant(x) + #define debug_require(x) + #define debug_ensure(x) + #define debug_invariant(x) #endif /** @@ -172,11 +171,11 @@ CGOGN_UTILS_API CGOGN_NORETURN void assertion_failed( * \note This assertion check is only active in parano mode. */ #ifdef CGOGN_PARANO - #define parano_assert(x) cgogn_assert(x) - #define parano_message_assert(x, msg) cgogn_message_assert(x, msg) + #define parano_assert(x) cgogn_assert(x) + #define parano_message_assert(x, msg) cgogn_message_assert(x, msg) #else - #define parano_assert(x) - #define parano_message_assert(x, msg) + #define parano_assert(x) + #define parano_message_assert(x, msg) #endif -#endif // UTILS_BASIC_ASSERT_ +#endif // UTILS_ASSERT_ diff --git a/cgogn/utils/buffers.h b/cgogn/utils/buffers.h index c47576e9..65a9643b 100644 --- a/cgogn/utils/buffers.h +++ b/cgogn/utils/buffers.h @@ -67,9 +67,8 @@ class Buffers { if (b->capacity() > 1024) { - std::vector v; - b->swap(v); - b->reserve(128); + b->resize(128); + b->shrink_to_fit(); } b->clear(); @@ -77,10 +76,6 @@ class Buffers } }; -/// buffers of pre-allocated vectors of dart or unsigned int -extern CGOGN_TLS Buffers* dart_buffers_thread; -extern CGOGN_TLS Buffers* uint_buffers_thread; - } // namespace cgogn #endif // UTILS_BUFFERS_H_ diff --git a/cgogn/utils/definitions.h b/cgogn/utils/definitions.h index 128e3afc..67d24010 100644 --- a/cgogn/utils/definitions.h +++ b/cgogn/utils/definitions.h @@ -21,8 +21,8 @@ * * *******************************************************************************/ -#ifndef UTILS_BASIC_DEFINITIONS_H_ -#define UTILS_BASIC_DEFINITIONS_H_ +#ifndef UTILS_DEFINITIONS_H_ +#define UTILS_DEFINITIONS_H_ /** * \brief No execpt declaration for CGOGN symbols. @@ -69,14 +69,4 @@ #define CGOGN_PARANO #endif -namespace cgogn -{ - -/** - * \brief The maximum nunmber of threads created by the API. - */ -const unsigned int NB_THREADS = 8u; - -} // namespace cgogn - -#endif // UTILS_BASIC_DEFINITIONS_H_ +#endif // UTILS_DEFINITIONS_H_ diff --git a/cgogn/utils/buffers.cpp b/cgogn/utils/thread.cpp similarity index 98% rename from cgogn/utils/buffers.cpp rename to cgogn/utils/thread.cpp index 8756c20a..dcf9d8c4 100644 --- a/cgogn/utils/buffers.cpp +++ b/cgogn/utils/thread.cpp @@ -21,7 +21,7 @@ * * *******************************************************************************/ -#include +#include namespace cgogn { diff --git a/cgogn/utils/thread.h b/cgogn/utils/thread.h index 924e82c5..4f99fcb9 100644 --- a/cgogn/utils/thread.h +++ b/cgogn/utils/thread.h @@ -29,6 +29,15 @@ namespace cgogn { +/** + * \brief The maximum nunmber of threads created by the API. + */ +const unsigned int NB_THREADS = 8u; + +/// buffers of pre-allocated vectors of dart or unsigned int +extern CGOGN_TLS Buffers* dart_buffers_thread; +extern CGOGN_TLS Buffers* uint_buffers_thread; + inline void thread_start() { if (dart_buffers_thread == nullptr) From 6b69fdd23a095a4beb25e6276531ef14d0d1cb22 Mon Sep 17 00:00:00 2001 From: Lionel Untereiner Date: Wed, 18 Nov 2015 20:16:01 +0100 Subject: [PATCH 090/185] correction warning "no newline at end of file" --- cgogn/utils/dll.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cgogn/utils/dll.h b/cgogn/utils/dll.h index 4c922408..a4b401b7 100644 --- a/cgogn/utils/dll.h +++ b/cgogn/utils/dll.h @@ -37,4 +37,4 @@ #define CGOGN_UTILS_API #endif -#endif // UTILS_DLL_H_ \ No newline at end of file +#endif // UTILS_DLL_H_ From c1a4c073e7b945a734d35fbb674d4e6d364935b7 Mon Sep 17 00:00:00 2001 From: Lionel Untereiner Date: Wed, 18 Nov 2015 20:17:41 +0100 Subject: [PATCH 091/185] correction warning -Wweak-vtables --- cgogn/core/CMakeLists.txt | 3 +++ cgogn/core/basic/cell_marker.cpp | 33 ++++++++++++++++++++++++++++++++ cgogn/core/basic/cell_marker.h | 3 +-- cgogn/core/basic/dart_marker.cpp | 33 ++++++++++++++++++++++++++++++++ cgogn/core/basic/dart_marker.h | 3 +-- 5 files changed, 71 insertions(+), 4 deletions(-) create mode 100644 cgogn/core/basic/cell_marker.cpp create mode 100644 cgogn/core/basic/dart_marker.cpp diff --git a/cgogn/core/CMakeLists.txt b/cgogn/core/CMakeLists.txt index 910f018f..3e5467ba 100644 --- a/cgogn/core/CMakeLists.txt +++ b/cgogn/core/CMakeLists.txt @@ -28,6 +28,9 @@ set(HEADER_FILES ) set(SOURCE_FILES + basic/cell_marker.cpp + basic/dart_marker.cpp + container/chunk_array_container.cpp map/map_base_data.cpp diff --git a/cgogn/core/basic/cell_marker.cpp b/cgogn/core/basic/cell_marker.cpp new file mode 100644 index 00000000..ccf8a9f8 --- /dev/null +++ b/cgogn/core/basic/cell_marker.cpp @@ -0,0 +1,33 @@ +/******************************************************************************* +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * +* Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France * +* * +* This library is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by the * +* Free Software Foundation; either version 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: http://cgogn.unistra.fr/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ + +#define CGOGN_CORE_DLL_EXPORT +#include + +namespace cgogn +{ + +CellMarkerGen::~CellMarkerGen() +{} + +} diff --git a/cgogn/core/basic/cell_marker.h b/cgogn/core/basic/cell_marker.h index 0e6e7cf5..f25c0940 100644 --- a/cgogn/core/basic/cell_marker.h +++ b/cgogn/core/basic/cell_marker.h @@ -37,8 +37,7 @@ class CellMarkerGen CellMarkerGen() {} - virtual ~CellMarkerGen() - {} + virtual ~CellMarkerGen(); CellMarkerGen(const CellMarkerGen& dm) = delete; CellMarkerGen(CellMarkerGen&& dm) = delete; diff --git a/cgogn/core/basic/dart_marker.cpp b/cgogn/core/basic/dart_marker.cpp new file mode 100644 index 00000000..77cd569c --- /dev/null +++ b/cgogn/core/basic/dart_marker.cpp @@ -0,0 +1,33 @@ +/******************************************************************************* +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * +* Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France * +* * +* This library is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by the * +* Free Software Foundation; either version 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: http://cgogn.unistra.fr/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ + +#define CGOGN_CORE_DLL_EXPORT +#include + +namespace cgogn +{ + +DartMarkerGen::~DartMarkerGen() +{} + +} diff --git a/cgogn/core/basic/dart_marker.h b/cgogn/core/basic/dart_marker.h index bb5c48c8..8494ae99 100644 --- a/cgogn/core/basic/dart_marker.h +++ b/cgogn/core/basic/dart_marker.h @@ -37,8 +37,7 @@ class DartMarkerGen DartMarkerGen() {} - virtual ~DartMarkerGen() - {} + virtual ~DartMarkerGen(); DartMarkerGen(const DartMarkerGen& dm) = delete; DartMarkerGen(DartMarkerGen&& dm) = delete; From d8b1c99bfcd46f0ca51ae616720c6d2dd3e80fe9 Mon Sep 17 00:00:00 2001 From: Lionel Untereiner Date: Wed, 18 Nov 2015 20:18:56 +0100 Subject: [PATCH 092/185] correction warning no newline at end of file --- cgogn/core/basic/dll.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cgogn/core/basic/dll.h b/cgogn/core/basic/dll.h index d324d846..c00be925 100644 --- a/cgogn/core/basic/dll.h +++ b/cgogn/core/basic/dll.h @@ -37,4 +37,4 @@ #define CGOGN_CORE_API #endif -#endif // CORE_DLL_H_ \ No newline at end of file +#endif // CORE_DLL_H_ From 210f6ba638fde2421b4dd944eaa1f8d9dcdb8e46 Mon Sep 17 00:00:00 2001 From: Lionel Untereiner Date: Wed, 18 Nov 2015 20:19:34 +0100 Subject: [PATCH 093/185] cosmetics --- cgogn/core/container/chunk_array_container.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cgogn/core/container/chunk_array_container.cpp b/cgogn/core/container/chunk_array_container.cpp index 2c53d062..59008348 100644 --- a/cgogn/core/container/chunk_array_container.cpp +++ b/cgogn/core/container/chunk_array_container.cpp @@ -28,7 +28,6 @@ namespace cgogn { ContainerBrowser::~ContainerBrowser() -{ +{} } -} From 4051a6f127388a0581512dec55cb6764686be6a9 Mon Sep 17 00:00:00 2001 From: Lionel Untereiner Date: Wed, 18 Nov 2015 20:19:52 +0100 Subject: [PATCH 094/185] local variable d was hidden --- test/map/test_map.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/map/test_map.cpp b/test/map/test_map.cpp index b8ff207a..39e903ea 100644 --- a/test/map/test_map.cpp +++ b/test/map/test_map.cpp @@ -66,9 +66,9 @@ int test1(MAP1& map) dm.mark(d); std::cout << "Darts :" << std::endl; - for (Dart d : map) + for (Dart dit : map) { - std::cout << d << std::endl; + std::cout << dit << std::endl; } // get ChunkArrayContainer -> get ChunkArray -> fill From d3b57d786c5d4cb95b7a6335cdf691aa6dc930a2 Mon Sep 17 00:00:00 2001 From: Lionel Untereiner Date: Wed, 18 Nov 2015 21:34:24 +0100 Subject: [PATCH 095/185] assert for non reachable point in programs --- cgogn/core/map/map1.h | 2 +- cgogn/core/map/map2.h | 2 +- cgogn/utils/assert.cpp | 16 ++++++++++++++++ cgogn/utils/assert.h | 28 +++++++++++++++++++++++++++- 4 files changed, 45 insertions(+), 3 deletions(-) diff --git a/cgogn/core/map/map1.h b/cgogn/core/map/map1.h index ff740c75..497f0bf5 100644 --- a/cgogn/core/map/map1.h +++ b/cgogn/core/map/map1.h @@ -253,7 +253,7 @@ class Map1 : public MapBase case Map1::VERTEX: f(c); break; case Map1::EDGE: foreach_dart_of_edge(c, f); break; case Map1::FACE: foreach_dart_of_face(c, f); break; - default: cgogn_message_assert(false, "Cells of this dimension are not handled"); break; + default: cgogn_assert_not_reached("Cells of this dimension are not handled"); break; } } }; diff --git a/cgogn/core/map/map2.h b/cgogn/core/map/map2.h index 355d75d2..2570c752 100644 --- a/cgogn/core/map/map2.h +++ b/cgogn/core/map/map2.h @@ -186,7 +186,7 @@ class Map2 : public Map1 case Map2::EDGE: foreach_dart_of_edge(c, f); break; case Map2::FACE: foreach_dart_of_face(c, f); break; case Map2::VOLUME: foreach_dart_of_volume(c, f); break; - default: cgogn_message_assert(false, "Cells of this dimension are not handled"); break; + default: cgogn_assert_not_reached("Cells of this dimension are not handled"); break; } } }; diff --git a/cgogn/utils/assert.cpp b/cgogn/utils/assert.cpp index 3e20ba0c..c99a9bc0 100644 --- a/cgogn/utils/assert.cpp +++ b/cgogn/utils/assert.cpp @@ -47,4 +47,20 @@ CGOGN_UTILS_API CGOGN_NORETURN void assertion_failed(const std::string& expressi std::abort(); } + CGOGN_UTILS_API CGOGN_NORETURN void assertion_not_reached(const std::string& message, + const std::string& file_name, const std::string& function_name, int line_number ) +{ + std::ostringstream os; + os << "Should not have reached this point"; + if(message.empty()) + os << ".\n"; + else + os<< " (" << message << ").\n"; + os << "file: " << file_name << ", function: " << function_name << ", line: " << line_number ; + + std::cerr << os.str() << std::endl; + std::abort(); +} + + } // namespace cgogn diff --git a/cgogn/utils/assert.h b/cgogn/utils/assert.h index 46f98a7c..84bfbc24 100644 --- a/cgogn/utils/assert.h +++ b/cgogn/utils/assert.h @@ -51,7 +51,6 @@ namespace cgogn * \param[in] file_name file where the assertion failed. * \param[in] function_name function where the assertion failed. * \param[in] line_number line where the assertion failed. - * */ CGOGN_UTILS_API CGOGN_NORETURN void assertion_failed( const std::string& expression, @@ -61,6 +60,23 @@ CGOGN_UTILS_API CGOGN_NORETURN void assertion_failed( int line_number ); +/** + * Prints an unreachable location failure. + * This function is called when execution reaches a point that + * should not be reached. It prints an error message and + * terminates the program. + * \param[in] message string information message to print out. + * \param[in] file_name file where the assertion failed. + * \param[in] function_name function where the assertion failed. + * \param[in] line_number line where the assertion failed. + */ +CGOGN_UTILS_API CGOGN_NORETURN void should_not_have_reached( + const std::string& message, + const std::string& file_name, + const std::string& function_name, + int line_number +); + } /** @@ -92,6 +108,16 @@ CGOGN_UTILS_API CGOGN_NORETURN void assertion_failed( } \ } +/** + * \brief Sets a non reachable point in the program + * \details + * \param[in] msg the specific information message + */ +#define cgogn_assert_not_reached(msg) \ +{ \ + cgogn::should_not_have_reached(msg, __FILE__, __func, __LINE__);\ +} + /** * \brief Verifies that the required contract condition is met. * \details From f024fad1093cca5f4d0656b76c4f235c4208c0c1 Mon Sep 17 00:00:00 2001 From: Pierre Kraemer Date: Wed, 18 Nov 2015 22:04:25 +0100 Subject: [PATCH 096/185] fix in assert functions --- cgogn/utils/assert.cpp | 30 +++++++++++++++++++----------- cgogn/utils/assert.h | 2 +- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/cgogn/utils/assert.cpp b/cgogn/utils/assert.cpp index c99a9bc0..f4614fae 100644 --- a/cgogn/utils/assert.cpp +++ b/cgogn/utils/assert.cpp @@ -32,35 +32,43 @@ namespace cgogn { -CGOGN_UTILS_API CGOGN_NORETURN void assertion_failed(const std::string& expression, const std::string& message, - const std::string& file_name, const std::string& function_name, int line_number ) +CGOGN_UTILS_API CGOGN_NORETURN void assertion_failed( + const std::string& expression, + const std::string& message, + const std::string& file_name, + const std::string& function_name, + int line_number +) { std::ostringstream os; os << "Assertion failed: " << expression; - if(message.empty()) + if (message.empty()) os << ".\n"; else - os<< " (" << message << ").\n"; - os << "file: " << file_name << ", function: " << function_name << ", line: " << line_number ; + os << " (" << message << ").\n"; + os << "file: " << file_name << ", function: " << function_name << ", line: " << line_number; std::cerr << os.str() << std::endl; std::abort(); } - CGOGN_UTILS_API CGOGN_NORETURN void assertion_not_reached(const std::string& message, - const std::string& file_name, const std::string& function_name, int line_number ) +CGOGN_UTILS_API CGOGN_NORETURN void should_not_have_reached( + const std::string& message, + const std::string& file_name, + const std::string& function_name, + int line_number +) { std::ostringstream os; os << "Should not have reached this point"; - if(message.empty()) + if (message.empty()) os << ".\n"; else - os<< " (" << message << ").\n"; - os << "file: " << file_name << ", function: " << function_name << ", line: " << line_number ; + os << " (" << message << ").\n"; + os << "file: " << file_name << ", function: " << function_name << ", line: " << line_number; std::cerr << os.str() << std::endl; std::abort(); } - } // namespace cgogn diff --git a/cgogn/utils/assert.h b/cgogn/utils/assert.h index 0ec9a735..b969464e 100644 --- a/cgogn/utils/assert.h +++ b/cgogn/utils/assert.h @@ -114,7 +114,7 @@ CGOGN_UTILS_API CGOGN_NORETURN void should_not_have_reached( */ #define cgogn_assert_not_reached(msg) \ { \ - cgogn::should_not_have_reached(msg, __FILE__, __func, __LINE__);\ + cgogn::should_not_have_reached(msg, __FILE__, __func__, __LINE__);\ } /** From 99a2d08823d93fccff9326888c6c367a3903ae34 Mon Sep 17 00:00:00 2001 From: Pierre Kraemer Date: Wed, 18 Nov 2015 23:23:01 +0100 Subject: [PATCH 097/185] naming conventions --- cgogn/core/basic/cell.h | 35 ++-- cgogn/core/basic/cell_marker.h | 32 ++-- cgogn/core/basic/dart.h | 15 +- cgogn/core/basic/dart_marker.h | 36 ++-- cgogn/core/basic/dll.h | 2 + cgogn/core/basic/nameTypes.h | 49 ++--- cgogn/core/container/chunk_array.h | 68 +++---- cgogn/core/container/chunk_array_container.h | 149 ++++++++------- cgogn/core/container/chunk_array_factory.h | 16 +- cgogn/core/container/chunk_array_gen.h | 20 +- cgogn/core/container/chunk_stack.h | 2 +- cgogn/core/map/attribute_handler.h | 88 ++++----- cgogn/core/map/map1.h | 34 ++-- cgogn/core/map/map2.h | 14 +- cgogn/core/map/map_base.h | 18 +- cgogn/core/map/map_base_data.h | 28 +-- cgogn/core/map/map_tri.h | 2 +- cgogn/utils/assert.h | 6 +- cgogn/utils/buffers.h | 4 +- cgogn/utils/definitions.h | 2 +- cgogn/utils/make_unique.h | 1 - cgogn/utils/thread.h | 2 +- test/chunk_array/bench_chunk_array.cpp | 134 ++++++------- test/chunk_array/test_chunk_array.cpp | 186 +++++++++---------- test/map/test_map.cpp | 22 +-- 25 files changed, 468 insertions(+), 497 deletions(-) diff --git a/cgogn/core/basic/cell.h b/cgogn/core/basic/cell.h index f2a703fc..3c501456 100644 --- a/cgogn/core/basic/cell.h +++ b/cgogn/core/basic/cell.h @@ -35,17 +35,17 @@ namespace cgogn { -const unsigned int NB_ORBITS = 8; -const unsigned int VERTEX1 = 0; -const unsigned int VERTEX2 = 1; -const unsigned int EDGE2 = 2; -const unsigned int FACE2 = 3; -const unsigned int VERTEX3 = 4; -const unsigned int EDGE3 = 5; -const unsigned int FACE3 = 6; -const unsigned int VOLUME3 = 7; - -inline std::string orbitName(unsigned int orbit) +const unsigned int NB_ORBITS = 8; +const unsigned int VERTEX1 = 0; +const unsigned int VERTEX2 = 1; +const unsigned int EDGE2 = 2; +const unsigned int FACE2 = 3; +const unsigned int VERTEX3 = 4; +const unsigned int EDGE3 = 5; +const unsigned int FACE3 = 6; +const unsigned int VOLUME3 = 7; + +inline std::string orbit_name(unsigned int orbit) { switch(orbit) { @@ -81,23 +81,26 @@ class Cell /** * \brief Constructs a new empty Cell with NIL dart. */ - inline Cell(): dart() {} + inline Cell() : dart() + {} /** * \brief Constructs a new Cell with a dart. * \param d dart to convert to a cell of a given orbit */ - inline Cell(Dart d): dart(d) {} + inline Cell(Dart d) : dart(d) + {} /// copy constructor - inline Cell(const Cell& c): dart(c.dart) {} + inline Cell(const Cell& c) : dart(c.dart) + {} /// Dart cast operator inline operator Dart() const { return dart; } - friend std::ostream& operator<<( std::ostream &out, const Cell& fa ) { return out << fa.dart; } + friend std::ostream& operator<<(std::ostream &out, const Cell& fa) { return out << fa.dart; } - inline bool valid() const { return !dart.isNil(); } + inline bool is_valid() const { return !dart.is_nil(); } }; } // namespace cgogn diff --git a/cgogn/core/basic/cell_marker.h b/cgogn/core/basic/cell_marker.h index f25c0940..21baa3cf 100644 --- a/cgogn/core/basic/cell_marker.h +++ b/cgogn/core/basic/cell_marker.h @@ -59,13 +59,13 @@ class CellMarkerT : public CellMarkerGen CellMarkerGen(), map_(map) { - mark_attribute_ = map_.template getMarkAttribute(); + mark_attribute_ = map_.template get_mark_attribute(); } ~CellMarkerT() override { - if (MapGen::isAlive(&map_)) - map_.template releaseMarkAttribute(mark_attribute_); + if (MapGen::is_alive(&map_)) + map_.template release_mark_attribute(mark_attribute_); } CellMarkerT(const CellMarkerT& dm) = delete; @@ -76,19 +76,19 @@ class CellMarkerT : public CellMarkerGen inline void mark(Cell c) { cgogn_message_assert(mark_attribute_ != nullptr, "CellMarker has null mark attribute"); - mark_attribute_->setTrue(map_.getEmbedding(c)); + mark_attribute_->set_true(map_.get_embedding(c)); } inline void unmark(Cell c) { cgogn_message_assert(mark_attribute_ != nullptr, "CellMarker has null mark attribute"); - mark_attribute_->setFalse(map_.getEmbedding(c)); + mark_attribute_->set_false(map_.get_embedding(c)); } - inline void isMarked(Cell c) const + inline void is_marked(Cell c) const { cgogn_message_assert(mark_attribute_ != nullptr, "CellMarker has null mark attribute"); - return (*mark_attribute_)[map_.getEmbedding(c)]; + return (*mark_attribute_)[map_.get_embedding(c)]; } }; @@ -105,7 +105,7 @@ class CellMarker : public CellMarkerT ~CellMarker() override { - unmarkAll() ; + unmark_all() ; } CellMarker(const CellMarker& dm) = delete; @@ -113,10 +113,10 @@ class CellMarker : public CellMarkerT CellMarker& operator=(CellMarker&& dm) = delete; CellMarker& operator=(const CellMarker& dm) = delete; - inline void unmarkAll() + inline void unmark_all() { cgogn_message_assert(this->mark_attribute_ != nullptr, "CellMarker has null mark attribute"); - this->mark_attribute_->allFalse(); + this->mark_attribute_->all_false(); } }; @@ -134,13 +134,13 @@ class CellMarkerStore : public CellMarkerT CellMarkerStore(MAP& map) : Inherit(map) { - marked_cells_ = uint_buffers_thread->getBuffer(); + marked_cells_ = uint_buffers_thread->get_buffer(); } ~CellMarkerStore() override { - unmarkAll(); - uint_buffers_thread->releaseBuffer(marked_cells_); + unmark_all(); + uint_buffers_thread->release_buffer(marked_cells_); } CellMarkerStore(const CellMarkerStore& dm) = delete; @@ -152,15 +152,15 @@ class CellMarkerStore : public CellMarkerT { cgogn_message_assert(this->mark_attribute_ != nullptr, "CellMarker has null mark attribute"); Inherit::mark(c); - marked_cells_->push_back(this->map_.getEmbedding(c)); + marked_cells_->push_back(this->map_.get_embedding(c)); } - inline void unmarkAll() + inline void unmark_all() { cgogn_message_assert(this->mark_attribute_ != nullptr, "CellMarker has null mark attribute"); for (unsigned int i : marked_cells_) { - this->mark_attribute_->setFalse(i); + this->mark_attribute_->set_false(i); } } }; diff --git a/cgogn/core/basic/dart.h b/cgogn/core/basic/dart.h index a88d938c..d8bbd5f5 100644 --- a/cgogn/core/basic/dart.h +++ b/cgogn/core/basic/dart.h @@ -65,27 +65,29 @@ struct Dart * * \param[in] v the value of the new dart */ - explicit Dart(unsigned int v): index(v) {} + explicit Dart(unsigned int v) : index(v) + {} /** * \brief Copy constructor. * Creates a new Dart from an another one. * \param[in] d a dart */ - Dart(const Dart& d): index(d.index) {} + Dart(const Dart& d) : index(d.index) + {} /** * \brief Name of this CGoGN type * \return a string representing the name of the class */ - static std::string CGoGNnameOfType() { return "Dart"; } + static std::string CGoGN_name_of_type() { return "Dart"; } /** * \brief Tests the nullity of the dart. * \retval true if the dart is nil * \retval false otherwise */ - bool isNil() const { return index == INVALID_INDEX ; } + bool is_nil() const { return index == INVALID_INDEX ; } /** * \brief Assigns to the left hand side dart the value @@ -127,15 +129,14 @@ struct Dart * \param[out] out the stream to print on * \param[in] rhs the dart to print */ - friend std::ostream& operator<<( std::ostream &out, const Dart& rhs ) { return out << rhs.index; } + friend std::ostream& operator<<(std::ostream &out, const Dart& rhs) { return out << rhs.index; } /** * \brief Reads a dart from a stream. * \param[in] in the stream to read from * \param[out] rhs the dart read */ - friend std::istream& operator>>( std::istream &in, Dart& rhs ) { in >> rhs.index; return in; } - + friend std::istream& operator>>(std::istream &in, Dart& rhs) { in >> rhs.index; return in; } }; /** diff --git a/cgogn/core/basic/dart_marker.h b/cgogn/core/basic/dart_marker.h index 8494ae99..56e2b7d7 100644 --- a/cgogn/core/basic/dart_marker.h +++ b/cgogn/core/basic/dart_marker.h @@ -59,13 +59,13 @@ class DartMarkerT : public DartMarkerGen DartMarkerGen(), map_(map) { - mark_attribute_ = map_.template getTopologyMarkAttribute(); + mark_attribute_ = map_.template get_topology_mark_attribute(); } ~DartMarkerT() override { - if (MapGen::isAlive(&map_)) - map_.template releaseTopologyMarkAttribute(mark_attribute_); + if (MapGen::is_alive(&map_)) + map_.template release_topology_mark_attribute(mark_attribute_); } DartMarkerT(const DartMarkerT& dm) = delete; @@ -76,38 +76,38 @@ class DartMarkerT : public DartMarkerGen inline void mark(Dart d) { cgogn_message_assert(mark_attribute_ != nullptr, "DartMarker has null mark attribute"); - mark_attribute_->setTrue(d.index); + mark_attribute_->set_true(d.index); } inline void unmark(Dart d) { cgogn_message_assert(mark_attribute_ != nullptr, "DartMarker has null mark attribute"); - mark_attribute_->setFalse(d.index); + mark_attribute_->set_false(d.index); } - inline void isMarked(Dart d) const + inline void is_marked(Dart d) const { cgogn_message_assert(mark_attribute_ != nullptr, "DartMarker has null mark attribute"); return (*mark_attribute_)[d.index]; } template - inline void markOrbit(Cell c) + inline void mark_orbit(Cell c) { cgogn_message_assert(mark_attribute_ != nullptr, "DartMarker has null mark attribute"); map_.foreach_dart_of_orbit(c, [&] (Dart d) { - mark_attribute_->setTrue(d.index); + mark_attribute_->set_true(d.index); }); } template - inline void unmarkOrbit(Cell c) + inline void unmark_orbit(Cell c) { cgogn_message_assert(mark_attribute_ != nullptr, "DartMarker has null mark attribute"); map_.foreach_dart_of_orbit(c, [&] (Dart d) { - mark_attribute_->setFalse(d.index); + mark_attribute_->set_false(d.index); }); } }; @@ -125,7 +125,7 @@ class DartMarker : public DartMarkerT ~DartMarker() override { - unmarkAll() ; + unmark_all() ; } DartMarker(const DartMarker& dm) = delete; @@ -133,10 +133,10 @@ class DartMarker : public DartMarkerT DartMarker& operator=(DartMarker&& dm) = delete; DartMarker& operator=(const DartMarker& dm) = delete; - inline void unmarkAll() + inline void unmark_all() { cgogn_message_assert(this->mark_attribute_ != nullptr, "DartMarker has null mark attribute"); - this->mark_attribute_->allFalse(); + this->mark_attribute_->all_false(); } }; @@ -154,13 +154,13 @@ class DartMarkerStore : public DartMarkerT DartMarkerStore(MAP& map) : Inherit(map) { - marked_darts_ = dart_buffers_thread->getBuffer(); + marked_darts_ = dart_buffers_thread->get_buffer(); } ~DartMarkerStore() override { - unmarkAll(); - dart_buffers_thread->releaseBuffer(marked_darts_); + unmark_all(); + dart_buffers_thread->release_buffer(marked_darts_); } DartMarkerStore(const DartMarkerStore& dm) = delete; @@ -176,7 +176,7 @@ class DartMarkerStore : public DartMarkerT } template - inline void markOrbit(Cell c) + inline void mark_orbit(Cell c) { cgogn_message_assert(this->mark_attribute_ != nullptr, "DartMarker has null mark attribute"); this->map_.foreach_dart_of_orbit(c, [&] (Dart d) @@ -186,7 +186,7 @@ class DartMarkerStore : public DartMarkerT }); } - inline void unmarkAll() + inline void unmark_all() { cgogn_message_assert(this->mark_attribute_ != nullptr, "DartMarker has null mark attribute"); for (Dart d : marked_darts_) diff --git a/cgogn/core/basic/dll.h b/cgogn/core/basic/dll.h index c00be925..9dc8f4fc 100644 --- a/cgogn/core/basic/dll.h +++ b/cgogn/core/basic/dll.h @@ -20,8 +20,10 @@ * Contact information: cgogn@unistra.fr * * * *******************************************************************************/ + #ifndef CORE_DLL_H_ #define CORE_DLL_H_ + /** * \brief Linkage declaration for CGOGN symbols. */ diff --git a/cgogn/core/basic/nameTypes.h b/cgogn/core/basic/nameTypes.h index a0275d98..db23b5e5 100644 --- a/cgogn/core/basic/nameTypes.h +++ b/cgogn/core/basic/nameTypes.h @@ -35,61 +35,62 @@ namespace cgogn * @brief function that give a name to a type. */ template -std::string nameOfType(const T& /*v*/) +std::string name_of_type(const T& /*v*/) { - return T::CGoGNnameOfType(); + return T::CGoGN_name_of_type(); } // first we need to declare some specializations -template inline std::string nameOfType(const std::list& /*v*/); -template inline std::string nameOfType(const std::vector& /*v*/); +template inline std::string name_of_type(const std::list& /*v*/); +template inline std::string name_of_type(const std::vector& /*v*/); -template <> inline std::string nameOfType(const bool& /*v*/) { return "bool"; } +template <> inline std::string name_of_type(const bool& /*v*/) { return "bool"; } -template <> inline std::string nameOfType(const char& /*v*/) { return "char"; } +template <> inline std::string name_of_type(const char& /*v*/) { return "char"; } -template <> inline std::string nameOfType(const short& /*v*/) { return "short"; } +template <> inline std::string name_of_type(const short& /*v*/) { return "short"; } -template <> inline std::string nameOfType(const int& /*v*/) { return "int"; } +template <> inline std::string name_of_type(const int& /*v*/) { return "int"; } -template <> inline std::string nameOfType(const long& /*v*/) { return "long"; } +template <> inline std::string name_of_type(const long& /*v*/) { return "long"; } -template <> inline std::string nameOfType(const long long& /*v*/) { return "long long"; } +template <> inline std::string name_of_type(const long long& /*v*/) { return "long long"; } // because signed char != char -template <> inline std::string nameOfType(const signed char& /*v*/) { return "signed char"; } +template <> inline std::string name_of_type(const signed char& /*v*/) { return "signed char"; } -template <> inline std::string nameOfType(const unsigned char& /*v*/) { return "unsigned char"; } +template <> inline std::string name_of_type(const unsigned char& /*v*/) { return "unsigned char"; } -template <> inline std::string nameOfType(const unsigned short& /*v*/) { return "unsigned short"; } +template <> inline std::string name_of_type(const unsigned short& /*v*/) { return "unsigned short"; } -template <> inline std::string nameOfType(const unsigned int& /*v*/) { return "unsigned int"; } +template <> inline std::string name_of_type(const unsigned int& /*v*/) { return "unsigned int"; } -template <> inline std::string nameOfType(const unsigned long& /*v*/) { return "unsigned long"; } +template <> inline std::string name_of_type(const unsigned long& /*v*/) { return "unsigned long"; } -template <> inline std::string nameOfType(const unsigned long long& /*v*/) { return "unsigned long long"; } +template <> inline std::string name_of_type(const unsigned long long& /*v*/) { return "unsigned long long"; } -template <> inline std::string nameOfType(const float& /*v*/) { return "float"; } +template <> inline std::string name_of_type(const float& /*v*/) { return "float"; } -template <> inline std::string nameOfType(const double& /*v*/) { return "double"; } +template <> inline std::string name_of_type(const double& /*v*/) { return "double"; } -template <> inline std::string nameOfType(const std::string& /*v*/) { return "std::string"; } +template <> inline std::string name_of_type(const std::string& /*v*/) { return "std::string"; } -template inline std::string nameOfType(const std::vector& /*v*/) { return std::string("std::vector<") + nameOfType(T()) + std::string(">"); } -template inline std::string nameOfType(const std::list& /*v*/) { return "std::list<"+ nameOfType(T()) + std::string(">"); } +template inline std::string name_of_type(const std::vector& /*v*/) { return std::string("std::vector<") + name_of_type(T()) + std::string(">"); } +template inline std::string name_of_type(const std::list& /*v*/) { return "std::list<"+ name_of_type(T()) + std::string(">"); } /** - * @brief add CGoGNnameOfType member to a class + * @brief add CGoGNname_of_type member to a class * * If the class that you want to use as attribute is not basic type nor std::list/std::vector, * use AddTypeName instead of T. - * If you develop the class T, just add as public member: static std::string CGoGNnameOfType() { return "type_name_you_develop"; } + * If you develop the class T, just add as public member: static std::string CGoGNname_of_type() { return "type_name_you_develop"; } */ template class AddTypeName : public T { public: - static std::string CGoGNnameOfType() { return "UNKNOWN"; } + + static std::string CGoGN_name_of_type() { return "UNKNOWN"; } }; } // namespace cgogn diff --git a/cgogn/core/container/chunk_array.h b/cgogn/core/container/chunk_array.h index 5b6331a4..1f97db9e 100644 --- a/cgogn/core/container/chunk_array.h +++ b/cgogn/core/container/chunk_array.h @@ -78,7 +78,7 @@ class ChunkArray : public ChunkArrayGen return new ChunkArray(); } - bool isBooleanArray() const override + bool is_boolean_array() const override { return false; } @@ -86,7 +86,7 @@ class ChunkArray : public ChunkArrayGen /** * @brief add a chunk (T[CHUNKSIZE]) */ - void addChunk() override + void add_chunk() override { table_data_.emplace_back(new T[CHUNKSIZE]()); } @@ -95,12 +95,12 @@ class ChunkArray : public ChunkArrayGen * @brief set number of chunks * @param nbc number of chunks */ - void setNbChunks(unsigned int nbc) override + void set_nb_chunks(unsigned int nbc) override { if (nbc >= table_data_.size()) { for (std::size_t i= table_data_.size(); i * @brief get the number of chunks of the array * @return the number of chunks */ - unsigned int getNbChunks() const override + unsigned int get_nb_chunks() const override { return static_cast(table_data_.size()); } @@ -144,7 +144,7 @@ class ChunkArray : public ChunkArrayGen * @param byte_block_size filled with CHUNKSIZE*sizeof(T) * @return addr.size() */ - unsigned int getChunksPointers(std::vector& addr, unsigned int& byte_block_size) const override + unsigned int get_chunks_pointers(std::vector& addr, unsigned int& byte_block_size) const override { byte_block_size = CHUNKSIZE * sizeof(T); @@ -161,7 +161,7 @@ class ChunkArray : public ChunkArrayGen * @brief initialize an element (overwrite with T()) * @param id index of the element */ - void initElement(unsigned int id) override + void init_element(unsigned int id) override { table_data_[id / CHUNKSIZE][id % CHUNKSIZE] = T(); } @@ -171,7 +171,7 @@ class ChunkArray : public ChunkArrayGen * @param dst destination index * @param src source index */ - void copyElement(unsigned int dst, unsigned int src) override + void copy_element(unsigned int dst, unsigned int src) override { table_data_[dst / CHUNKSIZE][dst % CHUNKSIZE] = table_data_[src / CHUNKSIZE][src % CHUNKSIZE]; } @@ -181,7 +181,7 @@ class ChunkArray : public ChunkArrayGen * @param idx1 first element index * @param idx2 second element index */ - void swapElements(unsigned int idx1, unsigned int idx2) override + void swap_elements(unsigned int idx1, unsigned int idx2) override { std::swap(table_data_[idx1 / CHUNKSIZE][idx1 % CHUNKSIZE], table_data_[idx2 / CHUNKSIZE][idx2 % CHUNKSIZE] ); } @@ -245,7 +245,7 @@ class ChunkArray : public ChunkArrayGen void save(std::ostream& fs, unsigned int nb_lines) const override { - cgogn_assert(nb_lines / CHUNKSIZE <= getNbChunks()); + cgogn_assert(nb_lines / CHUNKSIZE <= get_nb_chunks()); serialization::save(fs, &nb_lines, 1); @@ -253,7 +253,7 @@ class ChunkArray : public ChunkArrayGen if (nb_lines == 0) return; - unsigned int nbc = getNbChunks() - 1u; + unsigned int nbc = get_nb_chunks() - 1u; // save data chunks except last for(unsigned int i = 0u; i < nbc; ++i) @@ -279,7 +279,7 @@ class ChunkArray : public ChunkArrayGen if (nb_lines % CHUNKSIZE != 0) nbc++; - this->setNbChunks(nbc); + this->set_nb_chunks(nbc); // load data chunks except last nbc--; @@ -320,7 +320,7 @@ class ChunkArray : public ChunkArrayGen * @param i index of element to set * @param v value */ - inline void setValue(unsigned int i, const T& v) + inline void set_value(unsigned int i, const T& v) { cgogn_assert(i / CHUNKSIZE < table_data_.size()); table_data_[i / CHUNKSIZE][i % CHUNKSIZE] = v; @@ -365,7 +365,7 @@ class ChunkArray : public ChunkArrayGen return new ChunkArray(); } - bool isBooleanArray() const override + bool is_boolean_array() const override { return true; } @@ -373,7 +373,7 @@ class ChunkArray : public ChunkArrayGen /** * @brief add a chunk (T[CHUNKSIZE/32]) */ - void addChunk() override + void add_chunk() override { // adding the empty parentheses for default-initialization table_data_.push_back(new unsigned int[CHUNKSIZE/32u]()); @@ -383,12 +383,12 @@ class ChunkArray : public ChunkArrayGen * @brief set number of chunks * @param nbc number of chunks */ - void setNbChunks(unsigned int nbc) override + void set_nb_chunks(unsigned int nbc) override { if (nbc >= table_data_.size()) { for (std::size_t i = table_data_.size(); i < nbc; ++i) - addChunk(); + add_chunk(); } else { @@ -402,7 +402,7 @@ class ChunkArray : public ChunkArrayGen * @brief get the number of chunks of the array * @return the number of chunks */ - unsigned int getNbChunks() const override + unsigned int get_nb_chunks() const override { return static_cast(table_data_.size()); } @@ -432,7 +432,7 @@ class ChunkArray : public ChunkArrayGen * @param byte_block_size filled with CHUNKSIZE*sizeof(T) * @return addr.size() */ - inline unsigned int getChunksPointers(std::vector& addr, unsigned int& byte_block_size) const override + inline unsigned int get_chunks_pointers(std::vector& addr, unsigned int& byte_block_size) const override { byte_block_size = CHUNKSIZE / 8u; @@ -449,9 +449,9 @@ class ChunkArray : public ChunkArrayGen * @brief initialize an element (overwrite with T()) * @param id index of the element */ - inline void initElement(unsigned int id) override + inline void init_element(unsigned int id) override { - setFalse(id); + set_false(id); } /** @@ -459,9 +459,9 @@ class ChunkArray : public ChunkArrayGen * @param dst destination index * @param src source index */ - inline void copyElement(unsigned int dst, unsigned int src) override + inline void copy_element(unsigned int dst, unsigned int src) override { - setValue(dst, this->operator[](src)); + set_value(dst, this->operator[](src)); } /** @@ -469,11 +469,11 @@ class ChunkArray : public ChunkArrayGen * @param idx1 first element index * @param idx2 second element index */ - inline void swapElements(unsigned int idx1, unsigned int idx2) override + inline void swap_elements(unsigned int idx1, unsigned int idx2) override { bool data = this->operator[](idx1); - setValue(idx1, this->operator[](idx2)); - setValue(idx2, data); + set_value(idx1, this->operator[](idx2)); + set_value(idx2, data); } void save(std::ostream& fs, unsigned int nb_lines) const override @@ -492,7 +492,7 @@ class ChunkArray : public ChunkArrayGen if (nb_lines == 0u) return; - const unsigned int nbc = getNbChunks() - 1u; + const unsigned int nbc = get_nb_chunks() - 1u; // save data chunks except last for(unsigned int i = 0u; i < nbc; ++i) { @@ -519,7 +519,7 @@ class ChunkArray : public ChunkArrayGen if (nb_lines % CHUNKSIZE != 0u) nbc++; - this->setNbChunks(nbc); + this->set_nb_chunks(nbc); // load data chunks except last nbc--; @@ -551,7 +551,7 @@ class ChunkArray : public ChunkArrayGen return (table_data_[jj][x] & mask) != 0u; } - inline void setFalse(unsigned int i) + inline void set_false(unsigned int i) { const unsigned int jj = i / CHUNKSIZE; cgogn_assert(jj < table_data_.size()); @@ -562,7 +562,7 @@ class ChunkArray : public ChunkArrayGen table_data_[jj][x] &= ~mask; } - inline void setTrue(unsigned int i) + inline void set_true(unsigned int i) { const unsigned int jj = i / CHUNKSIZE; cgogn_assert(jj < table_data_.size()); @@ -573,7 +573,7 @@ class ChunkArray : public ChunkArrayGen table_data_[jj][x] |= mask; } - inline void setValue(unsigned int i, bool b) + inline void set_value(unsigned int i, bool b) { const unsigned int jj = i / CHUNKSIZE; cgogn_assert(jj < table_data_.size()); @@ -594,7 +594,7 @@ class ChunkArray : public ChunkArrayGen * This version overwrites element AND SOME OF HIS NEIGHBOURS with 0 * Use only if final goal is to set all array to 0 (MarkerStore) */ - inline void setFalse_byte(unsigned int i) + inline void set_false_byte(unsigned int i) { const unsigned int jj = i / CHUNKSIZE; cgogn_assert(jj < table_data_.size()); @@ -602,7 +602,7 @@ class ChunkArray : public ChunkArrayGen table_data_[jj][j] = 0u; } - inline void allFalse() + inline void all_false() { for (auto ptr : table_data_) { @@ -611,7 +611,7 @@ class ChunkArray : public ChunkArrayGen } } -// inline void allTrue() +// inline void all_true() // { // for (auto ptr : table_data_) // { diff --git a/cgogn/core/container/chunk_array_container.h b/cgogn/core/container/chunk_array_container.h index e4a30aca..c2b7d067 100644 --- a/cgogn/core/container/chunk_array_container.h +++ b/cgogn/core/container/chunk_array_container.h @@ -51,7 +51,7 @@ class CGOGN_CORE_API ContainerBrowser virtual unsigned int begin() const = 0; virtual unsigned int end() const = 0; virtual void next(unsigned int &it) const = 0; - virtual void nextPrimitive(unsigned int &it, unsigned int primSz) const = 0; + virtual void next_primitive(unsigned int &it, unsigned int primSz) const = 0; virtual void enable() = 0; virtual void disable() = 0; virtual ~ContainerBrowser(); @@ -65,10 +65,10 @@ class ContainerStandardBrowser : public ContainerBrowser public: ContainerStandardBrowser(const CONTAINER* cac) : cac_(cac) {} - virtual unsigned int begin() const { return cac_->realBegin(); } - virtual unsigned int end() const { return cac_->realEnd(); } - virtual void next(unsigned int &it) const { cac_->realNext(it); } - virtual void nextPrimitive(unsigned int &it, unsigned int primSz) const { cac_->realNextPrimitive(it,primSz); } + virtual unsigned int begin() const { return cac_->real_begin(); } + virtual unsigned int end() const { return cac_->real_end(); } + virtual void next(unsigned int &it) const { cac_->real_next(it); } + virtual void next_primitive(unsigned int &it, unsigned int primSz) const { cac_->real_next_primitive(it,primSz); } virtual void enable() {} virtual void disable() {} virtual ~ContainerStandardBrowser() {} @@ -78,8 +78,6 @@ class ContainerStandardBrowser : public ContainerBrowser /** * @brief class that manage the storage of several ChunkArray * @tparam CHUNKSIZE chunk size for ChunkArray - * @detail - * */ template class ChunkArrayContainer @@ -140,7 +138,7 @@ class ChunkArrayContainer * @param attribName name of ChunkArray * @return the index in table */ - unsigned int getArrayIndex(const std::string& attribute_name) const + unsigned int get_array_index(const std::string& attribute_name) const { for (unsigned int i = 0; i != names_.size(); ++i) { @@ -156,7 +154,7 @@ class ChunkArrayContainer * @param ptr of ChunkArray * @return the index in table */ - unsigned int getArrayIndex(const ChunkArrayGen* ptr) const + unsigned int get_array_index(const ChunkArrayGen* ptr) const { for (unsigned int i = 0u; i != table_arrays_.size(); ++i) { @@ -171,10 +169,10 @@ class ChunkArrayContainer * @param attribName name of attribute to remove * @return true if attribute exist and has been removed */ - bool removeAttribute(unsigned int index) + bool remove_attribute(unsigned int index) { // store ptr for using it before delete - ChunkArrayGen* ptrToDel = table_arrays_[index]; + ChunkArrayGen* ptr_to_del = table_arrays_[index]; // in case of Marker attribute, keep Marker attributes first ! if (index < nb_marker_attribs_) @@ -202,7 +200,7 @@ class ChunkArrayContainer names_.pop_back(); type_names_.pop_back(); - delete ptrToDel; + delete ptr_to_del; return true; } @@ -216,7 +214,7 @@ class ChunkArrayContainer nb_used_lines_(0u), nb_max_lines_(0u), nb_marker_attribs_(0), - std_browser_(make_unique< ContainerStandardBrowser> >(this)) + std_browser_(make_unique< ContainerStandardBrowser > >(this)) { current_browser_= std_browser_.get(); } @@ -233,7 +231,7 @@ class ChunkArrayContainer { if (current_browser_ != std_browser_.get()) delete current_browser_; - for (auto ptr: table_arrays_) + for (auto ptr : table_arrays_) delete ptr; } @@ -244,11 +242,10 @@ class ChunkArrayContainer * @return pointer on attribute ChunkArray */ template - ChunkArray* getAttribute(const std::string& attribute_name) + ChunkArray* get_attribute(const std::string& attribute_name) { - // first check if attribute already exist - unsigned int index = getArrayIndex(attribute_name); + unsigned int index = get_array_index(attribute_name); if (index == UNKNOWN) { std::cerr << "attribute " << attribute_name << " not found." << std::endl; @@ -265,12 +262,12 @@ class ChunkArrayContainer * @return pointer on created attribute ChunkArray */ template - ChunkArray* addAttribute(const std::string& attribute_name) + ChunkArray* add_attribute(const std::string& attribute_name) { cgogn_assert(attribute_name.size() != 0); // first check if attribute already exist - unsigned int index = getArrayIndex(attribute_name); + unsigned int index = get_array_index(attribute_name); if (index != UNKNOWN) { std::cerr << "attribute " << attribute_name << " already exists.." << std::endl; @@ -278,12 +275,12 @@ class ChunkArrayContainer } // create the new attribute - const std::string& typeName = nameOfType(T()); + const std::string& typeName = name_of_type(T()); ChunkArray* carr = new ChunkArray(); - ChunkArrayFactory::template registerCA(); + ChunkArrayFactory::template register_CA(); // reserve memory - carr->setNbChunks(refs_.getNbChunks()); + carr->set_nb_chunks(refs_.get_nb_chunks()); // store pointer, name & typename. table_arrays_.push_back(carr); @@ -298,9 +295,9 @@ class ChunkArrayContainer * @param attribute_name name of marker attribute * @return pointer on created ChunkArray */ - ChunkArray* addMarkerAttribute(const std::string& attribute_name) + ChunkArray* add_marker_attribute(const std::string& attribute_name) { - ChunkArray* ptr = addAttribute(attribute_name); + ChunkArray* ptr = add_attribute(attribute_name); if (table_arrays_.size() > nb_marker_attribs_) { @@ -322,9 +319,9 @@ class ChunkArrayContainer * @param attribute_name name of attribute to remove * @return true if attribute exists and has been removed */ - bool removeAttribute(const std::string& attribute_name) + bool remove_attribute(const std::string& attribute_name) { - unsigned int index = getArrayIndex(attribute_name); + unsigned int index = get_array_index(attribute_name); if (index == UNKNOWN) { @@ -332,7 +329,7 @@ class ChunkArrayContainer return false; } - removeAttribute(index); + remove_attribute(index); return true; } @@ -342,9 +339,9 @@ class ChunkArrayContainer * @param ptr ChunkArray pointer to the attribute to remove * @return true if attribute exists and has been removed */ - bool removeAttribute(const ChunkArrayGen* ptr) + bool remove_attribute(const ChunkArrayGen* ptr) { - unsigned int index = getArrayIndex(ptr); + unsigned int index = get_array_index(ptr); if (index == UNKNOWN) { @@ -352,7 +349,7 @@ class ChunkArrayContainer return false; } - removeAttribute(index); + remove_attribute(index); return true; } @@ -361,20 +358,20 @@ class ChunkArrayContainer * @brief Number of attributes of the container * @return number of attributes */ - unsigned int getNbAttributes() const + unsigned int get_nb_attributes() const { return table_arrays_.size(); } /** * @brief get a chunk_array - * @param attribName name of the array + * @param attribute_name name of the array * @return pointer on typed chunk_array */ template - ChunkArray* getDataArray(const std::string& attribute_name) + ChunkArray* get_data_array(const std::string& attribute_name) { - unsigned int index = getArrayIndex(attribute_name); + unsigned int index = get_array_index(attribute_name); if(index == UNKNOWN) return nullptr; @@ -387,12 +384,12 @@ class ChunkArrayContainer /** * @brief get a chunk_array - * @param attribName name of the array + * @param attribute_name name of the array * @return pointer on virtual chunk_array */ - ChunkArrayGen* getVirtualDataArray(const std::string& attribute_name) + ChunkArrayGen* get_virtual_data_array(const std::string& attribute_name) { - unsigned int index = getArrayIndex(attribute_name); + unsigned int index = get_array_index(attribute_name); if(index == UNKNOWN) return nullptr; @@ -418,17 +415,17 @@ class ChunkArrayContainer } /** - * @brief setCurrentBrowser + * @brief set the current container browser * @param browser, pointer to a heap-allocated ContainerBrowser */ - inline void setCurrentBrowser(ContainerBrowser* browser) + inline void set_current_browser(ContainerBrowser* browser) { if (current_browser_ != std_browser_.get()) delete current_browser_; current_browser_ = browser; } - inline void setStandardBrowser() + inline void set_standard_browser() { if (current_browser_ != std_browser_.get()) delete current_browser_; @@ -466,16 +463,16 @@ class ChunkArrayContainer * @brief next primitive: it <- next primitive used index in the container (eq to PRIMSIZE next) * @param it index to "increment" */ - inline void nextPrimitive(unsigned int& it, unsigned int prim_size) const + inline void next_primitive(unsigned int& it, unsigned int prim_size) const { - current_browser_->nextPrimitive(it, prim_size); + current_browser_->next_primitive(it, prim_size); } /** * @brief begin of container without browser * @return the real index of the first used line of the container */ - inline unsigned int realBegin() const + inline unsigned int real_begin() const { unsigned int it = 0u; while ((it < nb_max_lines_) && (!used(it))) @@ -487,7 +484,7 @@ class ChunkArrayContainer * @brief end of container without browser * @return the real index after the last used line of the container */ - inline unsigned int realEnd() const + inline unsigned int real_end() const { return nb_max_lines_; } @@ -496,7 +493,7 @@ class ChunkArrayContainer * @brief next without browser * @param it */ - inline void realNext(unsigned int& it) const + inline void real_next(unsigned int& it) const { do { @@ -508,7 +505,7 @@ class ChunkArrayContainer * @brief next primitive without browser * @param it */ - inline void realNextPrimitive(unsigned int &it, unsigned int prim_size) const + inline void real_next_primitive(unsigned int &it, unsigned int prim_size) const { do { @@ -520,7 +517,7 @@ class ChunkArrayContainer * @brief reverse begin of container without browser * @return the real index of the first used line of the container in reverse order */ - unsigned int realRBegin() const + unsigned int real_rbegin() const { unsigned int it = nb_max_lines_- 1u; while ((it != 0xffffffff) && (!used(it))) @@ -532,7 +529,7 @@ class ChunkArrayContainer * @brief reverse end of container without browser * @return the real index before the last used line of the container in reverse order */ - unsigned int realREnd() const + unsigned int real_rend() const { return 0xffffffff; // -1 } @@ -541,7 +538,7 @@ class ChunkArrayContainer * @brief reverse next without browser * @param it */ - void realRNext(unsigned int &it) const + void real_rnext(unsigned int &it) const { do { @@ -583,7 +580,7 @@ class ChunkArrayContainer */ float fragmentation() const { - return float(size()) / float(realEnd()); + return float(size()) / float(real_end()); } /** @@ -594,9 +591,9 @@ class ChunkArrayContainer void compact(std::vector& map_old_new) { map_old_new.clear(); - map_old_new.resize(realEnd(), 0xffffffff); + map_old_new.resize(real_end(), 0xffffffff); - unsigned int up = realRBegin(); + unsigned int up = real_rbegin(); unsigned int down = 0u; while (down < up) @@ -607,8 +604,8 @@ class ChunkArrayContainer { unsigned rdown = down + PRIMSIZE-1u - i; map_old_new[up] = rdown; - copyLine(rdown, up); - realRNext(up); + copy_line(rdown, up); + real_rnext(up); } down += PRIMSIZE; } @@ -621,8 +618,8 @@ class ChunkArrayContainer // free unused memory blocks unsigned int new_nb_blocks = nb_max_lines_/CHUNKSIZE + 1u; for (auto arr : table_arrays_) - arr->setNbChunks(new_nb_blocks); - refs_.setNbChunks(new_nb_blocks); + arr->set_nb_chunks(new_nb_blocks); + refs_.set_nb_chunks(new_nb_blocks); // clear holes holes_stack_.clear(); @@ -647,7 +644,7 @@ class ChunkArrayContainer * @return index of the first line of group */ template - unsigned int insertLines() + unsigned int insert_lines() { unsigned int index; @@ -656,11 +653,11 @@ class ChunkArrayContainer index = nb_max_lines_; nb_max_lines_ += PRIMSIZE; - if (nb_max_lines_%CHUNKSIZE <= PRIMSIZE) // prim on next block ? -> add block to C.A. + if (nb_max_lines_ % CHUNKSIZE <= PRIMSIZE) // prim on next block ? -> add block to C.A. { for (auto arr : table_arrays_) - arr->addChunk(); - refs_.addChunk(); + arr->add_chunk(); + refs_.add_chunk(); } } else @@ -671,7 +668,7 @@ class ChunkArrayContainer // mark lines as used for(unsigned int i = 0u; i < PRIMSIZE; ++i) - refs_.setValue(index + i, 1u); // do not use [] in case of refs_ is bool + refs_.set_value(index + i, 1u); // do not use [] in case of refs_ is bool nb_used_lines_ += PRIMSIZE; @@ -683,7 +680,7 @@ class ChunkArrayContainer * @param index index of one line of group to remove */ template - void removeLines(unsigned int index) + void remove_lines(unsigned int index) { unsigned int begin_prim_idx = (index/PRIMSIZE) * PRIMSIZE; @@ -693,7 +690,7 @@ class ChunkArrayContainer // mark lines as unused for(unsigned int i = 0u; i < PRIMSIZE; ++i) - refs_.setValue(begin_prim_idx++, 0u); // do not use [] in case of refs_ is bool + refs_.set_value(begin_prim_idx++, 0u); // do not use [] in case of refs_ is bool nb_used_lines_ -= PRIMSIZE; } @@ -702,21 +699,21 @@ class ChunkArrayContainer * @brief initialize a line of the container (an element of each attribute) * @param index line index */ - void initLine(unsigned int index) + void init_line(unsigned int index) { cgogn_message_assert(used(index), "initLine only with allocated lines"); - for (auto ptrAtt : table_arrays_) - // if (ptrAtt != nullptr) never null ! - ptrAtt->initElement(index); + for (auto ptr : table_arrays_) + // if (ptr != nullptr) never null ! + ptr->init_element(index); } - void initMarkersOfLine(unsigned int index) + void init_markers_of_line(unsigned int index) { cgogn_message_assert(used(index), "initMarkersOfLine only with allocated lines"); for (unsigned int i = 0u; i < nb_marker_attribs_; ++i) - table_arrays_[i]->initElement(index); + table_arrays_[i]->init_element(index); } /** @@ -724,11 +721,11 @@ class ChunkArrayContainer * @param dstIndex destination * @param srcIndex source */ - void copyLine(unsigned int dst, unsigned int src) + void copy_line(unsigned int dst, unsigned int src) { - for (auto ptrAtt : table_arrays_) - if (ptrAtt != nullptr) - ptrAtt->copyElement(dst, src); + for (auto ptr : table_arrays_) + if (ptr != nullptr) + ptr->copy_element(dst, src); refs_[dst] = refs_[src]; } @@ -736,7 +733,7 @@ class ChunkArrayContainer * @brief increment the reference counter of the given line (only for PRIMSIZE==1) * @param index index of the line */ - void refLine(unsigned int index) + void ref_line(unsigned int index) { // static_assert(PRIMSIZE == 1u, "refLine with container where PRIMSIZE!=1"); refs_[index]++; @@ -747,7 +744,7 @@ class ChunkArrayContainer * @param index index of the line * @return true if the line was removed */ - bool unrefLine(unsigned int index) + bool unref_line(unsigned int index) { // static_assert(PRIMSIZE == 1u, "unrefLine with container where PRIMSIZE!=1"); refs_[index]--; @@ -766,7 +763,7 @@ class ChunkArrayContainer * @param index index of the line * @return number of references of the line */ - T_REF getNbRefs(unsigned int index) const + T_REF get_nb_refs(unsigned int index) const { // static_assert(PRIMSIZE == 1u, "getNbRefs with container where PRIMSIZE!=1"); return refs_[index]; diff --git a/cgogn/core/container/chunk_array_factory.h b/cgogn/core/container/chunk_array_factory.h index 16b25773..d4a07852 100644 --- a/cgogn/core/container/chunk_array_factory.h +++ b/cgogn/core/container/chunk_array_factory.h @@ -41,7 +41,7 @@ class ChunkArrayFactory typedef std::unique_ptr< ChunkArrayGen > ChunkArrayGenPtr; typedef std::map Map; - static Map mapCA_; + static Map map_CA_; /** * @brief register a type @@ -49,11 +49,11 @@ class ChunkArrayFactory * @param obj a ptr on object (new ChunkArray<32,int> for example) ptr will be deleted by clean method */ template - static void registerCA() + static void register_CA() { - std::string&& keyType(nameOfType(T())); - if(mapCA_.find(keyType) == mapCA_.end()) - mapCA_[std::move(keyType)] = make_unique>(); + std::string&& keyType(name_of_type(T())); + if(map_CA_.find(keyType) == map_CA_.end()) + map_CA_[std::move(keyType)] = make_unique>(); } /** @@ -64,9 +64,9 @@ class ChunkArrayFactory static ChunkArrayGen* create(const std::string& keyType) { ChunkArrayGen* tmp = nullptr; - typename Map::const_iterator it = mapCA_.find(keyType); + typename Map::const_iterator it = map_CA_.find(keyType); - if(it != mapCA_.end()) + if(it != map_CA_.end()) { tmp = (it->second)->clone(); } @@ -78,7 +78,7 @@ class ChunkArrayFactory }; template -typename ChunkArrayFactory::Map ChunkArrayFactory::mapCA_= typename ChunkArrayFactory::Map(); +typename ChunkArrayFactory::Map ChunkArrayFactory::map_CA_= typename ChunkArrayFactory::Map(); } // namespace cgogn diff --git a/cgogn/core/container/chunk_array_gen.h b/cgogn/core/container/chunk_array_gen.h index b6d43eac..da17c6f8 100644 --- a/cgogn/core/container/chunk_array_gen.h +++ b/cgogn/core/container/chunk_array_gen.h @@ -56,24 +56,24 @@ class ChunkArrayGen */ virtual ChunkArrayGen* clone() const = 0; - virtual bool isBooleanArray() const = 0; + virtual bool is_boolean_array() const = 0; /** * @brief add a chunk (T[CHUNKSIZE]) */ - virtual void addChunk() = 0; + virtual void add_chunk() = 0; /** * @brief set number of chunks * @param nbc number of chunks */ - virtual void setNbChunks(unsigned int nbb) = 0; + virtual void set_nb_chunks(unsigned int nbb) = 0; /** * @brief get the number of chunks of the array * @return the number of chunks */ - virtual unsigned int getNbChunks() const = 0; + virtual unsigned int get_nb_chunks() const = 0; /** * @brief get the capacity of the array @@ -92,27 +92,27 @@ class ChunkArrayGen * @param byte_block_size filled with CHUNKSIZE*sizeof(T) * @return addr.size() */ - virtual unsigned int getChunksPointers(std::vector& addr, unsigned int& byte_block_size) const = 0; + virtual unsigned int get_chunks_pointers(std::vector& addr, unsigned int& byte_block_size) const = 0; /** * @brief initialize an element of the array (overwrite with T()) * @param id index of the element */ - virtual void initElement(unsigned int id) = 0; + virtual void init_element(unsigned int id) = 0; /** * @brief copy an element to another one * @param dst destination element index * @param src source element index */ - virtual void copyElement(unsigned int dst, unsigned int src) = 0; + virtual void copy_element(unsigned int dst, unsigned int src) = 0; /** * @brief swap two elements * @param idx1 first element index * @param idx2 second element index */ - virtual void swapElements(unsigned int idx1, unsigned int idx2) = 0; + virtual void swap_elements(unsigned int idx1, unsigned int idx2) = 0; /** * @brief save @@ -129,10 +129,6 @@ class ChunkArrayGen virtual bool load(std::istream& fs) = 0; }; -//template -//ChunkArrayGen::~ChunkArrayGen() -//{} - } // namespace cgogn #endif // CORE_CONTAINER_CHUNK_ARRAY_GEN_H_ diff --git a/cgogn/core/container/chunk_stack.h b/cgogn/core/container/chunk_stack.h index daa7ae45..94ad6730 100644 --- a/cgogn/core/container/chunk_stack.h +++ b/cgogn/core/container/chunk_stack.h @@ -75,7 +75,7 @@ class ChunkStack : public ChunkArray unsigned int blkId = stack_size_ / CHUNKSIZE; if (blkId >= this->table_data_.size()) - this->addChunk(); + this->add_chunk(); this->table_data_[blkId][offset] = val; } diff --git a/cgogn/core/map/attribute_handler.h b/cgogn/core/map/attribute_handler.h index 5e9deebf..b9606b40 100644 --- a/cgogn/core/map/attribute_handler.h +++ b/cgogn/core/map/attribute_handler.h @@ -54,8 +54,8 @@ class AttributeHandlerGen public: inline AttributeHandlerGen(MapData* const map) : - map_(map) - ,valid_(false) + map_(map), + valid_(false) {} /** @@ -63,8 +63,8 @@ class AttributeHandlerGen * @param atthg */ inline AttributeHandlerGen(const AttributeHandlerGen& atthg) : - map_(atthg.map_) - ,valid_(atthg.valid_) + map_(atthg.map_), + valid_(atthg.valid_) {} /** @@ -72,8 +72,8 @@ class AttributeHandlerGen * @param atthg */ inline AttributeHandlerGen(AttributeHandlerGen&& atthg) CGOGN_NOEXCEPT : - map_(atthg.map_) - ,valid_(atthg.valid_) + map_(atthg.map_), + valid_(atthg.valid_) {} /** @@ -103,15 +103,15 @@ class AttributeHandlerGen virtual ~AttributeHandlerGen() {} - inline bool isValid() const { return valid_; } + inline bool is_valid() const { return valid_; } - virtual unsigned int getOrbit() const = 0; + virtual unsigned int get_orbit() const = 0; protected: - inline void setInvalid() { valid_ = false ; } + inline void set_invalid() { valid_ = false ; } - inline void setValid() { valid_ = true ; } + inline void set_valid() { valid_ = true ; } }; @@ -134,12 +134,12 @@ class AttributeHandlerOrbit : public AttributeHandlerGen public: inline AttributeHandlerOrbit(MapData* const map) : - Inherit(map) - ,chunk_array_cont_(nullptr) + Inherit(map), + chunk_array_cont_(nullptr) { if (map != nullptr) { - chunk_array_cont_ = &(map->getAttributeContainer(ORBIT)); + chunk_array_cont_ = &(map->get_attribute_container(ORBIT)); } } @@ -148,8 +148,8 @@ class AttributeHandlerOrbit : public AttributeHandlerGen * @param attho */ inline AttributeHandlerOrbit(const AttributeHandlerOrbit< DATA_TRAITS, ORBIT >& attho) : - Inherit(attho) - ,chunk_array_cont_(attho.chunk_array_cont_) + Inherit(attho), + chunk_array_cont_(attho.chunk_array_cont_) {} /** @@ -157,8 +157,8 @@ class AttributeHandlerOrbit : public AttributeHandlerGen * @param attho */ inline AttributeHandlerOrbit(AttributeHandlerOrbit< DATA_TRAITS, ORBIT >&& attho) CGOGN_NOEXCEPT : - Inherit(std::move(attho)) - ,chunk_array_cont_(attho.chunk_array_cont_) + Inherit(std::move(attho)), + chunk_array_cont_(attho.chunk_array_cont_) {} /** @@ -168,7 +168,7 @@ class AttributeHandlerOrbit : public AttributeHandlerGen */ inline AttributeHandlerOrbit& operator=(const AttributeHandlerOrbit< DATA_TRAITS, ORBIT >& attho) { - Inherit::operator =(attho); + Inherit::operator=(attho); chunk_array_cont_ = attho.chunk_array_cont_; return *this; } @@ -179,13 +179,18 @@ class AttributeHandlerOrbit : public AttributeHandlerGen */ inline AttributeHandlerOrbit& operator=(AttributeHandlerOrbit< DATA_TRAITS, ORBIT >&& attho) { - Inherit::operator =(std::move(attho)); + Inherit::operator=(std::move(attho)); chunk_array_cont_ = attho.chunk_array_cont_; return *this; } - virtual unsigned int getOrbit() const override { return ORBIT; } - virtual ~AttributeHandlerOrbit() override {} + virtual unsigned int get_orbit() const override + { + return ORBIT; + } + + virtual ~AttributeHandlerOrbit() override + {} }; /** @@ -221,17 +226,15 @@ class AttributeHandler : public AttributeHandlerOrbit * @param m the map which belong attribute * @param attributeName name of attribute */ - AttributeHandler(MapData* const m, const std::string& attributeName) : + AttributeHandler(MapData* const m, const std::string& attribute_name) : Inherit(m) { cgogn_assert(this->chunk_array_cont_ != nullptr); - chunk_array_ = this->chunk_array_cont_->getAttribute(attributeName); + chunk_array_ = this->chunk_array_cont_->getAttribute(attribute_name); if (chunk_array_ == nullptr) - { - this->setInvalid(); - } else { - this->setValid(); - } + this->set_invalid(); + else + this->set_valid(); } AttributeHandler(MapData* const m, TChunkArray* const ca) : @@ -239,11 +242,9 @@ class AttributeHandler : public AttributeHandlerOrbit chunk_array_(ca) { if (chunk_array_ == nullptr) - { - this->setInvalid(); - } else { - this->setValid(); - } + this->set_invalid(); + else + this->set_valid(); } /** @@ -295,7 +296,7 @@ class AttributeHandler : public AttributeHandlerOrbit * \brief getDataVector * @return */ - TChunkArray const * getData() const + TChunkArray const* get_data() const { return chunk_array_; } @@ -307,8 +308,8 @@ class AttributeHandler : public AttributeHandlerOrbit */ inline T& operator[](Cell c) { - cgogn_message_assert(this->valid_, "Invalid AttributeHandler") ; - return chunk_array_->operator[]( this->map_->getEmbedding(c) ) ; + cgogn_message_assert(this->valid_, "Invalid AttributeHandler"); + return chunk_array_->operator[](this->map_->get_embedding(c)); } /** @@ -318,8 +319,8 @@ class AttributeHandler : public AttributeHandlerOrbit */ inline const T& operator[](Cell c) const { - cgogn_message_assert(this->valid_, "Invalid AttributeHandler") ; - return chunk_array_->operator[]( this->map_->getEmbedding(c) ) ; + cgogn_message_assert(this->valid_, "Invalid AttributeHandler"); + return chunk_array_->operator[](this->map_->get_embedding(c)); } /** @@ -329,8 +330,8 @@ class AttributeHandler : public AttributeHandlerOrbit */ inline T& operator[](unsigned int i) { - cgogn_message_assert(this->valid_, "Invalid AttributeHandler") ; - return chunk_array_->operator[](i) ; + cgogn_message_assert(this->valid_, "Invalid AttributeHandler"); + return chunk_array_->operator[](i); } /** @@ -340,8 +341,8 @@ class AttributeHandler : public AttributeHandlerOrbit */ inline const T& operator[](unsigned int i) const { - cgogn_message_assert(this->valid_, "Invalid AttributeHandler") ; - return chunk_array_->operator[](i) ; + cgogn_message_assert(this->valid_, "Invalid AttributeHandler"); + return chunk_array_->operator[](i); } @@ -392,7 +393,8 @@ class AttributeHandler : public AttributeHandlerOrbit unsigned int index_; inline iterator(AttributeHandler* ah, unsigned int i) : - ah_ptr_(ah), index_(i) + ah_ptr_(ah), + index_(i) {} inline iterator& operator++() diff --git a/cgogn/core/map/map1.h b/cgogn/core/map/map1.h index 497f0bf5..84d6d63a 100644 --- a/cgogn/core/map/map1.h +++ b/cgogn/core/map/map1.h @@ -59,8 +59,8 @@ class Map1 : public MapBase void init() { - ChunkArray* phi1 = this->topology_.template addAttribute("phi1"); - ChunkArray* phi_1 = this->topology_.template addAttribute("phi_1"); + ChunkArray* phi1 = this->topology_.template add_attribute("phi1"); + ChunkArray* phi_1 = this->topology_.template add_attribute("phi_1"); this->topo_relations_.push_back(phi1); this->topo_relations_.push_back(phi_1); } @@ -79,7 +79,7 @@ class Map1 : public MapBase * - It makes one cycle d->g->...->e->f->...->d * If e = g then insert e in the cycle of d : d->e->f->...->d */ - void phi1sew(Dart d, Dart e) + void phi1_sew(Dart d, Dart e) { Dart f = phi1(d); Dart g = phi1(e); @@ -95,7 +95,7 @@ class Map1 : public MapBase * - Before: d->e->f * - After: d->f and e->e */ - void phi1unsew(Dart d) + void phi1_unsew(Dart d) { Dart e = phi1(d); Dart f = phi1(e); @@ -143,10 +143,10 @@ class Map1 : public MapBase * \brief add a Dart in the map * @return the new Dart */ - inline Dart addDart() + inline Dart add_dart() { - unsigned int di = this->topology_.template insertLines<1>(); // insert a new dart line - this->topology_.initMarkersOfLine(di); + unsigned int di = this->topology_.template insert_lines<1>(); // insert a new dart line + this->topology_.init_markers_of_line(di); for(unsigned int i = 0; i < NB_ORBITS; ++i) { @@ -156,8 +156,8 @@ class Map1 : public MapBase Dart d(di); - for (auto relPtr : this->topo_relations_) - (*relPtr)[di] = d; + for (auto ptr : this->topo_relations_) + (*ptr)[di] = d; return d; } @@ -186,15 +186,15 @@ class Map1 : public MapBase */ Dart cut_edge(Dart d) { - Dart e = this->newDart(); // Create a new dart - phi1sew(d, e); // Insert dart e between d and phi1(d) + Dart e = this->new_dart(); // Create a new dart + phi1_sew(d, e); // Insert dart e between d and phi1(d) // TODO: doit on traiter les marker de bord 2/3 dans Map1 - if (this->template isBoundaryMarked<2>(d)) - this->template boundaryMark<2>(e); + if (this->template is_boundary_marked<2>(d)) + this->template boundary_mark<2>(e); - if (this->template isBoundaryMarked<3>(d)) - this->template boundaryMark<3>(e); + if (this->template is_boundary_marked<3>(d)) + this->template boundary_mark<3>(e); return e; } @@ -207,8 +207,8 @@ class Map1 : public MapBase void uncut_edge(Dart d) { Dart d1 = phi1(d); - phi1unsew(d); // Dart d is linked to the successor of its successor - this->deleteDart(d1); // Dart d1 is erased + phi1_unsew(d); // Dart d is linked to the successor of its successor + this->delete_dart(d1); // Dart d1 is erased } /** diff --git a/cgogn/core/map/map2.h b/cgogn/core/map/map2.h index 2570c752..5baaee62 100644 --- a/cgogn/core/map/map2.h +++ b/cgogn/core/map/map2.h @@ -55,7 +55,7 @@ class Map2 : public Map1 void init() { - ChunkArray* phi2 = this->topology_.template addAttribute("phi2"); + ChunkArray* phi2 = this->topology_.template add_attribute("phi2"); this->topo_relations_.push_back(phi2); } @@ -69,7 +69,7 @@ class Map2 : public Map1 * - Before: d->d and e->e * - After: d->e and e->d */ - void phi2sew(Dart d, Dart e) + void phi2_sew(Dart d, Dart e) { cgogn_assert(phi2(d) == d); cgogn_assert(phi2(e) == e); @@ -83,7 +83,7 @@ class Map2 : public Map1 * - Before: d->e and e->d * - After: d->d and e->e */ - void phi2unsew(Dart d) + void phi2_unsew(Dart d) { Dart e = phi2(d) ; (*(this->topo_relations_[2]))[d.index] = d; @@ -148,14 +148,14 @@ class Map2 : public Map1 { DartMarkerStore marker(*this); // get a marker - std::vector* visited_faces = dart_buffers_thread->getBuffer(); + std::vector* visited_faces = dart_buffers_thread->get_buffer(); visited_faces->push_back(d); // Start with the face of d // For every face added to the list for(unsigned int i = 0; i < visited_faces->size(); ++i) { - if (!marker.isMarked((*visited_faces)[i])) // Face has not been visited yet + if (!marker.is_marked((*visited_faces)[i])) // Face has not been visited yet { // Apply functor to the darts of the face Map2::foreach_dart_of_face((*visited_faces)[i], f); @@ -167,14 +167,14 @@ class Map2 : public Map1 { marker.mark(e); // Mark Dart adj = phi2(e); // Get adjacent face - if (!marker.isMarked(adj)) + if (!marker.is_marked(adj)) visited_faces->push_back(adj); // Add it e = this->phi1(e); } while(e != (*visited_faces)[i]); } } - dart_buffers_thread->releaseBuffer(visited_faces); + dart_buffers_thread->release_buffer(visited_faces); } template diff --git a/cgogn/core/map/map_base.h b/cgogn/core/map/map_base.h index 57aba92e..476cd9f2 100644 --- a/cgogn/core/map/map_base.h +++ b/cgogn/core/map/map_base.h @@ -62,19 +62,19 @@ class MapBase : public MapBaseData * @return a handler to the created attribute */ template - inline AttributeHandler addAttribute(const std::string& attribute_name = "") + inline AttributeHandler add_attribute(const std::string& attribute_name = "") { if (this->embeddings_[ORBIT] == nullptr) { std::ostringstream oss; - oss << "EMB_" << orbitName(ORBIT); - ChunkArray* idx = this->topology_.template addAttribute(oss.str()); + oss << "EMB_" << orbit_name(ORBIT); + ChunkArray* idx = this->topology_.template add_attribute(oss.str()); this->embeddings_[ORBIT] = idx; for (unsigned int i = this->topology_.begin(); i != this->topology_.end(); this->topology_.next(i)) (*idx)[i] = EMBNULL; } - ChunkArray* ca = this->attributes_[ORBIT].template addAttribute(attribute_name); + ChunkArray* ca = this->attributes_[ORBIT].template add_attribute(attribute_name); return AttributeHandler(this, ca); } @@ -84,16 +84,16 @@ class MapBase : public MapBaseData * @return true if remove succeed else false */ template - inline bool removeAttribute(AttributeHandler& ah) + inline bool remove_attribute(AttributeHandler& ah) { ChunkArray* ca = ah.getData(); - if (this->attributes_[ORBIT].removeAttribute(ca)) + if (this->attributes_[ORBIT].remove_attribute(ca)) { typedef typename std::multimap*, AttributeHandlerGen*>::iterator IT; std::pair bounds = attribute_handlers_.equal_range(ca); for(IT i = bounds.first; i != bounds.second; ++i) - (*i).second->setInvalid(); + (*i).second->set_invalid(); attribute_handlers_.erase(bounds.first, bounds.second); return true; } @@ -106,9 +106,9 @@ class MapBase : public MapBaseData * @return an AttributeHandler */ template - inline AttributeHandler< T, ORBIT> getAttribute(const std::string& attribute_name) + inline AttributeHandler< T, ORBIT> get_attribute(const std::string& attribute_name) { - ChunkArray* ca = this->attributes_[ORBIT].template getAttribute(attribute_name); + ChunkArray* ca = this->attributes_[ORBIT].template get_attribute(attribute_name); return AttributeHandler(this, ca); } diff --git a/cgogn/core/map/map_base_data.h b/cgogn/core/map/map_base_data.h index f67a34a1..8c078f8d 100644 --- a/cgogn/core/map/map_base_data.h +++ b/cgogn/core/map/map_base_data.h @@ -53,7 +53,7 @@ class MapGen virtual ~MapGen(); - static inline bool isAlive(MapGen* map) + static inline bool is_alive(MapGen* map) { return std::find(instances_->begin(), instances_->end(), map) != instances_->end(); } @@ -126,14 +126,14 @@ class MapBaseData : public MapGen * Containers management *******************************************************************************/ - inline ChunkArrayContainer& getAttributeContainer(unsigned int orbit) + inline ChunkArrayContainer& get_attribute_container(unsigned int orbit) { return attributes_[orbit]; } - inline ChunkArray* getTopologyMarkAttribute() + inline ChunkArray* get_topology_mark_attribute() { - unsigned int thread = getCurrentThreadIndex(); + unsigned int thread = get_current_thread_index(); if (!mark_attributes_topology_[thread].empty()) { ChunkArray* ca = mark_attributes_topology_[thread].back(); @@ -150,23 +150,23 @@ class MapBaseData : public MapGen number[1] = '0'+char(x%10u); x /= 10u; number[0] = '0'+char(x%10u); - ChunkArray* ca = topology_.addMarkerAttribute("marker_" + number); + ChunkArray* ca = topology_.add_marker_attribute("marker_" + number); return ca; } } - inline void releaseTopologyMarkAttribute(ChunkArray* ca) + inline void release_topology_mark_attribute(ChunkArray* ca) { - unsigned int thread = getCurrentThreadIndex(); + unsigned int thread = get_current_thread_index(); mark_attributes_topology_[thread].push_back(ca); } template - inline ChunkArray* getMarkAttribute() + inline ChunkArray* get_mark_attribute() { cgogn_message_assert(embeddings_[ORBIT] != NULL, "Invalid parameter: orbit not embedded"); - unsigned int thread = getCurrentThreadIndex(); + unsigned int thread = get_current_thread_index(); if (!mark_attributes_[ORBIT][thread].empty()) { ChunkArray* ca = mark_attributes_[ORBIT][thread].back(); @@ -183,17 +183,17 @@ class MapBaseData : public MapGen number[1] = '0'+char(x%10u); x /= 10u; number[0] = '0'+char(x%10u); - ChunkArray* ca = attributes_[ORBIT].addMarkerAttribute("marker_" + orbitName(ORBIT) + number); + ChunkArray* ca = attributes_[ORBIT].add_marker_attribute("marker_" + orbit_name(ORBIT) + number); return ca; } } template - inline void releaseMarkAttribute(ChunkArray* ca) + inline void release_mark_attribute(ChunkArray* ca) { cgogn_message_assert(embeddings_[ORBIT] != NULL, "Invalid parameter: orbit not embedded"); - unsigned int thread = getCurrentThreadIndex(); + unsigned int thread = get_current_thread_index(); mark_attributes_[ORBIT][thread].push_back(ca); } @@ -202,7 +202,7 @@ class MapBaseData : public MapGen *******************************************************************************/ template - inline unsigned int getEmbedding(const Cell& c) const + inline unsigned int get_embedding(const Cell& c) const { cgogn_message_assert(embeddings_[ORBIT] != NULL, "Invalid parameter: orbit not embedded"); @@ -215,7 +215,7 @@ class MapBaseData : public MapGen * Thread management *******************************************************************************/ - inline unsigned int getCurrentThreadIndex() const + inline unsigned int get_current_thread_index() const { std::thread::id id = std::this_thread::get_id(); unsigned int i = 0; diff --git a/cgogn/core/map/map_tri.h b/cgogn/core/map/map_tri.h index 2e4890f1..6e9c1b8d 100644 --- a/cgogn/core/map/map_tri.h +++ b/cgogn/core/map/map_tri.h @@ -31,7 +31,7 @@ namespace cgogn class Traits_map_tri { - static const int PRIM_SIZE=3; + static const int PRIM_SIZE = 3; }; class MapTri : public MapBase diff --git a/cgogn/utils/assert.h b/cgogn/utils/assert.h index b969464e..4ebadefc 100644 --- a/cgogn/utils/assert.h +++ b/cgogn/utils/assert.h @@ -21,8 +21,8 @@ * * *******************************************************************************/ -#ifndef UTILS_ASSERT_ -#define UTILS_ASSERT_ +#ifndef UTILS_ASSERT_H_ +#define UTILS_ASSERT_H_ #include #include @@ -204,4 +204,4 @@ CGOGN_UTILS_API CGOGN_NORETURN void should_not_have_reached( #define parano_message_assert(x, msg) #endif -#endif // UTILS_ASSERT_ +#endif // UTILS_ASSERT_H_ diff --git a/cgogn/utils/buffers.h b/cgogn/utils/buffers.h index 65a9643b..3dae9178 100644 --- a/cgogn/utils/buffers.h +++ b/cgogn/utils/buffers.h @@ -49,7 +49,7 @@ class Buffers } } - inline std::vector* getBuffer() + inline std::vector* get_buffer() { if (buffers_.empty()) { @@ -63,7 +63,7 @@ class Buffers return v; } - inline void releaseBuffer(std::vector* b) + inline void release_buffer(std::vector* b) { if (b->capacity() > 1024) { diff --git a/cgogn/utils/definitions.h b/cgogn/utils/definitions.h index 67d24010..21819cae 100644 --- a/cgogn/utils/definitions.h +++ b/cgogn/utils/definitions.h @@ -47,7 +47,7 @@ * \brief No return declaration for CGOGN symbols. */ #ifndef CGOGN_NORETURN -#if defined (_MSC_VER) +#if defined(_MSC_VER) #define CGOGN_NORETURN __declspec(noreturn) #else #define CGOGN_NORETURN [[noreturn]] diff --git a/cgogn/utils/make_unique.h b/cgogn/utils/make_unique.h index d95247a8..25770366 100644 --- a/cgogn/utils/make_unique.h +++ b/cgogn/utils/make_unique.h @@ -78,4 +78,3 @@ make_unique(Args&&...) = delete; } // namespace cgogn #endif // UTILS_MAKE_UNIQUE_H - diff --git a/cgogn/utils/thread.h b/cgogn/utils/thread.h index 4f99fcb9..b6058490 100644 --- a/cgogn/utils/thread.h +++ b/cgogn/utils/thread.h @@ -47,7 +47,7 @@ inline void thread_start() uint_buffers_thread = new Buffers(); } -inline void thread_end() +inline void thread_stop() { delete dart_buffers_thread; delete uint_buffers_thread; diff --git a/test/chunk_array/bench_chunk_array.cpp b/test/chunk_array/bench_chunk_array.cpp index c30810e5..71c1e475 100644 --- a/test/chunk_array/bench_chunk_array.cpp +++ b/test/chunk_array/bench_chunk_array.cpp @@ -11,22 +11,26 @@ int test3(); int test4(); int test5(); - /** * @brief The Vec3f class: just for the example */ class Vec3f { float data_[3]; + public: - Vec3f() {} + + Vec3f() + {} + Vec3f(float x,float y, float z) { - data_[0]=x; - data_[1]=y; - data_[2]=z; + data_[0] = x; + data_[1] = y; + data_[2] = z; } - static std::string CGoGNnameOfType() + + static std::string CGoGN_name_of_type() { return "Vec3f"; } @@ -39,36 +43,31 @@ int test1() std::cout << "= TEST 1 = ref unsigned char" << std::endl; ChunkArrayContainer container; - ChunkArray* att1 = container.addAttribute("entier"); - ChunkArray* att2 = container.addAttribute("reel"); - ChunkArray* att3 = container.addAttribute("Vec3f"); - - - for (unsigned int i=0;i(); - + ChunkArray* att1 = container.add_attribute("entier"); + ChunkArray* att2 = container.add_attribute("reel"); + ChunkArray* att3 = container.add_attribute("Vec3f"); + for (unsigned int i = 0; i < NB_LINES; ++i) + container.insert_lines<1>(); - for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) + for(unsigned int i = container.begin(); i != container.end(); container.next(i)) { (*att1)[i] = 1+int(i); (*att2)[i] = 3.0f + 0.1f*float(i); (*att3)[i] = Vec3f(float(i), float(i), float(i)); } - - for (unsigned int j=0; j<100; ++j) + for (unsigned int j = 0; j < 100; ++j) { - - for (unsigned int i=0;i(j%2+1+i*10); - container.removeLines<1>(j%2+3+i*10); - container.removeLines<1>(j%2+8+i*10); + container.remove_lines<1>(j%2+1+i*10); + container.remove_lines<1>(j%2+3+i*10); + container.remove_lines<1>(j%2+8+i*10); } - for (unsigned int i=0;i<3*NB_LINES/10;++i) - container.insertLines<1>(); + for (unsigned int i = 0; i < 3*NB_LINES/10; ++i) + container.insert_lines<1>(); } std::cout << "---> OK" << std::endl; @@ -80,64 +79,58 @@ int test2() std::cout << "= TEST 2 = ref bool" << std::endl; ChunkArrayContainer container; - ChunkArray* att1 = container.addAttribute("entier"); - ChunkArray* att2 = container.addAttribute("reel"); - ChunkArray* att3 = container.addAttribute("Vec3f"); - - - for (unsigned int i=0;i(); + ChunkArray* att1 = container.add_attribute("entier"); + ChunkArray* att2 = container.add_attribute("reel"); + ChunkArray* att3 = container.add_attribute("Vec3f"); + for (unsigned int i = 0; i < NB_LINES; ++i) + container.insert_lines<1>(); - for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) + for(unsigned int i = container.begin(); i != container.end(); container.next(i)) { (*att1)[i] = 1+int(i); (*att2)[i] = 3.0f + 0.1f*float(i); (*att3)[i] = Vec3f(float(i), float(i), float(i)); } - - for (unsigned int j=0; j<100; ++j) + for (unsigned int j = 0; j < 100; ++j) { - - for (unsigned int i=0;i(j%2+1+i*10); - container.removeLines<1>(j%2+3+i*10); - container.removeLines<1>(j%2+8+i*10); + container.remove_lines<1>(j%2+1+i*10); + container.remove_lines<1>(j%2+3+i*10); + container.remove_lines<1>(j%2+8+i*10); } - for (unsigned int i=0;i<3*NB_LINES/10;++i) - container.insertLines<1>(); + for (unsigned int i = 0; i < 3*NB_LINES/10; ++i) + container.insert_lines<1>(); } std::cout << "---> OK" << std::endl; return 0; } - - int test3() { std::cout << "= TEST 3 = random bool cleaning" << std::endl; ChunkArrayContainer container; - ChunkArray* att1 = container.addAttribute("bools"); + ChunkArray* att1 = container.add_attribute("bools"); for (unsigned int i = 0; i < NB_LINES; ++i) - container.insertLines<1>(); + container.insert_lines<1>(); for(unsigned int i = container.begin(); i != container.end(); container.next(i)) { - att1->setValue(i, true); + att1->set_value(i, true); } for (unsigned int j = 0; j < 100; ++j) { for (unsigned int i = 0; i < NB_LINES/2; ++i) { - att1->setFalse(i); - att1->setFalse(NB_LINES-1-i); + att1->set_false(i); + att1->set_false(NB_LINES-1-i); } } @@ -145,28 +138,27 @@ int test3() return 0; } - int test4() { - std::cout << "= TEST 4 = random bool cleaning with setFalse_byte" << std::endl; + std::cout << "= TEST 4 = random bool cleaning with set_false_byte" << std::endl; ChunkArrayContainer container; - ChunkArray* att1 = container.addAttribute("bools"); + ChunkArray* att1 = container.add_attribute("bools"); for (unsigned int i = 0; i < NB_LINES; ++i) - container.insertLines<1>(); + container.insert_lines<1>(); for(unsigned int i = container.begin(); i != container.end(); container.next(i)) { - att1->setValue(i, true); + att1->set_value(i, true); } for (unsigned int j = 0; j < 100; ++j) { for (unsigned int i = 0; i < NB_LINES/2; ++i) { - att1->setFalse_byte(i); - att1->setFalse_byte(NB_LINES-1-i); + att1->set_false_byte(i); + att1->set_false_byte(NB_LINES-1-i); } } @@ -174,32 +166,29 @@ int test4() return 0; } - - int test5() { std::cout << "= TEST 5 = Traversal" << std::endl; ChunkArrayContainer container; - ChunkArray* att1 = container.addAttribute("uints"); - - for (unsigned int i=0;i(); + ChunkArray* att1 = container.add_attribute("uints"); - for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) - att1->operator [](i) = i; + for (unsigned int i = 0; i < NB_LINES; ++i) + container.insert_lines<1>(); - for(unsigned int i=container.begin(); i(i); + for(unsigned int i = container.begin(); i != container.end(); container.next(i)) + att1->operator[](i) = i; + for(unsigned int i = container.begin(); i < container.end(); i += 9) + container.remove_lines<1>(i); int total = 0; - for (unsigned int j=0; j<50; ++j) + for (unsigned int j = 0; j < 50; ++j) { - for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) + for(unsigned int i = container.begin(); i != container.end(); container.next(i)) { - if (att1->operator [](i)%i != 0) - total += att1->operator [](i); + if (att1->operator[](i) % i != 0) + total += att1->operator[](i); } total = - total; } @@ -208,14 +197,11 @@ int test5() return 0; } - - - int main(int argc, char **argv) { - if (argc==1) + if (argc == 1) { - std::cout <<" PARAMETER: 1/2 for uint/bool refs ; 3/4 for random clear bool; 5 for traversal"; + std::cout << " PARAMETER: 1/2 for uint/bool refs ; 3/4 for random clear bool; 5 for traversal"; return 1; } diff --git a/test/chunk_array/test_chunk_array.cpp b/test/chunk_array/test_chunk_array.cpp index 57536d9a..5ff32a89 100644 --- a/test/chunk_array/test_chunk_array.cpp +++ b/test/chunk_array/test_chunk_array.cpp @@ -17,200 +17,187 @@ int test1() std::cout << "=============== TEST 1 ===============" << std::endl; ChunkArrayContainer container; - ChunkArray* att1 = container.addAttribute("entier"); - ChunkArray* att2 = container.addAttribute("reel"); + ChunkArray* att1 = container.add_attribute("entier"); + ChunkArray* att2 = container.add_attribute("reel"); + for (unsigned int i = 0; i < 41; ++i) + container.insert_lines<1>(); - for (int i=0;i<41;++i) - container.insertLines<1>(); - - - for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) + for(unsigned int i = container.begin(); i != container.end(); container.next(i)) { (*att1)[i] = 1+int(i); (*att2)[i] = 3.0f + 0.1f*float(i); } - container.removeLines<1>(3); - container.removeLines<1>(19); - container.removeLines<1>(35); + container.remove_lines<1>(3); + container.remove_lines<1>(19); + container.remove_lines<1>(35); - for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) + for(unsigned int i = container.begin(); i != container.end(); container.next(i)) { - std::cout << i << ": "<< (*att1)[i] << " / " << (*att2)[i] << std::endl; + std::cout << i << ": " << (*att1)[i] << " / " << (*att2)[i] << std::endl; } std::cout << "----------------------------------------" << std::endl; - unsigned int li = container.insertLines<1>(); + unsigned int li = container.insert_lines<1>(); (*att1)[li] = 110; (*att2)[li] = 123.1f; - li = container.insertLines<1>(); + li = container.insert_lines<1>(); (*att1)[li] = 111; (*att2)[li] = 223.1f; - li = container.insertLines<1>(); + li = container.insert_lines<1>(); (*att1)[li] = 112; (*att2)[li] = 323.1f; - for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) + for(unsigned int i = container.begin(); i != container.end(); container.next(i)) { - std::cout << i << ": "<< (*att1)[i] << " / " << (*att2)[i] << std::endl; + std::cout << i << ": " << (*att1)[i] << " / " << (*att2)[i] << std::endl; } std::cout << "----------------------------------------" << std::endl; - container.removeLines<1>(3); - container.removeLines<1>(19); - container.removeLines<1>(35); + container.remove_lines<1>(3); + container.remove_lines<1>(19); + container.remove_lines<1>(35); std::vector mapOldNew; container.compact<1>(mapOldNew); - for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) + for(unsigned int i = container.begin(); i != container.end(); container.next(i)) { - std::cout << i << ": "<< (*att1)[i] << " / " << (*att2)[i] << std::endl; + std::cout << i << ": " << (*att1)[i] << " / " << (*att2)[i] << std::endl; } std::cout << "----------------------------------------" << std::endl; - return 0; } - - int test2() { std::cout << "=============== TEST 2 ===============" << std::endl; ChunkArrayContainer container; - ChunkArray* att1 = container.addAttribute("entier"); + ChunkArray* att1 = container.add_attribute("entier"); - for (int i=0;i<13;++i) - container.insertLines<3>(); + for (int i = 0; i < 13; ++i) + container.insert_lines<3>(); - for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) + for(unsigned int i = container.begin(); i != container.end(); container.next(i)) (*att1)[i] = 1+int(i); - for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) + for(unsigned int i = container.begin(); i != container.end(); container.next(i)) { - std::cout << i << ": "<< (*att1)[i] << std::endl; + std::cout << i << ": " << (*att1)[i] << std::endl; } std::cout << "----------------------------------------" << std::endl; - container.removeLines<3>(2); - container.removeLines<3>(35); + container.remove_lines<3>(2); + container.remove_lines<3>(35); - unsigned int li = container.insertLines<3>(); + unsigned int li = container.insert_lines<3>(); (*att1)[li] = 110; (*att1)[li+1] = 111; (*att1)[li+2] = 112; - for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) - std::cout << i << ": "<< (*att1)[i] << std::endl; + for(unsigned int i = container.begin(); i != container.end(); container.next(i)) + std::cout << i << ": " << (*att1)[i] << std::endl; std::cout << "----------------------------------------" << std::endl; + container.remove_lines<3>(8); + container.remove_lines<3>(17); - container.removeLines<3>(8); - container.removeLines<3>(17); - - for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) - std::cout << i << ": "<< (*att1)[i] << std::endl; + for(unsigned int i = container.begin(); i != container.end(); container.next(i)) + std::cout << i << ": " << (*att1)[i] << std::endl; std::cout << "-Compact--------------------------------------" << std::endl; std::vector mapOldNew; container.compact<3>(mapOldNew); - for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) - std::cout << i << ": "<< (*att1)[i] << std::endl; + for(unsigned int i = container.begin(); i != container.end(); container.next(i)) + std::cout << i << ": " << (*att1)[i] << std::endl; std::cout << "----------------------------------------" << std::endl; - li = container.insertLines<3>(); + li = container.insert_lines<3>(); (*att1)[li] = 110; (*att1)[li+1] = 111; (*att1)[li+2] = 112; - li = container.insertLines<3>(); + li = container.insert_lines<3>(); (*att1)[li] = 210; (*att1)[li+1] = 211; (*att1)[li+2] = 212; - for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) - std::cout << i << ": "<< (*att1)[i] << std::endl; + for(unsigned int i = container.begin(); i != container.end(); container.next(i)) + std::cout << i << ": " << (*att1)[i] << std::endl; std::cout << "----------------------------------------" << std::endl; + ChunkArray* attB = container.add_attribute("bools"); - ChunkArray* attB = container.addAttribute("bools"); - - for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) - std::cout << i << ": "<< (*att1)[i]<< " / "<< (*attB)[i] << std::endl; + for(unsigned int i = container.begin(); i != container.end(); container.next(i)) + std::cout << i << ": " << (*att1)[i]<< " / "<< (*attB)[i] << std::endl; std::cout << "----------------------------------------" << std::endl; - return 0; - } - int test3() { std::cout << "=============== TEST 3 ===============" << std::endl; ChunkArrayContainer container; - ChunkArray* att1 = container.addAttribute("entier"); - ChunkArray >* att2 = container.addAttribute >("V_entier"); - ChunkArray >* att3 = container.addAttribute >("L_entier"); - + ChunkArray* att1 = container.add_attribute("entier"); + ChunkArray >* att2 = container.add_attribute >("V_entier"); + ChunkArray >* att3 = container.add_attribute >("L_entier"); - for (int i=0;i<13;++i) - container.insertLines<3>(); + for (unsigned int i = 0; i < 13; ++i) + container.insert_lines<3>(); std::vector vect = (*att2)[0]; - - for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) + for(unsigned int i = container.begin(); i != container.end(); container.next(i)) { (*att1)[i] = 1+int(i); - for (unsigned int j=0; j(3); - container.removeLines<3>(19); - container.removeLines<3>(35); + container.remove_lines<3>(3); + container.remove_lines<3>(19); + container.remove_lines<3>(35); - container.insertLines<3>(); + container.insert_lines<3>(); - for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) + for(unsigned int i = container.begin(); i != container.end(); container.next(i)) { - std::cout << i << ": "<< (*att1)[i]<< " // "; - for (auto j:(*att2)[i]) - std::cout<< j << ","; + std::cout << i << ": " << (*att1)[i] << " // "; + for (auto j : (*att2)[i]) + std::cout << j << ","; std::cout << " // "; - for (auto j:(*att3)[i]) - std::cout<< j << ","; - std::cout<< std::endl; + for (auto j : (*att3)[i]) + std::cout << j << ","; + std::cout << std::endl; } std::cout << "----------------------------------------" << std::endl; - - for(unsigned int i=container.begin(); i!=container.end(); container.nextPrimitive(i,3)) + for(unsigned int i = container.begin(); i != container.end(); container.next_primitive(i,3)) { - std::cout << i << ": "<< (*att1)[i]<< " // "; - for (auto j:(*att2)[i]) - std::cout<< j << ","; + std::cout << i << ": " << (*att1)[i] << " // "; + for (auto j : (*att2)[i]) + std::cout << j << ","; std::cout << " // "; - for (auto j:(*att3)[i]) - std::cout<< j << ","; - std::cout<< std::endl; + for (auto j : (*att3)[i]) + std::cout << j << ","; + std::cout << std::endl; } std::cout << "----------------------------------------" << std::endl; @@ -223,27 +210,26 @@ int test4() typedef std::vector< std::vector< double > > vecvecdouble; typedef std::vector< std::list< double > > veclistdouble; ChunkArrayContainer container; - ChunkArray* att1 = container.addAttribute("entier"); - ChunkArray* att2 = container.addAttribute("reel"); - ChunkArray* att3 = container.addAttribute("bools"); - ChunkArray* att4 = container.addAttribute("vecvecdouble"); - ChunkArray* att5 = container.addAttribute("veclistdouble"); + ChunkArray* att1 = container.add_attribute("entier"); + ChunkArray* att2 = container.add_attribute("reel"); + ChunkArray* att3 = container.add_attribute("bools"); + ChunkArray* att4 = container.add_attribute("vecvecdouble"); + ChunkArray* att5 = container.add_attribute("veclistdouble"); for (unsigned int i = 0u; i < 7u; ++i) - container.insertLines<3>(); - + container.insert_lines<3>(); for(unsigned int i = container.begin(); i != container.end(); container.next(i)) { (*att1)[i] = 1+int(i); (*att2)[i] = 3.0f + 0.1f*float(i); - (*att3).setValue(i, static_cast(i%2)); + (*att3).set_value(i, static_cast(i%2)); (*att4)[i] = {{3.0 + 0.1*double(i),15.0 + 0.1*double(i)}, {103.0 + 0.1*double(i), 203.0 + 0.1*double(i), 303.0 + 0.1*double(i)}}; (*att5)[i] = {{3.0 + 0.1*double(i),15.0 + 0.1*double(i)}, {103.0 + 0.1*double(i), 203.0 + 0.1*double(i), 303.0 + 0.1*double(i)}}; } - container.removeLines<3>(3); - container.removeLines<3>(13); + container.remove_lines<3>(3); + container.remove_lines<3>(13); std::ofstream of("pipo.map"); container.save(of); @@ -254,15 +240,15 @@ int test4() cont2.load(ifi); ifi.close(); - ChunkArray* load_att1 = cont2.getAttribute("entier"); - ChunkArray* load_att2 = cont2.getAttribute("reel"); - ChunkArray* load_att3 = cont2.getAttribute("bools"); - ChunkArray* load_att4 = cont2.getAttribute("vecvecdouble"); - ChunkArray* load_att5 = cont2.getAttribute("veclistdouble"); + ChunkArray* load_att1 = cont2.get_attribute("entier"); + ChunkArray* load_att2 = cont2.get_attribute("reel"); + ChunkArray* load_att3 = cont2.get_attribute("bools"); + ChunkArray* load_att4 = cont2.get_attribute("vecvecdouble"); + ChunkArray* load_att5 = cont2.get_attribute("veclistdouble"); for(unsigned int i = cont2.begin(); i != cont2.end(); cont2.next(i)) { - std::cout << i << ": "<< (*load_att1)[i] << " / " << (*load_att2)[i] << " / " << (*load_att3)[i] << " / "; + std::cout << i << ": " << (*load_att1)[i] << " / " << (*load_att2)[i] << " / " << (*load_att3)[i] << " / "; for (const auto& v : (*load_att4)[i]) for (auto x : v) std::cout << x << " "; @@ -279,7 +265,6 @@ int test4() return 0; } - int main() { test1(); @@ -287,4 +272,3 @@ int main() test3(); test4(); } - diff --git a/test/map/test_map.cpp b/test/map/test_map.cpp index 39e903ea..d6b88390 100644 --- a/test/map/test_map.cpp +++ b/test/map/test_map.cpp @@ -19,6 +19,9 @@ typedef Map1 MAP1; typedef Map2 MAP2; +void fonc_const(const MAP1::VertexAttributeHandler& ah); +void fonc_non_const(MAP1::VertexAttributeHandler& ah); +int test1(MAP1& map); void fonc_const(const MAP1::VertexAttributeHandler& ah) @@ -48,17 +51,16 @@ void fonc_non_const(MAP1::VertexAttributeHandler& ah) } } - int test1(MAP1& map) { // add an attribute on vertex of map with - MAP1::VertexAttributeHandler ah = map.addAttribute("floats"); + MAP1::VertexAttributeHandler ah = map.add_attribute("floats"); - std::vector* uib = cgogn::uint_buffers_thread->getBuffer(); + std::vector* uib = cgogn::uint_buffers_thread->get_buffer(); uib->push_back(3); - cgogn::uint_buffers_thread->releaseBuffer(uib); + cgogn::uint_buffers_thread->release_buffer(uib); - Dart d = map.addDart(); + Dart d = map.add_dart(); DartMarker dm(map); CellMarker cm(map); @@ -72,10 +74,10 @@ int test1(MAP1& map) } // get ChunkArrayContainer -> get ChunkArray -> fill - ChunkArrayContainer& container = map.getAttributeContainer(VERTEX1); - ChunkArray* att = container.getAttribute("floats"); + ChunkArrayContainer& container = map.get_attribute_container(VERTEX1); + ChunkArray* att = container.get_attribute("floats"); for (int i=0;i<10;++i) - container.insertLines<1>(); + container.insert_lines<1>(); for(unsigned int i=container.begin(); i!=container.end(); container.next(i)) (*att)[i] = 3.0f + 0.1f*float(i); @@ -93,14 +95,12 @@ int test1(MAP1& map) return 0; } - - int main() { cgogn::thread_start(); MAP1 map1; MAP2 map2; test1(map1); - cgogn::thread_end(); + cgogn::thread_stop(); return 0; } From 3a3c4326a57e8141dacbfcf8b6028461a9a7b3eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Schmitt?= Date: Mon, 16 Nov 2015 18:44:20 +0100 Subject: [PATCH 098/185] added CGOGN_CONSTEXPR macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Étienne Schmitt --- cgogn/utils/definitions.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/cgogn/utils/definitions.h b/cgogn/utils/definitions.h index 21819cae..c18ce98e 100644 --- a/cgogn/utils/definitions.h +++ b/cgogn/utils/definitions.h @@ -43,6 +43,17 @@ #define CGOGN_TLS __thread #endif +/* + * a constexrp function can be evaluated at compile time. + * Can be used to optimize the code. + * WARNING : cases where the use of constexpr is mandatory for the compilation are not allowed since it's not available in VS 2013. +*/ +#if defined(_MSC_VER) && _MSC_VER < 1900 +#define CGOGN_CONSTEXPR const +#else +#define CGOGN_CONSTEXPR constexpr +#endif + /** * \brief No return declaration for CGOGN symbols. */ From 835fa251bf143530c19011dbd8e134ac07d7ee7a Mon Sep 17 00:00:00 2001 From: Etienne Schmitt Date: Thu, 19 Nov 2015 15:16:34 +0100 Subject: [PATCH 099/185] fixed compilation under MSVC 2013 Signed-off-by: Etienne Schmitt --- cgogn/core/basic/cell_marker.h | 6 +++--- cgogn/core/basic/dart_marker.h | 14 ++++++-------- cgogn/core/map/map2.h | 4 ++-- cgogn/core/map/map_base_data.cpp | 7 ++----- cgogn/core/map/map_base_data.h | 2 +- cgogn/utils/thread.cpp | 26 +++++++++++++++++++++++++- cgogn/utils/thread.h | 20 +++++--------------- test/map/test_map.cpp | 6 +++--- 8 files changed, 47 insertions(+), 38 deletions(-) diff --git a/cgogn/core/basic/cell_marker.h b/cgogn/core/basic/cell_marker.h index d096f56c..3f9d1cd3 100644 --- a/cgogn/core/basic/cell_marker.h +++ b/cgogn/core/basic/cell_marker.h @@ -31,7 +31,7 @@ namespace cgogn { -class CellMarkerGen +class CGOGN_CORE_API CellMarkerGen { public: typedef CellMarkerGen Super; @@ -154,13 +154,13 @@ class CellMarkerStore : public CellMarkerT CellMarkerStore(Map& map) : Inherit(map) { - marked_cells_ = uint_buffers_thread->get_buffer(); + marked_cells_ = cgogn::getUINTBuffers()->get_buffer(); } ~CellMarkerStore() override { unmark_all(); - uint_buffers_thread->release_buffer(marked_cells_); + cgogn::getUINTBuffers()->release_buffer(marked_cells_); } CellMarkerStore(const Super& dm) = delete; diff --git a/cgogn/core/basic/dart_marker.h b/cgogn/core/basic/dart_marker.h index c47d9004..ed764e5d 100644 --- a/cgogn/core/basic/dart_marker.h +++ b/cgogn/core/basic/dart_marker.h @@ -30,7 +30,7 @@ namespace cgogn { -class DartMarkerGen +class CGOGN_CORE_API DartMarkerGen { public: typedef DartMarkerGen Super; @@ -67,19 +67,17 @@ class DartMarkerT : public DartMarkerGen Inherit(), map_(map) { - mark_attribute_ = map_.template get_topology_mark_attribute(); + mark_attribute_ = map_.get_topology_mark_attribute(); } ~DartMarkerT() override { if (MapGen::is_alive(&map_)) - map_.template release_topology_mark_attribute(mark_attribute_); + map_.release_topology_mark_attribute(mark_attribute_); } DartMarkerT(const Super& dm) = delete; - DartMarkerT(Super&& dm) = delete; DartMarkerT& operator=(Super& dm) = delete; - DartMarkerT& operator=(const Super& dm) = delete; inline void mark(Dart d) { @@ -125,8 +123,8 @@ class DartMarker : public DartMarkerT { public: - typedef DartMarker Super; typedef DartMarkerT Inherit; + typedef DartMarker Super; typedef MAP Map; DartMarker(MAP& map) : @@ -167,13 +165,13 @@ class DartMarkerStore : public DartMarkerT DartMarkerStore(Map& map) : Inherit(map) { - marked_darts_ = dart_buffers_thread->get_buffer(); + marked_darts_ = cgogn::getDartBuffers()->get_buffer(); } ~DartMarkerStore() override { unmark_all(); - dart_buffers_thread->release_buffer(marked_darts_); + cgogn::getDartBuffers()->release_buffer(marked_darts_); } DartMarkerStore(const Super& dm) = delete; diff --git a/cgogn/core/map/map2.h b/cgogn/core/map/map2.h index f3064e02..d3216b2a 100644 --- a/cgogn/core/map/map2.h +++ b/cgogn/core/map/map2.h @@ -156,7 +156,7 @@ class Map2 : public Map1 { DartMarkerStore marker(*this); // get a marker - std::vector* visited_faces = dart_buffers_thread->get_buffer(); + std::vector* visited_faces = cgogn::getDartBuffers()->get_buffer(); visited_faces->push_back(d); // Start with the face of d @@ -182,7 +182,7 @@ class Map2 : public Map1 } } - dart_buffers_thread->release_buffer(visited_faces); + cgogn::getDartBuffers()->release_buffer(visited_faces); } template diff --git a/cgogn/core/map/map_base_data.cpp b/cgogn/core/map/map_base_data.cpp index f7c63d20..423b3201 100644 --- a/cgogn/core/map/map_base_data.cpp +++ b/cgogn/core/map/map_base_data.cpp @@ -20,7 +20,7 @@ * Contact information: cgogn@unistra.fr * * * *******************************************************************************/ - +#define CGOGN_CORE_DLL_EXPORT #include namespace cgogn @@ -28,14 +28,11 @@ namespace cgogn std::vector* MapGen::instances_ = nullptr; -CGOGN_TLS Buffers* dart_buffers_thread = nullptr; -CGOGN_TLS Buffers* uint_buffers_thread = nullptr; - MapGen::MapGen() { if (instances_ == nullptr) instances_ = new std::vector; - + cgogn_message_assert(std::find(instances_->begin(), instances_->end(), this) == instances_->end(),"This map is already present in the instances vector."); // register the map in the vector of instances instances_->push_back(this); } diff --git a/cgogn/core/map/map_base_data.h b/cgogn/core/map/map_base_data.h index 2cbfa0b3..22c2c40a 100644 --- a/cgogn/core/map/map_base_data.h +++ b/cgogn/core/map/map_base_data.h @@ -41,7 +41,7 @@ namespace cgogn /** * @brief Generic Map class */ -class MapGen +class CGOGN_CORE_API MapGen { public: typedef MapGen Super; diff --git a/cgogn/utils/thread.cpp b/cgogn/utils/thread.cpp index dcf9d8c4..732be568 100644 --- a/cgogn/utils/thread.cpp +++ b/cgogn/utils/thread.cpp @@ -20,7 +20,7 @@ * Contact information: cgogn@unistra.fr * * * *******************************************************************************/ - +#define CGOGN_UTILS_DLL_EXPORT #include namespace cgogn @@ -29,4 +29,28 @@ namespace cgogn CGOGN_TLS Buffers* dart_buffers_thread = nullptr; CGOGN_TLS Buffers* uint_buffers_thread = nullptr; +CGOGN_UTILS_API void thread_start() +{ + if (dart_buffers_thread == nullptr) + dart_buffers_thread = new Buffers(); + + if (uint_buffers_thread == nullptr) + uint_buffers_thread = new Buffers(); +} + +CGOGN_UTILS_API void thread_stop() +{ + delete dart_buffers_thread; + delete uint_buffers_thread; +} + +CGOGN_UTILS_API Buffers* getDartBuffers() +{ + return dart_buffers_thread; +} +CGOGN_UTILS_API Buffers* getUINTBuffers() +{ + return uint_buffers_thread; +} + } // namespace cgogn diff --git a/cgogn/utils/thread.h b/cgogn/utils/thread.h index b6058490..86266c0b 100644 --- a/cgogn/utils/thread.h +++ b/cgogn/utils/thread.h @@ -25,7 +25,7 @@ #define UTILS_THREAD_H_ #include - +#include namespace cgogn { @@ -38,20 +38,10 @@ const unsigned int NB_THREADS = 8u; extern CGOGN_TLS Buffers* dart_buffers_thread; extern CGOGN_TLS Buffers* uint_buffers_thread; -inline void thread_start() -{ - if (dart_buffers_thread == nullptr) - dart_buffers_thread = new Buffers(); - - if (uint_buffers_thread == nullptr) - uint_buffers_thread = new Buffers(); -} - -inline void thread_stop() -{ - delete dart_buffers_thread; - delete uint_buffers_thread; -} +CGOGN_UTILS_API void thread_start(); +CGOGN_UTILS_API void thread_stop(); +CGOGN_UTILS_API Buffers* getDartBuffers(); +CGOGN_UTILS_API Buffers* getUINTBuffers(); } // namespace cgogn diff --git a/test/map/test_map.cpp b/test/map/test_map.cpp index d6b88390..86a73a21 100644 --- a/test/map/test_map.cpp +++ b/test/map/test_map.cpp @@ -56,9 +56,9 @@ int test1(MAP1& map) // add an attribute on vertex of map with MAP1::VertexAttributeHandler ah = map.add_attribute("floats"); - std::vector* uib = cgogn::uint_buffers_thread->get_buffer(); + std::vector* uib = cgogn::getUINTBuffers()->get_buffer(); uib->push_back(3); - cgogn::uint_buffers_thread->release_buffer(uib); + cgogn::getUINTBuffers()->release_buffer(uib); Dart d = map.add_dart(); @@ -101,6 +101,6 @@ int main() MAP1 map1; MAP2 map2; test1(map1); - cgogn::thread_stop(); + //cgogn::thread_stop(); return 0; } From 5fbbc482edf82952cc2a43b578f4b68fd861a9dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Schmitt?= Date: Thu, 19 Nov 2015 15:26:28 +0100 Subject: [PATCH 100/185] added many typedefs. *Super and Inherit for many classes *ChunkArray aliases in map classes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Étienne Schmitt --- cgogn/core/basic/cell_marker.h | 70 ++++++++++++++++++++++------------ cgogn/core/basic/dart_marker.h | 61 +++++++++++++++++------------ cgogn/core/map/map1.h | 18 ++++++--- cgogn/core/map/map2.h | 18 ++++++--- cgogn/core/map/map_base.h | 27 +++++++------ cgogn/core/map/map_base_data.h | 50 ++++++++++++++---------- cgogn/core/map/map_tri.h | 3 ++ cgogn/utils/buffers.h | 10 +++-- 8 files changed, 162 insertions(+), 95 deletions(-) diff --git a/cgogn/core/basic/cell_marker.h b/cgogn/core/basic/cell_marker.h index 21baa3cf..d096f56c 100644 --- a/cgogn/core/basic/cell_marker.h +++ b/cgogn/core/basic/cell_marker.h @@ -26,6 +26,7 @@ #include #include +#include namespace cgogn { @@ -33,30 +34,41 @@ namespace cgogn class CellMarkerGen { public: - + typedef CellMarkerGen Super; CellMarkerGen() {} virtual ~CellMarkerGen(); - CellMarkerGen(const CellMarkerGen& dm) = delete; - CellMarkerGen(CellMarkerGen&& dm) = delete; - CellMarkerGen& operator=(CellMarkerGen&& dm) = delete; - CellMarkerGen& operator=(const CellMarkerGen& dm) = delete; + CellMarkerGen(const Super& dm) = delete; + CellMarkerGen(Super&& dm) = delete; + CellMarkerGen& operator=(Super&& dm) = delete; + CellMarkerGen& operator=(const Super& dm) = delete; }; template class CellMarkerT : public CellMarkerGen { + static_assert(ORBIT >= VERTEX1, "ORBIT must be greater than or equal to VERTEX1"); + static_assert(ORBIT <= VOLUME3, "ORBIT must be less than or equal to VOLUME3"); +public: + typedef CellMarkerGen Inherit; + typedef CellMarkerT< MAP, ORBIT > Super; + + typedef std::integral_constant Orbit; + typedef MAP Map; + typedef typename Map::ChunkSizeType ChunkSizeType; + typedef ChunkArray ChunkArrayBool; + protected: MAP& map_; - ChunkArray* mark_attribute_; + ChunkArrayBool* mark_attribute_; public: - CellMarkerT(MAP& map) : - CellMarkerGen(), + CellMarkerT(Map& map) : + Inherit(), map_(map) { mark_attribute_ = map_.template get_mark_attribute(); @@ -68,10 +80,10 @@ class CellMarkerT : public CellMarkerGen map_.template release_mark_attribute(mark_attribute_); } - CellMarkerT(const CellMarkerT& dm) = delete; - CellMarkerT(CellMarkerT&& dm) = delete; - CellMarkerT& operator=(CellMarkerT&& dm) = delete; - CellMarkerT& operator=(const CellMarkerT& dm) = delete; + CellMarkerT(const Super& dm) = delete; + CellMarkerT(Super&& dm) = delete; + CellMarkerT& operator=(Super&& dm) = delete; + CellMarkerT& operator=(const Super& dm) = delete; inline void mark(Cell c) { @@ -96,10 +108,13 @@ template class CellMarker : public CellMarkerT { public: - typedef CellMarkerT Inherit; + typedef CellMarker< MAP, ORBIT > Super; + + typedef typename Inherit::Orbit Orbit; + typedef typename Inherit::Map Map; - CellMarker(MAP& map) : + CellMarker(Map& map) : Inherit(map) {} @@ -108,10 +123,10 @@ class CellMarker : public CellMarkerT unmark_all() ; } - CellMarker(const CellMarker& dm) = delete; - CellMarker(CellMarker&& dm) = delete; - CellMarker& operator=(CellMarker&& dm) = delete; - CellMarker& operator=(const CellMarker& dm) = delete; + CellMarker(const Super& dm) = delete; + CellMarker(Super&& dm) = delete; + CellMarker& operator=(Super&& dm) = delete; + CellMarker& operator=(const Super& dm) = delete; inline void unmark_all() { @@ -123,15 +138,20 @@ class CellMarker : public CellMarkerT template class CellMarkerStore : public CellMarkerT { +public: + typedef CellMarkerT Inherit; + typedef CellMarkerStore< MAP, ORBIT > Super; + + typedef typename Inherit::Orbit Orbit; + typedef typename Inherit::Map Map; + typedef typename Inherit::ProcessedCell ProcessedCell; protected: std::vector* marked_cells_; public: - typedef CellMarkerT Inherit; - - CellMarkerStore(MAP& map) : + CellMarkerStore(Map& map) : Inherit(map) { marked_cells_ = uint_buffers_thread->get_buffer(); @@ -143,10 +163,10 @@ class CellMarkerStore : public CellMarkerT uint_buffers_thread->release_buffer(marked_cells_); } - CellMarkerStore(const CellMarkerStore& dm) = delete; - CellMarkerStore(CellMarkerStore&& dm) = delete; - CellMarkerStore& operator=(CellMarkerStore&& dm) = delete; - CellMarkerStore& operator=(const CellMarkerStore& dm) = delete; + CellMarkerStore(const Super& dm) = delete; + CellMarkerStore(Super&& dm) = delete; + CellMarkerStore& operator=(Super&& dm) = delete; + CellMarkerStore& operator=(const Super& dm) = delete; inline void mark(Cell c) { diff --git a/cgogn/core/basic/dart_marker.h b/cgogn/core/basic/dart_marker.h index 56e2b7d7..c47d9004 100644 --- a/cgogn/core/basic/dart_marker.h +++ b/cgogn/core/basic/dart_marker.h @@ -33,30 +33,38 @@ namespace cgogn class DartMarkerGen { public: - + typedef DartMarkerGen Super; DartMarkerGen() {} virtual ~DartMarkerGen(); - DartMarkerGen(const DartMarkerGen& dm) = delete; - DartMarkerGen(DartMarkerGen&& dm) = delete; - DartMarkerGen& operator=(DartMarkerGen&& dm) = delete; - DartMarkerGen& operator=(const DartMarkerGen& dm) = delete; + DartMarkerGen(const Super& dm) = delete; + DartMarkerGen(Super&& dm) = delete; + DartMarkerGen& operator=(Super&& dm) = delete; + DartMarkerGen& operator=(const Super& dm) = delete; }; template class DartMarkerT : public DartMarkerGen { +public: + + typedef DartMarkerGen Inherit; + typedef DartMarkerT Super; + + typedef MAP Map; + typedef typename Map::ChunkSizeType ChunkSizeType; + using ChunkArrayBool = typename Map::template ChunkArray; protected: - MAP& map_; - ChunkArray* mark_attribute_; + Map& map_; + ChunkArrayBool* mark_attribute_; public: - DartMarkerT(MAP& map) : - DartMarkerGen(), + DartMarkerT(Map& map) : + Inherit(), map_(map) { mark_attribute_ = map_.template get_topology_mark_attribute(); @@ -68,10 +76,10 @@ class DartMarkerT : public DartMarkerGen map_.template release_topology_mark_attribute(mark_attribute_); } - DartMarkerT(const DartMarkerT& dm) = delete; - DartMarkerT(DartMarkerT&& dm) = delete; - DartMarkerT& operator=(DartMarkerT&& dm) = delete; - DartMarkerT& operator=(const DartMarkerT& dm) = delete; + DartMarkerT(const Super& dm) = delete; + DartMarkerT(Super&& dm) = delete; + DartMarkerT& operator=(Super& dm) = delete; + DartMarkerT& operator=(const Super& dm) = delete; inline void mark(Dart d) { @@ -117,7 +125,9 @@ class DartMarker : public DartMarkerT { public: + typedef DartMarker Super; typedef DartMarkerT Inherit; + typedef MAP Map; DartMarker(MAP& map) : Inherit(map) @@ -128,10 +138,10 @@ class DartMarker : public DartMarkerT unmark_all() ; } - DartMarker(const DartMarker& dm) = delete; - DartMarker(DartMarker&& dm) = delete; - DartMarker& operator=(DartMarker&& dm) = delete; - DartMarker& operator=(const DartMarker& dm) = delete; + DartMarker(const Super& dm) = delete; + DartMarker(Super&& dm) = delete; + DartMarker& operator=(Super&& dm) = delete; + DartMarker& operator=(const Super& dm) = delete; inline void unmark_all() { @@ -143,15 +153,18 @@ class DartMarker : public DartMarkerT template class DartMarkerStore : public DartMarkerT { +public: + typedef DartMarkerStore Super; + typedef DartMarkerT Inherit; + typedef MAP Map; + protected: std::vector* marked_darts_; public: - typedef DartMarkerT Inherit; - - DartMarkerStore(MAP& map) : + DartMarkerStore(Map& map) : Inherit(map) { marked_darts_ = dart_buffers_thread->get_buffer(); @@ -163,10 +176,10 @@ class DartMarkerStore : public DartMarkerT dart_buffers_thread->release_buffer(marked_darts_); } - DartMarkerStore(const DartMarkerStore& dm) = delete; - DartMarkerStore(DartMarkerStore&& dm) = delete; - DartMarkerStore& operator=(DartMarkerStore&& dm) = delete; - DartMarkerStore& operator=(const DartMarkerStore& dm) = delete; + DartMarkerStore(const Super& dm) = delete; + DartMarkerStore(Super&& dm) = delete; + DartMarkerStore& operator=(Super&& dm) = delete; + DartMarkerStore& operator=(const Super& dm) = delete; inline void mark(Dart d) { diff --git a/cgogn/core/map/map1.h b/cgogn/core/map/map1.h index 84d6d63a..aa43610c 100644 --- a/cgogn/core/map/map1.h +++ b/cgogn/core/map/map1.h @@ -39,28 +39,34 @@ template class Map1 : public MapBase { public: - typedef MapBase Inherit; + typedef Map1 Super; + template + using ChunkArray = typename Inherit::template ChunkArray; + template + using ChunkArrayContainer = typename Inherit::template ChunkArrayContainer; static const unsigned int VERTEX = VERTEX1; static const unsigned int EDGE = VERTEX1; static const unsigned int FACE = FACE2; + template + using AttributeHandler = typename Inherit::template AttributeHandler; template - using VertexAttributeHandler = cgogn::AttributeHandler; + using VertexAttributeHandler = AttributeHandler; template - using EdgeAttributeHandler = cgogn::AttributeHandler; + using EdgeAttributeHandler = AttributeHandler; template - using FaceAttributeHandler = cgogn::AttributeHandler; + using FaceAttributeHandler = AttributeHandler; protected: void init() { - ChunkArray* phi1 = this->topology_.template add_attribute("phi1"); - ChunkArray* phi_1 = this->topology_.template add_attribute("phi_1"); + ChunkArray* phi1 = this->topology_.template add_attribute("phi1"); + ChunkArray* phi_1 = this->topology_.template add_attribute("phi_1"); this->topo_relations_.push_back(phi1); this->topo_relations_.push_back(phi_1); } diff --git a/cgogn/core/map/map2.h b/cgogn/core/map/map2.h index 5baaee62..f3064e02 100644 --- a/cgogn/core/map/map2.h +++ b/cgogn/core/map/map2.h @@ -34,28 +34,36 @@ template class Map2 : public Map1 { public: - typedef Map1 Inherit; + typedef Map2 Super; + + template + using ChunkArray = typename Inherit::template ChunkArray; + template + using ChunkArrayContainer = typename Inherit::template ChunkArrayContainer; static const unsigned int VERTEX = VERTEX2; static const unsigned int EDGE = EDGE2; static const unsigned int FACE = FACE2; static const unsigned int VOLUME = VOLUME3; + template + using AttributeHandler = typename Inherit::template AttributeHandler; + template - using VertexAttributeHandler = cgogn::AttributeHandler; + using VertexAttributeHandler = typename Inherit::template VertexAttributeHandler; template - using EdgeAttributeHandler = cgogn::AttributeHandler; + using EdgeAttributeHandler = typename Inherit::template EdgeAttributeHandler; template - using FaceAttributeHandler = cgogn::AttributeHandler; + using FaceAttributeHandler = typename Inherit::template FaceAttributeHandler; protected: void init() { - ChunkArray* phi2 = this->topology_.template add_attribute("phi2"); + ChunkArray* phi2 = this->topology_.template add_attribute("phi2"); this->topo_relations_.push_back(phi2); } diff --git a/cgogn/core/map/map_base.h b/cgogn/core/map/map_base.h index 476cd9f2..306e4b85 100644 --- a/cgogn/core/map/map_base.h +++ b/cgogn/core/map/map_base.h @@ -35,14 +35,15 @@ namespace cgogn template class MapBase : public MapBaseData { -protected: - - std::multimap*, AttributeHandlerGen*> attribute_handlers_; - public: - typedef MapBaseData Inherit; + typedef MapBase Super; + + using typename Inherit::ChunkArrayGen; + template + using ChunkArray = typename Inherit::template ChunkArray; + using AttributeHandlerGen = cgogn::AttributeHandlerGen; template using AttributeHandler = cgogn::AttributeHandler; @@ -68,13 +69,13 @@ class MapBase : public MapBaseData { std::ostringstream oss; oss << "EMB_" << orbit_name(ORBIT); - ChunkArray* idx = this->topology_.template add_attribute(oss.str()); + ChunkArray* idx = this->topology_.template add_attribute(oss.str()); this->embeddings_[ORBIT] = idx; for (unsigned int i = this->topology_.begin(); i != this->topology_.end(); this->topology_.next(i)) (*idx)[i] = EMBNULL; } - ChunkArray* ca = this->attributes_[ORBIT].template add_attribute(attribute_name); + ChunkArray* ca = this->attributes_[ORBIT].template add_attribute(attribute_name); return AttributeHandler(this, ca); } @@ -86,11 +87,11 @@ class MapBase : public MapBaseData template inline bool remove_attribute(AttributeHandler& ah) { - ChunkArray* ca = ah.getData(); + ChunkArray* ca = ah.getData(); if (this->attributes_[ORBIT].remove_attribute(ca)) { - typedef typename std::multimap*, AttributeHandlerGen*>::iterator IT; + typedef typename std::multimap::iterator IT; std::pair bounds = attribute_handlers_.equal_range(ca); for(IT i = bounds.first; i != bounds.second; ++i) (*i).second->set_invalid(); @@ -108,10 +109,14 @@ class MapBase : public MapBaseData template inline AttributeHandler< T, ORBIT> get_attribute(const std::string& attribute_name) { - ChunkArray* ca = this->attributes_[ORBIT].template get_attribute(attribute_name); + ChunkArray* ca = this->attributes_[ORBIT].template get_attribute(attribute_name); return AttributeHandler(this, ca); } +protected: + + std::multimap attribute_handlers_; + /******************************************************************************* * Basic traversals *******************************************************************************/ @@ -145,7 +150,7 @@ class MapBase : public MapBaseData // this->topology_.next(d.index); // } -//public: +public: class iterator { diff --git a/cgogn/core/map/map_base_data.h b/cgogn/core/map/map_base_data.h index 8c078f8d..2cbfa0b3 100644 --- a/cgogn/core/map/map_base_data.h +++ b/cgogn/core/map/map_base_data.h @@ -33,6 +33,7 @@ #include #include #include +#include namespace cgogn { @@ -42,6 +43,8 @@ namespace cgogn */ class MapGen { +public: + typedef MapGen Super; private: /// vector of Map instances @@ -66,31 +69,40 @@ class MapGen template class MapBaseData : public MapGen { +public: + typedef MapGen Inherit; + typedef MapBaseData Super; + + typedef std::integral_constant ChunkSizeType; + template + using ChunkArrayContainer = cgogn::ChunkArrayContainer; + template + using ChunkArray = cgogn::ChunkArray; + using ChunkArrayGen = cgogn::ChunkArrayGen; protected: - /// topology & embedding indices - ChunkArrayContainer topology_; + ChunkArrayContainer topology_; /// embedding attributes - ChunkArrayContainer attributes_[NB_ORBITS]; + ChunkArrayContainer attributes_[NB_ORBITS]; /// embedding indices shortcuts - ChunkArray* embeddings_[NB_ORBITS]; + ChunkArray* embeddings_[NB_ORBITS]; /// boundary markers shortcuts - ChunkArray* boundary_markers_[2]; + ChunkArray* boundary_markers_[2]; // TODO: ?? store in a std::vector ? /// topo relations shortcuts - std::vector*> topo_relations_; + std::vector*> topo_relations_; /// vector of available mark attributes per orbit per thread - std::vector*> mark_attributes_[NB_ORBITS][NB_THREADS]; + std::vector*> mark_attributes_[NB_ORBITS][NB_THREADS]; unsigned int mark_attribute_id_[NB_ORBITS]; std::mutex mark_attributes_mutex_[NB_ORBITS]; /// vector of available mark attributes per thread on the topology container - std::vector*> mark_attributes_topology_[NB_THREADS]; + std::vector*> mark_attributes_topology_[NB_THREADS]; unsigned int mark_attribute_topology_id_; std::mutex mark_attributes_topology_mutex_; @@ -99,10 +111,6 @@ class MapBaseData : public MapGen public: - typedef MapGen Inherit; - - static const unsigned int CHUNK_SIZE = DATA_TRAITS::CHUNK_SIZE; - MapBaseData() : Inherit() { for (unsigned int i = 0; i < NB_ORBITS; ++i) @@ -126,17 +134,17 @@ class MapBaseData : public MapGen * Containers management *******************************************************************************/ - inline ChunkArrayContainer& get_attribute_container(unsigned int orbit) + inline ChunkArrayContainer& get_attribute_container(unsigned int orbit) { return attributes_[orbit]; } - inline ChunkArray* get_topology_mark_attribute() + inline ChunkArray* get_topology_mark_attribute() { unsigned int thread = get_current_thread_index(); if (!mark_attributes_topology_[thread].empty()) { - ChunkArray* ca = mark_attributes_topology_[thread].back(); + ChunkArray* ca = mark_attributes_topology_[thread].back(); mark_attributes_topology_[thread].pop_back(); return ca; } @@ -150,26 +158,26 @@ class MapBaseData : public MapGen number[1] = '0'+char(x%10u); x /= 10u; number[0] = '0'+char(x%10u); - ChunkArray* ca = topology_.add_marker_attribute("marker_" + number); + ChunkArray* ca = topology_.add_marker_attribute("marker_" + number); return ca; } } - inline void release_topology_mark_attribute(ChunkArray* ca) + inline void release_topology_mark_attribute(ChunkArray* ca) { unsigned int thread = get_current_thread_index(); mark_attributes_topology_[thread].push_back(ca); } template - inline ChunkArray* get_mark_attribute() + inline ChunkArray* get_mark_attribute() { cgogn_message_assert(embeddings_[ORBIT] != NULL, "Invalid parameter: orbit not embedded"); unsigned int thread = get_current_thread_index(); if (!mark_attributes_[ORBIT][thread].empty()) { - ChunkArray* ca = mark_attributes_[ORBIT][thread].back(); + ChunkArray* ca = mark_attributes_[ORBIT][thread].back(); mark_attributes_[ORBIT][thread].pop_back(); return ca; } @@ -183,13 +191,13 @@ class MapBaseData : public MapGen number[1] = '0'+char(x%10u); x /= 10u; number[0] = '0'+char(x%10u); - ChunkArray* ca = attributes_[ORBIT].add_marker_attribute("marker_" + orbit_name(ORBIT) + number); + ChunkArray* ca = attributes_[ORBIT].add_marker_attribute("marker_" + orbit_name(ORBIT) + number); return ca; } } template - inline void release_mark_attribute(ChunkArray* ca) + inline void release_mark_attribute(ChunkArray* ca) { cgogn_message_assert(embeddings_[ORBIT] != NULL, "Invalid parameter: orbit not embedded"); diff --git a/cgogn/core/map/map_tri.h b/cgogn/core/map/map_tri.h index 6e9c1b8d..bae7ce43 100644 --- a/cgogn/core/map/map_tri.h +++ b/cgogn/core/map/map_tri.h @@ -37,6 +37,9 @@ class Traits_map_tri class MapTri : public MapBase { public: + + typedef MapBase Inherit; + typedef MapTri Self; ~MapTri() override {} }; diff --git a/cgogn/utils/buffers.h b/cgogn/utils/buffers.h index 3dae9178..b7ecdf4d 100644 --- a/cgogn/utils/buffers.h +++ b/cgogn/utils/buffers.h @@ -28,6 +28,7 @@ #include #include +#include namespace cgogn { @@ -35,6 +36,9 @@ namespace cgogn template class Buffers { + typedef T value_type; + typedef std::integral_constant DEFAULT_SIZE; + typedef std::integral_constant SHRINK_SIZE; protected: std::vector*> buffers_; @@ -54,7 +58,7 @@ class Buffers if (buffers_.empty()) { std::vector* v = new std::vector; - v->reserve(128); + v->reserve(DEFAULT_SIZE::value); return v; } @@ -65,9 +69,9 @@ class Buffers inline void release_buffer(std::vector* b) { - if (b->capacity() > 1024) + if (b->capacity() > SHRINK_SIZE::value) { - b->resize(128); + b->resize(DEFAULT_SIZE::value); b->shrink_to_fit(); } From 058ca7e2c342fec7834b4aebd405a650e3a73f17 Mon Sep 17 00:00:00 2001 From: Etienne Schmitt Date: Thu, 19 Nov 2015 15:20:37 +0100 Subject: [PATCH 101/185] fixed compilation under MSVC 2013 Signed-off-by: Etienne Schmitt --- cgogn/core/basic/cell_marker.h | 6 +++--- cgogn/core/basic/dart_marker.h | 14 ++++++-------- cgogn/core/map/map2.h | 4 ++-- cgogn/core/map/map_base_data.cpp | 7 ++----- cgogn/core/map/map_base_data.h | 2 +- cgogn/utils/thread.cpp | 26 +++++++++++++++++++++++++- cgogn/utils/thread.h | 20 +++++--------------- test/map/test_map.cpp | 4 ++-- 8 files changed, 46 insertions(+), 37 deletions(-) diff --git a/cgogn/core/basic/cell_marker.h b/cgogn/core/basic/cell_marker.h index d096f56c..3f9d1cd3 100644 --- a/cgogn/core/basic/cell_marker.h +++ b/cgogn/core/basic/cell_marker.h @@ -31,7 +31,7 @@ namespace cgogn { -class CellMarkerGen +class CGOGN_CORE_API CellMarkerGen { public: typedef CellMarkerGen Super; @@ -154,13 +154,13 @@ class CellMarkerStore : public CellMarkerT CellMarkerStore(Map& map) : Inherit(map) { - marked_cells_ = uint_buffers_thread->get_buffer(); + marked_cells_ = cgogn::getUINTBuffers()->get_buffer(); } ~CellMarkerStore() override { unmark_all(); - uint_buffers_thread->release_buffer(marked_cells_); + cgogn::getUINTBuffers()->release_buffer(marked_cells_); } CellMarkerStore(const Super& dm) = delete; diff --git a/cgogn/core/basic/dart_marker.h b/cgogn/core/basic/dart_marker.h index c47d9004..ed764e5d 100644 --- a/cgogn/core/basic/dart_marker.h +++ b/cgogn/core/basic/dart_marker.h @@ -30,7 +30,7 @@ namespace cgogn { -class DartMarkerGen +class CGOGN_CORE_API DartMarkerGen { public: typedef DartMarkerGen Super; @@ -67,19 +67,17 @@ class DartMarkerT : public DartMarkerGen Inherit(), map_(map) { - mark_attribute_ = map_.template get_topology_mark_attribute(); + mark_attribute_ = map_.get_topology_mark_attribute(); } ~DartMarkerT() override { if (MapGen::is_alive(&map_)) - map_.template release_topology_mark_attribute(mark_attribute_); + map_.release_topology_mark_attribute(mark_attribute_); } DartMarkerT(const Super& dm) = delete; - DartMarkerT(Super&& dm) = delete; DartMarkerT& operator=(Super& dm) = delete; - DartMarkerT& operator=(const Super& dm) = delete; inline void mark(Dart d) { @@ -125,8 +123,8 @@ class DartMarker : public DartMarkerT { public: - typedef DartMarker Super; typedef DartMarkerT Inherit; + typedef DartMarker Super; typedef MAP Map; DartMarker(MAP& map) : @@ -167,13 +165,13 @@ class DartMarkerStore : public DartMarkerT DartMarkerStore(Map& map) : Inherit(map) { - marked_darts_ = dart_buffers_thread->get_buffer(); + marked_darts_ = cgogn::getDartBuffers()->get_buffer(); } ~DartMarkerStore() override { unmark_all(); - dart_buffers_thread->release_buffer(marked_darts_); + cgogn::getDartBuffers()->release_buffer(marked_darts_); } DartMarkerStore(const Super& dm) = delete; diff --git a/cgogn/core/map/map2.h b/cgogn/core/map/map2.h index f3064e02..d3216b2a 100644 --- a/cgogn/core/map/map2.h +++ b/cgogn/core/map/map2.h @@ -156,7 +156,7 @@ class Map2 : public Map1 { DartMarkerStore marker(*this); // get a marker - std::vector* visited_faces = dart_buffers_thread->get_buffer(); + std::vector* visited_faces = cgogn::getDartBuffers()->get_buffer(); visited_faces->push_back(d); // Start with the face of d @@ -182,7 +182,7 @@ class Map2 : public Map1 } } - dart_buffers_thread->release_buffer(visited_faces); + cgogn::getDartBuffers()->release_buffer(visited_faces); } template diff --git a/cgogn/core/map/map_base_data.cpp b/cgogn/core/map/map_base_data.cpp index f7c63d20..423b3201 100644 --- a/cgogn/core/map/map_base_data.cpp +++ b/cgogn/core/map/map_base_data.cpp @@ -20,7 +20,7 @@ * Contact information: cgogn@unistra.fr * * * *******************************************************************************/ - +#define CGOGN_CORE_DLL_EXPORT #include namespace cgogn @@ -28,14 +28,11 @@ namespace cgogn std::vector* MapGen::instances_ = nullptr; -CGOGN_TLS Buffers* dart_buffers_thread = nullptr; -CGOGN_TLS Buffers* uint_buffers_thread = nullptr; - MapGen::MapGen() { if (instances_ == nullptr) instances_ = new std::vector; - + cgogn_message_assert(std::find(instances_->begin(), instances_->end(), this) == instances_->end(),"This map is already present in the instances vector."); // register the map in the vector of instances instances_->push_back(this); } diff --git a/cgogn/core/map/map_base_data.h b/cgogn/core/map/map_base_data.h index 2cbfa0b3..22c2c40a 100644 --- a/cgogn/core/map/map_base_data.h +++ b/cgogn/core/map/map_base_data.h @@ -41,7 +41,7 @@ namespace cgogn /** * @brief Generic Map class */ -class MapGen +class CGOGN_CORE_API MapGen { public: typedef MapGen Super; diff --git a/cgogn/utils/thread.cpp b/cgogn/utils/thread.cpp index dcf9d8c4..732be568 100644 --- a/cgogn/utils/thread.cpp +++ b/cgogn/utils/thread.cpp @@ -20,7 +20,7 @@ * Contact information: cgogn@unistra.fr * * * *******************************************************************************/ - +#define CGOGN_UTILS_DLL_EXPORT #include namespace cgogn @@ -29,4 +29,28 @@ namespace cgogn CGOGN_TLS Buffers* dart_buffers_thread = nullptr; CGOGN_TLS Buffers* uint_buffers_thread = nullptr; +CGOGN_UTILS_API void thread_start() +{ + if (dart_buffers_thread == nullptr) + dart_buffers_thread = new Buffers(); + + if (uint_buffers_thread == nullptr) + uint_buffers_thread = new Buffers(); +} + +CGOGN_UTILS_API void thread_stop() +{ + delete dart_buffers_thread; + delete uint_buffers_thread; +} + +CGOGN_UTILS_API Buffers* getDartBuffers() +{ + return dart_buffers_thread; +} +CGOGN_UTILS_API Buffers* getUINTBuffers() +{ + return uint_buffers_thread; +} + } // namespace cgogn diff --git a/cgogn/utils/thread.h b/cgogn/utils/thread.h index b6058490..86266c0b 100644 --- a/cgogn/utils/thread.h +++ b/cgogn/utils/thread.h @@ -25,7 +25,7 @@ #define UTILS_THREAD_H_ #include - +#include namespace cgogn { @@ -38,20 +38,10 @@ const unsigned int NB_THREADS = 8u; extern CGOGN_TLS Buffers* dart_buffers_thread; extern CGOGN_TLS Buffers* uint_buffers_thread; -inline void thread_start() -{ - if (dart_buffers_thread == nullptr) - dart_buffers_thread = new Buffers(); - - if (uint_buffers_thread == nullptr) - uint_buffers_thread = new Buffers(); -} - -inline void thread_stop() -{ - delete dart_buffers_thread; - delete uint_buffers_thread; -} +CGOGN_UTILS_API void thread_start(); +CGOGN_UTILS_API void thread_stop(); +CGOGN_UTILS_API Buffers* getDartBuffers(); +CGOGN_UTILS_API Buffers* getUINTBuffers(); } // namespace cgogn diff --git a/test/map/test_map.cpp b/test/map/test_map.cpp index d6b88390..29d27636 100644 --- a/test/map/test_map.cpp +++ b/test/map/test_map.cpp @@ -56,9 +56,9 @@ int test1(MAP1& map) // add an attribute on vertex of map with MAP1::VertexAttributeHandler ah = map.add_attribute("floats"); - std::vector* uib = cgogn::uint_buffers_thread->get_buffer(); + std::vector* uib = cgogn::getUINTBuffers()->get_buffer(); uib->push_back(3); - cgogn::uint_buffers_thread->release_buffer(uib); + cgogn::getUINTBuffers()->release_buffer(uib); Dart d = map.add_dart(); From c5126e70a4e38bf02d8fa150536ddd3cae0af38c Mon Sep 17 00:00:00 2001 From: Etienne Schmitt Date: Thu, 19 Nov 2015 15:22:03 +0100 Subject: [PATCH 102/185] small fix. Signed-off-by: Etienne Schmitt --- test/map/test_map.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/map/test_map.cpp b/test/map/test_map.cpp index 86a73a21..29d27636 100644 --- a/test/map/test_map.cpp +++ b/test/map/test_map.cpp @@ -101,6 +101,6 @@ int main() MAP1 map1; MAP2 map2; test1(map1); - //cgogn::thread_stop(); + cgogn::thread_stop(); return 0; } From eb763f8bdae9d8db7a48d6b030cd3d6f7c79cdba Mon Sep 17 00:00:00 2001 From: Pierre Kraemer Date: Thu, 19 Nov 2015 15:39:17 +0100 Subject: [PATCH 103/185] first global traversor with iterators --- cgogn/core/CMakeLists.txt | 1 + cgogn/core/basic/cell.h | 4 +- cgogn/core/basic/cell_marker.h | 20 ++- cgogn/core/basic/dart_marker.h | 20 ++- cgogn/core/container/chunk_array_container.h | 128 +++++++++---------- cgogn/core/container/chunk_array_factory.h | 9 +- cgogn/core/map/map1.h | 48 ++++--- cgogn/core/map/map2.h | 40 ++++-- cgogn/core/map/map_base.h | 90 ++++++------- cgogn/core/map/map_base_data.h | 29 +---- cgogn/core/traversal/global.h | 64 ++++++++++ cgogn/core/traversal/traversor_cell.h | 81 ++++++++++++ test/map/test_map.cpp | 8 ++ 13 files changed, 370 insertions(+), 172 deletions(-) create mode 100644 cgogn/core/traversal/global.h diff --git a/cgogn/core/CMakeLists.txt b/cgogn/core/CMakeLists.txt index 3e5467ba..cee7aeaf 100644 --- a/cgogn/core/CMakeLists.txt +++ b/cgogn/core/CMakeLists.txt @@ -24,6 +24,7 @@ set(HEADER_FILES map/map_tri.h map/attribute_handler.h + traversal/global.h traversal/traversor_cell.h ) diff --git a/cgogn/core/basic/cell.h b/cgogn/core/basic/cell.h index 3c501456..bbe8a224 100644 --- a/cgogn/core/basic/cell.h +++ b/cgogn/core/basic/cell.h @@ -76,10 +76,12 @@ class Cell { public: + static const unsigned int Orbit = ORBIT; + Dart dart; /** - * \brief Constructs a new empty Cell with NIL dart. + * \brief Constructs a new empty Cell with NIL dart. */ inline Cell() : dart() {} diff --git a/cgogn/core/basic/cell_marker.h b/cgogn/core/basic/cell_marker.h index 21baa3cf..d7367fcb 100644 --- a/cgogn/core/basic/cell_marker.h +++ b/cgogn/core/basic/cell_marker.h @@ -62,6 +62,13 @@ class CellMarkerT : public CellMarkerGen mark_attribute_ = map_.template get_mark_attribute(); } + CellMarkerT(const MAP& map) : + CellMarkerGen(), + map_(const_cast(map)) + { + mark_attribute_ = map_.template get_mark_attribute(); + } + ~CellMarkerT() override { if (MapGen::is_alive(&map_)) @@ -85,7 +92,7 @@ class CellMarkerT : public CellMarkerGen mark_attribute_->set_false(map_.get_embedding(c)); } - inline void is_marked(Cell c) const + inline bool is_marked(Cell c) const { cgogn_message_assert(mark_attribute_ != nullptr, "CellMarker has null mark attribute"); return (*mark_attribute_)[map_.get_embedding(c)]; @@ -103,6 +110,10 @@ class CellMarker : public CellMarkerT Inherit(map) {} + CellMarker(const MAP& map) : + Inherit(map) + {} + ~CellMarker() override { unmark_all() ; @@ -137,6 +148,12 @@ class CellMarkerStore : public CellMarkerT marked_cells_ = uint_buffers_thread->get_buffer(); } + CellMarkerStore(const MAP& map) : + Inherit(map) + { + marked_cells_ = uint_buffers_thread->get_buffer(); + } + ~CellMarkerStore() override { unmark_all(); @@ -162,6 +179,7 @@ class CellMarkerStore : public CellMarkerT { this->mark_attribute_->set_false(i); } + marked_cells_->clear(); } }; diff --git a/cgogn/core/basic/dart_marker.h b/cgogn/core/basic/dart_marker.h index 56e2b7d7..3aced539 100644 --- a/cgogn/core/basic/dart_marker.h +++ b/cgogn/core/basic/dart_marker.h @@ -62,6 +62,13 @@ class DartMarkerT : public DartMarkerGen mark_attribute_ = map_.template get_topology_mark_attribute(); } + DartMarkerT(const MAP& map) : + DartMarkerGen(), + map_(const_cast(map)) + { + mark_attribute_ = map_.template get_topology_mark_attribute(); + } + ~DartMarkerT() override { if (MapGen::is_alive(&map_)) @@ -85,7 +92,7 @@ class DartMarkerT : public DartMarkerGen mark_attribute_->set_false(d.index); } - inline void is_marked(Dart d) const + inline bool is_marked(Dart d) const { cgogn_message_assert(mark_attribute_ != nullptr, "DartMarker has null mark attribute"); return (*mark_attribute_)[d.index]; @@ -123,6 +130,10 @@ class DartMarker : public DartMarkerT Inherit(map) {} + DartMarker(const MAP& map) : + Inherit(map) + {} + ~DartMarker() override { unmark_all() ; @@ -157,6 +168,12 @@ class DartMarkerStore : public DartMarkerT marked_darts_ = dart_buffers_thread->get_buffer(); } + DartMarkerStore(const MAP& map) : + Inherit(map) + { + marked_darts_ = dart_buffers_thread->get_buffer(); + } + ~DartMarkerStore() override { unmark_all(); @@ -193,6 +210,7 @@ class DartMarkerStore : public DartMarkerT { Inherit::unmark(d); } + marked_darts_->clear(); } }; diff --git a/cgogn/core/container/chunk_array_container.h b/cgogn/core/container/chunk_array_container.h index c2b7d067..68b8b7f8 100644 --- a/cgogn/core/container/chunk_array_container.h +++ b/cgogn/core/container/chunk_array_container.h @@ -92,7 +92,7 @@ class ChunkArrayContainer protected: /** - * vector of pointers to ChunkVector + * vector of pointers to ChunkArray */ std::vector*> table_arrays_; @@ -100,6 +100,14 @@ class ChunkArrayContainer std::vector type_names_; + /** + * vector of pointers to Marker ChunkArray + */ + std::vector*> table_marker_arrays_; + + /** + * @brief ChunkArray of refs + */ ChunkArray refs_; /** @@ -117,11 +125,6 @@ class ChunkArrayContainer */ unsigned int nb_max_lines_; - /** - * @brief number of bool attribs (which are alway in front of all others) - */ - unsigned int nb_marker_attribs_; - /** * Browser that allow special traversals */ @@ -140,7 +143,7 @@ class ChunkArrayContainer */ unsigned int get_array_index(const std::string& attribute_name) const { - for (unsigned int i = 0; i != names_.size(); ++i) + for (unsigned int i = 0u; i != names_.size(); ++i) { if (names_[i] == attribute_name) return i; @@ -165,30 +168,15 @@ class ChunkArrayContainer } /** - * @brief remove an attribute by its name - * @param attribName name of attribute to remove - * @return true if attribute exist and has been removed + * @brief remove an attribute by its index + * @param index index of attribute to remove + * @return true if attribute exists and has been removed */ - bool remove_attribute(unsigned int index) + void remove_attribute(unsigned int index) { // store ptr for using it before delete ChunkArrayGen* ptr_to_del = table_arrays_[index]; - // in case of Marker attribute, keep Marker attributes first ! - if (index < nb_marker_attribs_) - { - nb_marker_attribs_--; - - if (index < nb_marker_attribs_) // if attribute is not last of Markers - { - table_arrays_[index] = table_arrays_[nb_marker_attribs_]; // copy last of boolean on index - names_[index] = names_[nb_marker_attribs_]; - type_names_[index] = type_names_[nb_marker_attribs_]; - } - // now overwrite last of bool with last - index = nb_marker_attribs_; - } - if (index != table_arrays_.size() - std::size_t(1u)) { table_arrays_[index] = table_arrays_.back(); @@ -201,8 +189,6 @@ class ChunkArrayContainer type_names_.pop_back(); delete ptr_to_del; - - return true; } public: @@ -213,7 +199,6 @@ class ChunkArrayContainer ChunkArrayContainer(): nb_used_lines_(0u), nb_max_lines_(0u), - nb_marker_attribs_(0), std_browser_(make_unique< ContainerStandardBrowser > >(this)) { current_browser_= std_browser_.get(); @@ -231,8 +216,12 @@ class ChunkArrayContainer { if (current_browser_ != std_browser_.get()) delete current_browser_; + for (auto ptr : table_arrays_) delete ptr; + + for (auto ptr : table_marker_arrays_) + delete ptr; } /** @@ -242,7 +231,7 @@ class ChunkArrayContainer * @return pointer on attribute ChunkArray */ template - ChunkArray* get_attribute(const std::string& attribute_name) + ChunkArray* get_attribute(const std::string& attribute_name) const { // first check if attribute already exist unsigned int index = get_array_index(attribute_name); @@ -276,7 +265,7 @@ class ChunkArrayContainer // create the new attribute const std::string& typeName = name_of_type(T()); - ChunkArray* carr = new ChunkArray(); + ChunkArray* carr = new ChunkArray(); ChunkArrayFactory::template register_CA(); // reserve memory @@ -290,30 +279,6 @@ class ChunkArrayContainer return carr ; } - /** - * @brief add a Marker attribute - * @param attribute_name name of marker attribute - * @return pointer on created ChunkArray - */ - ChunkArray* add_marker_attribute(const std::string& attribute_name) - { - ChunkArray* ptr = add_attribute(attribute_name); - - if (table_arrays_.size() > nb_marker_attribs_) - { - // swap ptrs - auto tmp = table_arrays_.back(); - table_arrays_.back() = table_arrays_[nb_marker_attribs_]; - table_arrays_[nb_marker_attribs_] = tmp; - // swap names & typenames - names_.back().swap(names_[nb_marker_attribs_]); - type_names_.back().swap(type_names_[nb_marker_attribs_]); - } - nb_marker_attribs_++; - - return ptr; - } - /** * @brief remove an attribute by its name * @param attribute_name name of attribute to remove @@ -345,7 +310,7 @@ class ChunkArrayContainer if (index == UNKNOWN) { - std::cerr << "removeAttribute by ptr: attribute not found" << std::endl; + std::cerr << "remove_attribute by ptr: attribute not found" << std::endl; return false; } @@ -354,6 +319,41 @@ class ChunkArrayContainer return true; } + /** + * @brief add a Marker attribute + * @return pointer on created ChunkArray + */ + ChunkArray* add_marker_attribute() + { + ChunkArray* mca = new ChunkArray(); + mca->set_nb_chunks(refs_.get_nb_chunks()); + table_marker_arrays_.push_back(mca); + return mca; + } + + /** + * @brief remove a marker attribute by its ChunkArray pointer + * @param ptr ChunkArray pointer to the attribute to remove + * @return true if attribute exists and has been removed + */ + void remove_marker_attribute(const ChunkArray* ptr) + { + unsigned int index = 0u; + while (table_marker_arrays_[index] != ptr && index < table_marker_arrays_.size()) + ++index; + + cgogn_message_assert(index != table_marker_arrays_.size(), "remove_marker_attribute by ptr: attribute not found"); + + if (index != table_marker_arrays_.size() - std::size_t(1u)) + { + table_marker_arrays_[index] = table_marker_arrays_.back(); + } + + table_marker_arrays_.pop_back(); + + delete ptr; + } + /** * @brief Number of attributes of the container * @return number of attributes @@ -704,7 +704,6 @@ class ChunkArrayContainer cgogn_message_assert(used(index), "initLine only with allocated lines"); for (auto ptr : table_arrays_) - // if (ptr != nullptr) never null ! ptr->init_element(index); } @@ -712,8 +711,8 @@ class ChunkArrayContainer { cgogn_message_assert(used(index), "initMarkersOfLine only with allocated lines"); - for (unsigned int i = 0u; i < nb_marker_attribs_; ++i) - table_arrays_[i]->init_element(index); + for (ChunkArray* ptr : table_marker_arrays_) + ptr->set_false(index); } /** @@ -777,13 +776,14 @@ class ChunkArrayContainer buffer.push_back(static_cast(table_arrays_.size())); buffer.push_back(nb_used_lines_); buffer.push_back(nb_max_lines_); - buffer.push_back(nb_marker_attribs_); + for(unsigned int i = 0u; i < table_arrays_.size(); ++i) { buffer.push_back(static_cast(names_[i].size()+1)); buffer.push_back(static_cast(type_names_[i].size()+1)); } - fs.write(reinterpret_cast(&(buffer[0])),std::streamsize(buffer.size()*sizeof(unsigned int))); + + fs.write(reinterpret_cast(&(buffer[0])), std::streamsize(buffer.size()*sizeof(unsigned int))); // save names for(unsigned int i = 0; i < table_arrays_.size(); ++i) @@ -799,6 +799,7 @@ class ChunkArrayContainer { table_arrays_[i]->save(fs, nb_max_lines_); } + // save uses/refs refs_.save(fs, nb_max_lines_); @@ -810,11 +811,10 @@ class ChunkArrayContainer { // read info unsigned int buff1[4]; - fs.read(reinterpret_cast(buff1), 4u*sizeof(unsigned int)); + fs.read(reinterpret_cast(buff1), 3u*sizeof(unsigned int)); nb_used_lines_ = buff1[1]; nb_max_lines_ = buff1[2]; - nb_marker_attribs_ = buff1[3]; std::vector buff2(2u*buff1[0]); fs.read(reinterpret_cast(&(buff2[0])), std::streamsize(2u*buff1[0]*sizeof(unsigned int))); @@ -835,7 +835,7 @@ class ChunkArrayContainer // read chunk array table_arrays_.resize(buff1[0]); - bool ok=true; + bool ok = true; for (unsigned int i = 0u; i < buff1[0]; ++i) { table_arrays_[i] = ChunkArrayFactory::create(type_names_[i]); diff --git a/cgogn/core/container/chunk_array_factory.h b/cgogn/core/container/chunk_array_factory.h index d4a07852..7a37d229 100644 --- a/cgogn/core/container/chunk_array_factory.h +++ b/cgogn/core/container/chunk_array_factory.h @@ -31,6 +31,7 @@ #include #include #include + namespace cgogn { @@ -39,9 +40,9 @@ class ChunkArrayFactory { public: typedef std::unique_ptr< ChunkArrayGen > ChunkArrayGenPtr; - typedef std::map Map; + typedef std::map NamePtrMap; - static Map map_CA_; + static NamePtrMap map_CA_; /** * @brief register a type @@ -64,7 +65,7 @@ class ChunkArrayFactory static ChunkArrayGen* create(const std::string& keyType) { ChunkArrayGen* tmp = nullptr; - typename Map::const_iterator it = map_CA_.find(keyType); + typename NamePtrMap::const_iterator it = map_CA_.find(keyType); if(it != map_CA_.end()) { @@ -78,7 +79,7 @@ class ChunkArrayFactory }; template -typename ChunkArrayFactory::Map ChunkArrayFactory::map_CA_= typename ChunkArrayFactory::Map(); +typename ChunkArrayFactory::NamePtrMap ChunkArrayFactory::map_CA_= typename ChunkArrayFactory::NamePtrMap(); } // namespace cgogn diff --git a/cgogn/core/map/map1.h b/cgogn/core/map/map1.h index 84d6d63a..9b7bde45 100644 --- a/cgogn/core/map/map1.h +++ b/cgogn/core/map/map1.h @@ -46,6 +46,10 @@ class Map1 : public MapBase static const unsigned int EDGE = VERTEX1; static const unsigned int FACE = FACE2; + typedef Cell Vertex; + typedef Cell Edge; + typedef Cell Face; + template using VertexAttributeHandler = cgogn::AttributeHandler; @@ -57,12 +61,13 @@ class Map1 : public MapBase protected: + ChunkArray* phi1_; + ChunkArray* phi_1_; + void init() { - ChunkArray* phi1 = this->topology_.template add_attribute("phi1"); - ChunkArray* phi_1 = this->topology_.template add_attribute("phi_1"); - this->topo_relations_.push_back(phi1); - this->topo_relations_.push_back(phi_1); + phi1_ = this->topology_.template add_attribute("phi1"); + phi_1_ = this->topology_.template add_attribute("phi_1"); } /******************************************************************************* @@ -83,10 +88,10 @@ class Map1 : public MapBase { Dart f = phi1(d); Dart g = phi1(e); - (*(this->topo_relations_[0]))[d.index] = g; - (*(this->topo_relations_[0]))[e.index] = f; - (*(this->topo_relations_[1]))[g.index] = d; - (*(this->topo_relations_[1]))[f.index] = e; + (*phi1_)[d.index] = g; + (*phi1_)[e.index] = f; + (*phi_1_)[g.index] = d; + (*phi_1_)[f.index] = e; } /** @@ -99,10 +104,10 @@ class Map1 : public MapBase { Dart e = phi1(d); Dart f = phi1(e); - (*(this->topo_relations_[0]))[d.index] = f; - (*(this->topo_relations_[0]))[e.index] = e; - (*(this->topo_relations_[1]))[f.index] = d; - (*(this->topo_relations_[1]))[e.index] = e; + (*phi1_)[d.index] = f; + (*phi1_)[e.index] = e; + (*phi_1_)[f.index] = d; + (*phi_1_)[e.index] = e; } public: @@ -126,7 +131,7 @@ class Map1 : public MapBase */ inline Dart phi1(Dart d) const { - return (*(this->topo_relations_[0]))[d.index]; + return (*phi1_)[d.index]; } /** @@ -136,7 +141,7 @@ class Map1 : public MapBase */ Dart phi_1(Dart d) const { - return (*(this->topo_relations_[1]))[d.index]; + return (*phi_1_)[d.index]; } /** @@ -156,8 +161,8 @@ class Map1 : public MapBase Dart d(di); - for (auto ptr : this->topo_relations_) - (*ptr)[di] = d; + (*phi1_)[di] = d; + (*phi_1_)[di] = d; return d; } @@ -228,12 +233,6 @@ class Map1 : public MapBase f(d); } - template - inline void foreach_dart_of_edge(Dart d, const FUNC& f) const - { - f(d); - } - template inline void foreach_dart_of_face(Dart d, const FUNC& f) const { @@ -250,9 +249,8 @@ class Map1 : public MapBase { switch(ORBIT) { - case Map1::VERTEX: f(c); break; - case Map1::EDGE: foreach_dart_of_edge(c, f); break; - case Map1::FACE: foreach_dart_of_face(c, f); break; + case VERTEX1: foreach_dart_of_vertex(c, f); break; + case FACE2: foreach_dart_of_face(c, f); break; default: cgogn_assert_not_reached("Cells of this dimension are not handled"); break; } } diff --git a/cgogn/core/map/map2.h b/cgogn/core/map/map2.h index 5baaee62..ff309ecb 100644 --- a/cgogn/core/map/map2.h +++ b/cgogn/core/map/map2.h @@ -42,6 +42,11 @@ class Map2 : public Map1 static const unsigned int FACE = FACE2; static const unsigned int VOLUME = VOLUME3; + typedef Cell Vertex; + typedef Cell Edge; + typedef Cell Face; + typedef Cell Volume; + template using VertexAttributeHandler = cgogn::AttributeHandler; @@ -53,10 +58,11 @@ class Map2 : public Map1 protected: + ChunkArray* phi2_; + void init() { - ChunkArray* phi2 = this->topology_.template add_attribute("phi2"); - this->topo_relations_.push_back(phi2); + phi2_ = this->topology_.template add_attribute("phi2"); } /******************************************************************************* @@ -73,8 +79,8 @@ class Map2 : public Map1 { cgogn_assert(phi2(d) == d); cgogn_assert(phi2(e) == e); - (*(this->topo_relations_[2]))[d.index] = e; - (*(this->topo_relations_[2]))[e.index] = d; + (*phi2_)[d.index] = e; + (*phi2_)[e.index] = d; } /** @@ -86,8 +92,8 @@ class Map2 : public Map1 void phi2_unsew(Dart d) { Dart e = phi2(d) ; - (*(this->topo_relations_[2]))[d.index] = d; - (*(this->topo_relations_[2]))[e.index] = e; + (*phi2_)[d.index] = d; + (*phi2_)[e.index] = e; } public: @@ -115,6 +121,19 @@ class Map2 : public Map1 return (*(this->topo_relations_[2]))[d.index]; } + /** + * \brief add a Dart in the map + * @return the new Dart + */ + inline Dart add_dart() + { + Dart d = Inherit::add_dart(); + + (*phi2_)[d.index] = d; + + return d; + } + /******************************************************************************* * Orbits traversal *******************************************************************************/ @@ -182,10 +201,11 @@ class Map2 : public Map1 { switch(ORBIT) { - case Map2::VERTEX: f(c); break; - case Map2::EDGE: foreach_dart_of_edge(c, f); break; - case Map2::FACE: foreach_dart_of_face(c, f); break; - case Map2::VOLUME: foreach_dart_of_volume(c, f); break; + case VERTEX1: f(c); break; + case VERTEX2: foreach_dart_of_vertex(c, f); break; + case EDGE2: foreach_dart_of_edge(c, f); break; + case FACE2: foreach_dart_of_face(c, f); break; + case VOLUME3: foreach_dart_of_volume(c, f); break; default: cgogn_assert_not_reached("Cells of this dimension are not handled"); break; } } diff --git a/cgogn/core/map/map_base.h b/cgogn/core/map/map_base.h index 476cd9f2..0cf34c18 100644 --- a/cgogn/core/map/map_base.h +++ b/cgogn/core/map/map_base.h @@ -147,59 +147,61 @@ class MapBase : public MapBaseData //public: - class iterator - { - public: - MapBase* const map_; - Dart dart_; - - inline iterator(MapBase* map, Dart d) : - map_(map), - dart_(d) - {} - - inline iterator& operator++() - { - map_->topology_.next(dart_.index); - return *this; - } - - inline Dart& operator*() - { - return dart_; - } - - inline bool operator!=(iterator it) const - { - cgogn_assert(map_ == it.map_); - return dart_ != it.dart_; - } - }; - - inline iterator begin() - { - return iterator(this, Dart(this->topology_.begin())); - } +// class iterator +// { +// public: + +// MapBase* const map_; +// Dart dart_; + +// inline iterator(MapBase* map, Dart d) : +// map_(map), +// dart_(d) +// {} + +// inline iterator& operator++() +// { +// map_->topology_.next(dart_.index); +// return *this; +// } + +// inline Dart& operator*() +// { +// return dart_; +// } + +// inline bool operator!=(iterator it) const +// { +// cgogn_assert(map_ == it.map_); +// return dart_ != it.dart_; +// } +// }; + +// inline iterator begin() +// { +// return iterator(this, Dart(this->topology_.begin())); +// } - inline iterator end() - { - return iterator(this, Dart(this->topology_.end())); - } +// inline iterator end() +// { +// return iterator(this, Dart(this->topology_.end())); +// } class const_iterator { public: - const MapBase* const map_; + + const MapBase& map_; Dart dart_; - inline const_iterator(const MapBase* map, Dart d) : + inline const_iterator(const MapBase& map, Dart d) : map_(map), dart_(d) {} inline const_iterator& operator++() { - map_->topology_.next(dart_.index); + map_.topology_.next(dart_.index); return *this; } @@ -208,21 +210,21 @@ class MapBase : public MapBaseData return dart_; } - inline bool operator!=(iterator it) const + inline bool operator!=(const_iterator it) const { - cgogn_assert(map_ == it.map_); + cgogn_assert(&map_ == &(it.map_)); return dart_ != it.dart_; } }; inline const_iterator begin() const { - return const_iterator(this, Dart(this->topology_.begin())); + return const_iterator(*this, Dart(this->topology_.begin())); } inline const_iterator end() const { - return const_iterator(this, Dart(this->topology_.end())); + return const_iterator(*this, Dart(this->topology_.end())); } /** diff --git a/cgogn/core/map/map_base_data.h b/cgogn/core/map/map_base_data.h index 8c078f8d..8a9fd5c4 100644 --- a/cgogn/core/map/map_base_data.h +++ b/cgogn/core/map/map_base_data.h @@ -81,17 +81,12 @@ class MapBaseData : public MapGen ChunkArray* boundary_markers_[2]; // TODO: ?? store in a std::vector ? - /// topo relations shortcuts - std::vector*> topo_relations_; - /// vector of available mark attributes per orbit per thread std::vector*> mark_attributes_[NB_ORBITS][NB_THREADS]; - unsigned int mark_attribute_id_[NB_ORBITS]; std::mutex mark_attributes_mutex_[NB_ORBITS]; /// vector of available mark attributes per thread on the topology container std::vector*> mark_attributes_topology_[NB_THREADS]; - unsigned int mark_attribute_topology_id_; std::mutex mark_attributes_topology_mutex_; /// vector of thread ids known by the map that can pretend to data such as mark vectors @@ -108,7 +103,6 @@ class MapBaseData : public MapGen for (unsigned int i = 0; i < NB_ORBITS; ++i) { embeddings_[i] = nullptr; - mark_attribute_id_[i] = 0; for (unsigned int j = 0; j < NB_THREADS; ++j) { mark_attributes_[i][j].reserve(8); @@ -131,6 +125,11 @@ class MapBaseData : public MapGen return attributes_[orbit]; } + inline const ChunkArrayContainer& get_attribute_container(unsigned int orbit) const + { + return attributes_[orbit]; + } + inline ChunkArray* get_topology_mark_attribute() { unsigned int thread = get_current_thread_index(); @@ -143,14 +142,7 @@ class MapBaseData : public MapGen else { std::lock_guard lock(mark_attributes_topology_mutex_); - - unsigned int x = mark_attribute_topology_id_++; - std::string number("___"); - number[2] = '0'+char(x%10u); x /= 10u; - number[1] = '0'+char(x%10u); x /= 10u; - number[0] = '0'+char(x%10u); - - ChunkArray* ca = topology_.add_marker_attribute("marker_" + number); + ChunkArray* ca = topology_.add_marker_attribute(); return ca; } } @@ -176,14 +168,7 @@ class MapBaseData : public MapGen else { std::lock_guard lock(mark_attributes_mutex_[ORBIT]); - - unsigned int x = mark_attribute_id_[ORBIT]++; - std::string number("___"); - number[2] = '0'+char(x%10u); x /= 10u; - number[1] = '0'+char(x%10u); x /= 10u; - number[0] = '0'+char(x%10u); - - ChunkArray* ca = attributes_[ORBIT].add_marker_attribute("marker_" + orbit_name(ORBIT) + number); + ChunkArray* ca = attributes_[ORBIT].add_marker_attribute(); return ca; } } diff --git a/cgogn/core/traversal/global.h b/cgogn/core/traversal/global.h new file mode 100644 index 00000000..ed9415bc --- /dev/null +++ b/cgogn/core/traversal/global.h @@ -0,0 +1,64 @@ +/******************************************************************************* +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * +* Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France * +* * +* This library is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by the * +* Free Software Foundation; either version 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: http://cgogn.unistra.fr/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ + +#ifndef CORE_TRAVERSAL_GLOBAL_H_ +#define CORE_TRAVERSAL_GLOBAL_H_ + +#include + +namespace cgogn +{ + +template +inline TraversorCell cells(MAP& map) +{ + return TraversorCell(map); +} + +template +inline TraversorCell vertices(MAP& map) +{ + return TraversorCell(map); +} + +template +inline TraversorCell edges(MAP& map) +{ + return TraversorCell(map); +} + +template +inline TraversorCell faces(MAP& map) +{ + return TraversorCell(map); +} + +template +inline TraversorCell volumes(MAP& map) +{ + return TraversorCell(map); +} + +} // namespace cgogn + +#endif // CORE_TRAVERSAL_GLOBAL_H_ diff --git a/cgogn/core/traversal/traversor_cell.h b/cgogn/core/traversal/traversor_cell.h index c9ea711b..a73ef43d 100644 --- a/cgogn/core/traversal/traversor_cell.h +++ b/cgogn/core/traversal/traversor_cell.h @@ -24,13 +24,94 @@ #ifndef CORE_TRAVERSAL_TRAVERSORCELL_H_ #define CORE_TRAVERSAL_TRAVERSORCELL_H_ +#include +#include + namespace cgogn { template class TraversorCell { +protected: + + MAP& map_; + DartMarker* dm_; + +public: + + TraversorCell(MAP& map) : + map_(map) + { + dm_ = new DartMarker(map_); + } + + virtual ~TraversorCell() + { + delete dm_; + } + + class iterator + { + public: + + TraversorCell& traversor_; + typename MAP::const_iterator map_it_; + + inline iterator(TraversorCell& t) : + traversor_(t), + map_it_(t.map_.begin()) + { +// unsigned int dim = map_.dimension(); +// while(map_it_ != map_.end() && map_.is_boundary_marked(dim, *map_it_)) +// ++map_it_; + + if (map_it_ != traversor_.map_.end()) + traversor_.dm_->template mark_orbit(*map_it_); + } + + inline iterator(TraversorCell& t, typename MAP::const_iterator it) : + traversor_(t), + map_it_(it) + { +// unsigned int dim = map_.dimension(); +// while(map_it_ != map_.end() && map_.is_boundary_marked(dim, *map_it_)) +// ++map_it_; + + if (map_it_ != traversor_.map_.end()) + traversor_.dm_->template mark_orbit(*map_it_); + } + + inline iterator& operator++() + { + cgogn_message_assert(map_it_ != traversor_.map_.end(), "TraversorCell: iterator ++ after end"); + while (map_it_ != traversor_.map_.end() && (traversor_.dm_->is_marked(*map_it_) /*|| traversor_.map_.is_boundary_marked(dim, *it)*/)) + ++map_it_; + if (map_it_ != traversor_.map_.end()) + traversor_.dm_->template mark_orbit(*map_it_); + return *this; + } + + inline Cell operator*() + { + return Cell(*map_it_); + } + + inline bool operator!=(iterator it) const + { + return map_it_ != it.map_it_; + } + }; + + inline iterator begin() + { + return iterator(*this); + } + inline iterator end() + { + return iterator(*this, map_.end()); + } }; } // namespace cgogn diff --git a/test/map/test_map.cpp b/test/map/test_map.cpp index d6b88390..08c0fb33 100644 --- a/test/map/test_map.cpp +++ b/test/map/test_map.cpp @@ -5,6 +5,8 @@ #include #include +#include + using namespace cgogn; @@ -73,6 +75,12 @@ int test1(MAP1& map) std::cout << dit << std::endl; } + std::cout << "Vertices :" << std::endl; + for (MAP1::Vertex v : vertices(map)) + { + std::cout << v << std::endl; + } + // get ChunkArrayContainer -> get ChunkArray -> fill ChunkArrayContainer& container = map.get_attribute_container(VERTEX1); ChunkArray* att = container.get_attribute("floats"); From 19c65c8ccfc94b579ddafa1397fc3da14ea617c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Schmitt?= Date: Thu, 19 Nov 2015 17:13:50 +0100 Subject: [PATCH 104/185] * fixed wrong use of "Super". Using "Self" instead. * fixed wrong type aliases in map2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Étienne Schmitt --- cgogn/core/basic/cell_marker.h | 44 ++++++++--------- cgogn/core/basic/dart_marker.h | 38 +++++++-------- cgogn/core/container/chunk_array.h | 26 +++++++--- cgogn/core/container/chunk_array_container.h | 51 ++++++++++++-------- cgogn/core/container/chunk_array_factory.h | 9 ++-- cgogn/core/container/chunk_array_gen.h | 5 +- cgogn/core/container/chunk_stack.h | 16 ++++-- cgogn/core/map/attribute_handler.h | 45 +++++++++-------- cgogn/core/map/map1.h | 17 ++++--- cgogn/core/map/map2.h | 19 ++++---- cgogn/core/map/map_base.h | 2 +- cgogn/core/map/map_base_data.h | 13 ++--- cgogn/core/map/map_tri.h | 2 +- 13 files changed, 162 insertions(+), 125 deletions(-) diff --git a/cgogn/core/basic/cell_marker.h b/cgogn/core/basic/cell_marker.h index 3f9d1cd3..36d589a7 100644 --- a/cgogn/core/basic/cell_marker.h +++ b/cgogn/core/basic/cell_marker.h @@ -34,16 +34,16 @@ namespace cgogn class CGOGN_CORE_API CellMarkerGen { public: - typedef CellMarkerGen Super; + typedef CellMarkerGen Self; CellMarkerGen() {} virtual ~CellMarkerGen(); - CellMarkerGen(const Super& dm) = delete; - CellMarkerGen(Super&& dm) = delete; - CellMarkerGen& operator=(Super&& dm) = delete; - CellMarkerGen& operator=(const Super& dm) = delete; + CellMarkerGen(const Self& dm) = delete; + CellMarkerGen(Self&& dm) = delete; + CellMarkerGen& operator=(Self&& dm) = delete; + CellMarkerGen& operator=(const Self& dm) = delete; }; template @@ -53,12 +53,12 @@ class CellMarkerT : public CellMarkerGen static_assert(ORBIT <= VOLUME3, "ORBIT must be less than or equal to VOLUME3"); public: typedef CellMarkerGen Inherit; - typedef CellMarkerT< MAP, ORBIT > Super; + typedef CellMarkerT< MAP, ORBIT > Self; typedef std::integral_constant Orbit; typedef MAP Map; - typedef typename Map::ChunkSizeType ChunkSizeType; - typedef ChunkArray ChunkArrayBool; + typedef typename Map::chunksize_type chunksize_type; + typedef ChunkArray ChunkArrayBool; protected: @@ -80,10 +80,10 @@ class CellMarkerT : public CellMarkerGen map_.template release_mark_attribute(mark_attribute_); } - CellMarkerT(const Super& dm) = delete; - CellMarkerT(Super&& dm) = delete; - CellMarkerT& operator=(Super&& dm) = delete; - CellMarkerT& operator=(const Super& dm) = delete; + CellMarkerT(const Self& dm) = delete; + CellMarkerT(Self&& dm) = delete; + CellMarkerT& operator=(Self&& dm) = delete; + CellMarkerT& operator=(const Self& dm) = delete; inline void mark(Cell c) { @@ -109,7 +109,7 @@ class CellMarker : public CellMarkerT { public: typedef CellMarkerT Inherit; - typedef CellMarker< MAP, ORBIT > Super; + typedef CellMarker< MAP, ORBIT > Self; typedef typename Inherit::Orbit Orbit; typedef typename Inherit::Map Map; @@ -123,10 +123,10 @@ class CellMarker : public CellMarkerT unmark_all() ; } - CellMarker(const Super& dm) = delete; - CellMarker(Super&& dm) = delete; - CellMarker& operator=(Super&& dm) = delete; - CellMarker& operator=(const Super& dm) = delete; + CellMarker(const Self& dm) = delete; + CellMarker(Self&& dm) = delete; + CellMarker& operator=(Self&& dm) = delete; + CellMarker& operator=(const Self& dm) = delete; inline void unmark_all() { @@ -140,7 +140,7 @@ class CellMarkerStore : public CellMarkerT { public: typedef CellMarkerT Inherit; - typedef CellMarkerStore< MAP, ORBIT > Super; + typedef CellMarkerStore< MAP, ORBIT > Self; typedef typename Inherit::Orbit Orbit; typedef typename Inherit::Map Map; @@ -163,10 +163,10 @@ class CellMarkerStore : public CellMarkerT cgogn::getUINTBuffers()->release_buffer(marked_cells_); } - CellMarkerStore(const Super& dm) = delete; - CellMarkerStore(Super&& dm) = delete; - CellMarkerStore& operator=(Super&& dm) = delete; - CellMarkerStore& operator=(const Super& dm) = delete; + CellMarkerStore(const Self& dm) = delete; + CellMarkerStore(Self&& dm) = delete; + CellMarkerStore& operator=(Self&& dm) = delete; + CellMarkerStore& operator=(const Self& dm) = delete; inline void mark(Cell c) { diff --git a/cgogn/core/basic/dart_marker.h b/cgogn/core/basic/dart_marker.h index ed764e5d..bbb8f479 100644 --- a/cgogn/core/basic/dart_marker.h +++ b/cgogn/core/basic/dart_marker.h @@ -33,16 +33,16 @@ namespace cgogn class CGOGN_CORE_API DartMarkerGen { public: - typedef DartMarkerGen Super; + typedef DartMarkerGen Self; DartMarkerGen() {} virtual ~DartMarkerGen(); - DartMarkerGen(const Super& dm) = delete; - DartMarkerGen(Super&& dm) = delete; - DartMarkerGen& operator=(Super&& dm) = delete; - DartMarkerGen& operator=(const Super& dm) = delete; + DartMarkerGen(const Self& dm) = delete; + DartMarkerGen(Self&& dm) = delete; + DartMarkerGen& operator=(Self&& dm) = delete; + DartMarkerGen& operator=(const Self& dm) = delete; }; template @@ -51,10 +51,10 @@ class DartMarkerT : public DartMarkerGen public: typedef DartMarkerGen Inherit; - typedef DartMarkerT Super; + typedef DartMarkerT Self; typedef MAP Map; - typedef typename Map::ChunkSizeType ChunkSizeType; + typedef typename Map::chunksize_type chunksize_type; using ChunkArrayBool = typename Map::template ChunkArray; protected: @@ -76,8 +76,8 @@ class DartMarkerT : public DartMarkerGen map_.release_topology_mark_attribute(mark_attribute_); } - DartMarkerT(const Super& dm) = delete; - DartMarkerT& operator=(Super& dm) = delete; + DartMarkerT(const Self& dm) = delete; + DartMarkerT& operator=(Self& dm) = delete; inline void mark(Dart d) { @@ -124,7 +124,7 @@ class DartMarker : public DartMarkerT public: typedef DartMarkerT Inherit; - typedef DartMarker Super; + typedef DartMarker Self; typedef MAP Map; DartMarker(MAP& map) : @@ -136,10 +136,10 @@ class DartMarker : public DartMarkerT unmark_all() ; } - DartMarker(const Super& dm) = delete; - DartMarker(Super&& dm) = delete; - DartMarker& operator=(Super&& dm) = delete; - DartMarker& operator=(const Super& dm) = delete; + DartMarker(const Self& dm) = delete; + DartMarker(Self&& dm) = delete; + DartMarker& operator=(Self&& dm) = delete; + DartMarker& operator=(const Self& dm) = delete; inline void unmark_all() { @@ -152,7 +152,7 @@ template class DartMarkerStore : public DartMarkerT { public: - typedef DartMarkerStore Super; + typedef DartMarkerStore Self; typedef DartMarkerT Inherit; typedef MAP Map; @@ -174,10 +174,10 @@ class DartMarkerStore : public DartMarkerT cgogn::getDartBuffers()->release_buffer(marked_darts_); } - DartMarkerStore(const Super& dm) = delete; - DartMarkerStore(Super&& dm) = delete; - DartMarkerStore& operator=(Super&& dm) = delete; - DartMarkerStore& operator=(const Super& dm) = delete; + DartMarkerStore(const Self& dm) = delete; + DartMarkerStore(Self&& dm) = delete; + DartMarkerStore& operator=(Self&& dm) = delete; + DartMarkerStore& operator=(const Self& dm) = delete; inline void mark(Dart d) { diff --git a/cgogn/core/container/chunk_array.h b/cgogn/core/container/chunk_array.h index 1f97db9e..50416e69 100644 --- a/cgogn/core/container/chunk_array.h +++ b/cgogn/core/container/chunk_array.h @@ -43,6 +43,12 @@ namespace cgogn template class ChunkArray : public ChunkArrayGen { +public: + typedef ChunkArrayGen Inherit; + typedef ChunkArray Self; + typedef std::integral_constant chunksize_type; + typedef T value_type; + protected: /// vector of block pointers @@ -53,7 +59,7 @@ class ChunkArray : public ChunkArrayGen /** * @brief Constructor of ChunkArray */ - inline ChunkArray() : ChunkArrayGen() + inline ChunkArray() : Inherit() { table_data_.reserve(1024u); } @@ -75,7 +81,7 @@ class ChunkArray : public ChunkArrayGen */ ChunkArrayGen* clone() const override { - return new ChunkArray(); + return new Self(); } bool is_boolean_array() const override @@ -333,6 +339,12 @@ class ChunkArray : public ChunkArrayGen template class ChunkArray : public ChunkArrayGen { +public: + + typedef ChunkArrayGen Inherit; + typedef ChunkArray Self; + typedef std::integral_constant chunksize_type; + typedef unsigned int value_type; protected: /// vector of block pointers @@ -345,10 +357,10 @@ class ChunkArray : public ChunkArrayGen table_data_.reserve(1024u); } - ChunkArray(const ChunkArray& ca) = delete; - ChunkArray(ChunkArray&& ca) = delete; - ChunkArray& operator=(ChunkArray&& ca) = delete; - ChunkArray& operator=(const ChunkArray& ca) = delete; + ChunkArray(const Self& ca) = delete; + ChunkArray(Self&& ca) = delete; + ChunkArray& operator=(Self&& ca) = delete; + ChunkArray& operator=(Self& ca) = delete; ~ChunkArray() override { @@ -362,7 +374,7 @@ class ChunkArray : public ChunkArrayGen */ ChunkArrayGen* clone() const override { - return new ChunkArray(); + return new Self(); } bool is_boolean_array() const override diff --git a/cgogn/core/container/chunk_array_container.h b/cgogn/core/container/chunk_array_container.h index c2b7d067..8a125b03 100644 --- a/cgogn/core/container/chunk_array_container.h +++ b/cgogn/core/container/chunk_array_container.h @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -83,29 +84,37 @@ template class ChunkArrayContainer { public: + typedef ChunkArrayContainer Self; + typedef std::integral_constant chunksize_type; + typedef T_REF ref_type; + using ChunkArrayGen = cgogn::ChunkArrayGen; + template + using ChunkArray = cgogn::ChunkArray; + template + using ChunkStack = cgogn::ChunkStack; /** * constante d'attribut inconnu */ - static const unsigned int UNKNOWN = 0xffffffff; + static const unsigned int UNKNOWN = UINT_MAX; protected: /** * vector of pointers to ChunkVector */ - std::vector*> table_arrays_; + std::vector table_arrays_; std::vector names_; std::vector type_names_; - ChunkArray refs_; + ChunkArray refs_; /** * stack of holes */ - ChunkStack holes_stack_; + ChunkStack holes_stack_; /** * size (number of elts) of the container @@ -154,7 +163,7 @@ class ChunkArrayContainer * @param ptr of ChunkArray * @return the index in table */ - unsigned int get_array_index(const ChunkArrayGen* ptr) const + unsigned int get_array_index(const ChunkArrayGen* ptr) const { for (unsigned int i = 0u; i != table_arrays_.size(); ++i) { @@ -172,7 +181,7 @@ class ChunkArrayContainer bool remove_attribute(unsigned int index) { // store ptr for using it before delete - ChunkArrayGen* ptr_to_del = table_arrays_[index]; + ChunkArrayGen* ptr_to_del = table_arrays_[index]; // in case of Marker attribute, keep Marker attributes first ! if (index < nb_marker_attribs_) @@ -214,15 +223,15 @@ class ChunkArrayContainer nb_used_lines_(0u), nb_max_lines_(0u), nb_marker_attribs_(0), - std_browser_(make_unique< ContainerStandardBrowser > >(this)) + std_browser_(make_unique< ContainerStandardBrowser >(this)) { current_browser_= std_browser_.get(); } - ChunkArrayContainer(ChunkArrayContainerconst& ) = delete; - ChunkArrayContainer(ChunkArrayContainer&& ) = delete; - ChunkArrayContainer& operator=(ChunkArrayContainerconst& ) = delete; - ChunkArrayContainer& operator=(ChunkArrayContainer&& ) = delete; + ChunkArrayContainer(Self const& ) = delete; + ChunkArrayContainer(Self&& ) = delete; + ChunkArrayContainer& operator=(Self const& ) = delete; + ChunkArrayContainer& operator=(Self&& ) = delete; /** * @brief ChunkArrayContainer destructor @@ -242,7 +251,7 @@ class ChunkArrayContainer * @return pointer on attribute ChunkArray */ template - ChunkArray* get_attribute(const std::string& attribute_name) + ChunkArray* get_attribute(const std::string& attribute_name) { // first check if attribute already exist unsigned int index = get_array_index(attribute_name); @@ -252,7 +261,7 @@ class ChunkArrayContainer return nullptr; } - return static_cast*>(table_arrays_[index]); + return static_cast*>(table_arrays_[index]); } /** @@ -262,7 +271,7 @@ class ChunkArrayContainer * @return pointer on created attribute ChunkArray */ template - ChunkArray* add_attribute(const std::string& attribute_name) + ChunkArray* add_attribute(const std::string& attribute_name) { cgogn_assert(attribute_name.size() != 0); @@ -276,7 +285,7 @@ class ChunkArrayContainer // create the new attribute const std::string& typeName = name_of_type(T()); - ChunkArray* carr = new ChunkArray(); + ChunkArray* carr = new ChunkArray(); ChunkArrayFactory::template register_CA(); // reserve memory @@ -295,9 +304,9 @@ class ChunkArrayContainer * @param attribute_name name of marker attribute * @return pointer on created ChunkArray */ - ChunkArray* add_marker_attribute(const std::string& attribute_name) + ChunkArray* add_marker_attribute(const std::string& attribute_name) { - ChunkArray* ptr = add_attribute(attribute_name); + ChunkArray* ptr = add_attribute(attribute_name); if (table_arrays_.size() > nb_marker_attribs_) { @@ -339,7 +348,7 @@ class ChunkArrayContainer * @param ptr ChunkArray pointer to the attribute to remove * @return true if attribute exists and has been removed */ - bool remove_attribute(const ChunkArrayGen* ptr) + bool remove_attribute(const ChunkArrayGen* ptr) { unsigned int index = get_array_index(ptr); @@ -369,13 +378,13 @@ class ChunkArrayContainer * @return pointer on typed chunk_array */ template - ChunkArray* get_data_array(const std::string& attribute_name) + ChunkArray* get_data_array(const std::string& attribute_name) { unsigned int index = get_array_index(attribute_name); if(index == UNKNOWN) return nullptr; - ChunkArray* atm = dynamic_cast*>(table_arrays_[index]); + ChunkArray* atm = dynamic_cast*>(table_arrays_[index]); cgogn_message_assert(atm != nullptr, "getDataArray: wrong type"); @@ -387,7 +396,7 @@ class ChunkArrayContainer * @param attribute_name name of the array * @return pointer on virtual chunk_array */ - ChunkArrayGen* get_virtual_data_array(const std::string& attribute_name) + ChunkArrayGen* get_virtual_data_array(const std::string& attribute_name) { unsigned int index = get_array_index(attribute_name); if(index == UNKNOWN) diff --git a/cgogn/core/container/chunk_array_factory.h b/cgogn/core/container/chunk_array_factory.h index d4a07852..71c78502 100644 --- a/cgogn/core/container/chunk_array_factory.h +++ b/cgogn/core/container/chunk_array_factory.h @@ -38,10 +38,11 @@ template class ChunkArrayFactory { public: + typedef std::integral_constant chunksize_type; typedef std::unique_ptr< ChunkArrayGen > ChunkArrayGenPtr; - typedef std::map Map; + typedef std::map string_chunkArrayGen_map; - static Map map_CA_; + static string_chunkArrayGen_map map_CA_; /** * @brief register a type @@ -64,7 +65,7 @@ class ChunkArrayFactory static ChunkArrayGen* create(const std::string& keyType) { ChunkArrayGen* tmp = nullptr; - typename Map::const_iterator it = map_CA_.find(keyType); + typename string_chunkArrayGen_map::const_iterator it = map_CA_.find(keyType); if(it != map_CA_.end()) { @@ -78,7 +79,7 @@ class ChunkArrayFactory }; template -typename ChunkArrayFactory::Map ChunkArrayFactory::map_CA_= typename ChunkArrayFactory::Map(); +typename ChunkArrayFactory::string_chunkArrayGen_map ChunkArrayFactory::map_CA_= typename ChunkArrayFactory::string_chunkArrayGen_map(); } // namespace cgogn diff --git a/cgogn/core/container/chunk_array_gen.h b/cgogn/core/container/chunk_array_gen.h index da17c6f8..ee458858 100644 --- a/cgogn/core/container/chunk_array_gen.h +++ b/cgogn/core/container/chunk_array_gen.h @@ -37,9 +37,10 @@ template class ChunkArrayGen { public: + typedef ChunkArrayGen Self; + typedef std::integral_constant chunksize_type; ChunkArrayGen() = default; - ChunkArrayGen(ChunkArrayGenconst& ) = delete; ChunkArrayGen(ChunkArrayGen&& ) = delete; ChunkArrayGen& operator=(ChunkArrayGenconst& ) = delete; @@ -54,7 +55,7 @@ class ChunkArrayGen * @brief create a ChunkArray object without knowning type * @return generic pointer */ - virtual ChunkArrayGen* clone() const = 0; + virtual Self* clone() const = 0; virtual bool is_boolean_array() const = 0; diff --git a/cgogn/core/container/chunk_stack.h b/cgogn/core/container/chunk_stack.h index 94ad6730..226c3ca9 100644 --- a/cgogn/core/container/chunk_stack.h +++ b/cgogn/core/container/chunk_stack.h @@ -41,6 +41,11 @@ class ChunkStack : public ChunkArray { public: typedef ChunkArray Inherit; + typedef ChunkStack Self; + + typedef std::integral_constant chunksize_type; + typedef T value_type; + protected: unsigned int stack_size_; @@ -50,6 +55,7 @@ class ChunkStack : public ChunkArray * @brief ChunkStack constructor */ ChunkStack(): + Inherit(), stack_size_(0u) {} @@ -59,10 +65,10 @@ class ChunkStack : public ChunkArray inline ~ChunkStack() override {} - inline ChunkStack(const ChunkStack& cs) = delete; - inline ChunkStack(ChunkStack&& cs) = delete; - inline ChunkStack& operator=(const ChunkStack& cs) = delete; - inline ChunkStack& operator=(ChunkStack&& cs) = delete; + inline ChunkStack(const Self& cs) = delete; + inline ChunkStack(Self&& cs) = delete; + inline ChunkStack& operator=(const Self& cs) = delete; + inline ChunkStack& operator=(Self&& cs) = delete; /** * @brief push a value on top of heap @@ -137,7 +143,7 @@ class ChunkStack : public ChunkArray void clear() override { stack_size_ = 0u; - ChunkArray::clear(); + Inherit::clear(); } }; diff --git a/cgogn/core/map/attribute_handler.h b/cgogn/core/map/attribute_handler.h index b9606b40..6b22d2eb 100644 --- a/cgogn/core/map/attribute_handler.h +++ b/cgogn/core/map/attribute_handler.h @@ -41,6 +41,7 @@ template class AttributeHandlerGen { public: + typedef AttributeHandlerGen Self; typedef MapBaseData MapData; @@ -62,7 +63,7 @@ class AttributeHandlerGen * \brief copy constructor * @param atthg */ - inline AttributeHandlerGen(const AttributeHandlerGen& atthg) : + inline AttributeHandlerGen(const Self& atthg) : map_(atthg.map_), valid_(atthg.valid_) {} @@ -71,7 +72,7 @@ class AttributeHandlerGen * \brief move constructor * @param atthg */ - inline AttributeHandlerGen(AttributeHandlerGen&& atthg) CGOGN_NOEXCEPT : + inline AttributeHandlerGen(Self&& atthg) CGOGN_NOEXCEPT : map_(atthg.map_), valid_(atthg.valid_) {} @@ -81,7 +82,7 @@ class AttributeHandlerGen * @param atthg * @return */ - inline AttributeHandlerGen& operator=(const AttributeHandlerGen& atthg) + inline AttributeHandlerGen& operator=(const Self& atthg) { this->map_ = atthg.map_; this->valid_ = atthg.valid_; @@ -93,7 +94,7 @@ class AttributeHandlerGen * @param atthg * @return */ - inline AttributeHandlerGen& operator=(AttributeHandlerGen&& atthg) + inline AttributeHandlerGen& operator=(Self&& atthg) { this->map_ = atthg.map_; this->valid_ = atthg.valid_; @@ -123,13 +124,15 @@ template class AttributeHandlerOrbit : public AttributeHandlerGen { public: + typedef AttributeHandlerGen Inherit; + typedef AttributeHandlerOrbit Self; - typedef AttributeHandlerGen Inherit; - typedef typename Inherit::MapData MapData; - + typedef typename Inherit::MapData MapData; + typedef typename MapData::chunksize_type chunksize_type; + typedef std::integral_constant orbit_type; protected: - ChunkArrayContainer* chunk_array_cont_; + ChunkArrayContainer* chunk_array_cont_; public: @@ -147,7 +150,7 @@ class AttributeHandlerOrbit : public AttributeHandlerGen * \brief copy constructor * @param attho */ - inline AttributeHandlerOrbit(const AttributeHandlerOrbit< DATA_TRAITS, ORBIT >& attho) : + inline AttributeHandlerOrbit(const Self& attho) : Inherit(attho), chunk_array_cont_(attho.chunk_array_cont_) {} @@ -156,7 +159,7 @@ class AttributeHandlerOrbit : public AttributeHandlerGen * \brief move constructor * @param attho */ - inline AttributeHandlerOrbit(AttributeHandlerOrbit< DATA_TRAITS, ORBIT >&& attho) CGOGN_NOEXCEPT : + inline AttributeHandlerOrbit(Self&& attho) CGOGN_NOEXCEPT : Inherit(std::move(attho)), chunk_array_cont_(attho.chunk_array_cont_) {} @@ -166,7 +169,7 @@ class AttributeHandlerOrbit : public AttributeHandlerGen * @param attho * @return */ - inline AttributeHandlerOrbit& operator=(const AttributeHandlerOrbit< DATA_TRAITS, ORBIT >& attho) + inline AttributeHandlerOrbit& operator=(const Self& attho) { Inherit::operator=(attho); chunk_array_cont_ = attho.chunk_array_cont_; @@ -177,7 +180,7 @@ class AttributeHandlerOrbit : public AttributeHandlerGen * @param attho * @return */ - inline AttributeHandlerOrbit& operator=(AttributeHandlerOrbit< DATA_TRAITS, ORBIT >&& attho) + inline AttributeHandlerOrbit& operator=(Self&& attho) { Inherit::operator=(std::move(attho)); chunk_array_cont_ = attho.chunk_array_cont_; @@ -202,9 +205,13 @@ class AttributeHandler : public AttributeHandlerOrbit { public: - typedef AttributeHandlerOrbit Inherit; - typedef ChunkArray TChunkArray; - typedef typename Inherit::MapData MapData; + typedef AttributeHandlerOrbit Inherit; + typedef AttributeHandler Self; + typedef typename Inherit::chunksize_type chunksize_type; + typedef T value_type; + typedef typename Inherit::orbit_type orbit_type; + typedef ChunkArray TChunkArray; + typedef typename Inherit::MapData MapData; protected: @@ -251,7 +258,7 @@ class AttributeHandler : public AttributeHandlerOrbit * \brief Copy constructor * @param att */ - AttributeHandler(const AttributeHandler& att) : + AttributeHandler(const Self& att) : Inherit(att), chunk_array_(att.chunk_array_) {} @@ -260,7 +267,7 @@ class AttributeHandler : public AttributeHandlerOrbit * \brief Move constructor * @param att */ - AttributeHandler(AttributeHandler&& att) CGOGN_NOEXCEPT : + AttributeHandler(Self&& att) CGOGN_NOEXCEPT : Inherit(std::move(att)), chunk_array_(att.chunk_array_) {} @@ -270,7 +277,7 @@ class AttributeHandler : public AttributeHandlerOrbit * @param att * @return */ - AttributeHandler& operator=(const AttributeHandler& att) + AttributeHandler& operator=(const Self& att) { Inherit::operator=(att); chunk_array_ = att.chunk_array_; @@ -282,7 +289,7 @@ class AttributeHandler : public AttributeHandlerOrbit * @param att * @return */ - AttributeHandler& operator=(AttributeHandler&& att) + AttributeHandler& operator=(Self&& att) { Inherit::operator=(std::move(att)); chunk_array_ = att.chunk_array_; diff --git a/cgogn/core/map/map1.h b/cgogn/core/map/map1.h index aa43610c..d614b92c 100644 --- a/cgogn/core/map/map1.h +++ b/cgogn/core/map/map1.h @@ -40,26 +40,27 @@ class Map1 : public MapBase { public: typedef MapBase Inherit; - typedef Map1 Super; - template - using ChunkArray = typename Inherit::template ChunkArray; - template - using ChunkArrayContainer = typename Inherit::template ChunkArrayContainer; + typedef Map1 Self; static const unsigned int VERTEX = VERTEX1; static const unsigned int EDGE = VERTEX1; static const unsigned int FACE = FACE2; + template + using ChunkArray = typename Inherit::template ChunkArray; + template + using ChunkArrayContainer = typename Inherit::template ChunkArrayContainer; + template using AttributeHandler = typename Inherit::template AttributeHandler; template - using VertexAttributeHandler = AttributeHandler; + using VertexAttributeHandler = AttributeHandler; template - using EdgeAttributeHandler = AttributeHandler; + using EdgeAttributeHandler = AttributeHandler; template - using FaceAttributeHandler = AttributeHandler; + using FaceAttributeHandler = AttributeHandler; protected: diff --git a/cgogn/core/map/map2.h b/cgogn/core/map/map2.h index d3216b2a..ef223372 100644 --- a/cgogn/core/map/map2.h +++ b/cgogn/core/map/map2.h @@ -35,30 +35,29 @@ class Map2 : public Map1 { public: typedef Map1 Inherit; - typedef Map2 Super; - - template - using ChunkArray = typename Inherit::template ChunkArray; - template - using ChunkArrayContainer = typename Inherit::template ChunkArrayContainer; + typedef Map2 Self; static const unsigned int VERTEX = VERTEX2; static const unsigned int EDGE = EDGE2; static const unsigned int FACE = FACE2; static const unsigned int VOLUME = VOLUME3; + template + using ChunkArray = typename Inherit::template ChunkArray; + template + using ChunkArrayContainer = typename Inherit::template ChunkArrayContainer; + template using AttributeHandler = typename Inherit::template AttributeHandler; template - using VertexAttributeHandler = typename Inherit::template VertexAttributeHandler; + using VertexAttributeHandler = AttributeHandler; template - using EdgeAttributeHandler = typename Inherit::template EdgeAttributeHandler; + using EdgeAttributeHandler = AttributeHandler; template - using FaceAttributeHandler = typename Inherit::template FaceAttributeHandler; - + using FaceAttributeHandler = AttributeHandler; protected: void init() diff --git a/cgogn/core/map/map_base.h b/cgogn/core/map/map_base.h index 306e4b85..6ff44a28 100644 --- a/cgogn/core/map/map_base.h +++ b/cgogn/core/map/map_base.h @@ -37,7 +37,7 @@ class MapBase : public MapBaseData { public: typedef MapBaseData Inherit; - typedef MapBase Super; + typedef MapBase Self; using typename Inherit::ChunkArrayGen; template diff --git a/cgogn/core/map/map_base_data.h b/cgogn/core/map/map_base_data.h index 22c2c40a..5e0f6393 100644 --- a/cgogn/core/map/map_base_data.h +++ b/cgogn/core/map/map_base_data.h @@ -44,7 +44,8 @@ namespace cgogn class CGOGN_CORE_API MapGen { public: - typedef MapGen Super; + typedef MapGen Self; + private: /// vector of Map instances @@ -71,14 +72,14 @@ class MapBaseData : public MapGen { public: typedef MapGen Inherit; - typedef MapBaseData Super; + typedef MapBaseData Self; - typedef std::integral_constant ChunkSizeType; + typedef std::integral_constant chunksize_type; template - using ChunkArrayContainer = cgogn::ChunkArrayContainer; + using ChunkArrayContainer = cgogn::ChunkArrayContainer; template - using ChunkArray = cgogn::ChunkArray; - using ChunkArrayGen = cgogn::ChunkArrayGen; + using ChunkArray = cgogn::ChunkArray; + using ChunkArrayGen = cgogn::ChunkArrayGen; protected: /// topology & embedding indices ChunkArrayContainer topology_; diff --git a/cgogn/core/map/map_tri.h b/cgogn/core/map/map_tri.h index bae7ce43..718a20ca 100644 --- a/cgogn/core/map/map_tri.h +++ b/cgogn/core/map/map_tri.h @@ -37,9 +37,9 @@ class Traits_map_tri class MapTri : public MapBase { public: - typedef MapBase Inherit; typedef MapTri Self; + ~MapTri() override {} }; From 9fa1a22c1fec8be6591c14ac62696fb8d2cda944 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Schmitt?= Date: Thu, 19 Nov 2015 18:01:15 +0100 Subject: [PATCH 105/185] added typedefs for TraversorCell MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Étienne Schmitt --- cgogn/core/map/map_base_data.h | 2 +- cgogn/core/traversal/traversor_cell.h | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/cgogn/core/map/map_base_data.h b/cgogn/core/map/map_base_data.h index dc25b2da..2ddbc4ae 100644 --- a/cgogn/core/map/map_base_data.h +++ b/cgogn/core/map/map_base_data.h @@ -77,9 +77,9 @@ class MapBaseData : public MapGen typedef std::integral_constant chunksize_type; template using ChunkArrayContainer = cgogn::ChunkArrayContainer; + using ChunkArrayGen = cgogn::ChunkArrayGen; template using ChunkArray = cgogn::ChunkArray; - using ChunkArrayGen = cgogn::ChunkArrayGen; protected: /// topology & embedding indices diff --git a/cgogn/core/traversal/traversor_cell.h b/cgogn/core/traversal/traversor_cell.h index a73ef43d..c28c6d62 100644 --- a/cgogn/core/traversal/traversor_cell.h +++ b/cgogn/core/traversal/traversor_cell.h @@ -33,17 +33,22 @@ namespace cgogn template class TraversorCell { +public: + typedef TraversorCell Self; + typedef MAP Map; + typedef std::integral_constant orbit_type; + using DartMarker = cgogn::DartMarker; protected: MAP& map_; - DartMarker* dm_; + DartMarker* dm_; public: TraversorCell(MAP& map) : map_(map) { - dm_ = new DartMarker(map_); + dm_ = new DartMarker(map_); } virtual ~TraversorCell() From 81d0fa7f120370b34d5c1d0564be7f5272a4bde6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Schmitt?= Date: Thu, 19 Nov 2015 18:30:05 +0100 Subject: [PATCH 106/185] adding const version of MapBaseData::get_attribute_container that was incorrectly merged. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Étienne Schmitt --- cgogn/core/map/map_base_data.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cgogn/core/map/map_base_data.h b/cgogn/core/map/map_base_data.h index 2ddbc4ae..6780d6ac 100644 --- a/cgogn/core/map/map_base_data.h +++ b/cgogn/core/map/map_base_data.h @@ -132,6 +132,11 @@ class MapBaseData : public MapGen * Containers management *******************************************************************************/ + inline const ChunkArrayContainer& get_attribute_container(unsigned int orbit) const + { + return attributes_[orbit]; + } + inline ChunkArrayContainer& get_attribute_container(unsigned int orbit) { return attributes_[orbit]; From 502ce02a34cef6d75302b83536353011876a0f1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Schmitt?= Date: Fri, 20 Nov 2015 11:10:42 +0100 Subject: [PATCH 107/185] added eigen 3.2.7 as optional thirdparty MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Étienne Schmitt --- CMakeLists.txt | 11 + cmake/Modules/FindEigen3.cmake | 81 + thirdparty/CMakeLists.txt | 3 + thirdparty/eigen-3.2.7/CMakeLists.txt | 9 + thirdparty/eigen-3.2.7/Eigen/Array | 11 + thirdparty/eigen-3.2.7/Eigen/Cholesky | 32 + thirdparty/eigen-3.2.7/Eigen/CholmodSupport | 45 + thirdparty/eigen-3.2.7/Eigen/Core | 376 ++++ thirdparty/eigen-3.2.7/Eigen/Dense | 7 + thirdparty/eigen-3.2.7/Eigen/Eigen | 2 + thirdparty/eigen-3.2.7/Eigen/Eigen2Support | 95 + thirdparty/eigen-3.2.7/Eigen/Eigenvalues | 48 + thirdparty/eigen-3.2.7/Eigen/Geometry | 63 + thirdparty/eigen-3.2.7/Eigen/Householder | 23 + .../eigen-3.2.7/Eigen/IterativeLinearSolvers | 40 + thirdparty/eigen-3.2.7/Eigen/Jacobi | 26 + thirdparty/eigen-3.2.7/Eigen/LU | 41 + thirdparty/eigen-3.2.7/Eigen/LeastSquares | 32 + thirdparty/eigen-3.2.7/Eigen/MetisSupport | 28 + thirdparty/eigen-3.2.7/Eigen/OrderingMethods | 66 + thirdparty/eigen-3.2.7/Eigen/PaStiXSupport | 46 + thirdparty/eigen-3.2.7/Eigen/PardisoSupport | 30 + thirdparty/eigen-3.2.7/Eigen/QR | 45 + thirdparty/eigen-3.2.7/Eigen/QtAlignedMalloc | 34 + thirdparty/eigen-3.2.7/Eigen/SPQRSupport | 29 + thirdparty/eigen-3.2.7/Eigen/SVD | 37 + thirdparty/eigen-3.2.7/Eigen/Sparse | 27 + thirdparty/eigen-3.2.7/Eigen/SparseCholesky | 47 + thirdparty/eigen-3.2.7/Eigen/SparseCore | 64 + thirdparty/eigen-3.2.7/Eigen/SparseLU | 49 + thirdparty/eigen-3.2.7/Eigen/SparseQR | 33 + thirdparty/eigen-3.2.7/Eigen/StdDeque | 27 + thirdparty/eigen-3.2.7/Eigen/StdList | 26 + thirdparty/eigen-3.2.7/Eigen/StdVector | 27 + thirdparty/eigen-3.2.7/Eigen/SuperLUSupport | 59 + thirdparty/eigen-3.2.7/Eigen/UmfPackSupport | 36 + .../eigen-3.2.7/Eigen/src/Cholesky/LDLT.h | 611 ++++++ .../eigen-3.2.7/Eigen/src/Cholesky/LLT.h | 498 +++++ .../eigen-3.2.7/Eigen/src/Cholesky/LLT_MKL.h | 102 + .../Eigen/src/CholmodSupport/CholmodSupport.h | 607 ++++++ thirdparty/eigen-3.2.7/Eigen/src/Core/Array.h | 323 +++ .../eigen-3.2.7/Eigen/src/Core/ArrayBase.h | 226 ++ .../eigen-3.2.7/Eigen/src/Core/ArrayWrapper.h | 264 +++ .../eigen-3.2.7/Eigen/src/Core/Assign.h | 590 ++++++ .../eigen-3.2.7/Eigen/src/Core/Assign_MKL.h | 224 ++ .../eigen-3.2.7/Eigen/src/Core/BandMatrix.h | 334 +++ thirdparty/eigen-3.2.7/Eigen/src/Core/Block.h | 406 ++++ .../eigen-3.2.7/Eigen/src/Core/BooleanRedux.h | 154 ++ .../Eigen/src/Core/CommaInitializer.h | 154 ++ .../Eigen/src/Core/CoreIterators.h | 61 + .../Eigen/src/Core/CwiseBinaryOp.h | 230 ++ .../Eigen/src/Core/CwiseNullaryOp.h | 864 ++++++++ .../eigen-3.2.7/Eigen/src/Core/CwiseUnaryOp.h | 126 ++ .../Eigen/src/Core/CwiseUnaryView.h | 139 ++ .../eigen-3.2.7/Eigen/src/Core/DenseBase.h | 521 +++++ .../Eigen/src/Core/DenseCoeffsBase.h | 754 +++++++ .../eigen-3.2.7/Eigen/src/Core/DenseStorage.h | 434 ++++ .../eigen-3.2.7/Eigen/src/Core/Diagonal.h | 237 +++ .../Eigen/src/Core/DiagonalMatrix.h | 313 +++ .../Eigen/src/Core/DiagonalProduct.h | 131 ++ thirdparty/eigen-3.2.7/Eigen/src/Core/Dot.h | 263 +++ .../eigen-3.2.7/Eigen/src/Core/EigenBase.h | 131 ++ .../eigen-3.2.7/Eigen/src/Core/Flagged.h | 140 ++ .../Eigen/src/Core/ForceAlignedAccess.h | 146 ++ .../eigen-3.2.7/Eigen/src/Core/Functors.h | 1026 +++++++++ thirdparty/eigen-3.2.7/Eigen/src/Core/Fuzzy.h | 150 ++ .../Eigen/src/Core/GeneralProduct.h | 635 ++++++ .../Eigen/src/Core/GenericPacketMath.h | 350 ++++ .../Eigen/src/Core/GlobalFunctions.h | 92 + thirdparty/eigen-3.2.7/Eigen/src/Core/IO.h | 250 +++ thirdparty/eigen-3.2.7/Eigen/src/Core/Map.h | 192 ++ .../eigen-3.2.7/Eigen/src/Core/MapBase.h | 247 +++ .../Eigen/src/Core/MathFunctions.h | 768 +++++++ .../eigen-3.2.7/Eigen/src/Core/Matrix.h | 420 ++++ .../eigen-3.2.7/Eigen/src/Core/MatrixBase.h | 563 +++++ .../eigen-3.2.7/Eigen/src/Core/NestByValue.h | 111 + .../eigen-3.2.7/Eigen/src/Core/NoAlias.h | 134 ++ .../eigen-3.2.7/Eigen/src/Core/NumTraits.h | 150 ++ .../Eigen/src/Core/PermutationMatrix.h | 721 +++++++ .../Eigen/src/Core/PlainObjectBase.h | 822 ++++++++ .../eigen-3.2.7/Eigen/src/Core/ProductBase.h | 290 +++ .../eigen-3.2.7/Eigen/src/Core/Random.h | 152 ++ thirdparty/eigen-3.2.7/Eigen/src/Core/Redux.h | 409 ++++ thirdparty/eigen-3.2.7/Eigen/src/Core/Ref.h | 278 +++ .../eigen-3.2.7/Eigen/src/Core/Replicate.h | 177 ++ .../Eigen/src/Core/ReturnByValue.h | 99 + .../eigen-3.2.7/Eigen/src/Core/Reverse.h | 224 ++ .../eigen-3.2.7/Eigen/src/Core/Select.h | 162 ++ .../Eigen/src/Core/SelfAdjointView.h | 314 +++ .../Eigen/src/Core/SelfCwiseBinaryOp.h | 191 ++ .../Eigen/src/Core/SolveTriangular.h | 260 +++ .../eigen-3.2.7/Eigen/src/Core/StableNorm.h | 203 ++ .../eigen-3.2.7/Eigen/src/Core/Stride.h | 108 + thirdparty/eigen-3.2.7/Eigen/src/Core/Swap.h | 126 ++ .../eigen-3.2.7/Eigen/src/Core/Transpose.h | 419 ++++ .../Eigen/src/Core/Transpositions.h | 436 ++++ .../Eigen/src/Core/TriangularMatrix.h | 839 ++++++++ .../eigen-3.2.7/Eigen/src/Core/VectorBlock.h | 95 + .../eigen-3.2.7/Eigen/src/Core/VectorwiseOp.h | 642 ++++++ .../eigen-3.2.7/Eigen/src/Core/Visitor.h | 237 +++ .../Eigen/src/Core/arch/AltiVec/Complex.h | 217 ++ .../Eigen/src/Core/arch/AltiVec/PacketMath.h | 501 +++++ .../Eigen/src/Core/arch/Default/Settings.h | 49 + .../Eigen/src/Core/arch/NEON/Complex.h | 253 +++ .../Eigen/src/Core/arch/NEON/PacketMath.h | 420 ++++ .../Eigen/src/Core/arch/SSE/Complex.h | 442 ++++ .../Eigen/src/Core/arch/SSE/MathFunctions.h | 475 +++++ .../Eigen/src/Core/arch/SSE/PacketMath.h | 649 ++++++ .../src/Core/products/CoeffBasedProduct.h | 476 +++++ .../Core/products/GeneralBlockPanelKernel.h | 1341 ++++++++++++ .../src/Core/products/GeneralMatrixMatrix.h | 427 ++++ .../products/GeneralMatrixMatrixTriangular.h | 278 +++ .../GeneralMatrixMatrixTriangular_MKL.h | 146 ++ .../Core/products/GeneralMatrixMatrix_MKL.h | 118 ++ .../src/Core/products/GeneralMatrixVector.h | 566 +++++ .../Core/products/GeneralMatrixVector_MKL.h | 131 ++ .../Eigen/src/Core/products/Parallelizer.h | 162 ++ .../Core/products/SelfadjointMatrixMatrix.h | 436 ++++ .../products/SelfadjointMatrixMatrix_MKL.h | 295 +++ .../Core/products/SelfadjointMatrixVector.h | 281 +++ .../products/SelfadjointMatrixVector_MKL.h | 114 + .../src/Core/products/SelfadjointProduct.h | 123 ++ .../Core/products/SelfadjointRank2Update.h | 93 + .../Core/products/TriangularMatrixMatrix.h | 427 ++++ .../products/TriangularMatrixMatrix_MKL.h | 309 +++ .../Core/products/TriangularMatrixVector.h | 348 ++++ .../products/TriangularMatrixVector_MKL.h | 247 +++ .../Core/products/TriangularSolverMatrix.h | 332 +++ .../products/TriangularSolverMatrix_MKL.h | 155 ++ .../Core/products/TriangularSolverVector.h | 139 ++ .../Eigen/src/Core/util/BlasUtil.h | 264 +++ .../Eigen/src/Core/util/Constants.h | 451 ++++ .../src/Core/util/DisableStupidWarnings.h | 40 + .../Eigen/src/Core/util/ForwardDeclarations.h | 302 +++ .../Eigen/src/Core/util/MKL_support.h | 158 ++ .../eigen-3.2.7/Eigen/src/Core/util/Macros.h | 451 ++++ .../eigen-3.2.7/Eigen/src/Core/util/Memory.h | 977 +++++++++ .../eigen-3.2.7/Eigen/src/Core/util/Meta.h | 243 +++ .../eigen-3.2.7/Eigen/src/Core/util/NonMPL2.h | 3 + .../src/Core/util/ReenableStupidWarnings.h | 14 + .../Eigen/src/Core/util/StaticAssert.h | 208 ++ .../Eigen/src/Core/util/XprHelper.h | 469 +++++ .../Eigen/src/Eigen2Support/Block.h | 126 ++ .../Eigen/src/Eigen2Support/Cwise.h | 192 ++ .../Eigen/src/Eigen2Support/CwiseOperators.h | 298 +++ .../src/Eigen2Support/Geometry/AlignedBox.h | 159 ++ .../Eigen/src/Eigen2Support/Geometry/All.h | 115 + .../src/Eigen2Support/Geometry/AngleAxis.h | 214 ++ .../src/Eigen2Support/Geometry/Hyperplane.h | 254 +++ .../Eigen2Support/Geometry/ParametrizedLine.h | 141 ++ .../src/Eigen2Support/Geometry/Quaternion.h | 495 +++++ .../src/Eigen2Support/Geometry/Rotation2D.h | 145 ++ .../src/Eigen2Support/Geometry/RotationBase.h | 123 ++ .../src/Eigen2Support/Geometry/Scaling.h | 167 ++ .../src/Eigen2Support/Geometry/Transform.h | 786 +++++++ .../src/Eigen2Support/Geometry/Translation.h | 184 ++ .../eigen-3.2.7/Eigen/src/Eigen2Support/LU.h | 120 ++ .../Eigen/src/Eigen2Support/Lazy.h | 71 + .../Eigen/src/Eigen2Support/LeastSquares.h | 169 ++ .../Eigen/src/Eigen2Support/Macros.h | 20 + .../Eigen/src/Eigen2Support/MathFunctions.h | 57 + .../Eigen/src/Eigen2Support/Memory.h | 45 + .../Eigen/src/Eigen2Support/Meta.h | 75 + .../Eigen/src/Eigen2Support/Minor.h | 117 ++ .../eigen-3.2.7/Eigen/src/Eigen2Support/QR.h | 67 + .../eigen-3.2.7/Eigen/src/Eigen2Support/SVD.h | 637 ++++++ .../src/Eigen2Support/TriangularSolver.h | 42 + .../Eigen/src/Eigen2Support/VectorBlock.h | 94 + .../src/Eigenvalues/ComplexEigenSolver.h | 341 +++ .../Eigen/src/Eigenvalues/ComplexSchur.h | 456 ++++ .../Eigen/src/Eigenvalues/ComplexSchur_MKL.h | 94 + .../Eigen/src/Eigenvalues/EigenSolver.h | 607 ++++++ .../src/Eigenvalues/GeneralizedEigenSolver.h | 350 ++++ .../GeneralizedSelfAdjointEigenSolver.h | 227 ++ .../src/Eigenvalues/HessenbergDecomposition.h | 373 ++++ .../src/Eigenvalues/MatrixBaseEigenvalues.h | 160 ++ .../Eigen/src/Eigenvalues/RealQZ.h | 624 ++++++ .../Eigen/src/Eigenvalues/RealSchur.h | 525 +++++ .../Eigen/src/Eigenvalues/RealSchur_MKL.h | 83 + .../src/Eigenvalues/SelfAdjointEigenSolver.h | 801 +++++++ .../Eigenvalues/SelfAdjointEigenSolver_MKL.h | 92 + .../src/Eigenvalues/Tridiagonalization.h | 557 +++++ .../Eigen/src/Geometry/AlignedBox.h | 392 ++++ .../Eigen/src/Geometry/AngleAxis.h | 233 +++ .../Eigen/src/Geometry/EulerAngles.h | 104 + .../Eigen/src/Geometry/Homogeneous.h | 307 +++ .../Eigen/src/Geometry/Hyperplane.h | 280 +++ .../Eigen/src/Geometry/OrthoMethods.h | 218 ++ .../Eigen/src/Geometry/ParametrizedLine.h | 195 ++ .../Eigen/src/Geometry/Quaternion.h | 776 +++++++ .../Eigen/src/Geometry/Rotation2D.h | 160 ++ .../Eigen/src/Geometry/RotationBase.h | 206 ++ .../eigen-3.2.7/Eigen/src/Geometry/Scaling.h | 166 ++ .../Eigen/src/Geometry/Transform.h | 1455 +++++++++++++ .../Eigen/src/Geometry/Translation.h | 206 ++ .../eigen-3.2.7/Eigen/src/Geometry/Umeyama.h | 177 ++ .../Eigen/src/Geometry/arch/Geometry_SSE.h | 115 + .../Eigen/src/Householder/BlockHouseholder.h | 68 + .../Eigen/src/Householder/Householder.h | 171 ++ .../src/Householder/HouseholderSequence.h | 441 ++++ .../BasicPreconditioners.h | 149 ++ .../src/IterativeLinearSolvers/BiCGSTAB.h | 263 +++ .../ConjugateGradient.h | 256 +++ .../IterativeLinearSolvers/IncompleteLUT.h | 478 +++++ .../IterativeSolverBase.h | 282 +++ .../eigen-3.2.7/Eigen/src/Jacobi/Jacobi.h | 433 ++++ .../eigen-3.2.7/Eigen/src/LU/Determinant.h | 101 + .../eigen-3.2.7/Eigen/src/LU/FullPivLU.h | 751 +++++++ thirdparty/eigen-3.2.7/Eigen/src/LU/Inverse.h | 400 ++++ .../eigen-3.2.7/Eigen/src/LU/PartialPivLU.h | 509 +++++ .../Eigen/src/LU/PartialPivLU_MKL.h | 85 + .../Eigen/src/LU/arch/Inverse_SSE.h | 329 +++ .../Eigen/src/MetisSupport/MetisSupport.h | 137 ++ .../Eigen/src/OrderingMethods/Amd.h | 444 ++++ .../Eigen/src/OrderingMethods/Eigen_Colamd.h | 1850 +++++++++++++++++ .../Eigen/src/OrderingMethods/Ordering.h | 154 ++ .../Eigen/src/PaStiXSupport/PaStiXSupport.h | 721 +++++++ .../Eigen/src/PardisoSupport/PardisoSupport.h | 592 ++++++ .../Eigen/src/QR/ColPivHouseholderQR.h | 580 ++++++ .../Eigen/src/QR/ColPivHouseholderQR_MKL.h | 99 + .../Eigen/src/QR/FullPivHouseholderQR.h | 622 ++++++ .../eigen-3.2.7/Eigen/src/QR/HouseholderQR.h | 388 ++++ .../Eigen/src/QR/HouseholderQR_MKL.h | 71 + .../src/SPQRSupport/SuiteSparseQRSupport.h | 338 +++ .../eigen-3.2.7/Eigen/src/SVD/JacobiSVD.h | 976 +++++++++ .../eigen-3.2.7/Eigen/src/SVD/JacobiSVD_MKL.h | 92 + .../Eigen/src/SVD/UpperBidiagonalization.h | 148 ++ .../src/SparseCholesky/SimplicialCholesky.h | 671 ++++++ .../SparseCholesky/SimplicialCholesky_impl.h | 199 ++ .../Eigen/src/SparseCore/AmbiVector.h | 373 ++++ .../Eigen/src/SparseCore/CompressedStorage.h | 233 +++ .../ConservativeSparseSparseProduct.h | 245 +++ .../Eigen/src/SparseCore/MappedSparseMatrix.h | 181 ++ .../Eigen/src/SparseCore/SparseBlock.h | 537 +++++ .../Eigen/src/SparseCore/SparseColEtree.h | 206 ++ .../src/SparseCore/SparseCwiseBinaryOp.h | 325 +++ .../Eigen/src/SparseCore/SparseCwiseUnaryOp.h | 163 ++ .../Eigen/src/SparseCore/SparseDenseProduct.h | 311 +++ .../src/SparseCore/SparseDiagonalProduct.h | 196 ++ .../Eigen/src/SparseCore/SparseDot.h | 101 + .../Eigen/src/SparseCore/SparseFuzzy.h | 26 + .../Eigen/src/SparseCore/SparseMatrix.h | 1262 +++++++++++ .../Eigen/src/SparseCore/SparseMatrixBase.h | 461 ++++ .../Eigen/src/SparseCore/SparsePermutation.h | 148 ++ .../Eigen/src/SparseCore/SparseProduct.h | 188 ++ .../Eigen/src/SparseCore/SparseRedux.h | 45 + .../src/SparseCore/SparseSelfAdjointView.h | 507 +++++ .../SparseSparseProductWithPruning.h | 150 ++ .../Eigen/src/SparseCore/SparseTranspose.h | 63 + .../src/SparseCore/SparseTriangularView.h | 179 ++ .../Eigen/src/SparseCore/SparseUtil.h | 172 ++ .../Eigen/src/SparseCore/SparseVector.h | 448 ++++ .../Eigen/src/SparseCore/SparseView.h | 99 + .../Eigen/src/SparseCore/TriangularSolver.h | 334 +++ .../eigen-3.2.7/Eigen/src/SparseLU/SparseLU.h | 806 +++++++ .../Eigen/src/SparseLU/SparseLUImpl.h | 66 + .../Eigen/src/SparseLU/SparseLU_Memory.h | 227 ++ .../Eigen/src/SparseLU/SparseLU_Structs.h | 111 + .../src/SparseLU/SparseLU_SupernodalMatrix.h | 298 +++ .../Eigen/src/SparseLU/SparseLU_Utils.h | 80 + .../Eigen/src/SparseLU/SparseLU_column_bmod.h | 180 ++ .../Eigen/src/SparseLU/SparseLU_column_dfs.h | 177 ++ .../src/SparseLU/SparseLU_copy_to_ucol.h | 106 + .../Eigen/src/SparseLU/SparseLU_gemm_kernel.h | 279 +++ .../src/SparseLU/SparseLU_heap_relax_snode.h | 127 ++ .../Eigen/src/SparseLU/SparseLU_kernel_bmod.h | 130 ++ .../Eigen/src/SparseLU/SparseLU_panel_bmod.h | 223 ++ .../Eigen/src/SparseLU/SparseLU_panel_dfs.h | 258 +++ .../Eigen/src/SparseLU/SparseLU_pivotL.h | 137 ++ .../Eigen/src/SparseLU/SparseLU_pruneL.h | 135 ++ .../Eigen/src/SparseLU/SparseLU_relax_snode.h | 83 + .../eigen-3.2.7/Eigen/src/SparseQR/SparseQR.h | 714 +++++++ .../Eigen/src/StlSupport/StdDeque.h | 134 ++ .../Eigen/src/StlSupport/StdList.h | 114 + .../Eigen/src/StlSupport/StdVector.h | 126 ++ .../Eigen/src/StlSupport/details.h | 84 + .../Eigen/src/SuperLUSupport/SuperLUSupport.h | 1026 +++++++++ .../Eigen/src/UmfPackSupport/UmfPackSupport.h | 474 +++++ thirdparty/eigen-3.2.7/Eigen/src/misc/Image.h | 84 + .../eigen-3.2.7/Eigen/src/misc/Kernel.h | 81 + thirdparty/eigen-3.2.7/Eigen/src/misc/Solve.h | 76 + .../eigen-3.2.7/Eigen/src/misc/SparseSolve.h | 128 ++ thirdparty/eigen-3.2.7/Eigen/src/misc/blas.h | 658 ++++++ .../Eigen/src/plugins/ArrayCwiseBinaryOps.h | 253 +++ .../Eigen/src/plugins/ArrayCwiseUnaryOps.h | 187 ++ .../Eigen/src/plugins/BlockMethods.h | 935 +++++++++ .../Eigen/src/plugins/CommonCwiseBinaryOps.h | 46 + .../Eigen/src/plugins/CommonCwiseUnaryOps.h | 172 ++ .../Eigen/src/plugins/MatrixCwiseBinaryOps.h | 143 ++ .../Eigen/src/plugins/MatrixCwiseUnaryOps.h | 52 + 290 files changed, 80314 insertions(+) create mode 100644 cmake/Modules/FindEigen3.cmake create mode 100644 thirdparty/CMakeLists.txt create mode 100644 thirdparty/eigen-3.2.7/CMakeLists.txt create mode 100644 thirdparty/eigen-3.2.7/Eigen/Array create mode 100644 thirdparty/eigen-3.2.7/Eigen/Cholesky create mode 100644 thirdparty/eigen-3.2.7/Eigen/CholmodSupport create mode 100644 thirdparty/eigen-3.2.7/Eigen/Core create mode 100644 thirdparty/eigen-3.2.7/Eigen/Dense create mode 100644 thirdparty/eigen-3.2.7/Eigen/Eigen create mode 100644 thirdparty/eigen-3.2.7/Eigen/Eigen2Support create mode 100644 thirdparty/eigen-3.2.7/Eigen/Eigenvalues create mode 100644 thirdparty/eigen-3.2.7/Eigen/Geometry create mode 100644 thirdparty/eigen-3.2.7/Eigen/Householder create mode 100644 thirdparty/eigen-3.2.7/Eigen/IterativeLinearSolvers create mode 100644 thirdparty/eigen-3.2.7/Eigen/Jacobi create mode 100644 thirdparty/eigen-3.2.7/Eigen/LU create mode 100644 thirdparty/eigen-3.2.7/Eigen/LeastSquares create mode 100644 thirdparty/eigen-3.2.7/Eigen/MetisSupport create mode 100644 thirdparty/eigen-3.2.7/Eigen/OrderingMethods create mode 100644 thirdparty/eigen-3.2.7/Eigen/PaStiXSupport create mode 100644 thirdparty/eigen-3.2.7/Eigen/PardisoSupport create mode 100644 thirdparty/eigen-3.2.7/Eigen/QR create mode 100644 thirdparty/eigen-3.2.7/Eigen/QtAlignedMalloc create mode 100644 thirdparty/eigen-3.2.7/Eigen/SPQRSupport create mode 100644 thirdparty/eigen-3.2.7/Eigen/SVD create mode 100644 thirdparty/eigen-3.2.7/Eigen/Sparse create mode 100644 thirdparty/eigen-3.2.7/Eigen/SparseCholesky create mode 100644 thirdparty/eigen-3.2.7/Eigen/SparseCore create mode 100644 thirdparty/eigen-3.2.7/Eigen/SparseLU create mode 100644 thirdparty/eigen-3.2.7/Eigen/SparseQR create mode 100644 thirdparty/eigen-3.2.7/Eigen/StdDeque create mode 100644 thirdparty/eigen-3.2.7/Eigen/StdList create mode 100644 thirdparty/eigen-3.2.7/Eigen/StdVector create mode 100644 thirdparty/eigen-3.2.7/Eigen/SuperLUSupport create mode 100644 thirdparty/eigen-3.2.7/Eigen/UmfPackSupport create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Cholesky/LDLT.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Cholesky/LLT.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Cholesky/LLT_MKL.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/CholmodSupport/CholmodSupport.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/Array.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/ArrayBase.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/ArrayWrapper.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/Assign.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/Assign_MKL.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/BandMatrix.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/Block.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/BooleanRedux.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/CommaInitializer.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/CoreIterators.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/CwiseBinaryOp.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/CwiseNullaryOp.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/CwiseUnaryOp.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/CwiseUnaryView.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/DenseBase.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/DenseCoeffsBase.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/DenseStorage.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/Diagonal.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/DiagonalMatrix.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/DiagonalProduct.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/Dot.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/EigenBase.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/Flagged.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/ForceAlignedAccess.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/Functors.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/Fuzzy.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/GeneralProduct.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/GenericPacketMath.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/GlobalFunctions.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/IO.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/Map.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/MapBase.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/MathFunctions.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/Matrix.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/MatrixBase.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/NestByValue.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/NoAlias.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/NumTraits.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/PermutationMatrix.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/PlainObjectBase.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/ProductBase.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/Random.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/Redux.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/Ref.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/Replicate.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/ReturnByValue.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/Reverse.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/Select.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/SelfAdjointView.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/SelfCwiseBinaryOp.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/SolveTriangular.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/StableNorm.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/Stride.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/Swap.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/Transpose.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/Transpositions.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/TriangularMatrix.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/VectorBlock.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/VectorwiseOp.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/Visitor.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/arch/AltiVec/Complex.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/arch/AltiVec/PacketMath.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/arch/Default/Settings.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/arch/NEON/Complex.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/arch/NEON/PacketMath.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/arch/SSE/Complex.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/arch/SSE/MathFunctions.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/arch/SSE/PacketMath.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/products/CoeffBasedProduct.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/products/GeneralBlockPanelKernel.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/products/GeneralMatrixMatrix.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_MKL.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/products/GeneralMatrixMatrix_MKL.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/products/GeneralMatrixVector.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/products/GeneralMatrixVector_MKL.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/products/Parallelizer.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/products/SelfadjointMatrixMatrix.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/products/SelfadjointMatrixMatrix_MKL.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/products/SelfadjointMatrixVector.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/products/SelfadjointMatrixVector_MKL.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/products/SelfadjointProduct.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/products/SelfadjointRank2Update.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/products/TriangularMatrixMatrix.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/products/TriangularMatrixMatrix_MKL.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/products/TriangularMatrixVector.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/products/TriangularMatrixVector_MKL.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/products/TriangularSolverMatrix.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/products/TriangularSolverMatrix_MKL.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/products/TriangularSolverVector.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/util/BlasUtil.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/util/Constants.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/util/DisableStupidWarnings.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/util/ForwardDeclarations.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/util/MKL_support.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/util/Macros.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/util/Memory.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/util/Meta.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/util/NonMPL2.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/util/ReenableStupidWarnings.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/util/StaticAssert.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/util/XprHelper.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Block.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Cwise.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/CwiseOperators.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/AlignedBox.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/All.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/AngleAxis.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/Hyperplane.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/ParametrizedLine.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/Quaternion.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/Rotation2D.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/RotationBase.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/Scaling.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/Transform.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/Translation.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/LU.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Lazy.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/LeastSquares.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Macros.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/MathFunctions.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Memory.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Meta.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Minor.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/QR.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/SVD.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/TriangularSolver.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/VectorBlock.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/ComplexEigenSolver.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/ComplexSchur.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/ComplexSchur_MKL.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/EigenSolver.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/HessenbergDecomposition.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/RealQZ.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/RealSchur.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/RealSchur_MKL.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_MKL.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/Tridiagonalization.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Geometry/AlignedBox.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Geometry/AngleAxis.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Geometry/EulerAngles.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Geometry/Homogeneous.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Geometry/Hyperplane.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Geometry/OrthoMethods.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Geometry/ParametrizedLine.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Geometry/Quaternion.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Geometry/Rotation2D.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Geometry/RotationBase.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Geometry/Scaling.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Geometry/Transform.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Geometry/Translation.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Geometry/Umeyama.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Geometry/arch/Geometry_SSE.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Householder/BlockHouseholder.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Householder/Householder.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Householder/HouseholderSequence.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Jacobi/Jacobi.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/LU/Determinant.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/LU/FullPivLU.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/LU/Inverse.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/LU/PartialPivLU.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/LU/PartialPivLU_MKL.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/LU/arch/Inverse_SSE.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/MetisSupport/MetisSupport.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/OrderingMethods/Amd.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/OrderingMethods/Eigen_Colamd.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/OrderingMethods/Ordering.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/PaStiXSupport/PaStiXSupport.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/PardisoSupport/PardisoSupport.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/QR/ColPivHouseholderQR.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/QR/ColPivHouseholderQR_MKL.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/QR/FullPivHouseholderQR.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/QR/HouseholderQR.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/QR/HouseholderQR_MKL.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SVD/JacobiSVD.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SVD/JacobiSVD_MKL.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SVD/UpperBidiagonalization.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCholesky/SimplicialCholesky.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCholesky/SimplicialCholesky_impl.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCore/AmbiVector.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCore/CompressedStorage.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCore/MappedSparseMatrix.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseBlock.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseColEtree.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseCwiseBinaryOp.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseCwiseUnaryOp.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseDenseProduct.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseDiagonalProduct.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseDot.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseFuzzy.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseMatrix.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseMatrixBase.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparsePermutation.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseProduct.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseRedux.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseSelfAdjointView.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseSparseProductWithPruning.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseTranspose.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseTriangularView.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseUtil.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseVector.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseView.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCore/TriangularSolver.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLUImpl.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_Memory.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_Structs.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_Utils.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_column_bmod.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_column_dfs.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_copy_to_ucol.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_gemm_kernel.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_heap_relax_snode.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_kernel_bmod.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_panel_bmod.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_panel_dfs.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_pivotL.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_pruneL.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_relax_snode.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseQR/SparseQR.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/StlSupport/StdDeque.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/StlSupport/StdList.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/StlSupport/StdVector.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/StlSupport/details.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SuperLUSupport/SuperLUSupport.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/UmfPackSupport/UmfPackSupport.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/misc/Image.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/misc/Kernel.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/misc/Solve.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/misc/SparseSolve.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/misc/blas.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/plugins/ArrayCwiseBinaryOps.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/plugins/ArrayCwiseUnaryOps.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/plugins/BlockMethods.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/plugins/CommonCwiseBinaryOps.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/plugins/CommonCwiseUnaryOps.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/plugins/MatrixCwiseBinaryOps.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/plugins/MatrixCwiseUnaryOps.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 9503a6ca..f8342401 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,6 +14,10 @@ if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release") endif() + +#### Here are located the FindPackages that we need +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules") + #### Compile Options include(cmake/CompilerOptions.cmake) @@ -23,6 +27,11 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib) set(CGOGN_SOURCE_DIR ${CMAKE_SOURCE_DIR}/cgogn) + +#### ThirdParty options +option(CGOGN_PROVIDE_EIGEN "Use the version of eigen that is packaged with CGoGN" ON) + + #### RPATH if(UNIX) # RPATH is a field in ELF binaries that is used as a hint by the system @@ -47,6 +56,8 @@ setBuildType() add_subdirectory(doc) +add_subdirectory(thirdparty) + add_subdirectory(${CGOGN_SOURCE_DIR}) add_subdirectory(test) diff --git a/cmake/Modules/FindEigen3.cmake b/cmake/Modules/FindEigen3.cmake new file mode 100644 index 00000000..9c546a05 --- /dev/null +++ b/cmake/Modules/FindEigen3.cmake @@ -0,0 +1,81 @@ +# - Try to find Eigen3 lib +# +# This module supports requiring a minimum version, e.g. you can do +# find_package(Eigen3 3.1.2) +# to require version 3.1.2 or newer of Eigen3. +# +# Once done this will define +# +# EIGEN3_FOUND - system has eigen lib with correct version +# EIGEN3_INCLUDE_DIR - the eigen include directory +# EIGEN3_VERSION - eigen version + +# Copyright (c) 2006, 2007 Montel Laurent, +# Copyright (c) 2008, 2009 Gael Guennebaud, +# Copyright (c) 2009 Benoit Jacob +# Redistribution and use is allowed according to the terms of the 2-clause BSD license. + +if(NOT Eigen3_FIND_VERSION) + if(NOT Eigen3_FIND_VERSION_MAJOR) + set(Eigen3_FIND_VERSION_MAJOR 2) + endif(NOT Eigen3_FIND_VERSION_MAJOR) + if(NOT Eigen3_FIND_VERSION_MINOR) + set(Eigen3_FIND_VERSION_MINOR 91) + endif(NOT Eigen3_FIND_VERSION_MINOR) + if(NOT Eigen3_FIND_VERSION_PATCH) + set(Eigen3_FIND_VERSION_PATCH 0) + endif(NOT Eigen3_FIND_VERSION_PATCH) + + set(Eigen3_FIND_VERSION "${Eigen3_FIND_VERSION_MAJOR}.${Eigen3_FIND_VERSION_MINOR}.${Eigen3_FIND_VERSION_PATCH}") +endif(NOT Eigen3_FIND_VERSION) + +macro(_eigen3_check_version) + file(READ "${EIGEN3_INCLUDE_DIR}/Eigen/src/Core/util/Macros.h" _eigen3_version_header) + + string(REGEX MATCH "define[ \t]+EIGEN_WORLD_VERSION[ \t]+([0-9]+)" _eigen3_world_version_match "${_eigen3_version_header}") + set(EIGEN3_WORLD_VERSION "${CMAKE_MATCH_1}") + string(REGEX MATCH "define[ \t]+EIGEN_MAJOR_VERSION[ \t]+([0-9]+)" _eigen3_major_version_match "${_eigen3_version_header}") + set(EIGEN3_MAJOR_VERSION "${CMAKE_MATCH_1}") + string(REGEX MATCH "define[ \t]+EIGEN_MINOR_VERSION[ \t]+([0-9]+)" _eigen3_minor_version_match "${_eigen3_version_header}") + set(EIGEN3_MINOR_VERSION "${CMAKE_MATCH_1}") + + set(EIGEN3_VERSION ${EIGEN3_WORLD_VERSION}.${EIGEN3_MAJOR_VERSION}.${EIGEN3_MINOR_VERSION}) + if(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION}) + set(EIGEN3_VERSION_OK FALSE) + else(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION}) + set(EIGEN3_VERSION_OK TRUE) + endif(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION}) + + if(NOT EIGEN3_VERSION_OK) + + message(STATUS "Eigen3 version ${EIGEN3_VERSION} found in ${EIGEN3_INCLUDE_DIR}, " + "but at least version ${Eigen3_FIND_VERSION} is required") + endif(NOT EIGEN3_VERSION_OK) +endmacro(_eigen3_check_version) + +if (EIGEN3_INCLUDE_DIR) + + # in cache already + _eigen3_check_version() + set(EIGEN3_FOUND ${EIGEN3_VERSION_OK}) + +else (EIGEN3_INCLUDE_DIR) + + find_path(EIGEN3_INCLUDE_DIR NAMES signature_of_eigen3_matrix_library + PATHS + ${CMAKE_INSTALL_PREFIX}/include + ${KDE4_INCLUDE_DIR} + PATH_SUFFIXES eigen3 eigen + ) + + if(EIGEN3_INCLUDE_DIR) + _eigen3_check_version() + endif(EIGEN3_INCLUDE_DIR) + + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(Eigen3 DEFAULT_MSG EIGEN3_INCLUDE_DIR EIGEN3_VERSION_OK) + + mark_as_advanced(EIGEN3_INCLUDE_DIR) + +endif(EIGEN3_INCLUDE_DIR) + diff --git a/thirdparty/CMakeLists.txt b/thirdparty/CMakeLists.txt new file mode 100644 index 00000000..63706033 --- /dev/null +++ b/thirdparty/CMakeLists.txt @@ -0,0 +1,3 @@ +if (CGOGN_PROVIDE_EIGEN) + add_subdirectory(eigen-3.2.7) +endif() \ No newline at end of file diff --git a/thirdparty/eigen-3.2.7/CMakeLists.txt b/thirdparty/eigen-3.2.7/CMakeLists.txt new file mode 100644 index 00000000..5b8d58e9 --- /dev/null +++ b/thirdparty/eigen-3.2.7/CMakeLists.txt @@ -0,0 +1,9 @@ +set(EIGEN_ROOT "${CMAKE_CURRENT_SOURCE_DIR}" CACHE PATH "Directory for find_package(Eigen3)") +set(EIGEN3_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}" CACHE PATH "Include directory for find_package(Eigen3)") + +install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/Eigen + COMPONENT Eigen_headers + DESTINATION include + PATTERN "*.in" EXCLUDE + PATTERN "*.txt" EXCLUDE + PATTERN "*.cpp" EXCLUDE) \ No newline at end of file diff --git a/thirdparty/eigen-3.2.7/Eigen/Array b/thirdparty/eigen-3.2.7/Eigen/Array new file mode 100644 index 00000000..3d004fb6 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/Array @@ -0,0 +1,11 @@ +#ifndef EIGEN_ARRAY_MODULE_H +#define EIGEN_ARRAY_MODULE_H + +// include Core first to handle Eigen2 support macros +#include "Core" + +#ifndef EIGEN2_SUPPORT + #error The Eigen/Array header does no longer exist in Eigen3. All that functionality has moved to Eigen/Core. +#endif + +#endif // EIGEN_ARRAY_MODULE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/Cholesky b/thirdparty/eigen-3.2.7/Eigen/Cholesky new file mode 100644 index 00000000..f727f5d8 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/Cholesky @@ -0,0 +1,32 @@ +#ifndef EIGEN_CHOLESKY_MODULE_H +#define EIGEN_CHOLESKY_MODULE_H + +#include "Core" + +#include "src/Core/util/DisableStupidWarnings.h" + +/** \defgroup Cholesky_Module Cholesky module + * + * + * + * This module provides two variants of the Cholesky decomposition for selfadjoint (hermitian) matrices. + * Those decompositions are accessible via the following MatrixBase methods: + * - MatrixBase::llt(), + * - MatrixBase::ldlt() + * + * \code + * #include + * \endcode + */ + +#include "src/misc/Solve.h" +#include "src/Cholesky/LLT.h" +#include "src/Cholesky/LDLT.h" +#ifdef EIGEN_USE_LAPACKE +#include "src/Cholesky/LLT_MKL.h" +#endif + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_CHOLESKY_MODULE_H +/* vim: set filetype=cpp et sw=2 ts=2 ai: */ diff --git a/thirdparty/eigen-3.2.7/Eigen/CholmodSupport b/thirdparty/eigen-3.2.7/Eigen/CholmodSupport new file mode 100644 index 00000000..745b884e --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/CholmodSupport @@ -0,0 +1,45 @@ +#ifndef EIGEN_CHOLMODSUPPORT_MODULE_H +#define EIGEN_CHOLMODSUPPORT_MODULE_H + +#include "SparseCore" + +#include "src/Core/util/DisableStupidWarnings.h" + +extern "C" { + #include +} + +/** \ingroup Support_modules + * \defgroup CholmodSupport_Module CholmodSupport module + * + * This module provides an interface to the Cholmod library which is part of the suitesparse package. + * It provides the two following main factorization classes: + * - class CholmodSupernodalLLT: a supernodal LLT Cholesky factorization. + * - class CholmodDecomposiiton: a general L(D)LT Cholesky factorization with automatic or explicit runtime selection of the underlying factorization method (supernodal or simplicial). + * + * For the sake of completeness, this module also propose the two following classes: + * - class CholmodSimplicialLLT + * - class CholmodSimplicialLDLT + * Note that these classes does not bring any particular advantage compared to the built-in + * SimplicialLLT and SimplicialLDLT factorization classes. + * + * \code + * #include + * \endcode + * + * In order to use this module, the cholmod headers must be accessible from the include paths, and your binary must be linked to the cholmod library and its dependencies. + * The dependencies depend on how cholmod has been compiled. + * For a cmake based project, you can use our FindCholmod.cmake module to help you in this task. + * + */ + +#include "src/misc/Solve.h" +#include "src/misc/SparseSolve.h" + +#include "src/CholmodSupport/CholmodSupport.h" + + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_CHOLMODSUPPORT_MODULE_H + diff --git a/thirdparty/eigen-3.2.7/Eigen/Core b/thirdparty/eigen-3.2.7/Eigen/Core new file mode 100644 index 00000000..509c529e --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/Core @@ -0,0 +1,376 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008 Gael Guennebaud +// Copyright (C) 2007-2011 Benoit Jacob +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_CORE_H +#define EIGEN_CORE_H + +// first thing Eigen does: stop the compiler from committing suicide +#include "src/Core/util/DisableStupidWarnings.h" + +// then include this file where all our macros are defined. It's really important to do it first because +// it's where we do all the alignment settings (platform detection and honoring the user's will if he +// defined e.g. EIGEN_DONT_ALIGN) so it needs to be done before we do anything with vectorization. +#include "src/Core/util/Macros.h" + +// Disable the ipa-cp-clone optimization flag with MinGW 6.x or newer (enabled by default with -O3) +// See http://eigen.tuxfamily.org/bz/show_bug.cgi?id=556 for details. +#if defined(__MINGW32__) && EIGEN_GNUC_AT_LEAST(4,6) + #pragma GCC optimize ("-fno-ipa-cp-clone") +#endif + +#include + +// this include file manages BLAS and MKL related macros +// and inclusion of their respective header files +#include "src/Core/util/MKL_support.h" + +// if alignment is disabled, then disable vectorization. Note: EIGEN_ALIGN is the proper check, it takes into +// account both the user's will (EIGEN_DONT_ALIGN) and our own platform checks +#if !EIGEN_ALIGN + #ifndef EIGEN_DONT_VECTORIZE + #define EIGEN_DONT_VECTORIZE + #endif +#endif + +#ifdef _MSC_VER + #include // for _aligned_malloc -- need it regardless of whether vectorization is enabled + #if (_MSC_VER >= 1500) // 2008 or later + // Remember that usage of defined() in a #define is undefined by the standard. + // a user reported that in 64-bit mode, MSVC doesn't care to define _M_IX86_FP. + #if (defined(_M_IX86_FP) && (_M_IX86_FP >= 2)) || defined(_M_X64) + #define EIGEN_SSE2_ON_MSVC_2008_OR_LATER + #endif + #endif +#else + // Remember that usage of defined() in a #define is undefined by the standard + #if (defined __SSE2__) && ( (!defined __GNUC__) || (defined __INTEL_COMPILER) || EIGEN_GNUC_AT_LEAST(4,2) ) + #define EIGEN_SSE2_ON_NON_MSVC_BUT_NOT_OLD_GCC + #endif +#endif + +#ifndef EIGEN_DONT_VECTORIZE + + #if defined (EIGEN_SSE2_ON_NON_MSVC_BUT_NOT_OLD_GCC) || defined(EIGEN_SSE2_ON_MSVC_2008_OR_LATER) + + // Defines symbols for compile-time detection of which instructions are + // used. + // EIGEN_VECTORIZE_YY is defined if and only if the instruction set YY is used + #define EIGEN_VECTORIZE + #define EIGEN_VECTORIZE_SSE + #define EIGEN_VECTORIZE_SSE2 + + // Detect sse3/ssse3/sse4: + // gcc and icc defines __SSE3__, ... + // there is no way to know about this on msvc. You can define EIGEN_VECTORIZE_SSE* if you + // want to force the use of those instructions with msvc. + #ifdef __SSE3__ + #define EIGEN_VECTORIZE_SSE3 + #endif + #ifdef __SSSE3__ + #define EIGEN_VECTORIZE_SSSE3 + #endif + #ifdef __SSE4_1__ + #define EIGEN_VECTORIZE_SSE4_1 + #endif + #ifdef __SSE4_2__ + #define EIGEN_VECTORIZE_SSE4_2 + #endif + + // include files + + // This extern "C" works around a MINGW-w64 compilation issue + // https://sourceforge.net/tracker/index.php?func=detail&aid=3018394&group_id=202880&atid=983354 + // In essence, intrin.h is included by windows.h and also declares intrinsics (just as emmintrin.h etc. below do). + // However, intrin.h uses an extern "C" declaration, and g++ thus complains of duplicate declarations + // with conflicting linkage. The linkage for intrinsics doesn't matter, but at that stage the compiler doesn't know; + // so, to avoid compile errors when windows.h is included after Eigen/Core, ensure intrinsics are extern "C" here too. + // notice that since these are C headers, the extern "C" is theoretically needed anyways. + extern "C" { + // In theory we should only include immintrin.h and not the other *mmintrin.h header files directly. + // Doing so triggers some issues with ICC. However old gcc versions seems to not have this file, thus: + #if defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 1110 + #include + #else + #include + #include + #ifdef EIGEN_VECTORIZE_SSE3 + #include + #endif + #ifdef EIGEN_VECTORIZE_SSSE3 + #include + #endif + #ifdef EIGEN_VECTORIZE_SSE4_1 + #include + #endif + #ifdef EIGEN_VECTORIZE_SSE4_2 + #include + #endif + #endif + } // end extern "C" + #elif defined __ALTIVEC__ + #define EIGEN_VECTORIZE + #define EIGEN_VECTORIZE_ALTIVEC + #include + // We need to #undef all these ugly tokens defined in + // => use __vector instead of vector + #undef bool + #undef vector + #undef pixel + #elif defined __ARM_NEON + #define EIGEN_VECTORIZE + #define EIGEN_VECTORIZE_NEON + #include + #endif +#endif + +#if (defined _OPENMP) && (!defined EIGEN_DONT_PARALLELIZE) + #define EIGEN_HAS_OPENMP +#endif + +#ifdef EIGEN_HAS_OPENMP +#include +#endif + +// MSVC for windows mobile does not have the errno.h file +#if !(defined(_MSC_VER) && defined(_WIN32_WCE)) && !defined(__ARMCC_VERSION) +#define EIGEN_HAS_ERRNO +#endif + +#ifdef EIGEN_HAS_ERRNO +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // for CHAR_BIT +// for min/max: +#include + +// for outputting debug info +#ifdef EIGEN_DEBUG_ASSIGN +#include +#endif + +// required for __cpuid, needs to be included after cmath +#if defined(_MSC_VER) && (defined(_M_IX86)||defined(_M_X64)) && (!defined(_WIN32_WCE)) + #include +#endif + +#if defined(_CPPUNWIND) || defined(__EXCEPTIONS) + #define EIGEN_EXCEPTIONS +#endif + +#ifdef EIGEN_EXCEPTIONS + #include +#endif + +/** \brief Namespace containing all symbols from the %Eigen library. */ +namespace Eigen { + +inline static const char *SimdInstructionSetsInUse(void) { +#if defined(EIGEN_VECTORIZE_SSE4_2) + return "SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2"; +#elif defined(EIGEN_VECTORIZE_SSE4_1) + return "SSE, SSE2, SSE3, SSSE3, SSE4.1"; +#elif defined(EIGEN_VECTORIZE_SSSE3) + return "SSE, SSE2, SSE3, SSSE3"; +#elif defined(EIGEN_VECTORIZE_SSE3) + return "SSE, SSE2, SSE3"; +#elif defined(EIGEN_VECTORIZE_SSE2) + return "SSE, SSE2"; +#elif defined(EIGEN_VECTORIZE_ALTIVEC) + return "AltiVec"; +#elif defined(EIGEN_VECTORIZE_NEON) + return "ARM NEON"; +#else + return "None"; +#endif +} + +} // end namespace Eigen + +#define STAGE10_FULL_EIGEN2_API 10 +#define STAGE20_RESOLVE_API_CONFLICTS 20 +#define STAGE30_FULL_EIGEN3_API 30 +#define STAGE40_FULL_EIGEN3_STRICTNESS 40 +#define STAGE99_NO_EIGEN2_SUPPORT 99 + +#if defined EIGEN2_SUPPORT_STAGE40_FULL_EIGEN3_STRICTNESS + #define EIGEN2_SUPPORT + #define EIGEN2_SUPPORT_STAGE STAGE40_FULL_EIGEN3_STRICTNESS +#elif defined EIGEN2_SUPPORT_STAGE30_FULL_EIGEN3_API + #define EIGEN2_SUPPORT + #define EIGEN2_SUPPORT_STAGE STAGE30_FULL_EIGEN3_API +#elif defined EIGEN2_SUPPORT_STAGE20_RESOLVE_API_CONFLICTS + #define EIGEN2_SUPPORT + #define EIGEN2_SUPPORT_STAGE STAGE20_RESOLVE_API_CONFLICTS +#elif defined EIGEN2_SUPPORT_STAGE10_FULL_EIGEN2_API + #define EIGEN2_SUPPORT + #define EIGEN2_SUPPORT_STAGE STAGE10_FULL_EIGEN2_API +#elif defined EIGEN2_SUPPORT + // default to stage 3, that's what it's always meant + #define EIGEN2_SUPPORT_STAGE30_FULL_EIGEN3_API + #define EIGEN2_SUPPORT_STAGE STAGE30_FULL_EIGEN3_API +#else + #define EIGEN2_SUPPORT_STAGE STAGE99_NO_EIGEN2_SUPPORT +#endif + +#ifdef EIGEN2_SUPPORT +#undef minor +#endif + +// we use size_t frequently and we'll never remember to prepend it with std:: everytime just to +// ensure QNX/QCC support +using std::size_t; +// gcc 4.6.0 wants std:: for ptrdiff_t +using std::ptrdiff_t; + +/** \defgroup Core_Module Core module + * This is the main module of Eigen providing dense matrix and vector support + * (both fixed and dynamic size) with all the features corresponding to a BLAS library + * and much more... + * + * \code + * #include + * \endcode + */ + +#include "src/Core/util/Constants.h" +#include "src/Core/util/ForwardDeclarations.h" +#include "src/Core/util/Meta.h" +#include "src/Core/util/StaticAssert.h" +#include "src/Core/util/XprHelper.h" +#include "src/Core/util/Memory.h" + +#include "src/Core/NumTraits.h" +#include "src/Core/MathFunctions.h" +#include "src/Core/GenericPacketMath.h" + +#if defined EIGEN_VECTORIZE_SSE + #include "src/Core/arch/SSE/PacketMath.h" + #include "src/Core/arch/SSE/MathFunctions.h" + #include "src/Core/arch/SSE/Complex.h" +#elif defined EIGEN_VECTORIZE_ALTIVEC + #include "src/Core/arch/AltiVec/PacketMath.h" + #include "src/Core/arch/AltiVec/Complex.h" +#elif defined EIGEN_VECTORIZE_NEON + #include "src/Core/arch/NEON/PacketMath.h" + #include "src/Core/arch/NEON/Complex.h" +#endif + +#include "src/Core/arch/Default/Settings.h" + +#include "src/Core/Functors.h" +#include "src/Core/DenseCoeffsBase.h" +#include "src/Core/DenseBase.h" +#include "src/Core/MatrixBase.h" +#include "src/Core/EigenBase.h" + +#ifndef EIGEN_PARSED_BY_DOXYGEN // work around Doxygen bug triggered by Assign.h r814874 + // at least confirmed with Doxygen 1.5.5 and 1.5.6 + #include "src/Core/Assign.h" +#endif + +#include "src/Core/util/BlasUtil.h" +#include "src/Core/DenseStorage.h" +#include "src/Core/NestByValue.h" +#include "src/Core/ForceAlignedAccess.h" +#include "src/Core/ReturnByValue.h" +#include "src/Core/NoAlias.h" +#include "src/Core/PlainObjectBase.h" +#include "src/Core/Matrix.h" +#include "src/Core/Array.h" +#include "src/Core/CwiseBinaryOp.h" +#include "src/Core/CwiseUnaryOp.h" +#include "src/Core/CwiseNullaryOp.h" +#include "src/Core/CwiseUnaryView.h" +#include "src/Core/SelfCwiseBinaryOp.h" +#include "src/Core/Dot.h" +#include "src/Core/StableNorm.h" +#include "src/Core/MapBase.h" +#include "src/Core/Stride.h" +#include "src/Core/Map.h" +#include "src/Core/Block.h" +#include "src/Core/VectorBlock.h" +#include "src/Core/Ref.h" +#include "src/Core/Transpose.h" +#include "src/Core/DiagonalMatrix.h" +#include "src/Core/Diagonal.h" +#include "src/Core/DiagonalProduct.h" +#include "src/Core/PermutationMatrix.h" +#include "src/Core/Transpositions.h" +#include "src/Core/Redux.h" +#include "src/Core/Visitor.h" +#include "src/Core/Fuzzy.h" +#include "src/Core/IO.h" +#include "src/Core/Swap.h" +#include "src/Core/CommaInitializer.h" +#include "src/Core/Flagged.h" +#include "src/Core/ProductBase.h" +#include "src/Core/GeneralProduct.h" +#include "src/Core/TriangularMatrix.h" +#include "src/Core/SelfAdjointView.h" +#include "src/Core/products/GeneralBlockPanelKernel.h" +#include "src/Core/products/Parallelizer.h" +#include "src/Core/products/CoeffBasedProduct.h" +#include "src/Core/products/GeneralMatrixVector.h" +#include "src/Core/products/GeneralMatrixMatrix.h" +#include "src/Core/SolveTriangular.h" +#include "src/Core/products/GeneralMatrixMatrixTriangular.h" +#include "src/Core/products/SelfadjointMatrixVector.h" +#include "src/Core/products/SelfadjointMatrixMatrix.h" +#include "src/Core/products/SelfadjointProduct.h" +#include "src/Core/products/SelfadjointRank2Update.h" +#include "src/Core/products/TriangularMatrixVector.h" +#include "src/Core/products/TriangularMatrixMatrix.h" +#include "src/Core/products/TriangularSolverMatrix.h" +#include "src/Core/products/TriangularSolverVector.h" +#include "src/Core/BandMatrix.h" +#include "src/Core/CoreIterators.h" + +#include "src/Core/BooleanRedux.h" +#include "src/Core/Select.h" +#include "src/Core/VectorwiseOp.h" +#include "src/Core/Random.h" +#include "src/Core/Replicate.h" +#include "src/Core/Reverse.h" +#include "src/Core/ArrayBase.h" +#include "src/Core/ArrayWrapper.h" + +#ifdef EIGEN_USE_BLAS +#include "src/Core/products/GeneralMatrixMatrix_MKL.h" +#include "src/Core/products/GeneralMatrixVector_MKL.h" +#include "src/Core/products/GeneralMatrixMatrixTriangular_MKL.h" +#include "src/Core/products/SelfadjointMatrixMatrix_MKL.h" +#include "src/Core/products/SelfadjointMatrixVector_MKL.h" +#include "src/Core/products/TriangularMatrixMatrix_MKL.h" +#include "src/Core/products/TriangularMatrixVector_MKL.h" +#include "src/Core/products/TriangularSolverMatrix_MKL.h" +#endif // EIGEN_USE_BLAS + +#ifdef EIGEN_USE_MKL_VML +#include "src/Core/Assign_MKL.h" +#endif + +#include "src/Core/GlobalFunctions.h" + +#include "src/Core/util/ReenableStupidWarnings.h" + +#ifdef EIGEN2_SUPPORT +#include "Eigen2Support" +#endif + +#endif // EIGEN_CORE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/Dense b/thirdparty/eigen-3.2.7/Eigen/Dense new file mode 100644 index 00000000..5768910b --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/Dense @@ -0,0 +1,7 @@ +#include "Core" +#include "LU" +#include "Cholesky" +#include "QR" +#include "SVD" +#include "Geometry" +#include "Eigenvalues" diff --git a/thirdparty/eigen-3.2.7/Eigen/Eigen b/thirdparty/eigen-3.2.7/Eigen/Eigen new file mode 100644 index 00000000..19b40ea4 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/Eigen @@ -0,0 +1,2 @@ +#include "Dense" +//#include "Sparse" diff --git a/thirdparty/eigen-3.2.7/Eigen/Eigen2Support b/thirdparty/eigen-3.2.7/Eigen/Eigen2Support new file mode 100644 index 00000000..6aa009d2 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/Eigen2Support @@ -0,0 +1,95 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2009 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN2SUPPORT_H +#define EIGEN2SUPPORT_H + +#if (!defined(EIGEN2_SUPPORT)) || (!defined(EIGEN_CORE_H)) +#error Eigen2 support must be enabled by defining EIGEN2_SUPPORT before including any Eigen header +#endif + +#ifndef EIGEN_NO_EIGEN2_DEPRECATED_WARNING + +#if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__clang__) +#warning "Eigen2 support is deprecated in Eigen 3.2.x and it will be removed in Eigen 3.3. (Define EIGEN_NO_EIGEN2_DEPRECATED_WARNING to disable this warning)" +#else +#pragma message ("Eigen2 support is deprecated in Eigen 3.2.x and it will be removed in Eigen 3.3. (Define EIGEN_NO_EIGEN2_DEPRECATED_WARNING to disable this warning)") +#endif + +#endif // EIGEN_NO_EIGEN2_DEPRECATED_WARNING + +#include "src/Core/util/DisableStupidWarnings.h" + +/** \ingroup Support_modules + * \defgroup Eigen2Support_Module Eigen2 support module + * + * \warning Eigen2 support is deprecated in Eigen 3.2.x and it will be removed in Eigen 3.3. + * + * This module provides a couple of deprecated functions improving the compatibility with Eigen2. + * + * To use it, define EIGEN2_SUPPORT before including any Eigen header + * \code + * #define EIGEN2_SUPPORT + * \endcode + * + */ + +#include "src/Eigen2Support/Macros.h" +#include "src/Eigen2Support/Memory.h" +#include "src/Eigen2Support/Meta.h" +#include "src/Eigen2Support/Lazy.h" +#include "src/Eigen2Support/Cwise.h" +#include "src/Eigen2Support/CwiseOperators.h" +#include "src/Eigen2Support/TriangularSolver.h" +#include "src/Eigen2Support/Block.h" +#include "src/Eigen2Support/VectorBlock.h" +#include "src/Eigen2Support/Minor.h" +#include "src/Eigen2Support/MathFunctions.h" + + +#include "src/Core/util/ReenableStupidWarnings.h" + +// Eigen2 used to include iostream +#include + +#define EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, SizeSuffix) \ +using Eigen::Matrix##SizeSuffix##TypeSuffix; \ +using Eigen::Vector##SizeSuffix##TypeSuffix; \ +using Eigen::RowVector##SizeSuffix##TypeSuffix; + +#define EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(TypeSuffix) \ +EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 2) \ +EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 3) \ +EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 4) \ +EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, X) \ + +#define EIGEN_USING_MATRIX_TYPEDEFS \ +EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(i) \ +EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(f) \ +EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(d) \ +EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(cf) \ +EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(cd) + +#define USING_PART_OF_NAMESPACE_EIGEN \ +EIGEN_USING_MATRIX_TYPEDEFS \ +using Eigen::Matrix; \ +using Eigen::MatrixBase; \ +using Eigen::ei_random; \ +using Eigen::ei_real; \ +using Eigen::ei_imag; \ +using Eigen::ei_conj; \ +using Eigen::ei_abs; \ +using Eigen::ei_abs2; \ +using Eigen::ei_sqrt; \ +using Eigen::ei_exp; \ +using Eigen::ei_log; \ +using Eigen::ei_sin; \ +using Eigen::ei_cos; + +#endif // EIGEN2SUPPORT_H diff --git a/thirdparty/eigen-3.2.7/Eigen/Eigenvalues b/thirdparty/eigen-3.2.7/Eigen/Eigenvalues new file mode 100644 index 00000000..53c5a73a --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/Eigenvalues @@ -0,0 +1,48 @@ +#ifndef EIGEN_EIGENVALUES_MODULE_H +#define EIGEN_EIGENVALUES_MODULE_H + +#include "Core" + +#include "src/Core/util/DisableStupidWarnings.h" + +#include "Cholesky" +#include "Jacobi" +#include "Householder" +#include "LU" +#include "Geometry" + +/** \defgroup Eigenvalues_Module Eigenvalues module + * + * + * + * This module mainly provides various eigenvalue solvers. + * This module also provides some MatrixBase methods, including: + * - MatrixBase::eigenvalues(), + * - MatrixBase::operatorNorm() + * + * \code + * #include + * \endcode + */ + +#include "src/Eigenvalues/Tridiagonalization.h" +#include "src/Eigenvalues/RealSchur.h" +#include "src/Eigenvalues/EigenSolver.h" +#include "src/Eigenvalues/SelfAdjointEigenSolver.h" +#include "src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h" +#include "src/Eigenvalues/HessenbergDecomposition.h" +#include "src/Eigenvalues/ComplexSchur.h" +#include "src/Eigenvalues/ComplexEigenSolver.h" +#include "src/Eigenvalues/RealQZ.h" +#include "src/Eigenvalues/GeneralizedEigenSolver.h" +#include "src/Eigenvalues/MatrixBaseEigenvalues.h" +#ifdef EIGEN_USE_LAPACKE +#include "src/Eigenvalues/RealSchur_MKL.h" +#include "src/Eigenvalues/ComplexSchur_MKL.h" +#include "src/Eigenvalues/SelfAdjointEigenSolver_MKL.h" +#endif + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_EIGENVALUES_MODULE_H +/* vim: set filetype=cpp et sw=2 ts=2 ai: */ diff --git a/thirdparty/eigen-3.2.7/Eigen/Geometry b/thirdparty/eigen-3.2.7/Eigen/Geometry new file mode 100644 index 00000000..efd9d450 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/Geometry @@ -0,0 +1,63 @@ +#ifndef EIGEN_GEOMETRY_MODULE_H +#define EIGEN_GEOMETRY_MODULE_H + +#include "Core" + +#include "src/Core/util/DisableStupidWarnings.h" + +#include "SVD" +#include "LU" +#include + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +/** \defgroup Geometry_Module Geometry module + * + * + * + * This module provides support for: + * - fixed-size homogeneous transformations + * - translation, scaling, 2D and 3D rotations + * - quaternions + * - \ref MatrixBase::cross() "cross product" + * - \ref MatrixBase::unitOrthogonal() "orthognal vector generation" + * - some linear components: parametrized-lines and hyperplanes + * + * \code + * #include + * \endcode + */ + +#include "src/Geometry/OrthoMethods.h" +#include "src/Geometry/EulerAngles.h" + +#if EIGEN2_SUPPORT_STAGE > STAGE20_RESOLVE_API_CONFLICTS + #include "src/Geometry/Homogeneous.h" + #include "src/Geometry/RotationBase.h" + #include "src/Geometry/Rotation2D.h" + #include "src/Geometry/Quaternion.h" + #include "src/Geometry/AngleAxis.h" + #include "src/Geometry/Transform.h" + #include "src/Geometry/Translation.h" + #include "src/Geometry/Scaling.h" + #include "src/Geometry/Hyperplane.h" + #include "src/Geometry/ParametrizedLine.h" + #include "src/Geometry/AlignedBox.h" + #include "src/Geometry/Umeyama.h" + + #if defined EIGEN_VECTORIZE_SSE + #include "src/Geometry/arch/Geometry_SSE.h" + #endif +#endif + +#ifdef EIGEN2_SUPPORT +#include "src/Eigen2Support/Geometry/All.h" +#endif + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_GEOMETRY_MODULE_H +/* vim: set filetype=cpp et sw=2 ts=2 ai: */ + diff --git a/thirdparty/eigen-3.2.7/Eigen/Householder b/thirdparty/eigen-3.2.7/Eigen/Householder new file mode 100644 index 00000000..6e348db5 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/Householder @@ -0,0 +1,23 @@ +#ifndef EIGEN_HOUSEHOLDER_MODULE_H +#define EIGEN_HOUSEHOLDER_MODULE_H + +#include "Core" + +#include "src/Core/util/DisableStupidWarnings.h" + +/** \defgroup Householder_Module Householder module + * This module provides Householder transformations. + * + * \code + * #include + * \endcode + */ + +#include "src/Householder/Householder.h" +#include "src/Householder/HouseholderSequence.h" +#include "src/Householder/BlockHouseholder.h" + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_HOUSEHOLDER_MODULE_H +/* vim: set filetype=cpp et sw=2 ts=2 ai: */ diff --git a/thirdparty/eigen-3.2.7/Eigen/IterativeLinearSolvers b/thirdparty/eigen-3.2.7/Eigen/IterativeLinearSolvers new file mode 100644 index 00000000..0f4159dc --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/IterativeLinearSolvers @@ -0,0 +1,40 @@ +#ifndef EIGEN_ITERATIVELINEARSOLVERS_MODULE_H +#define EIGEN_ITERATIVELINEARSOLVERS_MODULE_H + +#include "SparseCore" +#include "OrderingMethods" + +#include "src/Core/util/DisableStupidWarnings.h" + +/** + * \defgroup IterativeLinearSolvers_Module IterativeLinearSolvers module + * + * This module currently provides iterative methods to solve problems of the form \c A \c x = \c b, where \c A is a squared matrix, usually very large and sparse. + * Those solvers are accessible via the following classes: + * - ConjugateGradient for selfadjoint (hermitian) matrices, + * - BiCGSTAB for general square matrices. + * + * These iterative solvers are associated with some preconditioners: + * - IdentityPreconditioner - not really useful + * - DiagonalPreconditioner - also called JAcobi preconditioner, work very well on diagonal dominant matrices. + * - IncompleteILUT - incomplete LU factorization with dual thresholding + * + * Such problems can also be solved using the direct sparse decomposition modules: SparseCholesky, CholmodSupport, UmfPackSupport, SuperLUSupport. + * + * \code + * #include + * \endcode + */ + +#include "src/misc/Solve.h" +#include "src/misc/SparseSolve.h" + +#include "src/IterativeLinearSolvers/IterativeSolverBase.h" +#include "src/IterativeLinearSolvers/BasicPreconditioners.h" +#include "src/IterativeLinearSolvers/ConjugateGradient.h" +#include "src/IterativeLinearSolvers/BiCGSTAB.h" +#include "src/IterativeLinearSolvers/IncompleteLUT.h" + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_ITERATIVELINEARSOLVERS_MODULE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/Jacobi b/thirdparty/eigen-3.2.7/Eigen/Jacobi new file mode 100644 index 00000000..ba8a4dc3 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/Jacobi @@ -0,0 +1,26 @@ +#ifndef EIGEN_JACOBI_MODULE_H +#define EIGEN_JACOBI_MODULE_H + +#include "Core" + +#include "src/Core/util/DisableStupidWarnings.h" + +/** \defgroup Jacobi_Module Jacobi module + * This module provides Jacobi and Givens rotations. + * + * \code + * #include + * \endcode + * + * In addition to listed classes, it defines the two following MatrixBase methods to apply a Jacobi or Givens rotation: + * - MatrixBase::applyOnTheLeft() + * - MatrixBase::applyOnTheRight(). + */ + +#include "src/Jacobi/Jacobi.h" + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_JACOBI_MODULE_H +/* vim: set filetype=cpp et sw=2 ts=2 ai: */ + diff --git a/thirdparty/eigen-3.2.7/Eigen/LU b/thirdparty/eigen-3.2.7/Eigen/LU new file mode 100644 index 00000000..db579550 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/LU @@ -0,0 +1,41 @@ +#ifndef EIGEN_LU_MODULE_H +#define EIGEN_LU_MODULE_H + +#include "Core" + +#include "src/Core/util/DisableStupidWarnings.h" + +/** \defgroup LU_Module LU module + * This module includes %LU decomposition and related notions such as matrix inversion and determinant. + * This module defines the following MatrixBase methods: + * - MatrixBase::inverse() + * - MatrixBase::determinant() + * + * \code + * #include + * \endcode + */ + +#include "src/misc/Solve.h" +#include "src/misc/Kernel.h" +#include "src/misc/Image.h" +#include "src/LU/FullPivLU.h" +#include "src/LU/PartialPivLU.h" +#ifdef EIGEN_USE_LAPACKE +#include "src/LU/PartialPivLU_MKL.h" +#endif +#include "src/LU/Determinant.h" +#include "src/LU/Inverse.h" + +#if defined EIGEN_VECTORIZE_SSE + #include "src/LU/arch/Inverse_SSE.h" +#endif + +#ifdef EIGEN2_SUPPORT + #include "src/Eigen2Support/LU.h" +#endif + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_LU_MODULE_H +/* vim: set filetype=cpp et sw=2 ts=2 ai: */ diff --git a/thirdparty/eigen-3.2.7/Eigen/LeastSquares b/thirdparty/eigen-3.2.7/Eigen/LeastSquares new file mode 100644 index 00000000..35137c25 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/LeastSquares @@ -0,0 +1,32 @@ +#ifndef EIGEN_REGRESSION_MODULE_H +#define EIGEN_REGRESSION_MODULE_H + +#ifndef EIGEN2_SUPPORT +#error LeastSquares is only available in Eigen2 support mode (define EIGEN2_SUPPORT) +#endif + +// exclude from normal eigen3-only documentation +#ifdef EIGEN2_SUPPORT + +#include "Core" + +#include "src/Core/util/DisableStupidWarnings.h" + +#include "Eigenvalues" +#include "Geometry" + +/** \defgroup LeastSquares_Module LeastSquares module + * This module provides linear regression and related features. + * + * \code + * #include + * \endcode + */ + +#include "src/Eigen2Support/LeastSquares.h" + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN2_SUPPORT + +#endif // EIGEN_REGRESSION_MODULE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/MetisSupport b/thirdparty/eigen-3.2.7/Eigen/MetisSupport new file mode 100644 index 00000000..6a113f7a --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/MetisSupport @@ -0,0 +1,28 @@ +#ifndef EIGEN_METISSUPPORT_MODULE_H +#define EIGEN_METISSUPPORT_MODULE_H + +#include "SparseCore" + +#include "src/Core/util/DisableStupidWarnings.h" + +extern "C" { +#include +} + + +/** \ingroup Support_modules + * \defgroup MetisSupport_Module MetisSupport module + * + * \code + * #include + * \endcode + * This module defines an interface to the METIS reordering package (http://glaros.dtc.umn.edu/gkhome/views/metis). + * It can be used just as any other built-in method as explained in \link OrderingMethods_Module here. \endlink + */ + + +#include "src/MetisSupport/MetisSupport.h" + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_METISSUPPORT_MODULE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/OrderingMethods b/thirdparty/eigen-3.2.7/Eigen/OrderingMethods new file mode 100644 index 00000000..7c0f1fff --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/OrderingMethods @@ -0,0 +1,66 @@ +#ifndef EIGEN_ORDERINGMETHODS_MODULE_H +#define EIGEN_ORDERINGMETHODS_MODULE_H + +#include "SparseCore" + +#include "src/Core/util/DisableStupidWarnings.h" + +/** + * \defgroup OrderingMethods_Module OrderingMethods module + * + * This module is currently for internal use only + * + * It defines various built-in and external ordering methods for sparse matrices. + * They are typically used to reduce the number of elements during + * the sparse matrix decomposition (LLT, LU, QR). + * Precisely, in a preprocessing step, a permutation matrix P is computed using + * those ordering methods and applied to the columns of the matrix. + * Using for instance the sparse Cholesky decomposition, it is expected that + * the nonzeros elements in LLT(A*P) will be much smaller than that in LLT(A). + * + * + * Usage : + * \code + * #include + * \endcode + * + * A simple usage is as a template parameter in the sparse decomposition classes : + * + * \code + * SparseLU > solver; + * \endcode + * + * \code + * SparseQR > solver; + * \endcode + * + * It is possible as well to call directly a particular ordering method for your own purpose, + * \code + * AMDOrdering ordering; + * PermutationMatrix perm; + * SparseMatrix A; + * //Fill the matrix ... + * + * ordering(A, perm); // Call AMD + * \endcode + * + * \note Some of these methods (like AMD or METIS), need the sparsity pattern + * of the input matrix to be symmetric. When the matrix is structurally unsymmetric, + * Eigen computes internally the pattern of \f$A^T*A\f$ before calling the method. + * If your matrix is already symmetric (at leat in structure), you can avoid that + * by calling the method with a SelfAdjointView type. + * + * \code + * // Call the ordering on the pattern of the lower triangular matrix A + * ordering(A.selfadjointView(), perm); + * \endcode + */ + +#ifndef EIGEN_MPL2_ONLY +#include "src/OrderingMethods/Amd.h" +#endif + +#include "src/OrderingMethods/Ordering.h" +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_ORDERINGMETHODS_MODULE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/PaStiXSupport b/thirdparty/eigen-3.2.7/Eigen/PaStiXSupport new file mode 100644 index 00000000..7c616ee5 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/PaStiXSupport @@ -0,0 +1,46 @@ +#ifndef EIGEN_PASTIXSUPPORT_MODULE_H +#define EIGEN_PASTIXSUPPORT_MODULE_H + +#include "SparseCore" + +#include "src/Core/util/DisableStupidWarnings.h" + +#include +extern "C" { +#include +#include +} + +#ifdef complex +#undef complex +#endif + +/** \ingroup Support_modules + * \defgroup PaStiXSupport_Module PaStiXSupport module + * + * This module provides an interface to the PaSTiX library. + * PaSTiX is a general \b supernodal, \b parallel and \b opensource sparse solver. + * It provides the two following main factorization classes: + * - class PastixLLT : a supernodal, parallel LLt Cholesky factorization. + * - class PastixLDLT: a supernodal, parallel LDLt Cholesky factorization. + * - class PastixLU : a supernodal, parallel LU factorization (optimized for a symmetric pattern). + * + * \code + * #include + * \endcode + * + * In order to use this module, the PaSTiX headers must be accessible from the include paths, and your binary must be linked to the PaSTiX library and its dependencies. + * The dependencies depend on how PaSTiX has been compiled. + * For a cmake based project, you can use our FindPaSTiX.cmake module to help you in this task. + * + */ + +#include "src/misc/Solve.h" +#include "src/misc/SparseSolve.h" + +#include "src/PaStiXSupport/PaStiXSupport.h" + + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_PASTIXSUPPORT_MODULE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/PardisoSupport b/thirdparty/eigen-3.2.7/Eigen/PardisoSupport new file mode 100644 index 00000000..99330ce7 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/PardisoSupport @@ -0,0 +1,30 @@ +#ifndef EIGEN_PARDISOSUPPORT_MODULE_H +#define EIGEN_PARDISOSUPPORT_MODULE_H + +#include "SparseCore" + +#include "src/Core/util/DisableStupidWarnings.h" + +#include + +#include + +/** \ingroup Support_modules + * \defgroup PardisoSupport_Module PardisoSupport module + * + * This module brings support for the Intel(R) MKL PARDISO direct sparse solvers. + * + * \code + * #include + * \endcode + * + * In order to use this module, the MKL headers must be accessible from the include paths, and your binary must be linked to the MKL library and its dependencies. + * See this \ref TopicUsingIntelMKL "page" for more information on MKL-Eigen integration. + * + */ + +#include "src/PardisoSupport/PardisoSupport.h" + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_PARDISOSUPPORT_MODULE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/QR b/thirdparty/eigen-3.2.7/Eigen/QR new file mode 100644 index 00000000..ac5b0269 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/QR @@ -0,0 +1,45 @@ +#ifndef EIGEN_QR_MODULE_H +#define EIGEN_QR_MODULE_H + +#include "Core" + +#include "src/Core/util/DisableStupidWarnings.h" + +#include "Cholesky" +#include "Jacobi" +#include "Householder" + +/** \defgroup QR_Module QR module + * + * + * + * This module provides various QR decompositions + * This module also provides some MatrixBase methods, including: + * - MatrixBase::qr(), + * + * \code + * #include + * \endcode + */ + +#include "src/misc/Solve.h" +#include "src/QR/HouseholderQR.h" +#include "src/QR/FullPivHouseholderQR.h" +#include "src/QR/ColPivHouseholderQR.h" +#ifdef EIGEN_USE_LAPACKE +#include "src/QR/HouseholderQR_MKL.h" +#include "src/QR/ColPivHouseholderQR_MKL.h" +#endif + +#ifdef EIGEN2_SUPPORT +#include "src/Eigen2Support/QR.h" +#endif + +#include "src/Core/util/ReenableStupidWarnings.h" + +#ifdef EIGEN2_SUPPORT +#include "Eigenvalues" +#endif + +#endif // EIGEN_QR_MODULE_H +/* vim: set filetype=cpp et sw=2 ts=2 ai: */ diff --git a/thirdparty/eigen-3.2.7/Eigen/QtAlignedMalloc b/thirdparty/eigen-3.2.7/Eigen/QtAlignedMalloc new file mode 100644 index 00000000..46f7d83b --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/QtAlignedMalloc @@ -0,0 +1,34 @@ + +#ifndef EIGEN_QTMALLOC_MODULE_H +#define EIGEN_QTMALLOC_MODULE_H + +#include "Core" + +#if (!EIGEN_MALLOC_ALREADY_ALIGNED) + +#include "src/Core/util/DisableStupidWarnings.h" + +void *qMalloc(size_t size) +{ + return Eigen::internal::aligned_malloc(size); +} + +void qFree(void *ptr) +{ + Eigen::internal::aligned_free(ptr); +} + +void *qRealloc(void *ptr, size_t size) +{ + void* newPtr = Eigen::internal::aligned_malloc(size); + memcpy(newPtr, ptr, size); + Eigen::internal::aligned_free(ptr); + return newPtr; +} + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif + +#endif // EIGEN_QTMALLOC_MODULE_H +/* vim: set filetype=cpp et sw=2 ts=2 ai: */ diff --git a/thirdparty/eigen-3.2.7/Eigen/SPQRSupport b/thirdparty/eigen-3.2.7/Eigen/SPQRSupport new file mode 100644 index 00000000..77016442 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/SPQRSupport @@ -0,0 +1,29 @@ +#ifndef EIGEN_SPQRSUPPORT_MODULE_H +#define EIGEN_SPQRSUPPORT_MODULE_H + +#include "SparseCore" + +#include "src/Core/util/DisableStupidWarnings.h" + +#include "SuiteSparseQR.hpp" + +/** \ingroup Support_modules + * \defgroup SPQRSupport_Module SuiteSparseQR module + * + * This module provides an interface to the SPQR library, which is part of the suitesparse package. + * + * \code + * #include + * \endcode + * + * In order to use this module, the SPQR headers must be accessible from the include paths, and your binary must be linked to the SPQR library and its dependencies (Cholmod, AMD, COLAMD,...). + * For a cmake based project, you can use our FindSPQR.cmake and FindCholmod.Cmake modules + * + */ + +#include "src/misc/Solve.h" +#include "src/misc/SparseSolve.h" +#include "src/CholmodSupport/CholmodSupport.h" +#include "src/SPQRSupport/SuiteSparseQRSupport.h" + +#endif diff --git a/thirdparty/eigen-3.2.7/Eigen/SVD b/thirdparty/eigen-3.2.7/Eigen/SVD new file mode 100644 index 00000000..fd310017 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/SVD @@ -0,0 +1,37 @@ +#ifndef EIGEN_SVD_MODULE_H +#define EIGEN_SVD_MODULE_H + +#include "QR" +#include "Householder" +#include "Jacobi" + +#include "src/Core/util/DisableStupidWarnings.h" + +/** \defgroup SVD_Module SVD module + * + * + * + * This module provides SVD decomposition for matrices (both real and complex). + * This decomposition is accessible via the following MatrixBase method: + * - MatrixBase::jacobiSvd() + * + * \code + * #include + * \endcode + */ + +#include "src/misc/Solve.h" +#include "src/SVD/JacobiSVD.h" +#if defined(EIGEN_USE_LAPACKE) && !defined(EIGEN_USE_LAPACKE_STRICT) +#include "src/SVD/JacobiSVD_MKL.h" +#endif +#include "src/SVD/UpperBidiagonalization.h" + +#ifdef EIGEN2_SUPPORT +#include "src/Eigen2Support/SVD.h" +#endif + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_SVD_MODULE_H +/* vim: set filetype=cpp et sw=2 ts=2 ai: */ diff --git a/thirdparty/eigen-3.2.7/Eigen/Sparse b/thirdparty/eigen-3.2.7/Eigen/Sparse new file mode 100644 index 00000000..7cc9c091 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/Sparse @@ -0,0 +1,27 @@ +#ifndef EIGEN_SPARSE_MODULE_H +#define EIGEN_SPARSE_MODULE_H + +/** \defgroup Sparse_Module Sparse meta-module + * + * Meta-module including all related modules: + * - \ref SparseCore_Module + * - \ref OrderingMethods_Module + * - \ref SparseCholesky_Module + * - \ref SparseLU_Module + * - \ref SparseQR_Module + * - \ref IterativeLinearSolvers_Module + * + * \code + * #include + * \endcode + */ + +#include "SparseCore" +#include "OrderingMethods" +#include "SparseCholesky" +#include "SparseLU" +#include "SparseQR" +#include "IterativeLinearSolvers" + +#endif // EIGEN_SPARSE_MODULE_H + diff --git a/thirdparty/eigen-3.2.7/Eigen/SparseCholesky b/thirdparty/eigen-3.2.7/Eigen/SparseCholesky new file mode 100644 index 00000000..9f5056aa --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/SparseCholesky @@ -0,0 +1,47 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008-2013 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_SPARSECHOLESKY_MODULE_H +#define EIGEN_SPARSECHOLESKY_MODULE_H + +#include "SparseCore" +#include "OrderingMethods" + +#include "src/Core/util/DisableStupidWarnings.h" + +/** + * \defgroup SparseCholesky_Module SparseCholesky module + * + * This module currently provides two variants of the direct sparse Cholesky decomposition for selfadjoint (hermitian) matrices. + * Those decompositions are accessible via the following classes: + * - SimplicialLLt, + * - SimplicialLDLt + * + * Such problems can also be solved using the ConjugateGradient solver from the IterativeLinearSolvers module. + * + * \code + * #include + * \endcode + */ + +#ifdef EIGEN_MPL2_ONLY +#error The SparseCholesky module has nothing to offer in MPL2 only mode +#endif + +#include "src/misc/Solve.h" +#include "src/misc/SparseSolve.h" +#include "src/SparseCholesky/SimplicialCholesky.h" + +#ifndef EIGEN_MPL2_ONLY +#include "src/SparseCholesky/SimplicialCholesky_impl.h" +#endif + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_SPARSECHOLESKY_MODULE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/SparseCore b/thirdparty/eigen-3.2.7/Eigen/SparseCore new file mode 100644 index 00000000..24bcf015 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/SparseCore @@ -0,0 +1,64 @@ +#ifndef EIGEN_SPARSECORE_MODULE_H +#define EIGEN_SPARSECORE_MODULE_H + +#include "Core" + +#include "src/Core/util/DisableStupidWarnings.h" + +#include +#include +#include +#include +#include + +/** + * \defgroup SparseCore_Module SparseCore module + * + * This module provides a sparse matrix representation, and basic associated matrix manipulations + * and operations. + * + * See the \ref TutorialSparse "Sparse tutorial" + * + * \code + * #include + * \endcode + * + * This module depends on: Core. + */ + +namespace Eigen { + +/** The type used to identify a general sparse storage. */ +struct Sparse {}; + +} + +#include "src/SparseCore/SparseUtil.h" +#include "src/SparseCore/SparseMatrixBase.h" +#include "src/SparseCore/CompressedStorage.h" +#include "src/SparseCore/AmbiVector.h" +#include "src/SparseCore/SparseMatrix.h" +#include "src/SparseCore/MappedSparseMatrix.h" +#include "src/SparseCore/SparseVector.h" +#include "src/SparseCore/SparseBlock.h" +#include "src/SparseCore/SparseTranspose.h" +#include "src/SparseCore/SparseCwiseUnaryOp.h" +#include "src/SparseCore/SparseCwiseBinaryOp.h" +#include "src/SparseCore/SparseDot.h" +#include "src/SparseCore/SparsePermutation.h" +#include "src/SparseCore/SparseRedux.h" +#include "src/SparseCore/SparseFuzzy.h" +#include "src/SparseCore/ConservativeSparseSparseProduct.h" +#include "src/SparseCore/SparseSparseProductWithPruning.h" +#include "src/SparseCore/SparseProduct.h" +#include "src/SparseCore/SparseDenseProduct.h" +#include "src/SparseCore/SparseDiagonalProduct.h" +#include "src/SparseCore/SparseTriangularView.h" +#include "src/SparseCore/SparseSelfAdjointView.h" +#include "src/SparseCore/TriangularSolver.h" +#include "src/SparseCore/SparseView.h" + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_SPARSECORE_MODULE_H + diff --git a/thirdparty/eigen-3.2.7/Eigen/SparseLU b/thirdparty/eigen-3.2.7/Eigen/SparseLU new file mode 100644 index 00000000..8527a49b --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/SparseLU @@ -0,0 +1,49 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2012 Désiré Nuentsa-Wakam +// Copyright (C) 2012 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_SPARSELU_MODULE_H +#define EIGEN_SPARSELU_MODULE_H + +#include "SparseCore" + +/** + * \defgroup SparseLU_Module SparseLU module + * This module defines a supernodal factorization of general sparse matrices. + * The code is fully optimized for supernode-panel updates with specialized kernels. + * Please, see the documentation of the SparseLU class for more details. + */ + +#include "src/misc/Solve.h" +#include "src/misc/SparseSolve.h" + +// Ordering interface +#include "OrderingMethods" + +#include "src/SparseLU/SparseLU_gemm_kernel.h" + +#include "src/SparseLU/SparseLU_Structs.h" +#include "src/SparseLU/SparseLU_SupernodalMatrix.h" +#include "src/SparseLU/SparseLUImpl.h" +#include "src/SparseCore/SparseColEtree.h" +#include "src/SparseLU/SparseLU_Memory.h" +#include "src/SparseLU/SparseLU_heap_relax_snode.h" +#include "src/SparseLU/SparseLU_relax_snode.h" +#include "src/SparseLU/SparseLU_pivotL.h" +#include "src/SparseLU/SparseLU_panel_dfs.h" +#include "src/SparseLU/SparseLU_kernel_bmod.h" +#include "src/SparseLU/SparseLU_panel_bmod.h" +#include "src/SparseLU/SparseLU_column_dfs.h" +#include "src/SparseLU/SparseLU_column_bmod.h" +#include "src/SparseLU/SparseLU_copy_to_ucol.h" +#include "src/SparseLU/SparseLU_pruneL.h" +#include "src/SparseLU/SparseLU_Utils.h" +#include "src/SparseLU/SparseLU.h" + +#endif // EIGEN_SPARSELU_MODULE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/SparseQR b/thirdparty/eigen-3.2.7/Eigen/SparseQR new file mode 100644 index 00000000..4ee42065 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/SparseQR @@ -0,0 +1,33 @@ +#ifndef EIGEN_SPARSEQR_MODULE_H +#define EIGEN_SPARSEQR_MODULE_H + +#include "SparseCore" +#include "OrderingMethods" +#include "src/Core/util/DisableStupidWarnings.h" + +/** \defgroup SparseQR_Module SparseQR module + * \brief Provides QR decomposition for sparse matrices + * + * This module provides a simplicial version of the left-looking Sparse QR decomposition. + * The columns of the input matrix should be reordered to limit the fill-in during the + * decomposition. Built-in methods (COLAMD, AMD) or external methods (METIS) can be used to this end. + * See the \link OrderingMethods_Module OrderingMethods\endlink module for the list + * of built-in and external ordering methods. + * + * \code + * #include + * \endcode + * + * + */ + +#include "src/misc/Solve.h" +#include "src/misc/SparseSolve.h" + +#include "OrderingMethods" +#include "src/SparseCore/SparseColEtree.h" +#include "src/SparseQR/SparseQR.h" + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif diff --git a/thirdparty/eigen-3.2.7/Eigen/StdDeque b/thirdparty/eigen-3.2.7/Eigen/StdDeque new file mode 100644 index 00000000..f2723477 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/StdDeque @@ -0,0 +1,27 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2009 Gael Guennebaud +// Copyright (C) 2009 Hauke Heibel +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_STDDEQUE_MODULE_H +#define EIGEN_STDDEQUE_MODULE_H + +#include "Core" +#include + +#if (defined(_MSC_VER) && defined(_WIN64)) /* MSVC auto aligns in 64 bit builds */ + +#define EIGEN_DEFINE_STL_DEQUE_SPECIALIZATION(...) + +#else + +#include "src/StlSupport/StdDeque.h" + +#endif + +#endif // EIGEN_STDDEQUE_MODULE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/StdList b/thirdparty/eigen-3.2.7/Eigen/StdList new file mode 100644 index 00000000..225c1e18 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/StdList @@ -0,0 +1,26 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2009 Hauke Heibel +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_STDLIST_MODULE_H +#define EIGEN_STDLIST_MODULE_H + +#include "Core" +#include + +#if (defined(_MSC_VER) && defined(_WIN64)) /* MSVC auto aligns in 64 bit builds */ + +#define EIGEN_DEFINE_STL_LIST_SPECIALIZATION(...) + +#else + +#include "src/StlSupport/StdList.h" + +#endif + +#endif // EIGEN_STDLIST_MODULE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/StdVector b/thirdparty/eigen-3.2.7/Eigen/StdVector new file mode 100644 index 00000000..6b22627f --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/StdVector @@ -0,0 +1,27 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2009 Gael Guennebaud +// Copyright (C) 2009 Hauke Heibel +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_STDVECTOR_MODULE_H +#define EIGEN_STDVECTOR_MODULE_H + +#include "Core" +#include + +#if (defined(_MSC_VER) && defined(_WIN64)) /* MSVC auto aligns in 64 bit builds */ + +#define EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(...) + +#else + +#include "src/StlSupport/StdVector.h" + +#endif + +#endif // EIGEN_STDVECTOR_MODULE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/SuperLUSupport b/thirdparty/eigen-3.2.7/Eigen/SuperLUSupport new file mode 100644 index 00000000..575e14fb --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/SuperLUSupport @@ -0,0 +1,59 @@ +#ifndef EIGEN_SUPERLUSUPPORT_MODULE_H +#define EIGEN_SUPERLUSUPPORT_MODULE_H + +#include "SparseCore" + +#include "src/Core/util/DisableStupidWarnings.h" + +#ifdef EMPTY +#define EIGEN_EMPTY_WAS_ALREADY_DEFINED +#endif + +typedef int int_t; +#include +#include +#include + +// slu_util.h defines a preprocessor token named EMPTY which is really polluting, +// so we remove it in favor of a SUPERLU_EMPTY token. +// If EMPTY was already defined then we don't undef it. + +#if defined(EIGEN_EMPTY_WAS_ALREADY_DEFINED) +# undef EIGEN_EMPTY_WAS_ALREADY_DEFINED +#elif defined(EMPTY) +# undef EMPTY +#endif + +#define SUPERLU_EMPTY (-1) + +namespace Eigen { struct SluMatrix; } + +/** \ingroup Support_modules + * \defgroup SuperLUSupport_Module SuperLUSupport module + * + * This module provides an interface to the SuperLU library. + * It provides the following factorization class: + * - class SuperLU: a supernodal sequential LU factorization. + * - class SuperILU: a supernodal sequential incomplete LU factorization (to be used as a preconditioner for iterative methods). + * + * \warning When including this module, you have to use SUPERLU_EMPTY instead of EMPTY which is no longer defined because it is too polluting. + * + * \code + * #include + * \endcode + * + * In order to use this module, the superlu headers must be accessible from the include paths, and your binary must be linked to the superlu library and its dependencies. + * The dependencies depend on how superlu has been compiled. + * For a cmake based project, you can use our FindSuperLU.cmake module to help you in this task. + * + */ + +#include "src/misc/Solve.h" +#include "src/misc/SparseSolve.h" + +#include "src/SuperLUSupport/SuperLUSupport.h" + + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_SUPERLUSUPPORT_MODULE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/UmfPackSupport b/thirdparty/eigen-3.2.7/Eigen/UmfPackSupport new file mode 100644 index 00000000..984f64a8 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/UmfPackSupport @@ -0,0 +1,36 @@ +#ifndef EIGEN_UMFPACKSUPPORT_MODULE_H +#define EIGEN_UMFPACKSUPPORT_MODULE_H + +#include "SparseCore" + +#include "src/Core/util/DisableStupidWarnings.h" + +extern "C" { +#include +} + +/** \ingroup Support_modules + * \defgroup UmfPackSupport_Module UmfPackSupport module + * + * This module provides an interface to the UmfPack library which is part of the suitesparse package. + * It provides the following factorization class: + * - class UmfPackLU: a multifrontal sequential LU factorization. + * + * \code + * #include + * \endcode + * + * In order to use this module, the umfpack headers must be accessible from the include paths, and your binary must be linked to the umfpack library and its dependencies. + * The dependencies depend on how umfpack has been compiled. + * For a cmake based project, you can use our FindUmfPack.cmake module to help you in this task. + * + */ + +#include "src/misc/Solve.h" +#include "src/misc/SparseSolve.h" + +#include "src/UmfPackSupport/UmfPackSupport.h" + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_UMFPACKSUPPORT_MODULE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Cholesky/LDLT.h b/thirdparty/eigen-3.2.7/Eigen/src/Cholesky/LDLT.h new file mode 100644 index 00000000..abd30bd9 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Cholesky/LDLT.h @@ -0,0 +1,611 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008-2011 Gael Guennebaud +// Copyright (C) 2009 Keir Mierle +// Copyright (C) 2009 Benoit Jacob +// Copyright (C) 2011 Timothy E. Holy +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_LDLT_H +#define EIGEN_LDLT_H + +namespace Eigen { + +namespace internal { + template struct LDLT_Traits; + + // PositiveSemiDef means positive semi-definite and non-zero; same for NegativeSemiDef + enum SignMatrix { PositiveSemiDef, NegativeSemiDef, ZeroSign, Indefinite }; +} + +/** \ingroup Cholesky_Module + * + * \class LDLT + * + * \brief Robust Cholesky decomposition of a matrix with pivoting + * + * \param MatrixType the type of the matrix of which to compute the LDL^T Cholesky decomposition + * \param UpLo the triangular part that will be used for the decompositon: Lower (default) or Upper. + * The other triangular part won't be read. + * + * Perform a robust Cholesky decomposition of a positive semidefinite or negative semidefinite + * matrix \f$ A \f$ such that \f$ A = P^TLDL^*P \f$, where P is a permutation matrix, L + * is lower triangular with a unit diagonal and D is a diagonal matrix. + * + * The decomposition uses pivoting to ensure stability, so that L will have + * zeros in the bottom right rank(A) - n submatrix. Avoiding the square root + * on D also stabilizes the computation. + * + * Remember that Cholesky decompositions are not rank-revealing. Also, do not use a Cholesky + * decomposition to determine whether a system of equations has a solution. + * + * \sa MatrixBase::ldlt(), class LLT + */ +template class LDLT +{ + public: + typedef _MatrixType MatrixType; + enum { + RowsAtCompileTime = MatrixType::RowsAtCompileTime, + ColsAtCompileTime = MatrixType::ColsAtCompileTime, + Options = MatrixType::Options & ~RowMajorBit, // these are the options for the TmpMatrixType, we need a ColMajor matrix here! + MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime, + MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime, + UpLo = _UpLo + }; + typedef typename MatrixType::Scalar Scalar; + typedef typename NumTraits::Real RealScalar; + typedef typename MatrixType::Index Index; + typedef Matrix TmpMatrixType; + + typedef Transpositions TranspositionType; + typedef PermutationMatrix PermutationType; + + typedef internal::LDLT_Traits Traits; + + /** \brief Default Constructor. + * + * The default constructor is useful in cases in which the user intends to + * perform decompositions via LDLT::compute(const MatrixType&). + */ + LDLT() + : m_matrix(), + m_transpositions(), + m_sign(internal::ZeroSign), + m_isInitialized(false) + {} + + /** \brief Default Constructor with memory preallocation + * + * Like the default constructor but with preallocation of the internal data + * according to the specified problem \a size. + * \sa LDLT() + */ + LDLT(Index size) + : m_matrix(size, size), + m_transpositions(size), + m_temporary(size), + m_sign(internal::ZeroSign), + m_isInitialized(false) + {} + + /** \brief Constructor with decomposition + * + * This calculates the decomposition for the input \a matrix. + * \sa LDLT(Index size) + */ + LDLT(const MatrixType& matrix) + : m_matrix(matrix.rows(), matrix.cols()), + m_transpositions(matrix.rows()), + m_temporary(matrix.rows()), + m_sign(internal::ZeroSign), + m_isInitialized(false) + { + compute(matrix); + } + + /** Clear any existing decomposition + * \sa rankUpdate(w,sigma) + */ + void setZero() + { + m_isInitialized = false; + } + + /** \returns a view of the upper triangular matrix U */ + inline typename Traits::MatrixU matrixU() const + { + eigen_assert(m_isInitialized && "LDLT is not initialized."); + return Traits::getU(m_matrix); + } + + /** \returns a view of the lower triangular matrix L */ + inline typename Traits::MatrixL matrixL() const + { + eigen_assert(m_isInitialized && "LDLT is not initialized."); + return Traits::getL(m_matrix); + } + + /** \returns the permutation matrix P as a transposition sequence. + */ + inline const TranspositionType& transpositionsP() const + { + eigen_assert(m_isInitialized && "LDLT is not initialized."); + return m_transpositions; + } + + /** \returns the coefficients of the diagonal matrix D */ + inline Diagonal vectorD() const + { + eigen_assert(m_isInitialized && "LDLT is not initialized."); + return m_matrix.diagonal(); + } + + /** \returns true if the matrix is positive (semidefinite) */ + inline bool isPositive() const + { + eigen_assert(m_isInitialized && "LDLT is not initialized."); + return m_sign == internal::PositiveSemiDef || m_sign == internal::ZeroSign; + } + + #ifdef EIGEN2_SUPPORT + inline bool isPositiveDefinite() const + { + return isPositive(); + } + #endif + + /** \returns true if the matrix is negative (semidefinite) */ + inline bool isNegative(void) const + { + eigen_assert(m_isInitialized && "LDLT is not initialized."); + return m_sign == internal::NegativeSemiDef || m_sign == internal::ZeroSign; + } + + /** \returns a solution x of \f$ A x = b \f$ using the current decomposition of A. + * + * This function also supports in-place solves using the syntax x = decompositionObject.solve(x) . + * + * \note_about_checking_solutions + * + * More precisely, this method solves \f$ A x = b \f$ using the decomposition \f$ A = P^T L D L^* P \f$ + * by solving the systems \f$ P^T y_1 = b \f$, \f$ L y_2 = y_1 \f$, \f$ D y_3 = y_2 \f$, + * \f$ L^* y_4 = y_3 \f$ and \f$ P x = y_4 \f$ in succession. If the matrix \f$ A \f$ is singular, then + * \f$ D \f$ will also be singular (all the other matrices are invertible). In that case, the + * least-square solution of \f$ D y_3 = y_2 \f$ is computed. This does not mean that this function + * computes the least-square solution of \f$ A x = b \f$ is \f$ A \f$ is singular. + * + * \sa MatrixBase::ldlt() + */ + template + inline const internal::solve_retval + solve(const MatrixBase& b) const + { + eigen_assert(m_isInitialized && "LDLT is not initialized."); + eigen_assert(m_matrix.rows()==b.rows() + && "LDLT::solve(): invalid number of rows of the right hand side matrix b"); + return internal::solve_retval(*this, b.derived()); + } + + #ifdef EIGEN2_SUPPORT + template + bool solve(const MatrixBase& b, ResultType *result) const + { + *result = this->solve(b); + return true; + } + #endif + + template + bool solveInPlace(MatrixBase &bAndX) const; + + LDLT& compute(const MatrixType& matrix); + + template + LDLT& rankUpdate(const MatrixBase& w, const RealScalar& alpha=1); + + /** \returns the internal LDLT decomposition matrix + * + * TODO: document the storage layout + */ + inline const MatrixType& matrixLDLT() const + { + eigen_assert(m_isInitialized && "LDLT is not initialized."); + return m_matrix; + } + + MatrixType reconstructedMatrix() const; + + inline Index rows() const { return m_matrix.rows(); } + inline Index cols() const { return m_matrix.cols(); } + + /** \brief Reports whether previous computation was successful. + * + * \returns \c Success if computation was succesful, + * \c NumericalIssue if the matrix.appears to be negative. + */ + ComputationInfo info() const + { + eigen_assert(m_isInitialized && "LDLT is not initialized."); + return Success; + } + + protected: + + static void check_template_parameters() + { + EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar); + } + + /** \internal + * Used to compute and store the Cholesky decomposition A = L D L^* = U^* D U. + * The strict upper part is used during the decomposition, the strict lower + * part correspond to the coefficients of L (its diagonal is equal to 1 and + * is not stored), and the diagonal entries correspond to D. + */ + MatrixType m_matrix; + TranspositionType m_transpositions; + TmpMatrixType m_temporary; + internal::SignMatrix m_sign; + bool m_isInitialized; +}; + +namespace internal { + +template struct ldlt_inplace; + +template<> struct ldlt_inplace +{ + template + static bool unblocked(MatrixType& mat, TranspositionType& transpositions, Workspace& temp, SignMatrix& sign) + { + using std::abs; + typedef typename MatrixType::Scalar Scalar; + typedef typename MatrixType::RealScalar RealScalar; + typedef typename MatrixType::Index Index; + eigen_assert(mat.rows()==mat.cols()); + const Index size = mat.rows(); + + if (size <= 1) + { + transpositions.setIdentity(); + if (numext::real(mat.coeff(0,0)) > 0) sign = PositiveSemiDef; + else if (numext::real(mat.coeff(0,0)) < 0) sign = NegativeSemiDef; + else sign = ZeroSign; + return true; + } + + for (Index k = 0; k < size; ++k) + { + // Find largest diagonal element + Index index_of_biggest_in_corner; + mat.diagonal().tail(size-k).cwiseAbs().maxCoeff(&index_of_biggest_in_corner); + index_of_biggest_in_corner += k; + + transpositions.coeffRef(k) = index_of_biggest_in_corner; + if(k != index_of_biggest_in_corner) + { + // apply the transposition while taking care to consider only + // the lower triangular part + Index s = size-index_of_biggest_in_corner-1; // trailing size after the biggest element + mat.row(k).head(k).swap(mat.row(index_of_biggest_in_corner).head(k)); + mat.col(k).tail(s).swap(mat.col(index_of_biggest_in_corner).tail(s)); + std::swap(mat.coeffRef(k,k),mat.coeffRef(index_of_biggest_in_corner,index_of_biggest_in_corner)); + for(int i=k+1;i::IsComplex) + mat.coeffRef(index_of_biggest_in_corner,k) = numext::conj(mat.coeff(index_of_biggest_in_corner,k)); + } + + // partition the matrix: + // A00 | - | - + // lu = A10 | A11 | - + // A20 | A21 | A22 + Index rs = size - k - 1; + Block A21(mat,k+1,k,rs,1); + Block A10(mat,k,0,1,k); + Block A20(mat,k+1,0,rs,k); + + if(k>0) + { + temp.head(k) = mat.diagonal().real().head(k).asDiagonal() * A10.adjoint(); + mat.coeffRef(k,k) -= (A10 * temp.head(k)).value(); + if(rs>0) + A21.noalias() -= A20 * temp.head(k); + } + + // In some previous versions of Eigen (e.g., 3.2.1), the scaling was omitted if the pivot + // was smaller than the cutoff value. However, soince LDLT is not rank-revealing + // we should only make sure we do not introduce INF or NaN values. + // LAPACK also uses 0 as the cutoff value. + RealScalar realAkk = numext::real(mat.coeffRef(k,k)); + if((rs>0) && (abs(realAkk) > RealScalar(0))) + A21 /= realAkk; + + if (sign == PositiveSemiDef) { + if (realAkk < 0) sign = Indefinite; + } else if (sign == NegativeSemiDef) { + if (realAkk > 0) sign = Indefinite; + } else if (sign == ZeroSign) { + if (realAkk > 0) sign = PositiveSemiDef; + else if (realAkk < 0) sign = NegativeSemiDef; + } + } + + return true; + } + + // Reference for the algorithm: Davis and Hager, "Multiple Rank + // Modifications of a Sparse Cholesky Factorization" (Algorithm 1) + // Trivial rearrangements of their computations (Timothy E. Holy) + // allow their algorithm to work for rank-1 updates even if the + // original matrix is not of full rank. + // Here only rank-1 updates are implemented, to reduce the + // requirement for intermediate storage and improve accuracy + template + static bool updateInPlace(MatrixType& mat, MatrixBase& w, const typename MatrixType::RealScalar& sigma=1) + { + using numext::isfinite; + typedef typename MatrixType::Scalar Scalar; + typedef typename MatrixType::RealScalar RealScalar; + typedef typename MatrixType::Index Index; + + const Index size = mat.rows(); + eigen_assert(mat.cols() == size && w.size()==size); + + RealScalar alpha = 1; + + // Apply the update + for (Index j = 0; j < size; j++) + { + // Check for termination due to an original decomposition of low-rank + if (!(isfinite)(alpha)) + break; + + // Update the diagonal terms + RealScalar dj = numext::real(mat.coeff(j,j)); + Scalar wj = w.coeff(j); + RealScalar swj2 = sigma*numext::abs2(wj); + RealScalar gamma = dj*alpha + swj2; + + mat.coeffRef(j,j) += swj2/alpha; + alpha += swj2/dj; + + + // Update the terms of L + Index rs = size-j-1; + w.tail(rs) -= wj * mat.col(j).tail(rs); + if(gamma != 0) + mat.col(j).tail(rs) += (sigma*numext::conj(wj)/gamma)*w.tail(rs); + } + return true; + } + + template + static bool update(MatrixType& mat, const TranspositionType& transpositions, Workspace& tmp, const WType& w, const typename MatrixType::RealScalar& sigma=1) + { + // Apply the permutation to the input w + tmp = transpositions * w; + + return ldlt_inplace::updateInPlace(mat,tmp,sigma); + } +}; + +template<> struct ldlt_inplace +{ + template + static EIGEN_STRONG_INLINE bool unblocked(MatrixType& mat, TranspositionType& transpositions, Workspace& temp, SignMatrix& sign) + { + Transpose matt(mat); + return ldlt_inplace::unblocked(matt, transpositions, temp, sign); + } + + template + static EIGEN_STRONG_INLINE bool update(MatrixType& mat, TranspositionType& transpositions, Workspace& tmp, WType& w, const typename MatrixType::RealScalar& sigma=1) + { + Transpose matt(mat); + return ldlt_inplace::update(matt, transpositions, tmp, w.conjugate(), sigma); + } +}; + +template struct LDLT_Traits +{ + typedef const TriangularView MatrixL; + typedef const TriangularView MatrixU; + static inline MatrixL getL(const MatrixType& m) { return m; } + static inline MatrixU getU(const MatrixType& m) { return m.adjoint(); } +}; + +template struct LDLT_Traits +{ + typedef const TriangularView MatrixL; + typedef const TriangularView MatrixU; + static inline MatrixL getL(const MatrixType& m) { return m.adjoint(); } + static inline MatrixU getU(const MatrixType& m) { return m; } +}; + +} // end namespace internal + +/** Compute / recompute the LDLT decomposition A = L D L^* = U^* D U of \a matrix + */ +template +LDLT& LDLT::compute(const MatrixType& a) +{ + check_template_parameters(); + + eigen_assert(a.rows()==a.cols()); + const Index size = a.rows(); + + m_matrix = a; + + m_transpositions.resize(size); + m_isInitialized = false; + m_temporary.resize(size); + m_sign = internal::ZeroSign; + + internal::ldlt_inplace::unblocked(m_matrix, m_transpositions, m_temporary, m_sign); + + m_isInitialized = true; + return *this; +} + +/** Update the LDLT decomposition: given A = L D L^T, efficiently compute the decomposition of A + sigma w w^T. + * \param w a vector to be incorporated into the decomposition. + * \param sigma a scalar, +1 for updates and -1 for "downdates," which correspond to removing previously-added column vectors. Optional; default value is +1. + * \sa setZero() + */ +template +template +LDLT& LDLT::rankUpdate(const MatrixBase& w, const typename LDLT::RealScalar& sigma) +{ + const Index size = w.rows(); + if (m_isInitialized) + { + eigen_assert(m_matrix.rows()==size); + } + else + { + m_matrix.resize(size,size); + m_matrix.setZero(); + m_transpositions.resize(size); + for (Index i = 0; i < size; i++) + m_transpositions.coeffRef(i) = i; + m_temporary.resize(size); + m_sign = sigma>=0 ? internal::PositiveSemiDef : internal::NegativeSemiDef; + m_isInitialized = true; + } + + internal::ldlt_inplace::update(m_matrix, m_transpositions, m_temporary, w, sigma); + + return *this; +} + +namespace internal { +template +struct solve_retval, Rhs> + : solve_retval_base, Rhs> +{ + typedef LDLT<_MatrixType,_UpLo> LDLTType; + EIGEN_MAKE_SOLVE_HELPERS(LDLTType,Rhs) + + template void evalTo(Dest& dst) const + { + eigen_assert(rhs().rows() == dec().matrixLDLT().rows()); + // dst = P b + dst = dec().transpositionsP() * rhs(); + + // dst = L^-1 (P b) + dec().matrixL().solveInPlace(dst); + + // dst = D^-1 (L^-1 P b) + // more precisely, use pseudo-inverse of D (see bug 241) + using std::abs; + using std::max; + typedef typename LDLTType::MatrixType MatrixType; + typedef typename LDLTType::RealScalar RealScalar; + const typename Diagonal::RealReturnType vectorD(dec().vectorD()); + // In some previous versions, tolerance was set to the max of 1/highest and the maximal diagonal entry * epsilon + // as motivated by LAPACK's xGELSS: + // RealScalar tolerance = (max)(vectorD.array().abs().maxCoeff() *NumTraits::epsilon(),RealScalar(1) / NumTraits::highest()); + // However, LDLT is not rank revealing, and so adjusting the tolerance wrt to the highest + // diagonal element is not well justified and to numerical issues in some cases. + // Moreover, Lapack's xSYTRS routines use 0 for the tolerance. + RealScalar tolerance = RealScalar(1) / NumTraits::highest(); + + for (Index i = 0; i < vectorD.size(); ++i) { + if(abs(vectorD(i)) > tolerance) + dst.row(i) /= vectorD(i); + else + dst.row(i).setZero(); + } + + // dst = L^-T (D^-1 L^-1 P b) + dec().matrixU().solveInPlace(dst); + + // dst = P^-1 (L^-T D^-1 L^-1 P b) = A^-1 b + dst = dec().transpositionsP().transpose() * dst; + } +}; +} + +/** \internal use x = ldlt_object.solve(x); + * + * This is the \em in-place version of solve(). + * + * \param bAndX represents both the right-hand side matrix b and result x. + * + * \returns true always! If you need to check for existence of solutions, use another decomposition like LU, QR, or SVD. + * + * This version avoids a copy when the right hand side matrix b is not + * needed anymore. + * + * \sa LDLT::solve(), MatrixBase::ldlt() + */ +template +template +bool LDLT::solveInPlace(MatrixBase &bAndX) const +{ + eigen_assert(m_isInitialized && "LDLT is not initialized."); + eigen_assert(m_matrix.rows() == bAndX.rows()); + + bAndX = this->solve(bAndX); + + return true; +} + +/** \returns the matrix represented by the decomposition, + * i.e., it returns the product: P^T L D L^* P. + * This function is provided for debug purpose. */ +template +MatrixType LDLT::reconstructedMatrix() const +{ + eigen_assert(m_isInitialized && "LDLT is not initialized."); + const Index size = m_matrix.rows(); + MatrixType res(size,size); + + // P + res.setIdentity(); + res = transpositionsP() * res; + // L^* P + res = matrixU() * res; + // D(L^*P) + res = vectorD().real().asDiagonal() * res; + // L(DL^*P) + res = matrixL() * res; + // P^T (LDL^*P) + res = transpositionsP().transpose() * res; + + return res; +} + +/** \cholesky_module + * \returns the Cholesky decomposition with full pivoting without square root of \c *this + */ +template +inline const LDLT::PlainObject, UpLo> +SelfAdjointView::ldlt() const +{ + return LDLT(m_matrix); +} + +/** \cholesky_module + * \returns the Cholesky decomposition with full pivoting without square root of \c *this + */ +template +inline const LDLT::PlainObject> +MatrixBase::ldlt() const +{ + return LDLT(derived()); +} + +} // end namespace Eigen + +#endif // EIGEN_LDLT_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Cholesky/LLT.h b/thirdparty/eigen-3.2.7/Eigen/src/Cholesky/LLT.h new file mode 100644 index 00000000..7c11a2dc --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Cholesky/LLT.h @@ -0,0 +1,498 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_LLT_H +#define EIGEN_LLT_H + +namespace Eigen { + +namespace internal{ +template struct LLT_Traits; +} + +/** \ingroup Cholesky_Module + * + * \class LLT + * + * \brief Standard Cholesky decomposition (LL^T) of a matrix and associated features + * + * \param MatrixType the type of the matrix of which we are computing the LL^T Cholesky decomposition + * \param UpLo the triangular part that will be used for the decompositon: Lower (default) or Upper. + * The other triangular part won't be read. + * + * This class performs a LL^T Cholesky decomposition of a symmetric, positive definite + * matrix A such that A = LL^* = U^*U, where L is lower triangular. + * + * While the Cholesky decomposition is particularly useful to solve selfadjoint problems like D^*D x = b, + * for that purpose, we recommend the Cholesky decomposition without square root which is more stable + * and even faster. Nevertheless, this standard Cholesky decomposition remains useful in many other + * situations like generalised eigen problems with hermitian matrices. + * + * Remember that Cholesky decompositions are not rank-revealing. This LLT decomposition is only stable on positive definite matrices, + * use LDLT instead for the semidefinite case. Also, do not use a Cholesky decomposition to determine whether a system of equations + * has a solution. + * + * Example: \include LLT_example.cpp + * Output: \verbinclude LLT_example.out + * + * \sa MatrixBase::llt(), class LDLT + */ + /* HEY THIS DOX IS DISABLED BECAUSE THERE's A BUG EITHER HERE OR IN LDLT ABOUT THAT (OR BOTH) + * Note that during the decomposition, only the upper triangular part of A is considered. Therefore, + * the strict lower part does not have to store correct values. + */ +template class LLT +{ + public: + typedef _MatrixType MatrixType; + enum { + RowsAtCompileTime = MatrixType::RowsAtCompileTime, + ColsAtCompileTime = MatrixType::ColsAtCompileTime, + Options = MatrixType::Options, + MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime + }; + typedef typename MatrixType::Scalar Scalar; + typedef typename NumTraits::Real RealScalar; + typedef typename MatrixType::Index Index; + + enum { + PacketSize = internal::packet_traits::size, + AlignmentMask = int(PacketSize)-1, + UpLo = _UpLo + }; + + typedef internal::LLT_Traits Traits; + + /** + * \brief Default Constructor. + * + * The default constructor is useful in cases in which the user intends to + * perform decompositions via LLT::compute(const MatrixType&). + */ + LLT() : m_matrix(), m_isInitialized(false) {} + + /** \brief Default Constructor with memory preallocation + * + * Like the default constructor but with preallocation of the internal data + * according to the specified problem \a size. + * \sa LLT() + */ + LLT(Index size) : m_matrix(size, size), + m_isInitialized(false) {} + + LLT(const MatrixType& matrix) + : m_matrix(matrix.rows(), matrix.cols()), + m_isInitialized(false) + { + compute(matrix); + } + + /** \returns a view of the upper triangular matrix U */ + inline typename Traits::MatrixU matrixU() const + { + eigen_assert(m_isInitialized && "LLT is not initialized."); + return Traits::getU(m_matrix); + } + + /** \returns a view of the lower triangular matrix L */ + inline typename Traits::MatrixL matrixL() const + { + eigen_assert(m_isInitialized && "LLT is not initialized."); + return Traits::getL(m_matrix); + } + + /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. + * + * Since this LLT class assumes anyway that the matrix A is invertible, the solution + * theoretically exists and is unique regardless of b. + * + * Example: \include LLT_solve.cpp + * Output: \verbinclude LLT_solve.out + * + * \sa solveInPlace(), MatrixBase::llt() + */ + template + inline const internal::solve_retval + solve(const MatrixBase& b) const + { + eigen_assert(m_isInitialized && "LLT is not initialized."); + eigen_assert(m_matrix.rows()==b.rows() + && "LLT::solve(): invalid number of rows of the right hand side matrix b"); + return internal::solve_retval(*this, b.derived()); + } + + #ifdef EIGEN2_SUPPORT + template + bool solve(const MatrixBase& b, ResultType *result) const + { + *result = this->solve(b); + return true; + } + + bool isPositiveDefinite() const { return true; } + #endif + + template + void solveInPlace(MatrixBase &bAndX) const; + + LLT& compute(const MatrixType& matrix); + + /** \returns the LLT decomposition matrix + * + * TODO: document the storage layout + */ + inline const MatrixType& matrixLLT() const + { + eigen_assert(m_isInitialized && "LLT is not initialized."); + return m_matrix; + } + + MatrixType reconstructedMatrix() const; + + + /** \brief Reports whether previous computation was successful. + * + * \returns \c Success if computation was succesful, + * \c NumericalIssue if the matrix.appears to be negative. + */ + ComputationInfo info() const + { + eigen_assert(m_isInitialized && "LLT is not initialized."); + return m_info; + } + + inline Index rows() const { return m_matrix.rows(); } + inline Index cols() const { return m_matrix.cols(); } + + template + LLT rankUpdate(const VectorType& vec, const RealScalar& sigma = 1); + + protected: + + static void check_template_parameters() + { + EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar); + } + + /** \internal + * Used to compute and store L + * The strict upper part is not used and even not initialized. + */ + MatrixType m_matrix; + bool m_isInitialized; + ComputationInfo m_info; +}; + +namespace internal { + +template struct llt_inplace; + +template +static typename MatrixType::Index llt_rank_update_lower(MatrixType& mat, const VectorType& vec, const typename MatrixType::RealScalar& sigma) +{ + using std::sqrt; + typedef typename MatrixType::Scalar Scalar; + typedef typename MatrixType::RealScalar RealScalar; + typedef typename MatrixType::Index Index; + typedef typename MatrixType::ColXpr ColXpr; + typedef typename internal::remove_all::type ColXprCleaned; + typedef typename ColXprCleaned::SegmentReturnType ColXprSegment; + typedef Matrix TempVectorType; + typedef typename TempVectorType::SegmentReturnType TempVecSegment; + + Index n = mat.cols(); + eigen_assert(mat.rows()==n && vec.size()==n); + + TempVectorType temp; + + if(sigma>0) + { + // This version is based on Givens rotations. + // It is faster than the other one below, but only works for updates, + // i.e., for sigma > 0 + temp = sqrt(sigma) * vec; + + for(Index i=0; i g; + g.makeGivens(mat(i,i), -temp(i), &mat(i,i)); + + Index rs = n-i-1; + if(rs>0) + { + ColXprSegment x(mat.col(i).tail(rs)); + TempVecSegment y(temp.tail(rs)); + apply_rotation_in_the_plane(x, y, g); + } + } + } + else + { + temp = vec; + RealScalar beta = 1; + for(Index j=0; j struct llt_inplace +{ + typedef typename NumTraits::Real RealScalar; + template + static typename MatrixType::Index unblocked(MatrixType& mat) + { + using std::sqrt; + typedef typename MatrixType::Index Index; + + eigen_assert(mat.rows()==mat.cols()); + const Index size = mat.rows(); + for(Index k = 0; k < size; ++k) + { + Index rs = size-k-1; // remaining size + + Block A21(mat,k+1,k,rs,1); + Block A10(mat,k,0,1,k); + Block A20(mat,k+1,0,rs,k); + + RealScalar x = numext::real(mat.coeff(k,k)); + if (k>0) x -= A10.squaredNorm(); + if (x<=RealScalar(0)) + return k; + mat.coeffRef(k,k) = x = sqrt(x); + if (k>0 && rs>0) A21.noalias() -= A20 * A10.adjoint(); + if (rs>0) A21 /= x; + } + return -1; + } + + template + static typename MatrixType::Index blocked(MatrixType& m) + { + typedef typename MatrixType::Index Index; + eigen_assert(m.rows()==m.cols()); + Index size = m.rows(); + if(size<32) + return unblocked(m); + + Index blockSize = size/8; + blockSize = (blockSize/16)*16; + blockSize = (std::min)((std::max)(blockSize,Index(8)), Index(128)); + + for (Index k=0; k A11(m,k, k, bs,bs); + Block A21(m,k+bs,k, rs,bs); + Block A22(m,k+bs,k+bs,rs,rs); + + Index ret; + if((ret=unblocked(A11))>=0) return k+ret; + if(rs>0) A11.adjoint().template triangularView().template solveInPlace(A21); + if(rs>0) A22.template selfadjointView().rankUpdate(A21,-1); // bottleneck + } + return -1; + } + + template + static typename MatrixType::Index rankUpdate(MatrixType& mat, const VectorType& vec, const RealScalar& sigma) + { + return Eigen::internal::llt_rank_update_lower(mat, vec, sigma); + } +}; + +template struct llt_inplace +{ + typedef typename NumTraits::Real RealScalar; + + template + static EIGEN_STRONG_INLINE typename MatrixType::Index unblocked(MatrixType& mat) + { + Transpose matt(mat); + return llt_inplace::unblocked(matt); + } + template + static EIGEN_STRONG_INLINE typename MatrixType::Index blocked(MatrixType& mat) + { + Transpose matt(mat); + return llt_inplace::blocked(matt); + } + template + static typename MatrixType::Index rankUpdate(MatrixType& mat, const VectorType& vec, const RealScalar& sigma) + { + Transpose matt(mat); + return llt_inplace::rankUpdate(matt, vec.conjugate(), sigma); + } +}; + +template struct LLT_Traits +{ + typedef const TriangularView MatrixL; + typedef const TriangularView MatrixU; + static inline MatrixL getL(const MatrixType& m) { return m; } + static inline MatrixU getU(const MatrixType& m) { return m.adjoint(); } + static bool inplace_decomposition(MatrixType& m) + { return llt_inplace::blocked(m)==-1; } +}; + +template struct LLT_Traits +{ + typedef const TriangularView MatrixL; + typedef const TriangularView MatrixU; + static inline MatrixL getL(const MatrixType& m) { return m.adjoint(); } + static inline MatrixU getU(const MatrixType& m) { return m; } + static bool inplace_decomposition(MatrixType& m) + { return llt_inplace::blocked(m)==-1; } +}; + +} // end namespace internal + +/** Computes / recomputes the Cholesky decomposition A = LL^* = U^*U of \a matrix + * + * \returns a reference to *this + * + * Example: \include TutorialLinAlgComputeTwice.cpp + * Output: \verbinclude TutorialLinAlgComputeTwice.out + */ +template +LLT& LLT::compute(const MatrixType& a) +{ + check_template_parameters(); + + eigen_assert(a.rows()==a.cols()); + const Index size = a.rows(); + m_matrix.resize(size, size); + m_matrix = a; + + m_isInitialized = true; + bool ok = Traits::inplace_decomposition(m_matrix); + m_info = ok ? Success : NumericalIssue; + + return *this; +} + +/** Performs a rank one update (or dowdate) of the current decomposition. + * If A = LL^* before the rank one update, + * then after it we have LL^* = A + sigma * v v^* where \a v must be a vector + * of same dimension. + */ +template +template +LLT<_MatrixType,_UpLo> LLT<_MatrixType,_UpLo>::rankUpdate(const VectorType& v, const RealScalar& sigma) +{ + EIGEN_STATIC_ASSERT_VECTOR_ONLY(VectorType); + eigen_assert(v.size()==m_matrix.cols()); + eigen_assert(m_isInitialized); + if(internal::llt_inplace::rankUpdate(m_matrix,v,sigma)>=0) + m_info = NumericalIssue; + else + m_info = Success; + + return *this; +} + +namespace internal { +template +struct solve_retval, Rhs> + : solve_retval_base, Rhs> +{ + typedef LLT<_MatrixType,UpLo> LLTType; + EIGEN_MAKE_SOLVE_HELPERS(LLTType,Rhs) + + template void evalTo(Dest& dst) const + { + dst = rhs(); + dec().solveInPlace(dst); + } +}; +} + +/** \internal use x = llt_object.solve(x); + * + * This is the \em in-place version of solve(). + * + * \param bAndX represents both the right-hand side matrix b and result x. + * + * \returns true always! If you need to check for existence of solutions, use another decomposition like LU, QR, or SVD. + * + * This version avoids a copy when the right hand side matrix b is not + * needed anymore. + * + * \sa LLT::solve(), MatrixBase::llt() + */ +template +template +void LLT::solveInPlace(MatrixBase &bAndX) const +{ + eigen_assert(m_isInitialized && "LLT is not initialized."); + eigen_assert(m_matrix.rows()==bAndX.rows()); + matrixL().solveInPlace(bAndX); + matrixU().solveInPlace(bAndX); +} + +/** \returns the matrix represented by the decomposition, + * i.e., it returns the product: L L^*. + * This function is provided for debug purpose. */ +template +MatrixType LLT::reconstructedMatrix() const +{ + eigen_assert(m_isInitialized && "LLT is not initialized."); + return matrixL() * matrixL().adjoint().toDenseMatrix(); +} + +/** \cholesky_module + * \returns the LLT decomposition of \c *this + */ +template +inline const LLT::PlainObject> +MatrixBase::llt() const +{ + return LLT(derived()); +} + +/** \cholesky_module + * \returns the LLT decomposition of \c *this + */ +template +inline const LLT::PlainObject, UpLo> +SelfAdjointView::llt() const +{ + return LLT(m_matrix); +} + +} // end namespace Eigen + +#endif // EIGEN_LLT_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Cholesky/LLT_MKL.h b/thirdparty/eigen-3.2.7/Eigen/src/Cholesky/LLT_MKL.h new file mode 100644 index 00000000..66675d74 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Cholesky/LLT_MKL.h @@ -0,0 +1,102 @@ +/* + Copyright (c) 2011, Intel Corporation. All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of Intel Corporation nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ******************************************************************************** + * Content : Eigen bindings to Intel(R) MKL + * LLt decomposition based on LAPACKE_?potrf function. + ******************************************************************************** +*/ + +#ifndef EIGEN_LLT_MKL_H +#define EIGEN_LLT_MKL_H + +#include "Eigen/src/Core/util/MKL_support.h" +#include + +namespace Eigen { + +namespace internal { + +template struct mkl_llt; + +#define EIGEN_MKL_LLT(EIGTYPE, MKLTYPE, MKLPREFIX) \ +template<> struct mkl_llt \ +{ \ + template \ + static inline typename MatrixType::Index potrf(MatrixType& m, char uplo) \ + { \ + lapack_int matrix_order; \ + lapack_int size, lda, info, StorageOrder; \ + EIGTYPE* a; \ + eigen_assert(m.rows()==m.cols()); \ + /* Set up parameters for ?potrf */ \ + size = m.rows(); \ + StorageOrder = MatrixType::Flags&RowMajorBit?RowMajor:ColMajor; \ + matrix_order = StorageOrder==RowMajor ? LAPACK_ROW_MAJOR : LAPACK_COL_MAJOR; \ + a = &(m.coeffRef(0,0)); \ + lda = m.outerStride(); \ +\ + info = LAPACKE_##MKLPREFIX##potrf( matrix_order, uplo, size, (MKLTYPE*)a, lda ); \ + info = (info==0) ? -1 : info>0 ? info-1 : size; \ + return info; \ + } \ +}; \ +template<> struct llt_inplace \ +{ \ + template \ + static typename MatrixType::Index blocked(MatrixType& m) \ + { \ + return mkl_llt::potrf(m, 'L'); \ + } \ + template \ + static typename MatrixType::Index rankUpdate(MatrixType& mat, const VectorType& vec, const typename MatrixType::RealScalar& sigma) \ + { return Eigen::internal::llt_rank_update_lower(mat, vec, sigma); } \ +}; \ +template<> struct llt_inplace \ +{ \ + template \ + static typename MatrixType::Index blocked(MatrixType& m) \ + { \ + return mkl_llt::potrf(m, 'U'); \ + } \ + template \ + static typename MatrixType::Index rankUpdate(MatrixType& mat, const VectorType& vec, const typename MatrixType::RealScalar& sigma) \ + { \ + Transpose matt(mat); \ + return llt_inplace::rankUpdate(matt, vec.conjugate(), sigma); \ + } \ +}; + +EIGEN_MKL_LLT(double, double, d) +EIGEN_MKL_LLT(float, float, s) +EIGEN_MKL_LLT(dcomplex, MKL_Complex16, z) +EIGEN_MKL_LLT(scomplex, MKL_Complex8, c) + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_LLT_MKL_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/CholmodSupport/CholmodSupport.h b/thirdparty/eigen-3.2.7/Eigen/src/CholmodSupport/CholmodSupport.h new file mode 100644 index 00000000..99dbe171 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/CholmodSupport/CholmodSupport.h @@ -0,0 +1,607 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008-2010 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_CHOLMODSUPPORT_H +#define EIGEN_CHOLMODSUPPORT_H + +namespace Eigen { + +namespace internal { + +template +void cholmod_configure_matrix(CholmodType& mat) +{ + if (internal::is_same::value) + { + mat.xtype = CHOLMOD_REAL; + mat.dtype = CHOLMOD_SINGLE; + } + else if (internal::is_same::value) + { + mat.xtype = CHOLMOD_REAL; + mat.dtype = CHOLMOD_DOUBLE; + } + else if (internal::is_same >::value) + { + mat.xtype = CHOLMOD_COMPLEX; + mat.dtype = CHOLMOD_SINGLE; + } + else if (internal::is_same >::value) + { + mat.xtype = CHOLMOD_COMPLEX; + mat.dtype = CHOLMOD_DOUBLE; + } + else + { + eigen_assert(false && "Scalar type not supported by CHOLMOD"); + } +} + +} // namespace internal + +/** Wraps the Eigen sparse matrix \a mat into a Cholmod sparse matrix object. + * Note that the data are shared. + */ +template +cholmod_sparse viewAsCholmod(SparseMatrix<_Scalar,_Options,_Index>& mat) +{ + cholmod_sparse res; + res.nzmax = mat.nonZeros(); + res.nrow = mat.rows();; + res.ncol = mat.cols(); + res.p = mat.outerIndexPtr(); + res.i = mat.innerIndexPtr(); + res.x = mat.valuePtr(); + res.z = 0; + res.sorted = 1; + if(mat.isCompressed()) + { + res.packed = 1; + res.nz = 0; + } + else + { + res.packed = 0; + res.nz = mat.innerNonZeroPtr(); + } + + res.dtype = 0; + res.stype = -1; + + if (internal::is_same<_Index,int>::value) + { + res.itype = CHOLMOD_INT; + } + else if (internal::is_same<_Index,SuiteSparse_long>::value) + { + res.itype = CHOLMOD_LONG; + } + else + { + eigen_assert(false && "Index type not supported yet"); + } + + // setup res.xtype + internal::cholmod_configure_matrix<_Scalar>(res); + + res.stype = 0; + + return res; +} + +template +const cholmod_sparse viewAsCholmod(const SparseMatrix<_Scalar,_Options,_Index>& mat) +{ + cholmod_sparse res = viewAsCholmod(mat.const_cast_derived()); + return res; +} + +/** Returns a view of the Eigen sparse matrix \a mat as Cholmod sparse matrix. + * The data are not copied but shared. */ +template +cholmod_sparse viewAsCholmod(const SparseSelfAdjointView, UpLo>& mat) +{ + cholmod_sparse res = viewAsCholmod(mat.matrix().const_cast_derived()); + + if(UpLo==Upper) res.stype = 1; + if(UpLo==Lower) res.stype = -1; + + return res; +} + +/** Returns a view of the Eigen \b dense matrix \a mat as Cholmod dense matrix. + * The data are not copied but shared. */ +template +cholmod_dense viewAsCholmod(MatrixBase& mat) +{ + EIGEN_STATIC_ASSERT((internal::traits::Flags&RowMajorBit)==0,THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES); + typedef typename Derived::Scalar Scalar; + + cholmod_dense res; + res.nrow = mat.rows(); + res.ncol = mat.cols(); + res.nzmax = res.nrow * res.ncol; + res.d = Derived::IsVectorAtCompileTime ? mat.derived().size() : mat.derived().outerStride(); + res.x = (void*)(mat.derived().data()); + res.z = 0; + + internal::cholmod_configure_matrix(res); + + return res; +} + +/** Returns a view of the Cholmod sparse matrix \a cm as an Eigen sparse matrix. + * The data are not copied but shared. */ +template +MappedSparseMatrix viewAsEigen(cholmod_sparse& cm) +{ + return MappedSparseMatrix + (cm.nrow, cm.ncol, static_cast(cm.p)[cm.ncol], + static_cast(cm.p), static_cast(cm.i),static_cast(cm.x) ); +} + +enum CholmodMode { + CholmodAuto, CholmodSimplicialLLt, CholmodSupernodalLLt, CholmodLDLt +}; + + +/** \ingroup CholmodSupport_Module + * \class CholmodBase + * \brief The base class for the direct Cholesky factorization of Cholmod + * \sa class CholmodSupernodalLLT, class CholmodSimplicialLDLT, class CholmodSimplicialLLT + */ +template +class CholmodBase : internal::noncopyable +{ + public: + typedef _MatrixType MatrixType; + enum { UpLo = _UpLo }; + typedef typename MatrixType::Scalar Scalar; + typedef typename MatrixType::RealScalar RealScalar; + typedef MatrixType CholMatrixType; + typedef typename MatrixType::Index Index; + + public: + + CholmodBase() + : m_cholmodFactor(0), m_info(Success), m_isInitialized(false) + { + m_shiftOffset[0] = m_shiftOffset[1] = RealScalar(0.0); + cholmod_start(&m_cholmod); + } + + CholmodBase(const MatrixType& matrix) + : m_cholmodFactor(0), m_info(Success), m_isInitialized(false) + { + m_shiftOffset[0] = m_shiftOffset[1] = RealScalar(0.0); + cholmod_start(&m_cholmod); + compute(matrix); + } + + ~CholmodBase() + { + if(m_cholmodFactor) + cholmod_free_factor(&m_cholmodFactor, &m_cholmod); + cholmod_finish(&m_cholmod); + } + + inline Index cols() const { return m_cholmodFactor->n; } + inline Index rows() const { return m_cholmodFactor->n; } + + Derived& derived() { return *static_cast(this); } + const Derived& derived() const { return *static_cast(this); } + + /** \brief Reports whether previous computation was successful. + * + * \returns \c Success if computation was succesful, + * \c NumericalIssue if the matrix.appears to be negative. + */ + ComputationInfo info() const + { + eigen_assert(m_isInitialized && "Decomposition is not initialized."); + return m_info; + } + + /** Computes the sparse Cholesky decomposition of \a matrix */ + Derived& compute(const MatrixType& matrix) + { + analyzePattern(matrix); + factorize(matrix); + return derived(); + } + + /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. + * + * \sa compute() + */ + template + inline const internal::solve_retval + solve(const MatrixBase& b) const + { + eigen_assert(m_isInitialized && "LLT is not initialized."); + eigen_assert(rows()==b.rows() + && "CholmodDecomposition::solve(): invalid number of rows of the right hand side matrix b"); + return internal::solve_retval(*this, b.derived()); + } + + /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. + * + * \sa compute() + */ + template + inline const internal::sparse_solve_retval + solve(const SparseMatrixBase& b) const + { + eigen_assert(m_isInitialized && "LLT is not initialized."); + eigen_assert(rows()==b.rows() + && "CholmodDecomposition::solve(): invalid number of rows of the right hand side matrix b"); + return internal::sparse_solve_retval(*this, b.derived()); + } + + /** Performs a symbolic decomposition on the sparsity pattern of \a matrix. + * + * This function is particularly useful when solving for several problems having the same structure. + * + * \sa factorize() + */ + void analyzePattern(const MatrixType& matrix) + { + if(m_cholmodFactor) + { + cholmod_free_factor(&m_cholmodFactor, &m_cholmod); + m_cholmodFactor = 0; + } + cholmod_sparse A = viewAsCholmod(matrix.template selfadjointView()); + m_cholmodFactor = cholmod_analyze(&A, &m_cholmod); + + this->m_isInitialized = true; + this->m_info = Success; + m_analysisIsOk = true; + m_factorizationIsOk = false; + } + + /** Performs a numeric decomposition of \a matrix + * + * The given matrix must have the same sparsity pattern as the matrix on which the symbolic decomposition has been performed. + * + * \sa analyzePattern() + */ + void factorize(const MatrixType& matrix) + { + eigen_assert(m_analysisIsOk && "You must first call analyzePattern()"); + cholmod_sparse A = viewAsCholmod(matrix.template selfadjointView()); + cholmod_factorize_p(&A, m_shiftOffset, 0, 0, m_cholmodFactor, &m_cholmod); + + // If the factorization failed, minor is the column at which it did. On success minor == n. + this->m_info = (m_cholmodFactor->minor == m_cholmodFactor->n ? Success : NumericalIssue); + m_factorizationIsOk = true; + } + + /** Returns a reference to the Cholmod's configuration structure to get a full control over the performed operations. + * See the Cholmod user guide for details. */ + cholmod_common& cholmod() { return m_cholmod; } + + #ifndef EIGEN_PARSED_BY_DOXYGEN + /** \internal */ + template + void _solve(const MatrixBase &b, MatrixBase &dest) const + { + eigen_assert(m_factorizationIsOk && "The decomposition is not in a valid state for solving, you must first call either compute() or symbolic()/numeric()"); + const Index size = m_cholmodFactor->n; + EIGEN_UNUSED_VARIABLE(size); + eigen_assert(size==b.rows()); + + // note: cd stands for Cholmod Dense + Rhs& b_ref(b.const_cast_derived()); + cholmod_dense b_cd = viewAsCholmod(b_ref); + cholmod_dense* x_cd = cholmod_solve(CHOLMOD_A, m_cholmodFactor, &b_cd, &m_cholmod); + if(!x_cd) + { + this->m_info = NumericalIssue; + } + // TODO optimize this copy by swapping when possible (be careful with alignment, etc.) + dest = Matrix::Map(reinterpret_cast(x_cd->x),b.rows(),b.cols()); + cholmod_free_dense(&x_cd, &m_cholmod); + } + + /** \internal */ + template + void _solve(const SparseMatrix &b, SparseMatrix &dest) const + { + eigen_assert(m_factorizationIsOk && "The decomposition is not in a valid state for solving, you must first call either compute() or symbolic()/numeric()"); + const Index size = m_cholmodFactor->n; + EIGEN_UNUSED_VARIABLE(size); + eigen_assert(size==b.rows()); + + // note: cs stands for Cholmod Sparse + cholmod_sparse b_cs = viewAsCholmod(b); + cholmod_sparse* x_cs = cholmod_spsolve(CHOLMOD_A, m_cholmodFactor, &b_cs, &m_cholmod); + if(!x_cs) + { + this->m_info = NumericalIssue; + } + // TODO optimize this copy by swapping when possible (be careful with alignment, etc.) + dest = viewAsEigen(*x_cs); + cholmod_free_sparse(&x_cs, &m_cholmod); + } + #endif // EIGEN_PARSED_BY_DOXYGEN + + + /** Sets the shift parameter that will be used to adjust the diagonal coefficients during the numerical factorization. + * + * During the numerical factorization, an offset term is added to the diagonal coefficients:\n + * \c d_ii = \a offset + \c d_ii + * + * The default is \a offset=0. + * + * \returns a reference to \c *this. + */ + Derived& setShift(const RealScalar& offset) + { + m_shiftOffset[0] = offset; + return derived(); + } + + template + void dumpMemory(Stream& /*s*/) + {} + + protected: + mutable cholmod_common m_cholmod; + cholmod_factor* m_cholmodFactor; + RealScalar m_shiftOffset[2]; + mutable ComputationInfo m_info; + bool m_isInitialized; + int m_factorizationIsOk; + int m_analysisIsOk; +}; + +/** \ingroup CholmodSupport_Module + * \class CholmodSimplicialLLT + * \brief A simplicial direct Cholesky (LLT) factorization and solver based on Cholmod + * + * This class allows to solve for A.X = B sparse linear problems via a simplicial LL^T Cholesky factorization + * using the Cholmod library. + * This simplicial variant is equivalent to Eigen's built-in SimplicialLLT class. Therefore, it has little practical interest. + * The sparse matrix A must be selfadjoint and positive definite. The vectors or matrices + * X and B can be either dense or sparse. + * + * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> + * \tparam _UpLo the triangular part that will be used for the computations. It can be Lower + * or Upper. Default is Lower. + * + * This class supports all kind of SparseMatrix<>: row or column major; upper, lower, or both; compressed or non compressed. + * + * \sa \ref TutorialSparseDirectSolvers, class CholmodSupernodalLLT, class SimplicialLLT + */ +template +class CholmodSimplicialLLT : public CholmodBase<_MatrixType, _UpLo, CholmodSimplicialLLT<_MatrixType, _UpLo> > +{ + typedef CholmodBase<_MatrixType, _UpLo, CholmodSimplicialLLT> Base; + using Base::m_cholmod; + + public: + + typedef _MatrixType MatrixType; + + CholmodSimplicialLLT() : Base() { init(); } + + CholmodSimplicialLLT(const MatrixType& matrix) : Base() + { + init(); + Base::compute(matrix); + } + + ~CholmodSimplicialLLT() {} + protected: + void init() + { + m_cholmod.final_asis = 0; + m_cholmod.supernodal = CHOLMOD_SIMPLICIAL; + m_cholmod.final_ll = 1; + } +}; + + +/** \ingroup CholmodSupport_Module + * \class CholmodSimplicialLDLT + * \brief A simplicial direct Cholesky (LDLT) factorization and solver based on Cholmod + * + * This class allows to solve for A.X = B sparse linear problems via a simplicial LDL^T Cholesky factorization + * using the Cholmod library. + * This simplicial variant is equivalent to Eigen's built-in SimplicialLDLT class. Therefore, it has little practical interest. + * The sparse matrix A must be selfadjoint and positive definite. The vectors or matrices + * X and B can be either dense or sparse. + * + * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> + * \tparam _UpLo the triangular part that will be used for the computations. It can be Lower + * or Upper. Default is Lower. + * + * This class supports all kind of SparseMatrix<>: row or column major; upper, lower, or both; compressed or non compressed. + * + * \sa \ref TutorialSparseDirectSolvers, class CholmodSupernodalLLT, class SimplicialLDLT + */ +template +class CholmodSimplicialLDLT : public CholmodBase<_MatrixType, _UpLo, CholmodSimplicialLDLT<_MatrixType, _UpLo> > +{ + typedef CholmodBase<_MatrixType, _UpLo, CholmodSimplicialLDLT> Base; + using Base::m_cholmod; + + public: + + typedef _MatrixType MatrixType; + + CholmodSimplicialLDLT() : Base() { init(); } + + CholmodSimplicialLDLT(const MatrixType& matrix) : Base() + { + init(); + Base::compute(matrix); + } + + ~CholmodSimplicialLDLT() {} + protected: + void init() + { + m_cholmod.final_asis = 1; + m_cholmod.supernodal = CHOLMOD_SIMPLICIAL; + } +}; + +/** \ingroup CholmodSupport_Module + * \class CholmodSupernodalLLT + * \brief A supernodal Cholesky (LLT) factorization and solver based on Cholmod + * + * This class allows to solve for A.X = B sparse linear problems via a supernodal LL^T Cholesky factorization + * using the Cholmod library. + * This supernodal variant performs best on dense enough problems, e.g., 3D FEM, or very high order 2D FEM. + * The sparse matrix A must be selfadjoint and positive definite. The vectors or matrices + * X and B can be either dense or sparse. + * + * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> + * \tparam _UpLo the triangular part that will be used for the computations. It can be Lower + * or Upper. Default is Lower. + * + * This class supports all kind of SparseMatrix<>: row or column major; upper, lower, or both; compressed or non compressed. + * + * \sa \ref TutorialSparseDirectSolvers + */ +template +class CholmodSupernodalLLT : public CholmodBase<_MatrixType, _UpLo, CholmodSupernodalLLT<_MatrixType, _UpLo> > +{ + typedef CholmodBase<_MatrixType, _UpLo, CholmodSupernodalLLT> Base; + using Base::m_cholmod; + + public: + + typedef _MatrixType MatrixType; + + CholmodSupernodalLLT() : Base() { init(); } + + CholmodSupernodalLLT(const MatrixType& matrix) : Base() + { + init(); + Base::compute(matrix); + } + + ~CholmodSupernodalLLT() {} + protected: + void init() + { + m_cholmod.final_asis = 1; + m_cholmod.supernodal = CHOLMOD_SUPERNODAL; + } +}; + +/** \ingroup CholmodSupport_Module + * \class CholmodDecomposition + * \brief A general Cholesky factorization and solver based on Cholmod + * + * This class allows to solve for A.X = B sparse linear problems via a LL^T or LDL^T Cholesky factorization + * using the Cholmod library. The sparse matrix A must be selfadjoint and positive definite. The vectors or matrices + * X and B can be either dense or sparse. + * + * This variant permits to change the underlying Cholesky method at runtime. + * On the other hand, it does not provide access to the result of the factorization. + * The default is to let Cholmod automatically choose between a simplicial and supernodal factorization. + * + * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> + * \tparam _UpLo the triangular part that will be used for the computations. It can be Lower + * or Upper. Default is Lower. + * + * This class supports all kind of SparseMatrix<>: row or column major; upper, lower, or both; compressed or non compressed. + * + * \sa \ref TutorialSparseDirectSolvers + */ +template +class CholmodDecomposition : public CholmodBase<_MatrixType, _UpLo, CholmodDecomposition<_MatrixType, _UpLo> > +{ + typedef CholmodBase<_MatrixType, _UpLo, CholmodDecomposition> Base; + using Base::m_cholmod; + + public: + + typedef _MatrixType MatrixType; + + CholmodDecomposition() : Base() { init(); } + + CholmodDecomposition(const MatrixType& matrix) : Base() + { + init(); + Base::compute(matrix); + } + + ~CholmodDecomposition() {} + + void setMode(CholmodMode mode) + { + switch(mode) + { + case CholmodAuto: + m_cholmod.final_asis = 1; + m_cholmod.supernodal = CHOLMOD_AUTO; + break; + case CholmodSimplicialLLt: + m_cholmod.final_asis = 0; + m_cholmod.supernodal = CHOLMOD_SIMPLICIAL; + m_cholmod.final_ll = 1; + break; + case CholmodSupernodalLLt: + m_cholmod.final_asis = 1; + m_cholmod.supernodal = CHOLMOD_SUPERNODAL; + break; + case CholmodLDLt: + m_cholmod.final_asis = 1; + m_cholmod.supernodal = CHOLMOD_SIMPLICIAL; + break; + default: + break; + } + } + protected: + void init() + { + m_cholmod.final_asis = 1; + m_cholmod.supernodal = CHOLMOD_AUTO; + } +}; + +namespace internal { + +template +struct solve_retval, Rhs> + : solve_retval_base, Rhs> +{ + typedef CholmodBase<_MatrixType,_UpLo,Derived> Dec; + EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs) + + template void evalTo(Dest& dst) const + { + dec()._solve(rhs(),dst); + } +}; + +template +struct sparse_solve_retval, Rhs> + : sparse_solve_retval_base, Rhs> +{ + typedef CholmodBase<_MatrixType,_UpLo,Derived> Dec; + EIGEN_MAKE_SPARSE_SOLVE_HELPERS(Dec,Rhs) + + template void evalTo(Dest& dst) const + { + dec()._solve(rhs(),dst); + } +}; + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_CHOLMODSUPPORT_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/Array.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/Array.h new file mode 100644 index 00000000..0b9c38c8 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/Array.h @@ -0,0 +1,323 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2009 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_ARRAY_H +#define EIGEN_ARRAY_H + +namespace Eigen { + +/** \class Array + * \ingroup Core_Module + * + * \brief General-purpose arrays with easy API for coefficient-wise operations + * + * The %Array class is very similar to the Matrix class. It provides + * general-purpose one- and two-dimensional arrays. The difference between the + * %Array and the %Matrix class is primarily in the API: the API for the + * %Array class provides easy access to coefficient-wise operations, while the + * API for the %Matrix class provides easy access to linear-algebra + * operations. + * + * This class can be extended with the help of the plugin mechanism described on the page + * \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_ARRAY_PLUGIN. + * + * \sa \ref TutorialArrayClass, \ref TopicClassHierarchy + */ +namespace internal { +template +struct traits > : traits > +{ + typedef ArrayXpr XprKind; + typedef ArrayBase > XprBase; +}; +} + +template +class Array + : public PlainObjectBase > +{ + public: + + typedef PlainObjectBase Base; + EIGEN_DENSE_PUBLIC_INTERFACE(Array) + + enum { Options = _Options }; + typedef typename Base::PlainObject PlainObject; + + protected: + template + friend struct internal::conservative_resize_like_impl; + + using Base::m_storage; + + public: + + using Base::base; + using Base::coeff; + using Base::coeffRef; + + /** + * The usage of + * using Base::operator=; + * fails on MSVC. Since the code below is working with GCC and MSVC, we skipped + * the usage of 'using'. This should be done only for operator=. + */ + template + EIGEN_STRONG_INLINE Array& operator=(const EigenBase &other) + { + return Base::operator=(other); + } + + /** Copies the value of the expression \a other into \c *this with automatic resizing. + * + * *this might be resized to match the dimensions of \a other. If *this was a null matrix (not already initialized), + * it will be initialized. + * + * Note that copying a row-vector into a vector (and conversely) is allowed. + * The resizing, if any, is then done in the appropriate way so that row-vectors + * remain row-vectors and vectors remain vectors. + */ + template + EIGEN_STRONG_INLINE Array& operator=(const ArrayBase& other) + { + return Base::_set(other); + } + + /** This is a special case of the templated operator=. Its purpose is to + * prevent a default operator= from hiding the templated operator=. + */ + EIGEN_STRONG_INLINE Array& operator=(const Array& other) + { + return Base::_set(other); + } + + /** Default constructor. + * + * For fixed-size matrices, does nothing. + * + * For dynamic-size matrices, creates an empty matrix of size 0. Does not allocate any array. Such a matrix + * is called a null matrix. This constructor is the unique way to create null matrices: resizing + * a matrix to 0 is not supported. + * + * \sa resize(Index,Index) + */ + EIGEN_STRONG_INLINE Array() : Base() + { + Base::_check_template_params(); + EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED + } + +#ifndef EIGEN_PARSED_BY_DOXYGEN + // FIXME is it still needed ?? + /** \internal */ + Array(internal::constructor_without_unaligned_array_assert) + : Base(internal::constructor_without_unaligned_array_assert()) + { + Base::_check_template_params(); + EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED + } +#endif + +#ifdef EIGEN_HAVE_RVALUE_REFERENCES + Array(Array&& other) + : Base(std::move(other)) + { + Base::_check_template_params(); + if (RowsAtCompileTime!=Dynamic && ColsAtCompileTime!=Dynamic) + Base::_set_noalias(other); + } + Array& operator=(Array&& other) + { + other.swap(*this); + return *this; + } +#endif + + /** Constructs a vector or row-vector with given dimension. \only_for_vectors + * + * Note that this is only useful for dynamic-size vectors. For fixed-size vectors, + * it is redundant to pass the dimension here, so it makes more sense to use the default + * constructor Matrix() instead. + */ + EIGEN_STRONG_INLINE explicit Array(Index dim) + : Base(dim, RowsAtCompileTime == 1 ? 1 : dim, ColsAtCompileTime == 1 ? 1 : dim) + { + Base::_check_template_params(); + EIGEN_STATIC_ASSERT_VECTOR_ONLY(Array) + eigen_assert(dim >= 0); + eigen_assert(SizeAtCompileTime == Dynamic || SizeAtCompileTime == dim); + EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED + } + + #ifndef EIGEN_PARSED_BY_DOXYGEN + template + EIGEN_STRONG_INLINE Array(const T0& val0, const T1& val1) + { + Base::_check_template_params(); + this->template _init2(val0, val1); + } + #else + /** constructs an uninitialized matrix with \a rows rows and \a cols columns. + * + * This is useful for dynamic-size matrices. For fixed-size matrices, + * it is redundant to pass these parameters, so one should use the default constructor + * Matrix() instead. */ + Array(Index rows, Index cols); + /** constructs an initialized 2D vector with given coefficients */ + Array(const Scalar& val0, const Scalar& val1); + #endif + + /** constructs an initialized 3D vector with given coefficients */ + EIGEN_STRONG_INLINE Array(const Scalar& val0, const Scalar& val1, const Scalar& val2) + { + Base::_check_template_params(); + EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Array, 3) + m_storage.data()[0] = val0; + m_storage.data()[1] = val1; + m_storage.data()[2] = val2; + } + /** constructs an initialized 4D vector with given coefficients */ + EIGEN_STRONG_INLINE Array(const Scalar& val0, const Scalar& val1, const Scalar& val2, const Scalar& val3) + { + Base::_check_template_params(); + EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Array, 4) + m_storage.data()[0] = val0; + m_storage.data()[1] = val1; + m_storage.data()[2] = val2; + m_storage.data()[3] = val3; + } + + explicit Array(const Scalar *data); + + /** Constructor copying the value of the expression \a other */ + template + EIGEN_STRONG_INLINE Array(const ArrayBase& other) + : Base(other.rows() * other.cols(), other.rows(), other.cols()) + { + Base::_check_template_params(); + Base::_set_noalias(other); + } + /** Copy constructor */ + EIGEN_STRONG_INLINE Array(const Array& other) + : Base(other.rows() * other.cols(), other.rows(), other.cols()) + { + Base::_check_template_params(); + Base::_set_noalias(other); + } + /** Copy constructor with in-place evaluation */ + template + EIGEN_STRONG_INLINE Array(const ReturnByValue& other) + { + Base::_check_template_params(); + Base::resize(other.rows(), other.cols()); + other.evalTo(*this); + } + + /** \sa MatrixBase::operator=(const EigenBase&) */ + template + EIGEN_STRONG_INLINE Array(const EigenBase &other) + : Base(other.derived().rows() * other.derived().cols(), other.derived().rows(), other.derived().cols()) + { + Base::_check_template_params(); + Base::_resize_to_match(other); + *this = other; + } + + /** Override MatrixBase::swap() since for dynamic-sized matrices of same type it is enough to swap the + * data pointers. + */ + template + void swap(ArrayBase const & other) + { this->_swap(other.derived()); } + + inline Index innerStride() const { return 1; } + inline Index outerStride() const { return this->innerSize(); } + + #ifdef EIGEN_ARRAY_PLUGIN + #include EIGEN_ARRAY_PLUGIN + #endif + + private: + + template + friend struct internal::matrix_swap_impl; +}; + +/** \defgroup arraytypedefs Global array typedefs + * \ingroup Core_Module + * + * Eigen defines several typedef shortcuts for most common 1D and 2D array types. + * + * The general patterns are the following: + * + * \c ArrayRowsColsType where \c Rows and \c Cols can be \c 2,\c 3,\c 4 for fixed size square matrices or \c X for dynamic size, + * and where \c Type can be \c i for integer, \c f for float, \c d for double, \c cf for complex float, \c cd + * for complex double. + * + * For example, \c Array33d is a fixed-size 3x3 array type of doubles, and \c ArrayXXf is a dynamic-size matrix of floats. + * + * There are also \c ArraySizeType which are self-explanatory. For example, \c Array4cf is + * a fixed-size 1D array of 4 complex floats. + * + * \sa class Array + */ + +#define EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, Size, SizeSuffix) \ +/** \ingroup arraytypedefs */ \ +typedef Array Array##SizeSuffix##SizeSuffix##TypeSuffix; \ +/** \ingroup arraytypedefs */ \ +typedef Array Array##SizeSuffix##TypeSuffix; + +#define EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Type, TypeSuffix, Size) \ +/** \ingroup arraytypedefs */ \ +typedef Array Array##Size##X##TypeSuffix; \ +/** \ingroup arraytypedefs */ \ +typedef Array Array##X##Size##TypeSuffix; + +#define EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(Type, TypeSuffix) \ +EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, 2, 2) \ +EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, 3, 3) \ +EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, 4, 4) \ +EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, Dynamic, X) \ +EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Type, TypeSuffix, 2) \ +EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Type, TypeSuffix, 3) \ +EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Type, TypeSuffix, 4) + +EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(int, i) +EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(float, f) +EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(double, d) +EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(std::complex, cf) +EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(std::complex, cd) + +#undef EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES +#undef EIGEN_MAKE_ARRAY_TYPEDEFS + +#undef EIGEN_MAKE_ARRAY_TYPEDEFS_LARGE + +#define EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, SizeSuffix) \ +using Eigen::Matrix##SizeSuffix##TypeSuffix; \ +using Eigen::Vector##SizeSuffix##TypeSuffix; \ +using Eigen::RowVector##SizeSuffix##TypeSuffix; + +#define EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(TypeSuffix) \ +EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 2) \ +EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 3) \ +EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 4) \ +EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, X) \ + +#define EIGEN_USING_ARRAY_TYPEDEFS \ +EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(i) \ +EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(f) \ +EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(d) \ +EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(cf) \ +EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(cd) + +} // end namespace Eigen + +#endif // EIGEN_ARRAY_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/ArrayBase.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/ArrayBase.h new file mode 100644 index 00000000..33ff5537 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/ArrayBase.h @@ -0,0 +1,226 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2009 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_ARRAYBASE_H +#define EIGEN_ARRAYBASE_H + +namespace Eigen { + +template class MatrixWrapper; + +/** \class ArrayBase + * \ingroup Core_Module + * + * \brief Base class for all 1D and 2D array, and related expressions + * + * An array is similar to a dense vector or matrix. While matrices are mathematical + * objects with well defined linear algebra operators, an array is just a collection + * of scalar values arranged in a one or two dimensionnal fashion. As the main consequence, + * all operations applied to an array are performed coefficient wise. Furthermore, + * arrays support scalar math functions of the c++ standard library (e.g., std::sin(x)), and convenient + * constructors allowing to easily write generic code working for both scalar values + * and arrays. + * + * This class is the base that is inherited by all array expression types. + * + * \tparam Derived is the derived type, e.g., an array or an expression type. + * + * This class can be extended with the help of the plugin mechanism described on the page + * \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_ARRAYBASE_PLUGIN. + * + * \sa class MatrixBase, \ref TopicClassHierarchy + */ +template class ArrayBase + : public DenseBase +{ + public: +#ifndef EIGEN_PARSED_BY_DOXYGEN + /** The base class for a given storage type. */ + typedef ArrayBase StorageBaseType; + + typedef ArrayBase Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl; + + typedef typename internal::traits::StorageKind StorageKind; + typedef typename internal::traits::Index Index; + typedef typename internal::traits::Scalar Scalar; + typedef typename internal::packet_traits::type PacketScalar; + typedef typename NumTraits::Real RealScalar; + + typedef DenseBase Base; + using Base::operator*; + using Base::RowsAtCompileTime; + using Base::ColsAtCompileTime; + using Base::SizeAtCompileTime; + using Base::MaxRowsAtCompileTime; + using Base::MaxColsAtCompileTime; + using Base::MaxSizeAtCompileTime; + using Base::IsVectorAtCompileTime; + using Base::Flags; + using Base::CoeffReadCost; + + using Base::derived; + using Base::const_cast_derived; + using Base::rows; + using Base::cols; + using Base::size; + using Base::coeff; + using Base::coeffRef; + using Base::lazyAssign; + using Base::operator=; + using Base::operator+=; + using Base::operator-=; + using Base::operator*=; + using Base::operator/=; + + typedef typename Base::CoeffReturnType CoeffReturnType; + +#endif // not EIGEN_PARSED_BY_DOXYGEN + +#ifndef EIGEN_PARSED_BY_DOXYGEN + /** \internal the plain matrix type corresponding to this expression. Note that is not necessarily + * exactly the return type of eval(): in the case of plain matrices, the return type of eval() is a const + * reference to a matrix, not a matrix! It is however guaranteed that the return type of eval() is either + * PlainObject or const PlainObject&. + */ + typedef Array::Scalar, + internal::traits::RowsAtCompileTime, + internal::traits::ColsAtCompileTime, + AutoAlign | (internal::traits::Flags&RowMajorBit ? RowMajor : ColMajor), + internal::traits::MaxRowsAtCompileTime, + internal::traits::MaxColsAtCompileTime + > PlainObject; + + + /** \internal Represents a matrix with all coefficients equal to one another*/ + typedef CwiseNullaryOp,Derived> ConstantReturnType; +#endif // not EIGEN_PARSED_BY_DOXYGEN + +#define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::ArrayBase +# include "../plugins/CommonCwiseUnaryOps.h" +# include "../plugins/MatrixCwiseUnaryOps.h" +# include "../plugins/ArrayCwiseUnaryOps.h" +# include "../plugins/CommonCwiseBinaryOps.h" +# include "../plugins/MatrixCwiseBinaryOps.h" +# include "../plugins/ArrayCwiseBinaryOps.h" +# ifdef EIGEN_ARRAYBASE_PLUGIN +# include EIGEN_ARRAYBASE_PLUGIN +# endif +#undef EIGEN_CURRENT_STORAGE_BASE_CLASS + + /** Special case of the template operator=, in order to prevent the compiler + * from generating a default operator= (issue hit with g++ 4.1) + */ + Derived& operator=(const ArrayBase& other) + { + return internal::assign_selector::run(derived(), other.derived()); + } + + Derived& operator+=(const Scalar& scalar) + { return *this = derived() + scalar; } + Derived& operator-=(const Scalar& scalar) + { return *this = derived() - scalar; } + + template + Derived& operator+=(const ArrayBase& other); + template + Derived& operator-=(const ArrayBase& other); + + template + Derived& operator*=(const ArrayBase& other); + + template + Derived& operator/=(const ArrayBase& other); + + public: + ArrayBase& array() { return *this; } + const ArrayBase& array() const { return *this; } + + /** \returns an \link Eigen::MatrixBase Matrix \endlink expression of this array + * \sa MatrixBase::array() */ + MatrixWrapper matrix() { return derived(); } + const MatrixWrapper matrix() const { return derived(); } + +// template +// inline void evalTo(Dest& dst) const { dst = matrix(); } + + protected: + ArrayBase() : Base() {} + + private: + explicit ArrayBase(Index); + ArrayBase(Index,Index); + template explicit ArrayBase(const ArrayBase&); + protected: + // mixing arrays and matrices is not legal + template Derived& operator+=(const MatrixBase& ) + {EIGEN_STATIC_ASSERT(std::ptrdiff_t(sizeof(typename OtherDerived::Scalar))==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES); return *this;} + // mixing arrays and matrices is not legal + template Derived& operator-=(const MatrixBase& ) + {EIGEN_STATIC_ASSERT(std::ptrdiff_t(sizeof(typename OtherDerived::Scalar))==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES); return *this;} +}; + +/** replaces \c *this by \c *this - \a other. + * + * \returns a reference to \c *this + */ +template +template +EIGEN_STRONG_INLINE Derived & +ArrayBase::operator-=(const ArrayBase &other) +{ + SelfCwiseBinaryOp, Derived, OtherDerived> tmp(derived()); + tmp = other.derived(); + return derived(); +} + +/** replaces \c *this by \c *this + \a other. + * + * \returns a reference to \c *this + */ +template +template +EIGEN_STRONG_INLINE Derived & +ArrayBase::operator+=(const ArrayBase& other) +{ + SelfCwiseBinaryOp, Derived, OtherDerived> tmp(derived()); + tmp = other.derived(); + return derived(); +} + +/** replaces \c *this by \c *this * \a other coefficient wise. + * + * \returns a reference to \c *this + */ +template +template +EIGEN_STRONG_INLINE Derived & +ArrayBase::operator*=(const ArrayBase& other) +{ + SelfCwiseBinaryOp, Derived, OtherDerived> tmp(derived()); + tmp = other.derived(); + return derived(); +} + +/** replaces \c *this by \c *this / \a other coefficient wise. + * + * \returns a reference to \c *this + */ +template +template +EIGEN_STRONG_INLINE Derived & +ArrayBase::operator/=(const ArrayBase& other) +{ + SelfCwiseBinaryOp, Derived, OtherDerived> tmp(derived()); + tmp = other.derived(); + return derived(); +} + +} // end namespace Eigen + +#endif // EIGEN_ARRAYBASE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/ArrayWrapper.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/ArrayWrapper.h new file mode 100644 index 00000000..b4641e2a --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/ArrayWrapper.h @@ -0,0 +1,264 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2009-2010 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_ARRAYWRAPPER_H +#define EIGEN_ARRAYWRAPPER_H + +namespace Eigen { + +/** \class ArrayWrapper + * \ingroup Core_Module + * + * \brief Expression of a mathematical vector or matrix as an array object + * + * This class is the return type of MatrixBase::array(), and most of the time + * this is the only way it is use. + * + * \sa MatrixBase::array(), class MatrixWrapper + */ + +namespace internal { +template +struct traits > + : public traits::type > +{ + typedef ArrayXpr XprKind; + // Let's remove NestByRefBit + enum { + Flags0 = traits::type >::Flags, + Flags = Flags0 & ~NestByRefBit + }; +}; +} + +template +class ArrayWrapper : public ArrayBase > +{ + public: + typedef ArrayBase Base; + EIGEN_DENSE_PUBLIC_INTERFACE(ArrayWrapper) + EIGEN_INHERIT_ASSIGNMENT_OPERATORS(ArrayWrapper) + + typedef typename internal::conditional< + internal::is_lvalue::value, + Scalar, + const Scalar + >::type ScalarWithConstIfNotLvalue; + + typedef typename internal::nested::type NestedExpressionType; + + inline ArrayWrapper(ExpressionType& matrix) : m_expression(matrix) {} + + inline Index rows() const { return m_expression.rows(); } + inline Index cols() const { return m_expression.cols(); } + inline Index outerStride() const { return m_expression.outerStride(); } + inline Index innerStride() const { return m_expression.innerStride(); } + + inline ScalarWithConstIfNotLvalue* data() { return m_expression.const_cast_derived().data(); } + inline const Scalar* data() const { return m_expression.data(); } + + inline CoeffReturnType coeff(Index rowId, Index colId) const + { + return m_expression.coeff(rowId, colId); + } + + inline Scalar& coeffRef(Index rowId, Index colId) + { + return m_expression.const_cast_derived().coeffRef(rowId, colId); + } + + inline const Scalar& coeffRef(Index rowId, Index colId) const + { + return m_expression.const_cast_derived().coeffRef(rowId, colId); + } + + inline CoeffReturnType coeff(Index index) const + { + return m_expression.coeff(index); + } + + inline Scalar& coeffRef(Index index) + { + return m_expression.const_cast_derived().coeffRef(index); + } + + inline const Scalar& coeffRef(Index index) const + { + return m_expression.const_cast_derived().coeffRef(index); + } + + template + inline const PacketScalar packet(Index rowId, Index colId) const + { + return m_expression.template packet(rowId, colId); + } + + template + inline void writePacket(Index rowId, Index colId, const PacketScalar& val) + { + m_expression.const_cast_derived().template writePacket(rowId, colId, val); + } + + template + inline const PacketScalar packet(Index index) const + { + return m_expression.template packet(index); + } + + template + inline void writePacket(Index index, const PacketScalar& val) + { + m_expression.const_cast_derived().template writePacket(index, val); + } + + template + inline void evalTo(Dest& dst) const { dst = m_expression; } + + const typename internal::remove_all::type& + nestedExpression() const + { + return m_expression; + } + + /** Forwards the resizing request to the nested expression + * \sa DenseBase::resize(Index) */ + void resize(Index newSize) { m_expression.const_cast_derived().resize(newSize); } + /** Forwards the resizing request to the nested expression + * \sa DenseBase::resize(Index,Index)*/ + void resize(Index nbRows, Index nbCols) { m_expression.const_cast_derived().resize(nbRows,nbCols); } + + protected: + NestedExpressionType m_expression; +}; + +/** \class MatrixWrapper + * \ingroup Core_Module + * + * \brief Expression of an array as a mathematical vector or matrix + * + * This class is the return type of ArrayBase::matrix(), and most of the time + * this is the only way it is use. + * + * \sa MatrixBase::matrix(), class ArrayWrapper + */ + +namespace internal { +template +struct traits > + : public traits::type > +{ + typedef MatrixXpr XprKind; + // Let's remove NestByRefBit + enum { + Flags0 = traits::type >::Flags, + Flags = Flags0 & ~NestByRefBit + }; +}; +} + +template +class MatrixWrapper : public MatrixBase > +{ + public: + typedef MatrixBase > Base; + EIGEN_DENSE_PUBLIC_INTERFACE(MatrixWrapper) + EIGEN_INHERIT_ASSIGNMENT_OPERATORS(MatrixWrapper) + + typedef typename internal::conditional< + internal::is_lvalue::value, + Scalar, + const Scalar + >::type ScalarWithConstIfNotLvalue; + + typedef typename internal::nested::type NestedExpressionType; + + inline MatrixWrapper(ExpressionType& a_matrix) : m_expression(a_matrix) {} + + inline Index rows() const { return m_expression.rows(); } + inline Index cols() const { return m_expression.cols(); } + inline Index outerStride() const { return m_expression.outerStride(); } + inline Index innerStride() const { return m_expression.innerStride(); } + + inline ScalarWithConstIfNotLvalue* data() { return m_expression.const_cast_derived().data(); } + inline const Scalar* data() const { return m_expression.data(); } + + inline CoeffReturnType coeff(Index rowId, Index colId) const + { + return m_expression.coeff(rowId, colId); + } + + inline Scalar& coeffRef(Index rowId, Index colId) + { + return m_expression.const_cast_derived().coeffRef(rowId, colId); + } + + inline const Scalar& coeffRef(Index rowId, Index colId) const + { + return m_expression.derived().coeffRef(rowId, colId); + } + + inline CoeffReturnType coeff(Index index) const + { + return m_expression.coeff(index); + } + + inline Scalar& coeffRef(Index index) + { + return m_expression.const_cast_derived().coeffRef(index); + } + + inline const Scalar& coeffRef(Index index) const + { + return m_expression.const_cast_derived().coeffRef(index); + } + + template + inline const PacketScalar packet(Index rowId, Index colId) const + { + return m_expression.template packet(rowId, colId); + } + + template + inline void writePacket(Index rowId, Index colId, const PacketScalar& val) + { + m_expression.const_cast_derived().template writePacket(rowId, colId, val); + } + + template + inline const PacketScalar packet(Index index) const + { + return m_expression.template packet(index); + } + + template + inline void writePacket(Index index, const PacketScalar& val) + { + m_expression.const_cast_derived().template writePacket(index, val); + } + + const typename internal::remove_all::type& + nestedExpression() const + { + return m_expression; + } + + /** Forwards the resizing request to the nested expression + * \sa DenseBase::resize(Index) */ + void resize(Index newSize) { m_expression.const_cast_derived().resize(newSize); } + /** Forwards the resizing request to the nested expression + * \sa DenseBase::resize(Index,Index)*/ + void resize(Index nbRows, Index nbCols) { m_expression.const_cast_derived().resize(nbRows,nbCols); } + + protected: + NestedExpressionType m_expression; +}; + +} // end namespace Eigen + +#endif // EIGEN_ARRAYWRAPPER_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/Assign.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/Assign.h new file mode 100644 index 00000000..f4817317 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/Assign.h @@ -0,0 +1,590 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2007 Michael Olbrich +// Copyright (C) 2006-2010 Benoit Jacob +// Copyright (C) 2008 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_ASSIGN_H +#define EIGEN_ASSIGN_H + +namespace Eigen { + +namespace internal { + +/*************************************************************************** +* Part 1 : the logic deciding a strategy for traversal and unrolling * +***************************************************************************/ + +template +struct assign_traits +{ +public: + enum { + DstIsAligned = Derived::Flags & AlignedBit, + DstHasDirectAccess = Derived::Flags & DirectAccessBit, + SrcIsAligned = OtherDerived::Flags & AlignedBit, + JointAlignment = bool(DstIsAligned) && bool(SrcIsAligned) ? Aligned : Unaligned + }; + +private: + enum { + InnerSize = int(Derived::IsVectorAtCompileTime) ? int(Derived::SizeAtCompileTime) + : int(Derived::Flags)&RowMajorBit ? int(Derived::ColsAtCompileTime) + : int(Derived::RowsAtCompileTime), + InnerMaxSize = int(Derived::IsVectorAtCompileTime) ? int(Derived::MaxSizeAtCompileTime) + : int(Derived::Flags)&RowMajorBit ? int(Derived::MaxColsAtCompileTime) + : int(Derived::MaxRowsAtCompileTime), + MaxSizeAtCompileTime = Derived::SizeAtCompileTime, + PacketSize = packet_traits::size + }; + + enum { + StorageOrdersAgree = (int(Derived::IsRowMajor) == int(OtherDerived::IsRowMajor)), + MightVectorize = StorageOrdersAgree + && (int(Derived::Flags) & int(OtherDerived::Flags) & ActualPacketAccessBit), + MayInnerVectorize = MightVectorize && int(InnerSize)!=Dynamic && int(InnerSize)%int(PacketSize)==0 + && int(DstIsAligned) && int(SrcIsAligned), + MayLinearize = StorageOrdersAgree && (int(Derived::Flags) & int(OtherDerived::Flags) & LinearAccessBit), + MayLinearVectorize = MightVectorize && MayLinearize && DstHasDirectAccess + && (DstIsAligned || MaxSizeAtCompileTime == Dynamic), + /* If the destination isn't aligned, we have to do runtime checks and we don't unroll, + so it's only good for large enough sizes. */ + MaySliceVectorize = MightVectorize && DstHasDirectAccess + && (int(InnerMaxSize)==Dynamic || int(InnerMaxSize)>=3*PacketSize) + /* slice vectorization can be slow, so we only want it if the slices are big, which is + indicated by InnerMaxSize rather than InnerSize, think of the case of a dynamic block + in a fixed-size matrix */ + }; + +public: + enum { + Traversal = int(MayInnerVectorize) ? int(InnerVectorizedTraversal) + : int(MayLinearVectorize) ? int(LinearVectorizedTraversal) + : int(MaySliceVectorize) ? int(SliceVectorizedTraversal) + : int(MayLinearize) ? int(LinearTraversal) + : int(DefaultTraversal), + Vectorized = int(Traversal) == InnerVectorizedTraversal + || int(Traversal) == LinearVectorizedTraversal + || int(Traversal) == SliceVectorizedTraversal + }; + +private: + enum { + UnrollingLimit = EIGEN_UNROLLING_LIMIT * (Vectorized ? int(PacketSize) : 1), + MayUnrollCompletely = int(Derived::SizeAtCompileTime) != Dynamic + && int(OtherDerived::CoeffReadCost) != Dynamic + && int(Derived::SizeAtCompileTime) * int(OtherDerived::CoeffReadCost) <= int(UnrollingLimit), + MayUnrollInner = int(InnerSize) != Dynamic + && int(OtherDerived::CoeffReadCost) != Dynamic + && int(InnerSize) * int(OtherDerived::CoeffReadCost) <= int(UnrollingLimit) + }; + +public: + enum { + Unrolling = (int(Traversal) == int(InnerVectorizedTraversal) || int(Traversal) == int(DefaultTraversal)) + ? ( + int(MayUnrollCompletely) ? int(CompleteUnrolling) + : int(MayUnrollInner) ? int(InnerUnrolling) + : int(NoUnrolling) + ) + : int(Traversal) == int(LinearVectorizedTraversal) + ? ( bool(MayUnrollCompletely) && bool(DstIsAligned) ? int(CompleteUnrolling) : int(NoUnrolling) ) + : int(Traversal) == int(LinearTraversal) + ? ( bool(MayUnrollCompletely) ? int(CompleteUnrolling) : int(NoUnrolling) ) + : int(NoUnrolling) + }; + +#ifdef EIGEN_DEBUG_ASSIGN + static void debug() + { + EIGEN_DEBUG_VAR(DstIsAligned) + EIGEN_DEBUG_VAR(SrcIsAligned) + EIGEN_DEBUG_VAR(JointAlignment) + EIGEN_DEBUG_VAR(InnerSize) + EIGEN_DEBUG_VAR(InnerMaxSize) + EIGEN_DEBUG_VAR(PacketSize) + EIGEN_DEBUG_VAR(StorageOrdersAgree) + EIGEN_DEBUG_VAR(MightVectorize) + EIGEN_DEBUG_VAR(MayLinearize) + EIGEN_DEBUG_VAR(MayInnerVectorize) + EIGEN_DEBUG_VAR(MayLinearVectorize) + EIGEN_DEBUG_VAR(MaySliceVectorize) + EIGEN_DEBUG_VAR(Traversal) + EIGEN_DEBUG_VAR(UnrollingLimit) + EIGEN_DEBUG_VAR(MayUnrollCompletely) + EIGEN_DEBUG_VAR(MayUnrollInner) + EIGEN_DEBUG_VAR(Unrolling) + } +#endif +}; + +/*************************************************************************** +* Part 2 : meta-unrollers +***************************************************************************/ + +/************************ +*** Default traversal *** +************************/ + +template +struct assign_DefaultTraversal_CompleteUnrolling +{ + enum { + outer = Index / Derived1::InnerSizeAtCompileTime, + inner = Index % Derived1::InnerSizeAtCompileTime + }; + + static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) + { + dst.copyCoeffByOuterInner(outer, inner, src); + assign_DefaultTraversal_CompleteUnrolling::run(dst, src); + } +}; + +template +struct assign_DefaultTraversal_CompleteUnrolling +{ + static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &) {} +}; + +template +struct assign_DefaultTraversal_InnerUnrolling +{ + static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src, typename Derived1::Index outer) + { + dst.copyCoeffByOuterInner(outer, Index, src); + assign_DefaultTraversal_InnerUnrolling::run(dst, src, outer); + } +}; + +template +struct assign_DefaultTraversal_InnerUnrolling +{ + static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &, typename Derived1::Index) {} +}; + +/*********************** +*** Linear traversal *** +***********************/ + +template +struct assign_LinearTraversal_CompleteUnrolling +{ + static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) + { + dst.copyCoeff(Index, src); + assign_LinearTraversal_CompleteUnrolling::run(dst, src); + } +}; + +template +struct assign_LinearTraversal_CompleteUnrolling +{ + static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &) {} +}; + +/************************** +*** Inner vectorization *** +**************************/ + +template +struct assign_innervec_CompleteUnrolling +{ + enum { + outer = Index / Derived1::InnerSizeAtCompileTime, + inner = Index % Derived1::InnerSizeAtCompileTime, + JointAlignment = assign_traits::JointAlignment + }; + + static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) + { + dst.template copyPacketByOuterInner(outer, inner, src); + assign_innervec_CompleteUnrolling::size, Stop>::run(dst, src); + } +}; + +template +struct assign_innervec_CompleteUnrolling +{ + static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &) {} +}; + +template +struct assign_innervec_InnerUnrolling +{ + static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src, typename Derived1::Index outer) + { + dst.template copyPacketByOuterInner(outer, Index, src); + assign_innervec_InnerUnrolling::size, Stop>::run(dst, src, outer); + } +}; + +template +struct assign_innervec_InnerUnrolling +{ + static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &, typename Derived1::Index) {} +}; + +/*************************************************************************** +* Part 3 : implementation of all cases +***************************************************************************/ + +template::Traversal, + int Unrolling = assign_traits::Unrolling, + int Version = Specialized> +struct assign_impl; + +/************************ +*** Default traversal *** +************************/ + +template +struct assign_impl +{ + static inline void run(Derived1 &, const Derived2 &) { } +}; + +template +struct assign_impl +{ + typedef typename Derived1::Index Index; + static inline void run(Derived1 &dst, const Derived2 &src) + { + const Index innerSize = dst.innerSize(); + const Index outerSize = dst.outerSize(); + for(Index outer = 0; outer < outerSize; ++outer) + for(Index inner = 0; inner < innerSize; ++inner) + dst.copyCoeffByOuterInner(outer, inner, src); + } +}; + +template +struct assign_impl +{ + static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) + { + assign_DefaultTraversal_CompleteUnrolling + ::run(dst, src); + } +}; + +template +struct assign_impl +{ + typedef typename Derived1::Index Index; + static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) + { + const Index outerSize = dst.outerSize(); + for(Index outer = 0; outer < outerSize; ++outer) + assign_DefaultTraversal_InnerUnrolling + ::run(dst, src, outer); + } +}; + +/*********************** +*** Linear traversal *** +***********************/ + +template +struct assign_impl +{ + typedef typename Derived1::Index Index; + static inline void run(Derived1 &dst, const Derived2 &src) + { + const Index size = dst.size(); + for(Index i = 0; i < size; ++i) + dst.copyCoeff(i, src); + } +}; + +template +struct assign_impl +{ + static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) + { + assign_LinearTraversal_CompleteUnrolling + ::run(dst, src); + } +}; + +/************************** +*** Inner vectorization *** +**************************/ + +template +struct assign_impl +{ + typedef typename Derived1::Index Index; + static inline void run(Derived1 &dst, const Derived2 &src) + { + const Index innerSize = dst.innerSize(); + const Index outerSize = dst.outerSize(); + const Index packetSize = packet_traits::size; + for(Index outer = 0; outer < outerSize; ++outer) + for(Index inner = 0; inner < innerSize; inner+=packetSize) + dst.template copyPacketByOuterInner(outer, inner, src); + } +}; + +template +struct assign_impl +{ + static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) + { + assign_innervec_CompleteUnrolling + ::run(dst, src); + } +}; + +template +struct assign_impl +{ + typedef typename Derived1::Index Index; + static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) + { + const Index outerSize = dst.outerSize(); + for(Index outer = 0; outer < outerSize; ++outer) + assign_innervec_InnerUnrolling + ::run(dst, src, outer); + } +}; + +/*************************** +*** Linear vectorization *** +***************************/ + +template +struct unaligned_assign_impl +{ + template + static EIGEN_STRONG_INLINE void run(const Derived&, OtherDerived&, typename Derived::Index, typename Derived::Index) {} +}; + +template <> +struct unaligned_assign_impl +{ + // MSVC must not inline this functions. If it does, it fails to optimize the + // packet access path. +#ifdef _MSC_VER + template + static EIGEN_DONT_INLINE void run(const Derived& src, OtherDerived& dst, typename Derived::Index start, typename Derived::Index end) +#else + template + static EIGEN_STRONG_INLINE void run(const Derived& src, OtherDerived& dst, typename Derived::Index start, typename Derived::Index end) +#endif + { + for (typename Derived::Index index = start; index < end; ++index) + dst.copyCoeff(index, src); + } +}; + +template +struct assign_impl +{ + typedef typename Derived1::Index Index; + static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) + { + const Index size = dst.size(); + typedef packet_traits PacketTraits; + enum { + packetSize = PacketTraits::size, + dstAlignment = PacketTraits::AlignedOnScalar ? Aligned : int(assign_traits::DstIsAligned) , + srcAlignment = assign_traits::JointAlignment + }; + const Index alignedStart = assign_traits::DstIsAligned ? 0 + : internal::first_aligned(&dst.coeffRef(0), size); + const Index alignedEnd = alignedStart + ((size-alignedStart)/packetSize)*packetSize; + + unaligned_assign_impl::DstIsAligned!=0>::run(src,dst,0,alignedStart); + + for(Index index = alignedStart; index < alignedEnd; index += packetSize) + { + dst.template copyPacket(index, src); + } + + unaligned_assign_impl<>::run(src,dst,alignedEnd,size); + } +}; + +template +struct assign_impl +{ + typedef typename Derived1::Index Index; + static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) + { + enum { size = Derived1::SizeAtCompileTime, + packetSize = packet_traits::size, + alignedSize = (size/packetSize)*packetSize }; + + assign_innervec_CompleteUnrolling::run(dst, src); + assign_DefaultTraversal_CompleteUnrolling::run(dst, src); + } +}; + +/************************** +*** Slice vectorization *** +***************************/ + +template +struct assign_impl +{ + typedef typename Derived1::Index Index; + static inline void run(Derived1 &dst, const Derived2 &src) + { + typedef typename Derived1::Scalar Scalar; + typedef packet_traits PacketTraits; + enum { + packetSize = PacketTraits::size, + alignable = PacketTraits::AlignedOnScalar, + dstIsAligned = assign_traits::DstIsAligned, + dstAlignment = alignable ? Aligned : int(dstIsAligned), + srcAlignment = assign_traits::JointAlignment + }; + const Scalar *dst_ptr = &dst.coeffRef(0,0); + if((!bool(dstIsAligned)) && (size_t(dst_ptr) % sizeof(Scalar))>0) + { + // the pointer is not aligend-on scalar, so alignment is not possible + return assign_impl::run(dst, src); + } + const Index packetAlignedMask = packetSize - 1; + const Index innerSize = dst.innerSize(); + const Index outerSize = dst.outerSize(); + const Index alignedStep = alignable ? (packetSize - dst.outerStride() % packetSize) & packetAlignedMask : 0; + Index alignedStart = ((!alignable) || bool(dstIsAligned)) ? 0 : internal::first_aligned(dst_ptr, innerSize); + + for(Index outer = 0; outer < outerSize; ++outer) + { + const Index alignedEnd = alignedStart + ((innerSize-alignedStart) & ~packetAlignedMask); + // do the non-vectorizable part of the assignment + for(Index inner = 0; inner(outer, inner, src); + + // do the non-vectorizable part of the assignment + for(Index inner = alignedEnd; inner((alignedStart+alignedStep)%packetSize, innerSize); + } + } +}; + +} // end namespace internal + +/*************************************************************************** +* Part 4 : implementation of DenseBase methods +***************************************************************************/ + +template +template +EIGEN_STRONG_INLINE Derived& DenseBase + ::lazyAssign(const DenseBase& other) +{ + enum{ + SameType = internal::is_same::value + }; + + EIGEN_STATIC_ASSERT_LVALUE(Derived) + EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Derived,OtherDerived) + EIGEN_STATIC_ASSERT(SameType,YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) + +#ifdef EIGEN_DEBUG_ASSIGN + internal::assign_traits::debug(); +#endif + eigen_assert(rows() == other.rows() && cols() == other.cols()); + internal::assign_impl::Traversal) + : int(InvalidTraversal)>::run(derived(),other.derived()); +#ifndef EIGEN_NO_DEBUG + checkTransposeAliasing(other.derived()); +#endif + return derived(); +} + +namespace internal { + +template::Flags) & EvalBeforeAssigningBit) != 0, + bool NeedToTranspose = ((int(Derived::RowsAtCompileTime) == 1 && int(OtherDerived::ColsAtCompileTime) == 1) + | // FIXME | instead of || to please GCC 4.4.0 stupid warning "suggest parentheses around &&". + // revert to || as soon as not needed anymore. + (int(Derived::ColsAtCompileTime) == 1 && int(OtherDerived::RowsAtCompileTime) == 1)) + && int(Derived::SizeAtCompileTime) != 1> +struct assign_selector; + +template +struct assign_selector { + static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.derived()); } + template + static EIGEN_STRONG_INLINE Derived& evalTo(ActualDerived& dst, const ActualOtherDerived& other) { other.evalTo(dst); return dst; } +}; +template +struct assign_selector { + static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.eval()); } +}; +template +struct assign_selector { + static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.transpose()); } + template + static EIGEN_STRONG_INLINE Derived& evalTo(ActualDerived& dst, const ActualOtherDerived& other) { Transpose dstTrans(dst); other.evalTo(dstTrans); return dst; } +}; +template +struct assign_selector { + static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.transpose().eval()); } +}; + +} // end namespace internal + +template +template +EIGEN_STRONG_INLINE Derived& DenseBase::operator=(const DenseBase& other) +{ + return internal::assign_selector::run(derived(), other.derived()); +} + +template +EIGEN_STRONG_INLINE Derived& DenseBase::operator=(const DenseBase& other) +{ + return internal::assign_selector::run(derived(), other.derived()); +} + +template +EIGEN_STRONG_INLINE Derived& MatrixBase::operator=(const MatrixBase& other) +{ + return internal::assign_selector::run(derived(), other.derived()); +} + +template +template +EIGEN_STRONG_INLINE Derived& MatrixBase::operator=(const DenseBase& other) +{ + return internal::assign_selector::run(derived(), other.derived()); +} + +template +template +EIGEN_STRONG_INLINE Derived& MatrixBase::operator=(const EigenBase& other) +{ + return internal::assign_selector::evalTo(derived(), other.derived()); +} + +template +template +EIGEN_STRONG_INLINE Derived& MatrixBase::operator=(const ReturnByValue& other) +{ + return internal::assign_selector::evalTo(derived(), other.derived()); +} + +} // end namespace Eigen + +#endif // EIGEN_ASSIGN_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/Assign_MKL.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/Assign_MKL.h new file mode 100644 index 00000000..7772951b --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/Assign_MKL.h @@ -0,0 +1,224 @@ +/* + Copyright (c) 2011, Intel Corporation. All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of Intel Corporation nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ******************************************************************************** + * Content : Eigen bindings to Intel(R) MKL + * MKL VML support for coefficient-wise unary Eigen expressions like a=b.sin() + ******************************************************************************** +*/ + +#ifndef EIGEN_ASSIGN_VML_H +#define EIGEN_ASSIGN_VML_H + +namespace Eigen { + +namespace internal { + +template struct vml_call +{ enum { IsSupported = 0 }; }; + +template +class vml_assign_traits +{ + private: + enum { + DstHasDirectAccess = Dst::Flags & DirectAccessBit, + SrcHasDirectAccess = Src::Flags & DirectAccessBit, + + StorageOrdersAgree = (int(Dst::IsRowMajor) == int(Src::IsRowMajor)), + InnerSize = int(Dst::IsVectorAtCompileTime) ? int(Dst::SizeAtCompileTime) + : int(Dst::Flags)&RowMajorBit ? int(Dst::ColsAtCompileTime) + : int(Dst::RowsAtCompileTime), + InnerMaxSize = int(Dst::IsVectorAtCompileTime) ? int(Dst::MaxSizeAtCompileTime) + : int(Dst::Flags)&RowMajorBit ? int(Dst::MaxColsAtCompileTime) + : int(Dst::MaxRowsAtCompileTime), + MaxSizeAtCompileTime = Dst::SizeAtCompileTime, + + MightEnableVml = vml_call::IsSupported && StorageOrdersAgree && DstHasDirectAccess && SrcHasDirectAccess + && Src::InnerStrideAtCompileTime==1 && Dst::InnerStrideAtCompileTime==1, + MightLinearize = MightEnableVml && (int(Dst::Flags) & int(Src::Flags) & LinearAccessBit), + VmlSize = MightLinearize ? MaxSizeAtCompileTime : InnerMaxSize, + LargeEnough = VmlSize==Dynamic || VmlSize>=EIGEN_MKL_VML_THRESHOLD, + MayEnableVml = MightEnableVml && LargeEnough, + MayLinearize = MayEnableVml && MightLinearize + }; + public: + enum { + Traversal = MayLinearize ? LinearVectorizedTraversal + : MayEnableVml ? InnerVectorizedTraversal + : DefaultTraversal + }; +}; + +template::Traversal > +struct vml_assign_impl + : assign_impl,Traversal,Unrolling,BuiltIn> +{ +}; + +template +struct vml_assign_impl +{ + typedef typename Derived1::Scalar Scalar; + typedef typename Derived1::Index Index; + static inline void run(Derived1& dst, const CwiseUnaryOp& src) + { + // in case we want to (or have to) skip VML at runtime we can call: + // assign_impl,Traversal,Unrolling,BuiltIn>::run(dst,src); + const Index innerSize = dst.innerSize(); + const Index outerSize = dst.outerSize(); + for(Index outer = 0; outer < outerSize; ++outer) { + const Scalar *src_ptr = src.IsRowMajor ? &(src.nestedExpression().coeffRef(outer,0)) : + &(src.nestedExpression().coeffRef(0, outer)); + Scalar *dst_ptr = dst.IsRowMajor ? &(dst.coeffRef(outer,0)) : &(dst.coeffRef(0, outer)); + vml_call::run(src.functor(), innerSize, src_ptr, dst_ptr ); + } + } +}; + +template +struct vml_assign_impl +{ + static inline void run(Derived1& dst, const CwiseUnaryOp& src) + { + // in case we want to (or have to) skip VML at runtime we can call: + // assign_impl,Traversal,Unrolling,BuiltIn>::run(dst,src); + vml_call::run(src.functor(), dst.size(), src.nestedExpression().data(), dst.data() ); + } +}; + +// Macroses + +#define EIGEN_MKL_VML_SPECIALIZE_ASSIGN(TRAVERSAL,UNROLLING) \ + template \ + struct assign_impl, TRAVERSAL, UNROLLING, Specialized> { \ + static inline void run(Derived1 &dst, const Eigen::CwiseUnaryOp &src) { \ + vml_assign_impl::run(dst, src); \ + } \ + }; + +EIGEN_MKL_VML_SPECIALIZE_ASSIGN(DefaultTraversal,NoUnrolling) +EIGEN_MKL_VML_SPECIALIZE_ASSIGN(DefaultTraversal,CompleteUnrolling) +EIGEN_MKL_VML_SPECIALIZE_ASSIGN(DefaultTraversal,InnerUnrolling) +EIGEN_MKL_VML_SPECIALIZE_ASSIGN(LinearTraversal,NoUnrolling) +EIGEN_MKL_VML_SPECIALIZE_ASSIGN(LinearTraversal,CompleteUnrolling) +EIGEN_MKL_VML_SPECIALIZE_ASSIGN(InnerVectorizedTraversal,NoUnrolling) +EIGEN_MKL_VML_SPECIALIZE_ASSIGN(InnerVectorizedTraversal,CompleteUnrolling) +EIGEN_MKL_VML_SPECIALIZE_ASSIGN(InnerVectorizedTraversal,InnerUnrolling) +EIGEN_MKL_VML_SPECIALIZE_ASSIGN(LinearVectorizedTraversal,CompleteUnrolling) +EIGEN_MKL_VML_SPECIALIZE_ASSIGN(LinearVectorizedTraversal,NoUnrolling) +EIGEN_MKL_VML_SPECIALIZE_ASSIGN(SliceVectorizedTraversal,NoUnrolling) + + +#if !defined (EIGEN_FAST_MATH) || (EIGEN_FAST_MATH != 1) +#define EIGEN_MKL_VML_MODE VML_HA +#else +#define EIGEN_MKL_VML_MODE VML_LA +#endif + +#define EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, VMLOP, EIGENTYPE, VMLTYPE) \ + template<> struct vml_call< scalar_##EIGENOP##_op > { \ + enum { IsSupported = 1 }; \ + static inline void run( const scalar_##EIGENOP##_op& /*func*/, \ + int size, const EIGENTYPE* src, EIGENTYPE* dst) { \ + VMLOP(size, (const VMLTYPE*)src, (VMLTYPE*)dst); \ + } \ + }; + +#define EIGEN_MKL_VML_DECLARE_UNARY_CALL_LA(EIGENOP, VMLOP, EIGENTYPE, VMLTYPE) \ + template<> struct vml_call< scalar_##EIGENOP##_op > { \ + enum { IsSupported = 1 }; \ + static inline void run( const scalar_##EIGENOP##_op& /*func*/, \ + int size, const EIGENTYPE* src, EIGENTYPE* dst) { \ + MKL_INT64 vmlMode = EIGEN_MKL_VML_MODE; \ + VMLOP(size, (const VMLTYPE*)src, (VMLTYPE*)dst, vmlMode); \ + } \ + }; + +#define EIGEN_MKL_VML_DECLARE_POW_CALL(EIGENOP, VMLOP, EIGENTYPE, VMLTYPE) \ + template<> struct vml_call< scalar_##EIGENOP##_op > { \ + enum { IsSupported = 1 }; \ + static inline void run( const scalar_##EIGENOP##_op& func, \ + int size, const EIGENTYPE* src, EIGENTYPE* dst) { \ + EIGENTYPE exponent = func.m_exponent; \ + MKL_INT64 vmlMode = EIGEN_MKL_VML_MODE; \ + VMLOP(&size, (const VMLTYPE*)src, (const VMLTYPE*)&exponent, \ + (VMLTYPE*)dst, &vmlMode); \ + } \ + }; + +#define EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(EIGENOP, VMLOP) \ + EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, vs##VMLOP, float, float) \ + EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, vd##VMLOP, double, double) + +#define EIGEN_MKL_VML_DECLARE_UNARY_CALLS_COMPLEX(EIGENOP, VMLOP) \ + EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, vc##VMLOP, scomplex, MKL_Complex8) \ + EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, vz##VMLOP, dcomplex, MKL_Complex16) + +#define EIGEN_MKL_VML_DECLARE_UNARY_CALLS(EIGENOP, VMLOP) \ + EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(EIGENOP, VMLOP) \ + EIGEN_MKL_VML_DECLARE_UNARY_CALLS_COMPLEX(EIGENOP, VMLOP) + + +#define EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL_LA(EIGENOP, VMLOP) \ + EIGEN_MKL_VML_DECLARE_UNARY_CALL_LA(EIGENOP, vms##VMLOP, float, float) \ + EIGEN_MKL_VML_DECLARE_UNARY_CALL_LA(EIGENOP, vmd##VMLOP, double, double) + +#define EIGEN_MKL_VML_DECLARE_UNARY_CALLS_COMPLEX_LA(EIGENOP, VMLOP) \ + EIGEN_MKL_VML_DECLARE_UNARY_CALL_LA(EIGENOP, vmc##VMLOP, scomplex, MKL_Complex8) \ + EIGEN_MKL_VML_DECLARE_UNARY_CALL_LA(EIGENOP, vmz##VMLOP, dcomplex, MKL_Complex16) + +#define EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(EIGENOP, VMLOP) \ + EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL_LA(EIGENOP, VMLOP) \ + EIGEN_MKL_VML_DECLARE_UNARY_CALLS_COMPLEX_LA(EIGENOP, VMLOP) + + +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(sin, Sin) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(asin, Asin) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(cos, Cos) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(acos, Acos) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(tan, Tan) +//EIGEN_MKL_VML_DECLARE_UNARY_CALLS(abs, Abs) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(exp, Exp) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(log, Ln) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(sqrt, Sqrt) + +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(square, Sqr) + +// The vm*powx functions are not avaibale in the windows version of MKL. +#ifndef _WIN32 +EIGEN_MKL_VML_DECLARE_POW_CALL(pow, vmspowx_, float, float) +EIGEN_MKL_VML_DECLARE_POW_CALL(pow, vmdpowx_, double, double) +EIGEN_MKL_VML_DECLARE_POW_CALL(pow, vmcpowx_, scomplex, MKL_Complex8) +EIGEN_MKL_VML_DECLARE_POW_CALL(pow, vmzpowx_, dcomplex, MKL_Complex16) +#endif + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_ASSIGN_VML_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/BandMatrix.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/BandMatrix.h new file mode 100644 index 00000000..ffd7fe8b --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/BandMatrix.h @@ -0,0 +1,334 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2009 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_BANDMATRIX_H +#define EIGEN_BANDMATRIX_H + +namespace Eigen { + +namespace internal { + +template +class BandMatrixBase : public EigenBase +{ + public: + + enum { + Flags = internal::traits::Flags, + CoeffReadCost = internal::traits::CoeffReadCost, + RowsAtCompileTime = internal::traits::RowsAtCompileTime, + ColsAtCompileTime = internal::traits::ColsAtCompileTime, + MaxRowsAtCompileTime = internal::traits::MaxRowsAtCompileTime, + MaxColsAtCompileTime = internal::traits::MaxColsAtCompileTime, + Supers = internal::traits::Supers, + Subs = internal::traits::Subs, + Options = internal::traits::Options + }; + typedef typename internal::traits::Scalar Scalar; + typedef Matrix DenseMatrixType; + typedef typename DenseMatrixType::Index Index; + typedef typename internal::traits::CoefficientsType CoefficientsType; + typedef EigenBase Base; + + protected: + enum { + DataRowsAtCompileTime = ((Supers!=Dynamic) && (Subs!=Dynamic)) + ? 1 + Supers + Subs + : Dynamic, + SizeAtCompileTime = EIGEN_SIZE_MIN_PREFER_DYNAMIC(RowsAtCompileTime,ColsAtCompileTime) + }; + + public: + + using Base::derived; + using Base::rows; + using Base::cols; + + /** \returns the number of super diagonals */ + inline Index supers() const { return derived().supers(); } + + /** \returns the number of sub diagonals */ + inline Index subs() const { return derived().subs(); } + + /** \returns an expression of the underlying coefficient matrix */ + inline const CoefficientsType& coeffs() const { return derived().coeffs(); } + + /** \returns an expression of the underlying coefficient matrix */ + inline CoefficientsType& coeffs() { return derived().coeffs(); } + + /** \returns a vector expression of the \a i -th column, + * only the meaningful part is returned. + * \warning the internal storage must be column major. */ + inline Block col(Index i) + { + EIGEN_STATIC_ASSERT((Options&RowMajor)==0,THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES); + Index start = 0; + Index len = coeffs().rows(); + if (i<=supers()) + { + start = supers()-i; + len = (std::min)(rows(),std::max(0,coeffs().rows() - (supers()-i))); + } + else if (i>=rows()-subs()) + len = std::max(0,coeffs().rows() - (i + 1 - rows() + subs())); + return Block(coeffs(), start, i, len, 1); + } + + /** \returns a vector expression of the main diagonal */ + inline Block diagonal() + { return Block(coeffs(),supers(),0,1,(std::min)(rows(),cols())); } + + /** \returns a vector expression of the main diagonal (const version) */ + inline const Block diagonal() const + { return Block(coeffs(),supers(),0,1,(std::min)(rows(),cols())); } + + template struct DiagonalIntReturnType { + enum { + ReturnOpposite = (Options&SelfAdjoint) && (((Index)>0 && Supers==0) || ((Index)<0 && Subs==0)), + Conjugate = ReturnOpposite && NumTraits::IsComplex, + ActualIndex = ReturnOpposite ? -Index : Index, + DiagonalSize = (RowsAtCompileTime==Dynamic || ColsAtCompileTime==Dynamic) + ? Dynamic + : (ActualIndex<0 + ? EIGEN_SIZE_MIN_PREFER_DYNAMIC(ColsAtCompileTime, RowsAtCompileTime + ActualIndex) + : EIGEN_SIZE_MIN_PREFER_DYNAMIC(RowsAtCompileTime, ColsAtCompileTime - ActualIndex)) + }; + typedef Block BuildType; + typedef typename internal::conditional,BuildType >, + BuildType>::type Type; + }; + + /** \returns a vector expression of the \a N -th sub or super diagonal */ + template inline typename DiagonalIntReturnType::Type diagonal() + { + return typename DiagonalIntReturnType::BuildType(coeffs(), supers()-N, (std::max)(0,N), 1, diagonalLength(N)); + } + + /** \returns a vector expression of the \a N -th sub or super diagonal */ + template inline const typename DiagonalIntReturnType::Type diagonal() const + { + return typename DiagonalIntReturnType::BuildType(coeffs(), supers()-N, (std::max)(0,N), 1, diagonalLength(N)); + } + + /** \returns a vector expression of the \a i -th sub or super diagonal */ + inline Block diagonal(Index i) + { + eigen_assert((i<0 && -i<=subs()) || (i>=0 && i<=supers())); + return Block(coeffs(), supers()-i, std::max(0,i), 1, diagonalLength(i)); + } + + /** \returns a vector expression of the \a i -th sub or super diagonal */ + inline const Block diagonal(Index i) const + { + eigen_assert((i<0 && -i<=subs()) || (i>=0 && i<=supers())); + return Block(coeffs(), supers()-i, std::max(0,i), 1, diagonalLength(i)); + } + + template inline void evalTo(Dest& dst) const + { + dst.resize(rows(),cols()); + dst.setZero(); + dst.diagonal() = diagonal(); + for (Index i=1; i<=supers();++i) + dst.diagonal(i) = diagonal(i); + for (Index i=1; i<=subs();++i) + dst.diagonal(-i) = diagonal(-i); + } + + DenseMatrixType toDenseMatrix() const + { + DenseMatrixType res(rows(),cols()); + evalTo(res); + return res; + } + + protected: + + inline Index diagonalLength(Index i) const + { return i<0 ? (std::min)(cols(),rows()+i) : (std::min)(rows(),cols()-i); } +}; + +/** + * \class BandMatrix + * \ingroup Core_Module + * + * \brief Represents a rectangular matrix with a banded storage + * + * \param _Scalar Numeric type, i.e. float, double, int + * \param Rows Number of rows, or \b Dynamic + * \param Cols Number of columns, or \b Dynamic + * \param Supers Number of super diagonal + * \param Subs Number of sub diagonal + * \param _Options A combination of either \b #RowMajor or \b #ColMajor, and of \b #SelfAdjoint + * The former controls \ref TopicStorageOrders "storage order", and defaults to + * column-major. The latter controls whether the matrix represents a selfadjoint + * matrix in which case either Supers of Subs have to be null. + * + * \sa class TridiagonalMatrix + */ + +template +struct traits > +{ + typedef _Scalar Scalar; + typedef Dense StorageKind; + typedef DenseIndex Index; + enum { + CoeffReadCost = NumTraits::ReadCost, + RowsAtCompileTime = _Rows, + ColsAtCompileTime = _Cols, + MaxRowsAtCompileTime = _Rows, + MaxColsAtCompileTime = _Cols, + Flags = LvalueBit, + Supers = _Supers, + Subs = _Subs, + Options = _Options, + DataRowsAtCompileTime = ((Supers!=Dynamic) && (Subs!=Dynamic)) ? 1 + Supers + Subs : Dynamic + }; + typedef Matrix CoefficientsType; +}; + +template +class BandMatrix : public BandMatrixBase > +{ + public: + + typedef typename internal::traits::Scalar Scalar; + typedef typename internal::traits::Index Index; + typedef typename internal::traits::CoefficientsType CoefficientsType; + + inline BandMatrix(Index rows=Rows, Index cols=Cols, Index supers=Supers, Index subs=Subs) + : m_coeffs(1+supers+subs,cols), + m_rows(rows), m_supers(supers), m_subs(subs) + { + } + + /** \returns the number of columns */ + inline Index rows() const { return m_rows.value(); } + + /** \returns the number of rows */ + inline Index cols() const { return m_coeffs.cols(); } + + /** \returns the number of super diagonals */ + inline Index supers() const { return m_supers.value(); } + + /** \returns the number of sub diagonals */ + inline Index subs() const { return m_subs.value(); } + + inline const CoefficientsType& coeffs() const { return m_coeffs; } + inline CoefficientsType& coeffs() { return m_coeffs; } + + protected: + + CoefficientsType m_coeffs; + internal::variable_if_dynamic m_rows; + internal::variable_if_dynamic m_supers; + internal::variable_if_dynamic m_subs; +}; + +template +class BandMatrixWrapper; + +template +struct traits > +{ + typedef typename _CoefficientsType::Scalar Scalar; + typedef typename _CoefficientsType::StorageKind StorageKind; + typedef typename _CoefficientsType::Index Index; + enum { + CoeffReadCost = internal::traits<_CoefficientsType>::CoeffReadCost, + RowsAtCompileTime = _Rows, + ColsAtCompileTime = _Cols, + MaxRowsAtCompileTime = _Rows, + MaxColsAtCompileTime = _Cols, + Flags = LvalueBit, + Supers = _Supers, + Subs = _Subs, + Options = _Options, + DataRowsAtCompileTime = ((Supers!=Dynamic) && (Subs!=Dynamic)) ? 1 + Supers + Subs : Dynamic + }; + typedef _CoefficientsType CoefficientsType; +}; + +template +class BandMatrixWrapper : public BandMatrixBase > +{ + public: + + typedef typename internal::traits::Scalar Scalar; + typedef typename internal::traits::CoefficientsType CoefficientsType; + typedef typename internal::traits::Index Index; + + inline BandMatrixWrapper(const CoefficientsType& coeffs, Index rows=_Rows, Index cols=_Cols, Index supers=_Supers, Index subs=_Subs) + : m_coeffs(coeffs), + m_rows(rows), m_supers(supers), m_subs(subs) + { + EIGEN_UNUSED_VARIABLE(cols); + //internal::assert(coeffs.cols()==cols() && (supers()+subs()+1)==coeffs.rows()); + } + + /** \returns the number of columns */ + inline Index rows() const { return m_rows.value(); } + + /** \returns the number of rows */ + inline Index cols() const { return m_coeffs.cols(); } + + /** \returns the number of super diagonals */ + inline Index supers() const { return m_supers.value(); } + + /** \returns the number of sub diagonals */ + inline Index subs() const { return m_subs.value(); } + + inline const CoefficientsType& coeffs() const { return m_coeffs; } + + protected: + + const CoefficientsType& m_coeffs; + internal::variable_if_dynamic m_rows; + internal::variable_if_dynamic m_supers; + internal::variable_if_dynamic m_subs; +}; + +/** + * \class TridiagonalMatrix + * \ingroup Core_Module + * + * \brief Represents a tridiagonal matrix with a compact banded storage + * + * \param _Scalar Numeric type, i.e. float, double, int + * \param Size Number of rows and cols, or \b Dynamic + * \param _Options Can be 0 or \b SelfAdjoint + * + * \sa class BandMatrix + */ +template +class TridiagonalMatrix : public BandMatrix +{ + typedef BandMatrix Base; + typedef typename Base::Index Index; + public: + TridiagonalMatrix(Index size = Size) : Base(size,size,Options&SelfAdjoint?0:1,1) {} + + inline typename Base::template DiagonalIntReturnType<1>::Type super() + { return Base::template diagonal<1>(); } + inline const typename Base::template DiagonalIntReturnType<1>::Type super() const + { return Base::template diagonal<1>(); } + inline typename Base::template DiagonalIntReturnType<-1>::Type sub() + { return Base::template diagonal<-1>(); } + inline const typename Base::template DiagonalIntReturnType<-1>::Type sub() const + { return Base::template diagonal<-1>(); } + protected: +}; + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_BANDMATRIX_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/Block.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/Block.h new file mode 100644 index 00000000..82789444 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/Block.h @@ -0,0 +1,406 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008 Gael Guennebaud +// Copyright (C) 2006-2010 Benoit Jacob +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_BLOCK_H +#define EIGEN_BLOCK_H + +namespace Eigen { + +/** \class Block + * \ingroup Core_Module + * + * \brief Expression of a fixed-size or dynamic-size block + * + * \param XprType the type of the expression in which we are taking a block + * \param BlockRows the number of rows of the block we are taking at compile time (optional) + * \param BlockCols the number of columns of the block we are taking at compile time (optional) + * + * This class represents an expression of either a fixed-size or dynamic-size block. It is the return + * type of DenseBase::block(Index,Index,Index,Index) and DenseBase::block(Index,Index) and + * most of the time this is the only way it is used. + * + * However, if you want to directly maniputate block expressions, + * for instance if you want to write a function returning such an expression, you + * will need to use this class. + * + * Here is an example illustrating the dynamic case: + * \include class_Block.cpp + * Output: \verbinclude class_Block.out + * + * \note Even though this expression has dynamic size, in the case where \a XprType + * has fixed size, this expression inherits a fixed maximal size which means that evaluating + * it does not cause a dynamic memory allocation. + * + * Here is an example illustrating the fixed-size case: + * \include class_FixedBlock.cpp + * Output: \verbinclude class_FixedBlock.out + * + * \sa DenseBase::block(Index,Index,Index,Index), DenseBase::block(Index,Index), class VectorBlock + */ + +namespace internal { +template +struct traits > : traits +{ + typedef typename traits::Scalar Scalar; + typedef typename traits::StorageKind StorageKind; + typedef typename traits::XprKind XprKind; + typedef typename nested::type XprTypeNested; + typedef typename remove_reference::type _XprTypeNested; + enum{ + MatrixRows = traits::RowsAtCompileTime, + MatrixCols = traits::ColsAtCompileTime, + RowsAtCompileTime = MatrixRows == 0 ? 0 : BlockRows, + ColsAtCompileTime = MatrixCols == 0 ? 0 : BlockCols, + MaxRowsAtCompileTime = BlockRows==0 ? 0 + : RowsAtCompileTime != Dynamic ? int(RowsAtCompileTime) + : int(traits::MaxRowsAtCompileTime), + MaxColsAtCompileTime = BlockCols==0 ? 0 + : ColsAtCompileTime != Dynamic ? int(ColsAtCompileTime) + : int(traits::MaxColsAtCompileTime), + XprTypeIsRowMajor = (int(traits::Flags)&RowMajorBit) != 0, + IsDense = is_same::value, + IsRowMajor = (IsDense&&MaxRowsAtCompileTime==1&&MaxColsAtCompileTime!=1) ? 1 + : (IsDense&&MaxColsAtCompileTime==1&&MaxRowsAtCompileTime!=1) ? 0 + : XprTypeIsRowMajor, + HasSameStorageOrderAsXprType = (IsRowMajor == XprTypeIsRowMajor), + InnerSize = IsRowMajor ? int(ColsAtCompileTime) : int(RowsAtCompileTime), + InnerStrideAtCompileTime = HasSameStorageOrderAsXprType + ? int(inner_stride_at_compile_time::ret) + : int(outer_stride_at_compile_time::ret), + OuterStrideAtCompileTime = HasSameStorageOrderAsXprType + ? int(outer_stride_at_compile_time::ret) + : int(inner_stride_at_compile_time::ret), + MaskPacketAccessBit = (InnerSize == Dynamic || (InnerSize % packet_traits::size) == 0) + && (InnerStrideAtCompileTime == 1) + ? PacketAccessBit : 0, + MaskAlignedBit = (InnerPanel && (OuterStrideAtCompileTime!=Dynamic) && (((OuterStrideAtCompileTime * int(sizeof(Scalar))) % 16) == 0)) ? AlignedBit : 0, + FlagsLinearAccessBit = (RowsAtCompileTime == 1 || ColsAtCompileTime == 1 || (InnerPanel && (traits::Flags&LinearAccessBit))) ? LinearAccessBit : 0, + FlagsLvalueBit = is_lvalue::value ? LvalueBit : 0, + FlagsRowMajorBit = IsRowMajor ? RowMajorBit : 0, + Flags0 = traits::Flags & ( (HereditaryBits & ~RowMajorBit) | + DirectAccessBit | + MaskPacketAccessBit | + MaskAlignedBit), + Flags = Flags0 | FlagsLinearAccessBit | FlagsLvalueBit | FlagsRowMajorBit + }; +}; + +template::ret> class BlockImpl_dense; + +} // end namespace internal + +template class BlockImpl; + +template class Block + : public BlockImpl::StorageKind> +{ + typedef BlockImpl::StorageKind> Impl; + public: + //typedef typename Impl::Base Base; + typedef Impl Base; + EIGEN_GENERIC_PUBLIC_INTERFACE(Block) + EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Block) + + /** Column or Row constructor + */ + inline Block(XprType& xpr, Index i) : Impl(xpr,i) + { + eigen_assert( (i>=0) && ( + ((BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) && i= 0 && BlockRows >= 1 && a_startRow + BlockRows <= xpr.rows() + && a_startCol >= 0 && BlockCols >= 1 && a_startCol + BlockCols <= xpr.cols()); + } + + /** Dynamic-size constructor + */ + inline Block(XprType& xpr, + Index a_startRow, Index a_startCol, + Index blockRows, Index blockCols) + : Impl(xpr, a_startRow, a_startCol, blockRows, blockCols) + { + eigen_assert((RowsAtCompileTime==Dynamic || RowsAtCompileTime==blockRows) + && (ColsAtCompileTime==Dynamic || ColsAtCompileTime==blockCols)); + eigen_assert(a_startRow >= 0 && blockRows >= 0 && a_startRow <= xpr.rows() - blockRows + && a_startCol >= 0 && blockCols >= 0 && a_startCol <= xpr.cols() - blockCols); + } +}; + +// The generic default implementation for dense block simplu forward to the internal::BlockImpl_dense +// that must be specialized for direct and non-direct access... +template +class BlockImpl + : public internal::BlockImpl_dense +{ + typedef internal::BlockImpl_dense Impl; + typedef typename XprType::Index Index; + public: + typedef Impl Base; + EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl) + inline BlockImpl(XprType& xpr, Index i) : Impl(xpr,i) {} + inline BlockImpl(XprType& xpr, Index a_startRow, Index a_startCol) : Impl(xpr, a_startRow, a_startCol) {} + inline BlockImpl(XprType& xpr, Index a_startRow, Index a_startCol, Index blockRows, Index blockCols) + : Impl(xpr, a_startRow, a_startCol, blockRows, blockCols) {} +}; + +namespace internal { + +/** \internal Internal implementation of dense Blocks in the general case. */ +template class BlockImpl_dense + : public internal::dense_xpr_base >::type +{ + typedef Block BlockType; + public: + + typedef typename internal::dense_xpr_base::type Base; + EIGEN_DENSE_PUBLIC_INTERFACE(BlockType) + EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl_dense) + + class InnerIterator; + + /** Column or Row constructor + */ + inline BlockImpl_dense(XprType& xpr, Index i) + : m_xpr(xpr), + // It is a row if and only if BlockRows==1 and BlockCols==XprType::ColsAtCompileTime, + // and it is a column if and only if BlockRows==XprType::RowsAtCompileTime and BlockCols==1, + // all other cases are invalid. + // The case a 1x1 matrix seems ambiguous, but the result is the same anyway. + m_startRow( (BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) ? i : 0), + m_startCol( (BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) ? i : 0), + m_blockRows(BlockRows==1 ? 1 : xpr.rows()), + m_blockCols(BlockCols==1 ? 1 : xpr.cols()) + {} + + /** Fixed-size constructor + */ + inline BlockImpl_dense(XprType& xpr, Index a_startRow, Index a_startCol) + : m_xpr(xpr), m_startRow(a_startRow), m_startCol(a_startCol), + m_blockRows(BlockRows), m_blockCols(BlockCols) + {} + + /** Dynamic-size constructor + */ + inline BlockImpl_dense(XprType& xpr, + Index a_startRow, Index a_startCol, + Index blockRows, Index blockCols) + : m_xpr(xpr), m_startRow(a_startRow), m_startCol(a_startCol), + m_blockRows(blockRows), m_blockCols(blockCols) + {} + + inline Index rows() const { return m_blockRows.value(); } + inline Index cols() const { return m_blockCols.value(); } + + inline Scalar& coeffRef(Index rowId, Index colId) + { + EIGEN_STATIC_ASSERT_LVALUE(XprType) + return m_xpr.const_cast_derived() + .coeffRef(rowId + m_startRow.value(), colId + m_startCol.value()); + } + + inline const Scalar& coeffRef(Index rowId, Index colId) const + { + return m_xpr.derived() + .coeffRef(rowId + m_startRow.value(), colId + m_startCol.value()); + } + + EIGEN_STRONG_INLINE const CoeffReturnType coeff(Index rowId, Index colId) const + { + return m_xpr.coeff(rowId + m_startRow.value(), colId + m_startCol.value()); + } + + inline Scalar& coeffRef(Index index) + { + EIGEN_STATIC_ASSERT_LVALUE(XprType) + return m_xpr.const_cast_derived() + .coeffRef(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index), + m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0)); + } + + inline const Scalar& coeffRef(Index index) const + { + return m_xpr.const_cast_derived() + .coeffRef(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index), + m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0)); + } + + inline const CoeffReturnType coeff(Index index) const + { + return m_xpr + .coeff(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index), + m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0)); + } + + template + inline PacketScalar packet(Index rowId, Index colId) const + { + return m_xpr.template packet + (rowId + m_startRow.value(), colId + m_startCol.value()); + } + + template + inline void writePacket(Index rowId, Index colId, const PacketScalar& val) + { + m_xpr.const_cast_derived().template writePacket + (rowId + m_startRow.value(), colId + m_startCol.value(), val); + } + + template + inline PacketScalar packet(Index index) const + { + return m_xpr.template packet + (m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index), + m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0)); + } + + template + inline void writePacket(Index index, const PacketScalar& val) + { + m_xpr.const_cast_derived().template writePacket + (m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index), + m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0), val); + } + + #ifdef EIGEN_PARSED_BY_DOXYGEN + /** \sa MapBase::data() */ + inline const Scalar* data() const; + inline Index innerStride() const; + inline Index outerStride() const; + #endif + + const typename internal::remove_all::type& nestedExpression() const + { + return m_xpr; + } + + Index startRow() const + { + return m_startRow.value(); + } + + Index startCol() const + { + return m_startCol.value(); + } + + protected: + + const typename XprType::Nested m_xpr; + const internal::variable_if_dynamic m_startRow; + const internal::variable_if_dynamic m_startCol; + const internal::variable_if_dynamic m_blockRows; + const internal::variable_if_dynamic m_blockCols; +}; + +/** \internal Internal implementation of dense Blocks in the direct access case.*/ +template +class BlockImpl_dense + : public MapBase > +{ + typedef Block BlockType; + public: + + typedef MapBase Base; + EIGEN_DENSE_PUBLIC_INTERFACE(BlockType) + EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl_dense) + + /** Column or Row constructor + */ + inline BlockImpl_dense(XprType& xpr, Index i) + : Base(internal::const_cast_ptr(&xpr.coeffRef( + (BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) ? i : 0, + (BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) ? i : 0)), + BlockRows==1 ? 1 : xpr.rows(), + BlockCols==1 ? 1 : xpr.cols()), + m_xpr(xpr) + { + init(); + } + + /** Fixed-size constructor + */ + inline BlockImpl_dense(XprType& xpr, Index startRow, Index startCol) + : Base(internal::const_cast_ptr(&xpr.coeffRef(startRow,startCol))), m_xpr(xpr) + { + init(); + } + + /** Dynamic-size constructor + */ + inline BlockImpl_dense(XprType& xpr, + Index startRow, Index startCol, + Index blockRows, Index blockCols) + : Base(internal::const_cast_ptr(&xpr.coeffRef(startRow,startCol)), blockRows, blockCols), + m_xpr(xpr) + { + init(); + } + + const typename internal::remove_all::type& nestedExpression() const + { + return m_xpr; + } + + /** \sa MapBase::innerStride() */ + inline Index innerStride() const + { + return internal::traits::HasSameStorageOrderAsXprType + ? m_xpr.innerStride() + : m_xpr.outerStride(); + } + + /** \sa MapBase::outerStride() */ + inline Index outerStride() const + { + return m_outerStride; + } + + #ifndef __SUNPRO_CC + // FIXME sunstudio is not friendly with the above friend... + // META-FIXME there is no 'friend' keyword around here. Is this obsolete? + protected: + #endif + + #ifndef EIGEN_PARSED_BY_DOXYGEN + /** \internal used by allowAligned() */ + inline BlockImpl_dense(XprType& xpr, const Scalar* data, Index blockRows, Index blockCols) + : Base(data, blockRows, blockCols), m_xpr(xpr) + { + init(); + } + #endif + + protected: + void init() + { + m_outerStride = internal::traits::HasSameStorageOrderAsXprType + ? m_xpr.outerStride() + : m_xpr.innerStride(); + } + + typename XprType::Nested m_xpr; + Index m_outerStride; +}; + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_BLOCK_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/BooleanRedux.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/BooleanRedux.h new file mode 100644 index 00000000..be9f48a8 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/BooleanRedux.h @@ -0,0 +1,154 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_ALLANDANY_H +#define EIGEN_ALLANDANY_H + +namespace Eigen { + +namespace internal { + +template +struct all_unroller +{ + enum { + col = (UnrollCount-1) / Derived::RowsAtCompileTime, + row = (UnrollCount-1) % Derived::RowsAtCompileTime + }; + + static inline bool run(const Derived &mat) + { + return all_unroller::run(mat) && mat.coeff(row, col); + } +}; + +template +struct all_unroller +{ + static inline bool run(const Derived &/*mat*/) { return true; } +}; + +template +struct all_unroller +{ + static inline bool run(const Derived &) { return false; } +}; + +template +struct any_unroller +{ + enum { + col = (UnrollCount-1) / Derived::RowsAtCompileTime, + row = (UnrollCount-1) % Derived::RowsAtCompileTime + }; + + static inline bool run(const Derived &mat) + { + return any_unroller::run(mat) || mat.coeff(row, col); + } +}; + +template +struct any_unroller +{ + static inline bool run(const Derived & /*mat*/) { return false; } +}; + +template +struct any_unroller +{ + static inline bool run(const Derived &) { return false; } +}; + +} // end namespace internal + +/** \returns true if all coefficients are true + * + * Example: \include MatrixBase_all.cpp + * Output: \verbinclude MatrixBase_all.out + * + * \sa any(), Cwise::operator<() + */ +template +inline bool DenseBase::all() const +{ + enum { + unroll = SizeAtCompileTime != Dynamic + && CoeffReadCost != Dynamic + && NumTraits::AddCost != Dynamic + && SizeAtCompileTime * (CoeffReadCost + NumTraits::AddCost) <= EIGEN_UNROLLING_LIMIT + }; + if(unroll) + return internal::all_unroller::run(derived()); + else + { + for(Index j = 0; j < cols(); ++j) + for(Index i = 0; i < rows(); ++i) + if (!coeff(i, j)) return false; + return true; + } +} + +/** \returns true if at least one coefficient is true + * + * \sa all() + */ +template +inline bool DenseBase::any() const +{ + enum { + unroll = SizeAtCompileTime != Dynamic + && CoeffReadCost != Dynamic + && NumTraits::AddCost != Dynamic + && SizeAtCompileTime * (CoeffReadCost + NumTraits::AddCost) <= EIGEN_UNROLLING_LIMIT + }; + if(unroll) + return internal::any_unroller::run(derived()); + else + { + for(Index j = 0; j < cols(); ++j) + for(Index i = 0; i < rows(); ++i) + if (coeff(i, j)) return true; + return false; + } +} + +/** \returns the number of coefficients which evaluate to true + * + * \sa all(), any() + */ +template +inline typename DenseBase::Index DenseBase::count() const +{ + return derived().template cast().template cast().sum(); +} + +/** \returns true is \c *this contains at least one Not A Number (NaN). + * + * \sa allFinite() + */ +template +inline bool DenseBase::hasNaN() const +{ + return !((derived().array()==derived().array()).all()); +} + +/** \returns true if \c *this contains only finite numbers, i.e., no NaN and no +/-INF values. + * + * \sa hasNaN() + */ +template +inline bool DenseBase::allFinite() const +{ + return !((derived()-derived()).hasNaN()); +} + +} // end namespace Eigen + +#endif // EIGEN_ALLANDANY_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/CommaInitializer.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/CommaInitializer.h new file mode 100644 index 00000000..a036d8c3 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/CommaInitializer.h @@ -0,0 +1,154 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008 Gael Guennebaud +// Copyright (C) 2006-2008 Benoit Jacob +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_COMMAINITIALIZER_H +#define EIGEN_COMMAINITIALIZER_H + +namespace Eigen { + +/** \class CommaInitializer + * \ingroup Core_Module + * + * \brief Helper class used by the comma initializer operator + * + * This class is internally used to implement the comma initializer feature. It is + * the return type of MatrixBase::operator<<, and most of the time this is the only + * way it is used. + * + * \sa \ref MatrixBaseCommaInitRef "MatrixBase::operator<<", CommaInitializer::finished() + */ +template +struct CommaInitializer +{ + typedef typename XprType::Scalar Scalar; + typedef typename XprType::Index Index; + + inline CommaInitializer(XprType& xpr, const Scalar& s) + : m_xpr(xpr), m_row(0), m_col(1), m_currentBlockRows(1) + { + m_xpr.coeffRef(0,0) = s; + } + + template + inline CommaInitializer(XprType& xpr, const DenseBase& other) + : m_xpr(xpr), m_row(0), m_col(other.cols()), m_currentBlockRows(other.rows()) + { + m_xpr.block(0, 0, other.rows(), other.cols()) = other; + } + + /* Copy/Move constructor which transfers ownership. This is crucial in + * absence of return value optimization to avoid assertions during destruction. */ + // FIXME in C++11 mode this could be replaced by a proper RValue constructor + inline CommaInitializer(const CommaInitializer& o) + : m_xpr(o.m_xpr), m_row(o.m_row), m_col(o.m_col), m_currentBlockRows(o.m_currentBlockRows) { + // Mark original object as finished. In absence of R-value references we need to const_cast: + const_cast(o).m_row = m_xpr.rows(); + const_cast(o).m_col = m_xpr.cols(); + const_cast(o).m_currentBlockRows = 0; + } + + /* inserts a scalar value in the target matrix */ + CommaInitializer& operator,(const Scalar& s) + { + if (m_col==m_xpr.cols()) + { + m_row+=m_currentBlockRows; + m_col = 0; + m_currentBlockRows = 1; + eigen_assert(m_row + CommaInitializer& operator,(const DenseBase& other) + { + if(other.cols()==0 || other.rows()==0) + return *this; + if (m_col==m_xpr.cols()) + { + m_row+=m_currentBlockRows; + m_col = 0; + m_currentBlockRows = other.rows(); + eigen_assert(m_row+m_currentBlockRows<=m_xpr.rows() + && "Too many rows passed to comma initializer (operator<<)"); + } + eigen_assert(m_col + (m_row, m_col) = other; + else + m_xpr.block(m_row, m_col, other.rows(), other.cols()) = other; + m_col += other.cols(); + return *this; + } + + inline ~CommaInitializer() + { + eigen_assert((m_row+m_currentBlockRows) == m_xpr.rows() + && m_col == m_xpr.cols() + && "Too few coefficients passed to comma initializer (operator<<)"); + } + + /** \returns the built matrix once all its coefficients have been set. + * Calling finished is 100% optional. Its purpose is to write expressions + * like this: + * \code + * quaternion.fromRotationMatrix((Matrix3f() << axis0, axis1, axis2).finished()); + * \endcode + */ + inline XprType& finished() { return m_xpr; } + + XprType& m_xpr; // target expression + Index m_row; // current row id + Index m_col; // current col id + Index m_currentBlockRows; // current block height +}; + +/** \anchor MatrixBaseCommaInitRef + * Convenient operator to set the coefficients of a matrix. + * + * The coefficients must be provided in a row major order and exactly match + * the size of the matrix. Otherwise an assertion is raised. + * + * Example: \include MatrixBase_set.cpp + * Output: \verbinclude MatrixBase_set.out + * + * \note According the c++ standard, the argument expressions of this comma initializer are evaluated in arbitrary order. + * + * \sa CommaInitializer::finished(), class CommaInitializer + */ +template +inline CommaInitializer DenseBase::operator<< (const Scalar& s) +{ + return CommaInitializer(*static_cast(this), s); +} + +/** \sa operator<<(const Scalar&) */ +template +template +inline CommaInitializer +DenseBase::operator<<(const DenseBase& other) +{ + return CommaInitializer(*static_cast(this), other); +} + +} // end namespace Eigen + +#endif // EIGEN_COMMAINITIALIZER_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/CoreIterators.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/CoreIterators.h new file mode 100644 index 00000000..6da4683d --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/CoreIterators.h @@ -0,0 +1,61 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008-2010 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_COREITERATORS_H +#define EIGEN_COREITERATORS_H + +namespace Eigen { + +/* This file contains the respective InnerIterator definition of the expressions defined in Eigen/Core + */ + +/** \ingroup SparseCore_Module + * \class InnerIterator + * \brief An InnerIterator allows to loop over the element of a sparse (or dense) matrix or expression + * + * todo + */ + +// generic version for dense matrix and expressions +template class DenseBase::InnerIterator +{ + protected: + typedef typename Derived::Scalar Scalar; + typedef typename Derived::Index Index; + + enum { IsRowMajor = (Derived::Flags&RowMajorBit)==RowMajorBit }; + public: + EIGEN_STRONG_INLINE InnerIterator(const Derived& expr, Index outer) + : m_expression(expr), m_inner(0), m_outer(outer), m_end(expr.innerSize()) + {} + + EIGEN_STRONG_INLINE Scalar value() const + { + return (IsRowMajor) ? m_expression.coeff(m_outer, m_inner) + : m_expression.coeff(m_inner, m_outer); + } + + EIGEN_STRONG_INLINE InnerIterator& operator++() { m_inner++; return *this; } + + EIGEN_STRONG_INLINE Index index() const { return m_inner; } + inline Index row() const { return IsRowMajor ? m_outer : index(); } + inline Index col() const { return IsRowMajor ? index() : m_outer; } + + EIGEN_STRONG_INLINE operator bool() const { return m_inner < m_end && m_inner>=0; } + + protected: + const Derived& m_expression; + Index m_inner; + const Index m_outer; + const Index m_end; +}; + +} // end namespace Eigen + +#endif // EIGEN_COREITERATORS_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/CwiseBinaryOp.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/CwiseBinaryOp.h new file mode 100644 index 00000000..519a866e --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/CwiseBinaryOp.h @@ -0,0 +1,230 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008-2009 Gael Guennebaud +// Copyright (C) 2006-2008 Benoit Jacob +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_CWISE_BINARY_OP_H +#define EIGEN_CWISE_BINARY_OP_H + +namespace Eigen { + +/** \class CwiseBinaryOp + * \ingroup Core_Module + * + * \brief Generic expression where a coefficient-wise binary operator is applied to two expressions + * + * \param BinaryOp template functor implementing the operator + * \param Lhs the type of the left-hand side + * \param Rhs the type of the right-hand side + * + * This class represents an expression where a coefficient-wise binary operator is applied to two expressions. + * It is the return type of binary operators, by which we mean only those binary operators where + * both the left-hand side and the right-hand side are Eigen expressions. + * For example, the return type of matrix1+matrix2 is a CwiseBinaryOp. + * + * Most of the time, this is the only way that it is used, so you typically don't have to name + * CwiseBinaryOp types explicitly. + * + * \sa MatrixBase::binaryExpr(const MatrixBase &,const CustomBinaryOp &) const, class CwiseUnaryOp, class CwiseNullaryOp + */ + +namespace internal { +template +struct traits > +{ + // we must not inherit from traits since it has + // the potential to cause problems with MSVC + typedef typename remove_all::type Ancestor; + typedef typename traits::XprKind XprKind; + enum { + RowsAtCompileTime = traits::RowsAtCompileTime, + ColsAtCompileTime = traits::ColsAtCompileTime, + MaxRowsAtCompileTime = traits::MaxRowsAtCompileTime, + MaxColsAtCompileTime = traits::MaxColsAtCompileTime + }; + + // even though we require Lhs and Rhs to have the same scalar type (see CwiseBinaryOp constructor), + // we still want to handle the case when the result type is different. + typedef typename result_of< + BinaryOp( + typename Lhs::Scalar, + typename Rhs::Scalar + ) + >::type Scalar; + typedef typename promote_storage_type::StorageKind, + typename traits::StorageKind>::ret StorageKind; + typedef typename promote_index_type::Index, + typename traits::Index>::type Index; + typedef typename Lhs::Nested LhsNested; + typedef typename Rhs::Nested RhsNested; + typedef typename remove_reference::type _LhsNested; + typedef typename remove_reference::type _RhsNested; + enum { + LhsCoeffReadCost = _LhsNested::CoeffReadCost, + RhsCoeffReadCost = _RhsNested::CoeffReadCost, + LhsFlags = _LhsNested::Flags, + RhsFlags = _RhsNested::Flags, + SameType = is_same::value, + StorageOrdersAgree = (int(Lhs::Flags)&RowMajorBit)==(int(Rhs::Flags)&RowMajorBit), + Flags0 = (int(LhsFlags) | int(RhsFlags)) & ( + HereditaryBits + | (int(LhsFlags) & int(RhsFlags) & + ( AlignedBit + | (StorageOrdersAgree ? LinearAccessBit : 0) + | (functor_traits::PacketAccess && StorageOrdersAgree && SameType ? PacketAccessBit : 0) + ) + ) + ), + Flags = (Flags0 & ~RowMajorBit) | (LhsFlags & RowMajorBit), + Cost0 = EIGEN_ADD_COST(LhsCoeffReadCost,RhsCoeffReadCost), + CoeffReadCost = EIGEN_ADD_COST(Cost0,functor_traits::Cost) + }; +}; +} // end namespace internal + +// we require Lhs and Rhs to have the same scalar type. Currently there is no example of a binary functor +// that would take two operands of different types. If there were such an example, then this check should be +// moved to the BinaryOp functors, on a per-case basis. This would however require a change in the BinaryOp functors, as +// currently they take only one typename Scalar template parameter. +// It is tempting to always allow mixing different types but remember that this is often impossible in the vectorized paths. +// So allowing mixing different types gives very unexpected errors when enabling vectorization, when the user tries to +// add together a float matrix and a double matrix. +#define EIGEN_CHECK_BINARY_COMPATIBILIY(BINOP,LHS,RHS) \ + EIGEN_STATIC_ASSERT((internal::functor_is_product_like::ret \ + ? int(internal::scalar_product_traits::Defined) \ + : int(internal::is_same::value)), \ + YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) + +template +class CwiseBinaryOpImpl; + +template +class CwiseBinaryOp : internal::no_assignment_operator, + public CwiseBinaryOpImpl< + BinaryOp, Lhs, Rhs, + typename internal::promote_storage_type::StorageKind, + typename internal::traits::StorageKind>::ret> +{ + public: + + typedef typename CwiseBinaryOpImpl< + BinaryOp, Lhs, Rhs, + typename internal::promote_storage_type::StorageKind, + typename internal::traits::StorageKind>::ret>::Base Base; + EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseBinaryOp) + + typedef typename internal::nested::type LhsNested; + typedef typename internal::nested::type RhsNested; + typedef typename internal::remove_reference::type _LhsNested; + typedef typename internal::remove_reference::type _RhsNested; + + EIGEN_STRONG_INLINE CwiseBinaryOp(const Lhs& aLhs, const Rhs& aRhs, const BinaryOp& func = BinaryOp()) + : m_lhs(aLhs), m_rhs(aRhs), m_functor(func) + { + EIGEN_CHECK_BINARY_COMPATIBILIY(BinaryOp,typename Lhs::Scalar,typename Rhs::Scalar); + // require the sizes to match + EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Lhs, Rhs) + eigen_assert(aLhs.rows() == aRhs.rows() && aLhs.cols() == aRhs.cols()); + } + + EIGEN_STRONG_INLINE Index rows() const { + // return the fixed size type if available to enable compile time optimizations + if (internal::traits::type>::RowsAtCompileTime==Dynamic) + return m_rhs.rows(); + else + return m_lhs.rows(); + } + EIGEN_STRONG_INLINE Index cols() const { + // return the fixed size type if available to enable compile time optimizations + if (internal::traits::type>::ColsAtCompileTime==Dynamic) + return m_rhs.cols(); + else + return m_lhs.cols(); + } + + /** \returns the left hand side nested expression */ + const _LhsNested& lhs() const { return m_lhs; } + /** \returns the right hand side nested expression */ + const _RhsNested& rhs() const { return m_rhs; } + /** \returns the functor representing the binary operation */ + const BinaryOp& functor() const { return m_functor; } + + protected: + LhsNested m_lhs; + RhsNested m_rhs; + const BinaryOp m_functor; +}; + +template +class CwiseBinaryOpImpl + : public internal::dense_xpr_base >::type +{ + typedef CwiseBinaryOp Derived; + public: + + typedef typename internal::dense_xpr_base >::type Base; + EIGEN_DENSE_PUBLIC_INTERFACE( Derived ) + + EIGEN_STRONG_INLINE const Scalar coeff(Index rowId, Index colId) const + { + return derived().functor()(derived().lhs().coeff(rowId, colId), + derived().rhs().coeff(rowId, colId)); + } + + template + EIGEN_STRONG_INLINE PacketScalar packet(Index rowId, Index colId) const + { + return derived().functor().packetOp(derived().lhs().template packet(rowId, colId), + derived().rhs().template packet(rowId, colId)); + } + + EIGEN_STRONG_INLINE const Scalar coeff(Index index) const + { + return derived().functor()(derived().lhs().coeff(index), + derived().rhs().coeff(index)); + } + + template + EIGEN_STRONG_INLINE PacketScalar packet(Index index) const + { + return derived().functor().packetOp(derived().lhs().template packet(index), + derived().rhs().template packet(index)); + } +}; + +/** replaces \c *this by \c *this - \a other. + * + * \returns a reference to \c *this + */ +template +template +EIGEN_STRONG_INLINE Derived & +MatrixBase::operator-=(const MatrixBase &other) +{ + SelfCwiseBinaryOp, Derived, OtherDerived> tmp(derived()); + tmp = other.derived(); + return derived(); +} + +/** replaces \c *this by \c *this + \a other. + * + * \returns a reference to \c *this + */ +template +template +EIGEN_STRONG_INLINE Derived & +MatrixBase::operator+=(const MatrixBase& other) +{ + SelfCwiseBinaryOp, Derived, OtherDerived> tmp(derived()); + tmp = other.derived(); + return derived(); +} + +} // end namespace Eigen + +#endif // EIGEN_CWISE_BINARY_OP_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/CwiseNullaryOp.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/CwiseNullaryOp.h new file mode 100644 index 00000000..a93bab2d --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/CwiseNullaryOp.h @@ -0,0 +1,864 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008-2010 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_CWISE_NULLARY_OP_H +#define EIGEN_CWISE_NULLARY_OP_H + +namespace Eigen { + +/** \class CwiseNullaryOp + * \ingroup Core_Module + * + * \brief Generic expression of a matrix where all coefficients are defined by a functor + * + * \param NullaryOp template functor implementing the operator + * \param PlainObjectType the underlying plain matrix/array type + * + * This class represents an expression of a generic nullary operator. + * It is the return type of the Ones(), Zero(), Constant(), Identity() and Random() methods, + * and most of the time this is the only way it is used. + * + * However, if you want to write a function returning such an expression, you + * will need to use this class. + * + * \sa class CwiseUnaryOp, class CwiseBinaryOp, DenseBase::NullaryExpr() + */ + +namespace internal { +template +struct traits > : traits +{ + enum { + Flags = (traits::Flags + & ( HereditaryBits + | (functor_has_linear_access::ret ? LinearAccessBit : 0) + | (functor_traits::PacketAccess ? PacketAccessBit : 0))) + | (functor_traits::IsRepeatable ? 0 : EvalBeforeNestingBit), + CoeffReadCost = functor_traits::Cost + }; +}; +} + +template +class CwiseNullaryOp : internal::no_assignment_operator, + public internal::dense_xpr_base< CwiseNullaryOp >::type +{ + public: + + typedef typename internal::dense_xpr_base::type Base; + EIGEN_DENSE_PUBLIC_INTERFACE(CwiseNullaryOp) + + CwiseNullaryOp(Index nbRows, Index nbCols, const NullaryOp& func = NullaryOp()) + : m_rows(nbRows), m_cols(nbCols), m_functor(func) + { + eigen_assert(nbRows >= 0 + && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == nbRows) + && nbCols >= 0 + && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == nbCols)); + } + + EIGEN_STRONG_INLINE Index rows() const { return m_rows.value(); } + EIGEN_STRONG_INLINE Index cols() const { return m_cols.value(); } + + EIGEN_STRONG_INLINE const Scalar coeff(Index rowId, Index colId) const + { + return m_functor(rowId, colId); + } + + template + EIGEN_STRONG_INLINE PacketScalar packet(Index rowId, Index colId) const + { + return m_functor.packetOp(rowId, colId); + } + + EIGEN_STRONG_INLINE const Scalar coeff(Index index) const + { + return m_functor(index); + } + + template + EIGEN_STRONG_INLINE PacketScalar packet(Index index) const + { + return m_functor.packetOp(index); + } + + /** \returns the functor representing the nullary operation */ + const NullaryOp& functor() const { return m_functor; } + + protected: + const internal::variable_if_dynamic m_rows; + const internal::variable_if_dynamic m_cols; + const NullaryOp m_functor; +}; + + +/** \returns an expression of a matrix defined by a custom functor \a func + * + * The parameters \a rows and \a cols are the number of rows and of columns of + * the returned matrix. Must be compatible with this MatrixBase type. + * + * This variant is meant to be used for dynamic-size matrix types. For fixed-size types, + * it is redundant to pass \a rows and \a cols as arguments, so Zero() should be used + * instead. + * + * The template parameter \a CustomNullaryOp is the type of the functor. + * + * \sa class CwiseNullaryOp + */ +template +template +EIGEN_STRONG_INLINE const CwiseNullaryOp +DenseBase::NullaryExpr(Index rows, Index cols, const CustomNullaryOp& func) +{ + return CwiseNullaryOp(rows, cols, func); +} + +/** \returns an expression of a matrix defined by a custom functor \a func + * + * The parameter \a size is the size of the returned vector. + * Must be compatible with this MatrixBase type. + * + * \only_for_vectors + * + * This variant is meant to be used for dynamic-size vector types. For fixed-size types, + * it is redundant to pass \a size as argument, so Zero() should be used + * instead. + * + * The template parameter \a CustomNullaryOp is the type of the functor. + * + * \sa class CwiseNullaryOp + */ +template +template +EIGEN_STRONG_INLINE const CwiseNullaryOp +DenseBase::NullaryExpr(Index size, const CustomNullaryOp& func) +{ + EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) + if(RowsAtCompileTime == 1) return CwiseNullaryOp(1, size, func); + else return CwiseNullaryOp(size, 1, func); +} + +/** \returns an expression of a matrix defined by a custom functor \a func + * + * This variant is only for fixed-size DenseBase types. For dynamic-size types, you + * need to use the variants taking size arguments. + * + * The template parameter \a CustomNullaryOp is the type of the functor. + * + * \sa class CwiseNullaryOp + */ +template +template +EIGEN_STRONG_INLINE const CwiseNullaryOp +DenseBase::NullaryExpr(const CustomNullaryOp& func) +{ + return CwiseNullaryOp(RowsAtCompileTime, ColsAtCompileTime, func); +} + +/** \returns an expression of a constant matrix of value \a value + * + * The parameters \a nbRows and \a nbCols are the number of rows and of columns of + * the returned matrix. Must be compatible with this DenseBase type. + * + * This variant is meant to be used for dynamic-size matrix types. For fixed-size types, + * it is redundant to pass \a nbRows and \a nbCols as arguments, so Zero() should be used + * instead. + * + * The template parameter \a CustomNullaryOp is the type of the functor. + * + * \sa class CwiseNullaryOp + */ +template +EIGEN_STRONG_INLINE const typename DenseBase::ConstantReturnType +DenseBase::Constant(Index nbRows, Index nbCols, const Scalar& value) +{ + return DenseBase::NullaryExpr(nbRows, nbCols, internal::scalar_constant_op(value)); +} + +/** \returns an expression of a constant matrix of value \a value + * + * The parameter \a size is the size of the returned vector. + * Must be compatible with this DenseBase type. + * + * \only_for_vectors + * + * This variant is meant to be used for dynamic-size vector types. For fixed-size types, + * it is redundant to pass \a size as argument, so Zero() should be used + * instead. + * + * The template parameter \a CustomNullaryOp is the type of the functor. + * + * \sa class CwiseNullaryOp + */ +template +EIGEN_STRONG_INLINE const typename DenseBase::ConstantReturnType +DenseBase::Constant(Index size, const Scalar& value) +{ + return DenseBase::NullaryExpr(size, internal::scalar_constant_op(value)); +} + +/** \returns an expression of a constant matrix of value \a value + * + * This variant is only for fixed-size DenseBase types. For dynamic-size types, you + * need to use the variants taking size arguments. + * + * The template parameter \a CustomNullaryOp is the type of the functor. + * + * \sa class CwiseNullaryOp + */ +template +EIGEN_STRONG_INLINE const typename DenseBase::ConstantReturnType +DenseBase::Constant(const Scalar& value) +{ + EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived) + return DenseBase::NullaryExpr(RowsAtCompileTime, ColsAtCompileTime, internal::scalar_constant_op(value)); +} + +/** + * \brief Sets a linearly space vector. + * + * The function generates 'size' equally spaced values in the closed interval [low,high]. + * This particular version of LinSpaced() uses sequential access, i.e. vector access is + * assumed to be a(0), a(1), ..., a(size). This assumption allows for better vectorization + * and yields faster code than the random access version. + * + * When size is set to 1, a vector of length 1 containing 'high' is returned. + * + * \only_for_vectors + * + * Example: \include DenseBase_LinSpaced_seq.cpp + * Output: \verbinclude DenseBase_LinSpaced_seq.out + * + * \sa setLinSpaced(Index,const Scalar&,const Scalar&), LinSpaced(Index,Scalar,Scalar), CwiseNullaryOp + */ +template +EIGEN_STRONG_INLINE const typename DenseBase::SequentialLinSpacedReturnType +DenseBase::LinSpaced(Sequential_t, Index size, const Scalar& low, const Scalar& high) +{ + EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) + return DenseBase::NullaryExpr(size, internal::linspaced_op(low,high,size)); +} + +/** + * \copydoc DenseBase::LinSpaced(Sequential_t, Index, const Scalar&, const Scalar&) + * Special version for fixed size types which does not require the size parameter. + */ +template +EIGEN_STRONG_INLINE const typename DenseBase::SequentialLinSpacedReturnType +DenseBase::LinSpaced(Sequential_t, const Scalar& low, const Scalar& high) +{ + EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) + EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived) + return DenseBase::NullaryExpr(Derived::SizeAtCompileTime, internal::linspaced_op(low,high,Derived::SizeAtCompileTime)); +} + +/** + * \brief Sets a linearly space vector. + * + * The function generates 'size' equally spaced values in the closed interval [low,high]. + * When size is set to 1, a vector of length 1 containing 'high' is returned. + * + * \only_for_vectors + * + * Example: \include DenseBase_LinSpaced.cpp + * Output: \verbinclude DenseBase_LinSpaced.out + * + * \sa setLinSpaced(Index,const Scalar&,const Scalar&), LinSpaced(Sequential_t,Index,const Scalar&,const Scalar&,Index), CwiseNullaryOp + */ +template +EIGEN_STRONG_INLINE const typename DenseBase::RandomAccessLinSpacedReturnType +DenseBase::LinSpaced(Index size, const Scalar& low, const Scalar& high) +{ + EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) + return DenseBase::NullaryExpr(size, internal::linspaced_op(low,high,size)); +} + +/** + * \copydoc DenseBase::LinSpaced(Index, const Scalar&, const Scalar&) + * Special version for fixed size types which does not require the size parameter. + */ +template +EIGEN_STRONG_INLINE const typename DenseBase::RandomAccessLinSpacedReturnType +DenseBase::LinSpaced(const Scalar& low, const Scalar& high) +{ + EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) + EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived) + return DenseBase::NullaryExpr(Derived::SizeAtCompileTime, internal::linspaced_op(low,high,Derived::SizeAtCompileTime)); +} + +/** \returns true if all coefficients in this matrix are approximately equal to \a val, to within precision \a prec */ +template +bool DenseBase::isApproxToConstant +(const Scalar& val, const RealScalar& prec) const +{ + for(Index j = 0; j < cols(); ++j) + for(Index i = 0; i < rows(); ++i) + if(!internal::isApprox(this->coeff(i, j), val, prec)) + return false; + return true; +} + +/** This is just an alias for isApproxToConstant(). + * + * \returns true if all coefficients in this matrix are approximately equal to \a value, to within precision \a prec */ +template +bool DenseBase::isConstant +(const Scalar& val, const RealScalar& prec) const +{ + return isApproxToConstant(val, prec); +} + +/** Alias for setConstant(): sets all coefficients in this expression to \a val. + * + * \sa setConstant(), Constant(), class CwiseNullaryOp + */ +template +EIGEN_STRONG_INLINE void DenseBase::fill(const Scalar& val) +{ + setConstant(val); +} + +/** Sets all coefficients in this expression to \a value. + * + * \sa fill(), setConstant(Index,const Scalar&), setConstant(Index,Index,const Scalar&), setZero(), setOnes(), Constant(), class CwiseNullaryOp, setZero(), setOnes() + */ +template +EIGEN_STRONG_INLINE Derived& DenseBase::setConstant(const Scalar& val) +{ + return derived() = Constant(rows(), cols(), val); +} + +/** Resizes to the given \a size, and sets all coefficients in this expression to the given \a value. + * + * \only_for_vectors + * + * Example: \include Matrix_setConstant_int.cpp + * Output: \verbinclude Matrix_setConstant_int.out + * + * \sa MatrixBase::setConstant(const Scalar&), setConstant(Index,Index,const Scalar&), class CwiseNullaryOp, MatrixBase::Constant(const Scalar&) + */ +template +EIGEN_STRONG_INLINE Derived& +PlainObjectBase::setConstant(Index size, const Scalar& val) +{ + resize(size); + return setConstant(val); +} + +/** Resizes to the given size, and sets all coefficients in this expression to the given \a value. + * + * \param nbRows the new number of rows + * \param nbCols the new number of columns + * \param val the value to which all coefficients are set + * + * Example: \include Matrix_setConstant_int_int.cpp + * Output: \verbinclude Matrix_setConstant_int_int.out + * + * \sa MatrixBase::setConstant(const Scalar&), setConstant(Index,const Scalar&), class CwiseNullaryOp, MatrixBase::Constant(const Scalar&) + */ +template +EIGEN_STRONG_INLINE Derived& +PlainObjectBase::setConstant(Index nbRows, Index nbCols, const Scalar& val) +{ + resize(nbRows, nbCols); + return setConstant(val); +} + +/** + * \brief Sets a linearly space vector. + * + * The function generates 'size' equally spaced values in the closed interval [low,high]. + * When size is set to 1, a vector of length 1 containing 'high' is returned. + * + * \only_for_vectors + * + * Example: \include DenseBase_setLinSpaced.cpp + * Output: \verbinclude DenseBase_setLinSpaced.out + * + * \sa CwiseNullaryOp + */ +template +EIGEN_STRONG_INLINE Derived& DenseBase::setLinSpaced(Index newSize, const Scalar& low, const Scalar& high) +{ + EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) + return derived() = Derived::NullaryExpr(newSize, internal::linspaced_op(low,high,newSize)); +} + +/** + * \brief Sets a linearly space vector. + * + * The function fill *this with equally spaced values in the closed interval [low,high]. + * When size is set to 1, a vector of length 1 containing 'high' is returned. + * + * \only_for_vectors + * + * \sa setLinSpaced(Index, const Scalar&, const Scalar&), CwiseNullaryOp + */ +template +EIGEN_STRONG_INLINE Derived& DenseBase::setLinSpaced(const Scalar& low, const Scalar& high) +{ + EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) + return setLinSpaced(size(), low, high); +} + +// zero: + +/** \returns an expression of a zero matrix. + * + * The parameters \a rows and \a cols are the number of rows and of columns of + * the returned matrix. Must be compatible with this MatrixBase type. + * + * This variant is meant to be used for dynamic-size matrix types. For fixed-size types, + * it is redundant to pass \a rows and \a cols as arguments, so Zero() should be used + * instead. + * + * Example: \include MatrixBase_zero_int_int.cpp + * Output: \verbinclude MatrixBase_zero_int_int.out + * + * \sa Zero(), Zero(Index) + */ +template +EIGEN_STRONG_INLINE const typename DenseBase::ConstantReturnType +DenseBase::Zero(Index nbRows, Index nbCols) +{ + return Constant(nbRows, nbCols, Scalar(0)); +} + +/** \returns an expression of a zero vector. + * + * The parameter \a size is the size of the returned vector. + * Must be compatible with this MatrixBase type. + * + * \only_for_vectors + * + * This variant is meant to be used for dynamic-size vector types. For fixed-size types, + * it is redundant to pass \a size as argument, so Zero() should be used + * instead. + * + * Example: \include MatrixBase_zero_int.cpp + * Output: \verbinclude MatrixBase_zero_int.out + * + * \sa Zero(), Zero(Index,Index) + */ +template +EIGEN_STRONG_INLINE const typename DenseBase::ConstantReturnType +DenseBase::Zero(Index size) +{ + return Constant(size, Scalar(0)); +} + +/** \returns an expression of a fixed-size zero matrix or vector. + * + * This variant is only for fixed-size MatrixBase types. For dynamic-size types, you + * need to use the variants taking size arguments. + * + * Example: \include MatrixBase_zero.cpp + * Output: \verbinclude MatrixBase_zero.out + * + * \sa Zero(Index), Zero(Index,Index) + */ +template +EIGEN_STRONG_INLINE const typename DenseBase::ConstantReturnType +DenseBase::Zero() +{ + return Constant(Scalar(0)); +} + +/** \returns true if *this is approximately equal to the zero matrix, + * within the precision given by \a prec. + * + * Example: \include MatrixBase_isZero.cpp + * Output: \verbinclude MatrixBase_isZero.out + * + * \sa class CwiseNullaryOp, Zero() + */ +template +bool DenseBase::isZero(const RealScalar& prec) const +{ + for(Index j = 0; j < cols(); ++j) + for(Index i = 0; i < rows(); ++i) + if(!internal::isMuchSmallerThan(this->coeff(i, j), static_cast(1), prec)) + return false; + return true; +} + +/** Sets all coefficients in this expression to zero. + * + * Example: \include MatrixBase_setZero.cpp + * Output: \verbinclude MatrixBase_setZero.out + * + * \sa class CwiseNullaryOp, Zero() + */ +template +EIGEN_STRONG_INLINE Derived& DenseBase::setZero() +{ + return setConstant(Scalar(0)); +} + +/** Resizes to the given \a size, and sets all coefficients in this expression to zero. + * + * \only_for_vectors + * + * Example: \include Matrix_setZero_int.cpp + * Output: \verbinclude Matrix_setZero_int.out + * + * \sa DenseBase::setZero(), setZero(Index,Index), class CwiseNullaryOp, DenseBase::Zero() + */ +template +EIGEN_STRONG_INLINE Derived& +PlainObjectBase::setZero(Index newSize) +{ + resize(newSize); + return setConstant(Scalar(0)); +} + +/** Resizes to the given size, and sets all coefficients in this expression to zero. + * + * \param nbRows the new number of rows + * \param nbCols the new number of columns + * + * Example: \include Matrix_setZero_int_int.cpp + * Output: \verbinclude Matrix_setZero_int_int.out + * + * \sa DenseBase::setZero(), setZero(Index), class CwiseNullaryOp, DenseBase::Zero() + */ +template +EIGEN_STRONG_INLINE Derived& +PlainObjectBase::setZero(Index nbRows, Index nbCols) +{ + resize(nbRows, nbCols); + return setConstant(Scalar(0)); +} + +// ones: + +/** \returns an expression of a matrix where all coefficients equal one. + * + * The parameters \a nbRows and \a nbCols are the number of rows and of columns of + * the returned matrix. Must be compatible with this MatrixBase type. + * + * This variant is meant to be used for dynamic-size matrix types. For fixed-size types, + * it is redundant to pass \a rows and \a cols as arguments, so Ones() should be used + * instead. + * + * Example: \include MatrixBase_ones_int_int.cpp + * Output: \verbinclude MatrixBase_ones_int_int.out + * + * \sa Ones(), Ones(Index), isOnes(), class Ones + */ +template +EIGEN_STRONG_INLINE const typename DenseBase::ConstantReturnType +DenseBase::Ones(Index nbRows, Index nbCols) +{ + return Constant(nbRows, nbCols, Scalar(1)); +} + +/** \returns an expression of a vector where all coefficients equal one. + * + * The parameter \a newSize is the size of the returned vector. + * Must be compatible with this MatrixBase type. + * + * \only_for_vectors + * + * This variant is meant to be used for dynamic-size vector types. For fixed-size types, + * it is redundant to pass \a size as argument, so Ones() should be used + * instead. + * + * Example: \include MatrixBase_ones_int.cpp + * Output: \verbinclude MatrixBase_ones_int.out + * + * \sa Ones(), Ones(Index,Index), isOnes(), class Ones + */ +template +EIGEN_STRONG_INLINE const typename DenseBase::ConstantReturnType +DenseBase::Ones(Index newSize) +{ + return Constant(newSize, Scalar(1)); +} + +/** \returns an expression of a fixed-size matrix or vector where all coefficients equal one. + * + * This variant is only for fixed-size MatrixBase types. For dynamic-size types, you + * need to use the variants taking size arguments. + * + * Example: \include MatrixBase_ones.cpp + * Output: \verbinclude MatrixBase_ones.out + * + * \sa Ones(Index), Ones(Index,Index), isOnes(), class Ones + */ +template +EIGEN_STRONG_INLINE const typename DenseBase::ConstantReturnType +DenseBase::Ones() +{ + return Constant(Scalar(1)); +} + +/** \returns true if *this is approximately equal to the matrix where all coefficients + * are equal to 1, within the precision given by \a prec. + * + * Example: \include MatrixBase_isOnes.cpp + * Output: \verbinclude MatrixBase_isOnes.out + * + * \sa class CwiseNullaryOp, Ones() + */ +template +bool DenseBase::isOnes +(const RealScalar& prec) const +{ + return isApproxToConstant(Scalar(1), prec); +} + +/** Sets all coefficients in this expression to one. + * + * Example: \include MatrixBase_setOnes.cpp + * Output: \verbinclude MatrixBase_setOnes.out + * + * \sa class CwiseNullaryOp, Ones() + */ +template +EIGEN_STRONG_INLINE Derived& DenseBase::setOnes() +{ + return setConstant(Scalar(1)); +} + +/** Resizes to the given \a newSize, and sets all coefficients in this expression to one. + * + * \only_for_vectors + * + * Example: \include Matrix_setOnes_int.cpp + * Output: \verbinclude Matrix_setOnes_int.out + * + * \sa MatrixBase::setOnes(), setOnes(Index,Index), class CwiseNullaryOp, MatrixBase::Ones() + */ +template +EIGEN_STRONG_INLINE Derived& +PlainObjectBase::setOnes(Index newSize) +{ + resize(newSize); + return setConstant(Scalar(1)); +} + +/** Resizes to the given size, and sets all coefficients in this expression to one. + * + * \param nbRows the new number of rows + * \param nbCols the new number of columns + * + * Example: \include Matrix_setOnes_int_int.cpp + * Output: \verbinclude Matrix_setOnes_int_int.out + * + * \sa MatrixBase::setOnes(), setOnes(Index), class CwiseNullaryOp, MatrixBase::Ones() + */ +template +EIGEN_STRONG_INLINE Derived& +PlainObjectBase::setOnes(Index nbRows, Index nbCols) +{ + resize(nbRows, nbCols); + return setConstant(Scalar(1)); +} + +// Identity: + +/** \returns an expression of the identity matrix (not necessarily square). + * + * The parameters \a nbRows and \a nbCols are the number of rows and of columns of + * the returned matrix. Must be compatible with this MatrixBase type. + * + * This variant is meant to be used for dynamic-size matrix types. For fixed-size types, + * it is redundant to pass \a rows and \a cols as arguments, so Identity() should be used + * instead. + * + * Example: \include MatrixBase_identity_int_int.cpp + * Output: \verbinclude MatrixBase_identity_int_int.out + * + * \sa Identity(), setIdentity(), isIdentity() + */ +template +EIGEN_STRONG_INLINE const typename MatrixBase::IdentityReturnType +MatrixBase::Identity(Index nbRows, Index nbCols) +{ + return DenseBase::NullaryExpr(nbRows, nbCols, internal::scalar_identity_op()); +} + +/** \returns an expression of the identity matrix (not necessarily square). + * + * This variant is only for fixed-size MatrixBase types. For dynamic-size types, you + * need to use the variant taking size arguments. + * + * Example: \include MatrixBase_identity.cpp + * Output: \verbinclude MatrixBase_identity.out + * + * \sa Identity(Index,Index), setIdentity(), isIdentity() + */ +template +EIGEN_STRONG_INLINE const typename MatrixBase::IdentityReturnType +MatrixBase::Identity() +{ + EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived) + return MatrixBase::NullaryExpr(RowsAtCompileTime, ColsAtCompileTime, internal::scalar_identity_op()); +} + +/** \returns true if *this is approximately equal to the identity matrix + * (not necessarily square), + * within the precision given by \a prec. + * + * Example: \include MatrixBase_isIdentity.cpp + * Output: \verbinclude MatrixBase_isIdentity.out + * + * \sa class CwiseNullaryOp, Identity(), Identity(Index,Index), setIdentity() + */ +template +bool MatrixBase::isIdentity +(const RealScalar& prec) const +{ + for(Index j = 0; j < cols(); ++j) + { + for(Index i = 0; i < rows(); ++i) + { + if(i == j) + { + if(!internal::isApprox(this->coeff(i, j), static_cast(1), prec)) + return false; + } + else + { + if(!internal::isMuchSmallerThan(this->coeff(i, j), static_cast(1), prec)) + return false; + } + } + } + return true; +} + +namespace internal { + +template=16)> +struct setIdentity_impl +{ + static EIGEN_STRONG_INLINE Derived& run(Derived& m) + { + return m = Derived::Identity(m.rows(), m.cols()); + } +}; + +template +struct setIdentity_impl +{ + typedef typename Derived::Index Index; + static EIGEN_STRONG_INLINE Derived& run(Derived& m) + { + m.setZero(); + const Index size = (std::min)(m.rows(), m.cols()); + for(Index i = 0; i < size; ++i) m.coeffRef(i,i) = typename Derived::Scalar(1); + return m; + } +}; + +} // end namespace internal + +/** Writes the identity expression (not necessarily square) into *this. + * + * Example: \include MatrixBase_setIdentity.cpp + * Output: \verbinclude MatrixBase_setIdentity.out + * + * \sa class CwiseNullaryOp, Identity(), Identity(Index,Index), isIdentity() + */ +template +EIGEN_STRONG_INLINE Derived& MatrixBase::setIdentity() +{ + return internal::setIdentity_impl::run(derived()); +} + +/** \brief Resizes to the given size, and writes the identity expression (not necessarily square) into *this. + * + * \param nbRows the new number of rows + * \param nbCols the new number of columns + * + * Example: \include Matrix_setIdentity_int_int.cpp + * Output: \verbinclude Matrix_setIdentity_int_int.out + * + * \sa MatrixBase::setIdentity(), class CwiseNullaryOp, MatrixBase::Identity() + */ +template +EIGEN_STRONG_INLINE Derived& MatrixBase::setIdentity(Index nbRows, Index nbCols) +{ + derived().resize(nbRows, nbCols); + return setIdentity(); +} + +/** \returns an expression of the i-th unit (basis) vector. + * + * \only_for_vectors + * + * \sa MatrixBase::Unit(Index), MatrixBase::UnitX(), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW() + */ +template +EIGEN_STRONG_INLINE const typename MatrixBase::BasisReturnType MatrixBase::Unit(Index newSize, Index i) +{ + EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) + return BasisReturnType(SquareMatrixType::Identity(newSize,newSize), i); +} + +/** \returns an expression of the i-th unit (basis) vector. + * + * \only_for_vectors + * + * This variant is for fixed-size vector only. + * + * \sa MatrixBase::Unit(Index,Index), MatrixBase::UnitX(), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW() + */ +template +EIGEN_STRONG_INLINE const typename MatrixBase::BasisReturnType MatrixBase::Unit(Index i) +{ + EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) + return BasisReturnType(SquareMatrixType::Identity(),i); +} + +/** \returns an expression of the X axis unit vector (1{,0}^*) + * + * \only_for_vectors + * + * \sa MatrixBase::Unit(Index,Index), MatrixBase::Unit(Index), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW() + */ +template +EIGEN_STRONG_INLINE const typename MatrixBase::BasisReturnType MatrixBase::UnitX() +{ return Derived::Unit(0); } + +/** \returns an expression of the Y axis unit vector (0,1{,0}^*) + * + * \only_for_vectors + * + * \sa MatrixBase::Unit(Index,Index), MatrixBase::Unit(Index), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW() + */ +template +EIGEN_STRONG_INLINE const typename MatrixBase::BasisReturnType MatrixBase::UnitY() +{ return Derived::Unit(1); } + +/** \returns an expression of the Z axis unit vector (0,0,1{,0}^*) + * + * \only_for_vectors + * + * \sa MatrixBase::Unit(Index,Index), MatrixBase::Unit(Index), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW() + */ +template +EIGEN_STRONG_INLINE const typename MatrixBase::BasisReturnType MatrixBase::UnitZ() +{ return Derived::Unit(2); } + +/** \returns an expression of the W axis unit vector (0,0,0,1) + * + * \only_for_vectors + * + * \sa MatrixBase::Unit(Index,Index), MatrixBase::Unit(Index), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW() + */ +template +EIGEN_STRONG_INLINE const typename MatrixBase::BasisReturnType MatrixBase::UnitW() +{ return Derived::Unit(3); } + +} // end namespace Eigen + +#endif // EIGEN_CWISE_NULLARY_OP_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/CwiseUnaryOp.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/CwiseUnaryOp.h new file mode 100644 index 00000000..f7ee60e9 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/CwiseUnaryOp.h @@ -0,0 +1,126 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008-2010 Gael Guennebaud +// Copyright (C) 2006-2008 Benoit Jacob +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_CWISE_UNARY_OP_H +#define EIGEN_CWISE_UNARY_OP_H + +namespace Eigen { + +/** \class CwiseUnaryOp + * \ingroup Core_Module + * + * \brief Generic expression where a coefficient-wise unary operator is applied to an expression + * + * \param UnaryOp template functor implementing the operator + * \param XprType the type of the expression to which we are applying the unary operator + * + * This class represents an expression where a unary operator is applied to an expression. + * It is the return type of all operations taking exactly 1 input expression, regardless of the + * presence of other inputs such as scalars. For example, the operator* in the expression 3*matrix + * is considered unary, because only the right-hand side is an expression, and its + * return type is a specialization of CwiseUnaryOp. + * + * Most of the time, this is the only way that it is used, so you typically don't have to name + * CwiseUnaryOp types explicitly. + * + * \sa MatrixBase::unaryExpr(const CustomUnaryOp &) const, class CwiseBinaryOp, class CwiseNullaryOp + */ + +namespace internal { +template +struct traits > + : traits +{ + typedef typename result_of< + UnaryOp(typename XprType::Scalar) + >::type Scalar; + typedef typename XprType::Nested XprTypeNested; + typedef typename remove_reference::type _XprTypeNested; + enum { + Flags = _XprTypeNested::Flags & ( + HereditaryBits | LinearAccessBit | AlignedBit + | (functor_traits::PacketAccess ? PacketAccessBit : 0)), + CoeffReadCost = EIGEN_ADD_COST(_XprTypeNested::CoeffReadCost, functor_traits::Cost) + }; +}; +} + +template +class CwiseUnaryOpImpl; + +template +class CwiseUnaryOp : internal::no_assignment_operator, + public CwiseUnaryOpImpl::StorageKind> +{ + public: + + typedef typename CwiseUnaryOpImpl::StorageKind>::Base Base; + EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseUnaryOp) + + inline CwiseUnaryOp(const XprType& xpr, const UnaryOp& func = UnaryOp()) + : m_xpr(xpr), m_functor(func) {} + + EIGEN_STRONG_INLINE Index rows() const { return m_xpr.rows(); } + EIGEN_STRONG_INLINE Index cols() const { return m_xpr.cols(); } + + /** \returns the functor representing the unary operation */ + const UnaryOp& functor() const { return m_functor; } + + /** \returns the nested expression */ + const typename internal::remove_all::type& + nestedExpression() const { return m_xpr; } + + /** \returns the nested expression */ + typename internal::remove_all::type& + nestedExpression() { return m_xpr.const_cast_derived(); } + + protected: + typename XprType::Nested m_xpr; + const UnaryOp m_functor; +}; + +// This is the generic implementation for dense storage. +// It can be used for any expression types implementing the dense concept. +template +class CwiseUnaryOpImpl + : public internal::dense_xpr_base >::type +{ + public: + + typedef CwiseUnaryOp Derived; + typedef typename internal::dense_xpr_base >::type Base; + EIGEN_DENSE_PUBLIC_INTERFACE(Derived) + + EIGEN_STRONG_INLINE const Scalar coeff(Index rowId, Index colId) const + { + return derived().functor()(derived().nestedExpression().coeff(rowId, colId)); + } + + template + EIGEN_STRONG_INLINE PacketScalar packet(Index rowId, Index colId) const + { + return derived().functor().packetOp(derived().nestedExpression().template packet(rowId, colId)); + } + + EIGEN_STRONG_INLINE const Scalar coeff(Index index) const + { + return derived().functor()(derived().nestedExpression().coeff(index)); + } + + template + EIGEN_STRONG_INLINE PacketScalar packet(Index index) const + { + return derived().functor().packetOp(derived().nestedExpression().template packet(index)); + } +}; + +} // end namespace Eigen + +#endif // EIGEN_CWISE_UNARY_OP_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/CwiseUnaryView.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/CwiseUnaryView.h new file mode 100644 index 00000000..b2638d32 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/CwiseUnaryView.h @@ -0,0 +1,139 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2009-2010 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_CWISE_UNARY_VIEW_H +#define EIGEN_CWISE_UNARY_VIEW_H + +namespace Eigen { + +/** \class CwiseUnaryView + * \ingroup Core_Module + * + * \brief Generic lvalue expression of a coefficient-wise unary operator of a matrix or a vector + * + * \param ViewOp template functor implementing the view + * \param MatrixType the type of the matrix we are applying the unary operator + * + * This class represents a lvalue expression of a generic unary view operator of a matrix or a vector. + * It is the return type of real() and imag(), and most of the time this is the only way it is used. + * + * \sa MatrixBase::unaryViewExpr(const CustomUnaryOp &) const, class CwiseUnaryOp + */ + +namespace internal { +template +struct traits > + : traits +{ + typedef typename result_of< + ViewOp(typename traits::Scalar) + >::type Scalar; + typedef typename MatrixType::Nested MatrixTypeNested; + typedef typename remove_all::type _MatrixTypeNested; + enum { + Flags = (traits<_MatrixTypeNested>::Flags & (HereditaryBits | LvalueBit | LinearAccessBit | DirectAccessBit)), + CoeffReadCost = traits<_MatrixTypeNested>::CoeffReadCost + functor_traits::Cost, + MatrixTypeInnerStride = inner_stride_at_compile_time::ret, + // need to cast the sizeof's from size_t to int explicitly, otherwise: + // "error: no integral type can represent all of the enumerator values + InnerStrideAtCompileTime = MatrixTypeInnerStride == Dynamic + ? int(Dynamic) + : int(MatrixTypeInnerStride) * int(sizeof(typename traits::Scalar) / sizeof(Scalar)), + OuterStrideAtCompileTime = outer_stride_at_compile_time::ret == Dynamic + ? int(Dynamic) + : outer_stride_at_compile_time::ret * int(sizeof(typename traits::Scalar) / sizeof(Scalar)) + }; +}; +} + +template +class CwiseUnaryViewImpl; + +template +class CwiseUnaryView : public CwiseUnaryViewImpl::StorageKind> +{ + public: + + typedef typename CwiseUnaryViewImpl::StorageKind>::Base Base; + EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseUnaryView) + + inline CwiseUnaryView(const MatrixType& mat, const ViewOp& func = ViewOp()) + : m_matrix(mat), m_functor(func) {} + + EIGEN_INHERIT_ASSIGNMENT_OPERATORS(CwiseUnaryView) + + EIGEN_STRONG_INLINE Index rows() const { return m_matrix.rows(); } + EIGEN_STRONG_INLINE Index cols() const { return m_matrix.cols(); } + + /** \returns the functor representing unary operation */ + const ViewOp& functor() const { return m_functor; } + + /** \returns the nested expression */ + const typename internal::remove_all::type& + nestedExpression() const { return m_matrix; } + + /** \returns the nested expression */ + typename internal::remove_all::type& + nestedExpression() { return m_matrix.const_cast_derived(); } + + protected: + // FIXME changed from MatrixType::Nested because of a weird compilation error with sun CC + typename internal::nested::type m_matrix; + ViewOp m_functor; +}; + +template +class CwiseUnaryViewImpl + : public internal::dense_xpr_base< CwiseUnaryView >::type +{ + public: + + typedef CwiseUnaryView Derived; + typedef typename internal::dense_xpr_base< CwiseUnaryView >::type Base; + + EIGEN_DENSE_PUBLIC_INTERFACE(Derived) + EIGEN_INHERIT_ASSIGNMENT_OPERATORS(CwiseUnaryViewImpl) + + inline Scalar* data() { return &coeffRef(0); } + inline const Scalar* data() const { return &coeff(0); } + + inline Index innerStride() const + { + return derived().nestedExpression().innerStride() * sizeof(typename internal::traits::Scalar) / sizeof(Scalar); + } + + inline Index outerStride() const + { + return derived().nestedExpression().outerStride() * sizeof(typename internal::traits::Scalar) / sizeof(Scalar); + } + + EIGEN_STRONG_INLINE CoeffReturnType coeff(Index row, Index col) const + { + return derived().functor()(derived().nestedExpression().coeff(row, col)); + } + + EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index) const + { + return derived().functor()(derived().nestedExpression().coeff(index)); + } + + EIGEN_STRONG_INLINE Scalar& coeffRef(Index row, Index col) + { + return derived().functor()(const_cast_derived().nestedExpression().coeffRef(row, col)); + } + + EIGEN_STRONG_INLINE Scalar& coeffRef(Index index) + { + return derived().functor()(const_cast_derived().nestedExpression().coeffRef(index)); + } +}; + +} // end namespace Eigen + +#endif // EIGEN_CWISE_UNARY_VIEW_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/DenseBase.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/DenseBase.h new file mode 100644 index 00000000..4b371b07 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/DenseBase.h @@ -0,0 +1,521 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2007-2010 Benoit Jacob +// Copyright (C) 2008-2010 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_DENSEBASE_H +#define EIGEN_DENSEBASE_H + +namespace Eigen { + +namespace internal { + +// The index type defined by EIGEN_DEFAULT_DENSE_INDEX_TYPE must be a signed type. +// This dummy function simply aims at checking that at compile time. +static inline void check_DenseIndex_is_signed() { + EIGEN_STATIC_ASSERT(NumTraits::IsSigned,THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE); +} + +} // end namespace internal + +/** \class DenseBase + * \ingroup Core_Module + * + * \brief Base class for all dense matrices, vectors, and arrays + * + * This class is the base that is inherited by all dense objects (matrix, vector, arrays, + * and related expression types). The common Eigen API for dense objects is contained in this class. + * + * \tparam Derived is the derived type, e.g., a matrix type or an expression. + * + * This class can be extended with the help of the plugin mechanism described on the page + * \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_DENSEBASE_PLUGIN. + * + * \sa \ref TopicClassHierarchy + */ +template class DenseBase +#ifndef EIGEN_PARSED_BY_DOXYGEN + : public internal::special_scalar_op_base::Scalar, + typename NumTraits::Scalar>::Real, + DenseCoeffsBase > +#else + : public DenseCoeffsBase +#endif // not EIGEN_PARSED_BY_DOXYGEN +{ + public: + + class InnerIterator; + + typedef typename internal::traits::StorageKind StorageKind; + + /** \brief The type of indices + * \details To change this, \c \#define the preprocessor symbol \c EIGEN_DEFAULT_DENSE_INDEX_TYPE. + * \sa \ref TopicPreprocessorDirectives. + */ + typedef typename internal::traits::Index Index; + + typedef typename internal::traits::Scalar Scalar; + typedef typename internal::packet_traits::type PacketScalar; + typedef typename NumTraits::Real RealScalar; + typedef internal::special_scalar_op_base > Base; + + using Base::operator*; + using Base::derived; + using Base::const_cast_derived; + using Base::rows; + using Base::cols; + using Base::size; + using Base::rowIndexByOuterInner; + using Base::colIndexByOuterInner; + using Base::coeff; + using Base::coeffByOuterInner; + using Base::packet; + using Base::packetByOuterInner; + using Base::writePacket; + using Base::writePacketByOuterInner; + using Base::coeffRef; + using Base::coeffRefByOuterInner; + using Base::copyCoeff; + using Base::copyCoeffByOuterInner; + using Base::copyPacket; + using Base::copyPacketByOuterInner; + using Base::operator(); + using Base::operator[]; + using Base::x; + using Base::y; + using Base::z; + using Base::w; + using Base::stride; + using Base::innerStride; + using Base::outerStride; + using Base::rowStride; + using Base::colStride; + typedef typename Base::CoeffReturnType CoeffReturnType; + + enum { + + RowsAtCompileTime = internal::traits::RowsAtCompileTime, + /**< The number of rows at compile-time. This is just a copy of the value provided + * by the \a Derived type. If a value is not known at compile-time, + * it is set to the \a Dynamic constant. + * \sa MatrixBase::rows(), MatrixBase::cols(), ColsAtCompileTime, SizeAtCompileTime */ + + ColsAtCompileTime = internal::traits::ColsAtCompileTime, + /**< The number of columns at compile-time. This is just a copy of the value provided + * by the \a Derived type. If a value is not known at compile-time, + * it is set to the \a Dynamic constant. + * \sa MatrixBase::rows(), MatrixBase::cols(), RowsAtCompileTime, SizeAtCompileTime */ + + + SizeAtCompileTime = (internal::size_at_compile_time::RowsAtCompileTime, + internal::traits::ColsAtCompileTime>::ret), + /**< This is equal to the number of coefficients, i.e. the number of + * rows times the number of columns, or to \a Dynamic if this is not + * known at compile-time. \sa RowsAtCompileTime, ColsAtCompileTime */ + + MaxRowsAtCompileTime = internal::traits::MaxRowsAtCompileTime, + /**< This value is equal to the maximum possible number of rows that this expression + * might have. If this expression might have an arbitrarily high number of rows, + * this value is set to \a Dynamic. + * + * This value is useful to know when evaluating an expression, in order to determine + * whether it is possible to avoid doing a dynamic memory allocation. + * + * \sa RowsAtCompileTime, MaxColsAtCompileTime, MaxSizeAtCompileTime + */ + + MaxColsAtCompileTime = internal::traits::MaxColsAtCompileTime, + /**< This value is equal to the maximum possible number of columns that this expression + * might have. If this expression might have an arbitrarily high number of columns, + * this value is set to \a Dynamic. + * + * This value is useful to know when evaluating an expression, in order to determine + * whether it is possible to avoid doing a dynamic memory allocation. + * + * \sa ColsAtCompileTime, MaxRowsAtCompileTime, MaxSizeAtCompileTime + */ + + MaxSizeAtCompileTime = (internal::size_at_compile_time::MaxRowsAtCompileTime, + internal::traits::MaxColsAtCompileTime>::ret), + /**< This value is equal to the maximum possible number of coefficients that this expression + * might have. If this expression might have an arbitrarily high number of coefficients, + * this value is set to \a Dynamic. + * + * This value is useful to know when evaluating an expression, in order to determine + * whether it is possible to avoid doing a dynamic memory allocation. + * + * \sa SizeAtCompileTime, MaxRowsAtCompileTime, MaxColsAtCompileTime + */ + + IsVectorAtCompileTime = internal::traits::MaxRowsAtCompileTime == 1 + || internal::traits::MaxColsAtCompileTime == 1, + /**< This is set to true if either the number of rows or the number of + * columns is known at compile-time to be equal to 1. Indeed, in that case, + * we are dealing with a column-vector (if there is only one column) or with + * a row-vector (if there is only one row). */ + + Flags = internal::traits::Flags, + /**< This stores expression \ref flags flags which may or may not be inherited by new expressions + * constructed from this one. See the \ref flags "list of flags". + */ + + IsRowMajor = int(Flags) & RowMajorBit, /**< True if this expression has row-major storage order. */ + + InnerSizeAtCompileTime = int(IsVectorAtCompileTime) ? int(SizeAtCompileTime) + : int(IsRowMajor) ? int(ColsAtCompileTime) : int(RowsAtCompileTime), + + CoeffReadCost = internal::traits::CoeffReadCost, + /**< This is a rough measure of how expensive it is to read one coefficient from + * this expression. + */ + + InnerStrideAtCompileTime = internal::inner_stride_at_compile_time::ret, + OuterStrideAtCompileTime = internal::outer_stride_at_compile_time::ret + }; + + enum { ThisConstantIsPrivateInPlainObjectBase }; + + /** \returns the number of nonzero coefficients which is in practice the number + * of stored coefficients. */ + inline Index nonZeros() const { return size(); } + + /** \returns the outer size. + * + * \note For a vector, this returns just 1. For a matrix (non-vector), this is the major dimension + * with respect to the \ref TopicStorageOrders "storage order", i.e., the number of columns for a + * column-major matrix, and the number of rows for a row-major matrix. */ + Index outerSize() const + { + return IsVectorAtCompileTime ? 1 + : int(IsRowMajor) ? this->rows() : this->cols(); + } + + /** \returns the inner size. + * + * \note For a vector, this is just the size. For a matrix (non-vector), this is the minor dimension + * with respect to the \ref TopicStorageOrders "storage order", i.e., the number of rows for a + * column-major matrix, and the number of columns for a row-major matrix. */ + Index innerSize() const + { + return IsVectorAtCompileTime ? this->size() + : int(IsRowMajor) ? this->cols() : this->rows(); + } + + /** Only plain matrices/arrays, not expressions, may be resized; therefore the only useful resize methods are + * Matrix::resize() and Array::resize(). The present method only asserts that the new size equals the old size, and does + * nothing else. + */ + void resize(Index newSize) + { + EIGEN_ONLY_USED_FOR_DEBUG(newSize); + eigen_assert(newSize == this->size() + && "DenseBase::resize() does not actually allow to resize."); + } + /** Only plain matrices/arrays, not expressions, may be resized; therefore the only useful resize methods are + * Matrix::resize() and Array::resize(). The present method only asserts that the new size equals the old size, and does + * nothing else. + */ + void resize(Index nbRows, Index nbCols) + { + EIGEN_ONLY_USED_FOR_DEBUG(nbRows); + EIGEN_ONLY_USED_FOR_DEBUG(nbCols); + eigen_assert(nbRows == this->rows() && nbCols == this->cols() + && "DenseBase::resize() does not actually allow to resize."); + } + +#ifndef EIGEN_PARSED_BY_DOXYGEN + + /** \internal Represents a matrix with all coefficients equal to one another*/ + typedef CwiseNullaryOp,Derived> ConstantReturnType; + /** \internal Represents a vector with linearly spaced coefficients that allows sequential access only. */ + typedef CwiseNullaryOp,Derived> SequentialLinSpacedReturnType; + /** \internal Represents a vector with linearly spaced coefficients that allows random access. */ + typedef CwiseNullaryOp,Derived> RandomAccessLinSpacedReturnType; + /** \internal the return type of MatrixBase::eigenvalues() */ + typedef Matrix::Scalar>::Real, internal::traits::ColsAtCompileTime, 1> EigenvaluesReturnType; + +#endif // not EIGEN_PARSED_BY_DOXYGEN + + /** Copies \a other into *this. \returns a reference to *this. */ + template + Derived& operator=(const DenseBase& other); + + /** Special case of the template operator=, in order to prevent the compiler + * from generating a default operator= (issue hit with g++ 4.1) + */ + Derived& operator=(const DenseBase& other); + + template + Derived& operator=(const EigenBase &other); + + template + Derived& operator+=(const EigenBase &other); + + template + Derived& operator-=(const EigenBase &other); + + template + Derived& operator=(const ReturnByValue& func); + + /** \internal Copies \a other into *this without evaluating other. \returns a reference to *this. */ + template + Derived& lazyAssign(const DenseBase& other); + + /** \internal Evaluates \a other into *this. \returns a reference to *this. */ + template + Derived& lazyAssign(const ReturnByValue& other); + + CommaInitializer operator<< (const Scalar& s); + + template + const Flagged flagged() const; + + template + CommaInitializer operator<< (const DenseBase& other); + + Eigen::Transpose transpose(); + typedef typename internal::add_const >::type ConstTransposeReturnType; + ConstTransposeReturnType transpose() const; + void transposeInPlace(); +#ifndef EIGEN_NO_DEBUG + protected: + template + void checkTransposeAliasing(const OtherDerived& other) const; + public: +#endif + + + static const ConstantReturnType + Constant(Index rows, Index cols, const Scalar& value); + static const ConstantReturnType + Constant(Index size, const Scalar& value); + static const ConstantReturnType + Constant(const Scalar& value); + + static const SequentialLinSpacedReturnType + LinSpaced(Sequential_t, Index size, const Scalar& low, const Scalar& high); + static const RandomAccessLinSpacedReturnType + LinSpaced(Index size, const Scalar& low, const Scalar& high); + static const SequentialLinSpacedReturnType + LinSpaced(Sequential_t, const Scalar& low, const Scalar& high); + static const RandomAccessLinSpacedReturnType + LinSpaced(const Scalar& low, const Scalar& high); + + template + static const CwiseNullaryOp + NullaryExpr(Index rows, Index cols, const CustomNullaryOp& func); + template + static const CwiseNullaryOp + NullaryExpr(Index size, const CustomNullaryOp& func); + template + static const CwiseNullaryOp + NullaryExpr(const CustomNullaryOp& func); + + static const ConstantReturnType Zero(Index rows, Index cols); + static const ConstantReturnType Zero(Index size); + static const ConstantReturnType Zero(); + static const ConstantReturnType Ones(Index rows, Index cols); + static const ConstantReturnType Ones(Index size); + static const ConstantReturnType Ones(); + + void fill(const Scalar& value); + Derived& setConstant(const Scalar& value); + Derived& setLinSpaced(Index size, const Scalar& low, const Scalar& high); + Derived& setLinSpaced(const Scalar& low, const Scalar& high); + Derived& setZero(); + Derived& setOnes(); + Derived& setRandom(); + + template + bool isApprox(const DenseBase& other, + const RealScalar& prec = NumTraits::dummy_precision()) const; + bool isMuchSmallerThan(const RealScalar& other, + const RealScalar& prec = NumTraits::dummy_precision()) const; + template + bool isMuchSmallerThan(const DenseBase& other, + const RealScalar& prec = NumTraits::dummy_precision()) const; + + bool isApproxToConstant(const Scalar& value, const RealScalar& prec = NumTraits::dummy_precision()) const; + bool isConstant(const Scalar& value, const RealScalar& prec = NumTraits::dummy_precision()) const; + bool isZero(const RealScalar& prec = NumTraits::dummy_precision()) const; + bool isOnes(const RealScalar& prec = NumTraits::dummy_precision()) const; + + inline bool hasNaN() const; + inline bool allFinite() const; + + inline Derived& operator*=(const Scalar& other); + inline Derived& operator/=(const Scalar& other); + + typedef typename internal::add_const_on_value_type::type>::type EvalReturnType; + /** \returns the matrix or vector obtained by evaluating this expression. + * + * Notice that in the case of a plain matrix or vector (not an expression) this function just returns + * a const reference, in order to avoid a useless copy. + */ + EIGEN_STRONG_INLINE EvalReturnType eval() const + { + // Even though MSVC does not honor strong inlining when the return type + // is a dynamic matrix, we desperately need strong inlining for fixed + // size types on MSVC. + return typename internal::eval::type(derived()); + } + + /** swaps *this with the expression \a other. + * + */ + template + void swap(const DenseBase& other, + int = OtherDerived::ThisConstantIsPrivateInPlainObjectBase) + { + SwapWrapper(derived()).lazyAssign(other.derived()); + } + + /** swaps *this with the matrix or array \a other. + * + */ + template + void swap(PlainObjectBase& other) + { + SwapWrapper(derived()).lazyAssign(other.derived()); + } + + + inline const NestByValue nestByValue() const; + inline const ForceAlignedAccess forceAlignedAccess() const; + inline ForceAlignedAccess forceAlignedAccess(); + template inline const typename internal::conditional,Derived&>::type forceAlignedAccessIf() const; + template inline typename internal::conditional,Derived&>::type forceAlignedAccessIf(); + + Scalar sum() const; + Scalar mean() const; + Scalar trace() const; + + Scalar prod() const; + + typename internal::traits::Scalar minCoeff() const; + typename internal::traits::Scalar maxCoeff() const; + + template + typename internal::traits::Scalar minCoeff(IndexType* row, IndexType* col) const; + template + typename internal::traits::Scalar maxCoeff(IndexType* row, IndexType* col) const; + template + typename internal::traits::Scalar minCoeff(IndexType* index) const; + template + typename internal::traits::Scalar maxCoeff(IndexType* index) const; + + template + typename internal::result_of::Scalar)>::type + redux(const BinaryOp& func) const; + + template + void visit(Visitor& func) const; + + inline const WithFormat format(const IOFormat& fmt) const; + + /** \returns the unique coefficient of a 1x1 expression */ + CoeffReturnType value() const + { + EIGEN_STATIC_ASSERT_SIZE_1x1(Derived) + eigen_assert(this->rows() == 1 && this->cols() == 1); + return derived().coeff(0,0); + } + + bool all(void) const; + bool any(void) const; + Index count() const; + + typedef VectorwiseOp RowwiseReturnType; + typedef const VectorwiseOp ConstRowwiseReturnType; + typedef VectorwiseOp ColwiseReturnType; + typedef const VectorwiseOp ConstColwiseReturnType; + + ConstRowwiseReturnType rowwise() const; + RowwiseReturnType rowwise(); + ConstColwiseReturnType colwise() const; + ColwiseReturnType colwise(); + + static const CwiseNullaryOp,Derived> Random(Index rows, Index cols); + static const CwiseNullaryOp,Derived> Random(Index size); + static const CwiseNullaryOp,Derived> Random(); + + template + const Select + select(const DenseBase& thenMatrix, + const DenseBase& elseMatrix) const; + + template + inline const Select + select(const DenseBase& thenMatrix, const typename ThenDerived::Scalar& elseScalar) const; + + template + inline const Select + select(const typename ElseDerived::Scalar& thenScalar, const DenseBase& elseMatrix) const; + + template RealScalar lpNorm() const; + + template + inline const Replicate replicate() const; + + typedef Replicate ReplicateReturnType; + inline const ReplicateReturnType replicate(Index rowFacor,Index colFactor) const; + + typedef Reverse ReverseReturnType; + typedef const Reverse ConstReverseReturnType; + ReverseReturnType reverse(); + ConstReverseReturnType reverse() const; + void reverseInPlace(); + +#define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::DenseBase +# include "../plugins/BlockMethods.h" +# ifdef EIGEN_DENSEBASE_PLUGIN +# include EIGEN_DENSEBASE_PLUGIN +# endif +#undef EIGEN_CURRENT_STORAGE_BASE_CLASS + +#ifdef EIGEN2_SUPPORT + + Block corner(CornerType type, Index cRows, Index cCols); + const Block corner(CornerType type, Index cRows, Index cCols) const; + template + Block corner(CornerType type); + template + const Block corner(CornerType type) const; + +#endif // EIGEN2_SUPPORT + + + // disable the use of evalTo for dense objects with a nice compilation error + template inline void evalTo(Dest& ) const + { + EIGEN_STATIC_ASSERT((internal::is_same::value),THE_EVAL_EVALTO_FUNCTION_SHOULD_NEVER_BE_CALLED_FOR_DENSE_OBJECTS); + } + + protected: + /** Default constructor. Do nothing. */ + DenseBase() + { + /* Just checks for self-consistency of the flags. + * Only do it when debugging Eigen, as this borders on paranoiac and could slow compilation down + */ +#ifdef EIGEN_INTERNAL_DEBUGGING + EIGEN_STATIC_ASSERT((EIGEN_IMPLIES(MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1, int(IsRowMajor)) + && EIGEN_IMPLIES(MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1, int(!IsRowMajor))), + INVALID_STORAGE_ORDER_FOR_THIS_VECTOR_EXPRESSION) +#endif + } + + private: + explicit DenseBase(int); + DenseBase(int,int); + template explicit DenseBase(const DenseBase&); +}; + +} // end namespace Eigen + +#endif // EIGEN_DENSEBASE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/DenseCoeffsBase.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/DenseCoeffsBase.h new file mode 100644 index 00000000..3c890f21 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/DenseCoeffsBase.h @@ -0,0 +1,754 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2006-2010 Benoit Jacob +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_DENSECOEFFSBASE_H +#define EIGEN_DENSECOEFFSBASE_H + +namespace Eigen { + +namespace internal { +template struct add_const_on_value_type_if_arithmetic +{ + typedef typename conditional::value, T, typename add_const_on_value_type::type>::type type; +}; +} + +/** \brief Base class providing read-only coefficient access to matrices and arrays. + * \ingroup Core_Module + * \tparam Derived Type of the derived class + * \tparam #ReadOnlyAccessors Constant indicating read-only access + * + * This class defines the \c operator() \c const function and friends, which can be used to read specific + * entries of a matrix or array. + * + * \sa DenseCoeffsBase, DenseCoeffsBase, + * \ref TopicClassHierarchy + */ +template +class DenseCoeffsBase : public EigenBase +{ + public: + typedef typename internal::traits::StorageKind StorageKind; + typedef typename internal::traits::Index Index; + typedef typename internal::traits::Scalar Scalar; + typedef typename internal::packet_traits::type PacketScalar; + + // Explanation for this CoeffReturnType typedef. + // - This is the return type of the coeff() method. + // - The LvalueBit means exactly that we can offer a coeffRef() method, which means exactly that we can get references + // to coeffs, which means exactly that we can have coeff() return a const reference (as opposed to returning a value). + // - The is_artihmetic check is required since "const int", "const double", etc. will cause warnings on some systems + // while the declaration of "const T", where T is a non arithmetic type does not. Always returning "const Scalar&" is + // not possible, since the underlying expressions might not offer a valid address the reference could be referring to. + typedef typename internal::conditional::Flags&LvalueBit), + const Scalar&, + typename internal::conditional::value, Scalar, const Scalar>::type + >::type CoeffReturnType; + + typedef typename internal::add_const_on_value_type_if_arithmetic< + typename internal::packet_traits::type + >::type PacketReturnType; + + typedef EigenBase Base; + using Base::rows; + using Base::cols; + using Base::size; + using Base::derived; + + EIGEN_STRONG_INLINE Index rowIndexByOuterInner(Index outer, Index inner) const + { + return int(Derived::RowsAtCompileTime) == 1 ? 0 + : int(Derived::ColsAtCompileTime) == 1 ? inner + : int(Derived::Flags)&RowMajorBit ? outer + : inner; + } + + EIGEN_STRONG_INLINE Index colIndexByOuterInner(Index outer, Index inner) const + { + return int(Derived::ColsAtCompileTime) == 1 ? 0 + : int(Derived::RowsAtCompileTime) == 1 ? inner + : int(Derived::Flags)&RowMajorBit ? inner + : outer; + } + + /** Short version: don't use this function, use + * \link operator()(Index,Index) const \endlink instead. + * + * Long version: this function is similar to + * \link operator()(Index,Index) const \endlink, but without the assertion. + * Use this for limiting the performance cost of debugging code when doing + * repeated coefficient access. Only use this when it is guaranteed that the + * parameters \a row and \a col are in range. + * + * If EIGEN_INTERNAL_DEBUGGING is defined, an assertion will be made, making this + * function equivalent to \link operator()(Index,Index) const \endlink. + * + * \sa operator()(Index,Index) const, coeffRef(Index,Index), coeff(Index) const + */ + EIGEN_STRONG_INLINE CoeffReturnType coeff(Index row, Index col) const + { + eigen_internal_assert(row >= 0 && row < rows() + && col >= 0 && col < cols()); + return derived().coeff(row, col); + } + + EIGEN_STRONG_INLINE CoeffReturnType coeffByOuterInner(Index outer, Index inner) const + { + return coeff(rowIndexByOuterInner(outer, inner), + colIndexByOuterInner(outer, inner)); + } + + /** \returns the coefficient at given the given row and column. + * + * \sa operator()(Index,Index), operator[](Index) + */ + EIGEN_STRONG_INLINE CoeffReturnType operator()(Index row, Index col) const + { + eigen_assert(row >= 0 && row < rows() + && col >= 0 && col < cols()); + return derived().coeff(row, col); + } + + /** Short version: don't use this function, use + * \link operator[](Index) const \endlink instead. + * + * Long version: this function is similar to + * \link operator[](Index) const \endlink, but without the assertion. + * Use this for limiting the performance cost of debugging code when doing + * repeated coefficient access. Only use this when it is guaranteed that the + * parameter \a index is in range. + * + * If EIGEN_INTERNAL_DEBUGGING is defined, an assertion will be made, making this + * function equivalent to \link operator[](Index) const \endlink. + * + * \sa operator[](Index) const, coeffRef(Index), coeff(Index,Index) const + */ + + EIGEN_STRONG_INLINE CoeffReturnType + coeff(Index index) const + { + eigen_internal_assert(index >= 0 && index < size()); + return derived().coeff(index); + } + + + /** \returns the coefficient at given index. + * + * This method is allowed only for vector expressions, and for matrix expressions having the LinearAccessBit. + * + * \sa operator[](Index), operator()(Index,Index) const, x() const, y() const, + * z() const, w() const + */ + + EIGEN_STRONG_INLINE CoeffReturnType + operator[](Index index) const + { + #ifndef EIGEN2_SUPPORT + EIGEN_STATIC_ASSERT(Derived::IsVectorAtCompileTime, + THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD) + #endif + eigen_assert(index >= 0 && index < size()); + return derived().coeff(index); + } + + /** \returns the coefficient at given index. + * + * This is synonymous to operator[](Index) const. + * + * This method is allowed only for vector expressions, and for matrix expressions having the LinearAccessBit. + * + * \sa operator[](Index), operator()(Index,Index) const, x() const, y() const, + * z() const, w() const + */ + + EIGEN_STRONG_INLINE CoeffReturnType + operator()(Index index) const + { + eigen_assert(index >= 0 && index < size()); + return derived().coeff(index); + } + + /** equivalent to operator[](0). */ + + EIGEN_STRONG_INLINE CoeffReturnType + x() const { return (*this)[0]; } + + /** equivalent to operator[](1). */ + + EIGEN_STRONG_INLINE CoeffReturnType + y() const { return (*this)[1]; } + + /** equivalent to operator[](2). */ + + EIGEN_STRONG_INLINE CoeffReturnType + z() const { return (*this)[2]; } + + /** equivalent to operator[](3). */ + + EIGEN_STRONG_INLINE CoeffReturnType + w() const { return (*this)[3]; } + + /** \internal + * \returns the packet of coefficients starting at the given row and column. It is your responsibility + * to ensure that a packet really starts there. This method is only available on expressions having the + * PacketAccessBit. + * + * The \a LoadMode parameter may have the value \a #Aligned or \a #Unaligned. Its effect is to select + * the appropriate vectorization instruction. Aligned access is faster, but is only possible for packets + * starting at an address which is a multiple of the packet size. + */ + + template + EIGEN_STRONG_INLINE PacketReturnType packet(Index row, Index col) const + { + eigen_internal_assert(row >= 0 && row < rows() + && col >= 0 && col < cols()); + return derived().template packet(row,col); + } + + + /** \internal */ + template + EIGEN_STRONG_INLINE PacketReturnType packetByOuterInner(Index outer, Index inner) const + { + return packet(rowIndexByOuterInner(outer, inner), + colIndexByOuterInner(outer, inner)); + } + + /** \internal + * \returns the packet of coefficients starting at the given index. It is your responsibility + * to ensure that a packet really starts there. This method is only available on expressions having the + * PacketAccessBit and the LinearAccessBit. + * + * The \a LoadMode parameter may have the value \a #Aligned or \a #Unaligned. Its effect is to select + * the appropriate vectorization instruction. Aligned access is faster, but is only possible for packets + * starting at an address which is a multiple of the packet size. + */ + + template + EIGEN_STRONG_INLINE PacketReturnType packet(Index index) const + { + eigen_internal_assert(index >= 0 && index < size()); + return derived().template packet(index); + } + + protected: + // explanation: DenseBase is doing "using ..." on the methods from DenseCoeffsBase. + // But some methods are only available in the DirectAccess case. + // So we add dummy methods here with these names, so that "using... " doesn't fail. + // It's not private so that the child class DenseBase can access them, and it's not public + // either since it's an implementation detail, so has to be protected. + void coeffRef(); + void coeffRefByOuterInner(); + void writePacket(); + void writePacketByOuterInner(); + void copyCoeff(); + void copyCoeffByOuterInner(); + void copyPacket(); + void copyPacketByOuterInner(); + void stride(); + void innerStride(); + void outerStride(); + void rowStride(); + void colStride(); +}; + +/** \brief Base class providing read/write coefficient access to matrices and arrays. + * \ingroup Core_Module + * \tparam Derived Type of the derived class + * \tparam #WriteAccessors Constant indicating read/write access + * + * This class defines the non-const \c operator() function and friends, which can be used to write specific + * entries of a matrix or array. This class inherits DenseCoeffsBase which + * defines the const variant for reading specific entries. + * + * \sa DenseCoeffsBase, \ref TopicClassHierarchy + */ +template +class DenseCoeffsBase : public DenseCoeffsBase +{ + public: + + typedef DenseCoeffsBase Base; + + typedef typename internal::traits::StorageKind StorageKind; + typedef typename internal::traits::Index Index; + typedef typename internal::traits::Scalar Scalar; + typedef typename internal::packet_traits::type PacketScalar; + typedef typename NumTraits::Real RealScalar; + + using Base::coeff; + using Base::rows; + using Base::cols; + using Base::size; + using Base::derived; + using Base::rowIndexByOuterInner; + using Base::colIndexByOuterInner; + using Base::operator[]; + using Base::operator(); + using Base::x; + using Base::y; + using Base::z; + using Base::w; + + /** Short version: don't use this function, use + * \link operator()(Index,Index) \endlink instead. + * + * Long version: this function is similar to + * \link operator()(Index,Index) \endlink, but without the assertion. + * Use this for limiting the performance cost of debugging code when doing + * repeated coefficient access. Only use this when it is guaranteed that the + * parameters \a row and \a col are in range. + * + * If EIGEN_INTERNAL_DEBUGGING is defined, an assertion will be made, making this + * function equivalent to \link operator()(Index,Index) \endlink. + * + * \sa operator()(Index,Index), coeff(Index, Index) const, coeffRef(Index) + */ + EIGEN_STRONG_INLINE Scalar& coeffRef(Index row, Index col) + { + eigen_internal_assert(row >= 0 && row < rows() + && col >= 0 && col < cols()); + return derived().coeffRef(row, col); + } + + EIGEN_STRONG_INLINE Scalar& + coeffRefByOuterInner(Index outer, Index inner) + { + return coeffRef(rowIndexByOuterInner(outer, inner), + colIndexByOuterInner(outer, inner)); + } + + /** \returns a reference to the coefficient at given the given row and column. + * + * \sa operator[](Index) + */ + + EIGEN_STRONG_INLINE Scalar& + operator()(Index row, Index col) + { + eigen_assert(row >= 0 && row < rows() + && col >= 0 && col < cols()); + return derived().coeffRef(row, col); + } + + + /** Short version: don't use this function, use + * \link operator[](Index) \endlink instead. + * + * Long version: this function is similar to + * \link operator[](Index) \endlink, but without the assertion. + * Use this for limiting the performance cost of debugging code when doing + * repeated coefficient access. Only use this when it is guaranteed that the + * parameters \a row and \a col are in range. + * + * If EIGEN_INTERNAL_DEBUGGING is defined, an assertion will be made, making this + * function equivalent to \link operator[](Index) \endlink. + * + * \sa operator[](Index), coeff(Index) const, coeffRef(Index,Index) + */ + + EIGEN_STRONG_INLINE Scalar& + coeffRef(Index index) + { + eigen_internal_assert(index >= 0 && index < size()); + return derived().coeffRef(index); + } + + /** \returns a reference to the coefficient at given index. + * + * This method is allowed only for vector expressions, and for matrix expressions having the LinearAccessBit. + * + * \sa operator[](Index) const, operator()(Index,Index), x(), y(), z(), w() + */ + + EIGEN_STRONG_INLINE Scalar& + operator[](Index index) + { + #ifndef EIGEN2_SUPPORT + EIGEN_STATIC_ASSERT(Derived::IsVectorAtCompileTime, + THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD) + #endif + eigen_assert(index >= 0 && index < size()); + return derived().coeffRef(index); + } + + /** \returns a reference to the coefficient at given index. + * + * This is synonymous to operator[](Index). + * + * This method is allowed only for vector expressions, and for matrix expressions having the LinearAccessBit. + * + * \sa operator[](Index) const, operator()(Index,Index), x(), y(), z(), w() + */ + + EIGEN_STRONG_INLINE Scalar& + operator()(Index index) + { + eigen_assert(index >= 0 && index < size()); + return derived().coeffRef(index); + } + + /** equivalent to operator[](0). */ + + EIGEN_STRONG_INLINE Scalar& + x() { return (*this)[0]; } + + /** equivalent to operator[](1). */ + + EIGEN_STRONG_INLINE Scalar& + y() { return (*this)[1]; } + + /** equivalent to operator[](2). */ + + EIGEN_STRONG_INLINE Scalar& + z() { return (*this)[2]; } + + /** equivalent to operator[](3). */ + + EIGEN_STRONG_INLINE Scalar& + w() { return (*this)[3]; } + + /** \internal + * Stores the given packet of coefficients, at the given row and column of this expression. It is your responsibility + * to ensure that a packet really starts there. This method is only available on expressions having the + * PacketAccessBit. + * + * The \a LoadMode parameter may have the value \a #Aligned or \a #Unaligned. Its effect is to select + * the appropriate vectorization instruction. Aligned access is faster, but is only possible for packets + * starting at an address which is a multiple of the packet size. + */ + + template + EIGEN_STRONG_INLINE void writePacket + (Index row, Index col, const typename internal::packet_traits::type& val) + { + eigen_internal_assert(row >= 0 && row < rows() + && col >= 0 && col < cols()); + derived().template writePacket(row,col,val); + } + + + /** \internal */ + template + EIGEN_STRONG_INLINE void writePacketByOuterInner + (Index outer, Index inner, const typename internal::packet_traits::type& val) + { + writePacket(rowIndexByOuterInner(outer, inner), + colIndexByOuterInner(outer, inner), + val); + } + + /** \internal + * Stores the given packet of coefficients, at the given index in this expression. It is your responsibility + * to ensure that a packet really starts there. This method is only available on expressions having the + * PacketAccessBit and the LinearAccessBit. + * + * The \a LoadMode parameter may have the value \a Aligned or \a Unaligned. Its effect is to select + * the appropriate vectorization instruction. Aligned access is faster, but is only possible for packets + * starting at an address which is a multiple of the packet size. + */ + template + EIGEN_STRONG_INLINE void writePacket + (Index index, const typename internal::packet_traits::type& val) + { + eigen_internal_assert(index >= 0 && index < size()); + derived().template writePacket(index,val); + } + +#ifndef EIGEN_PARSED_BY_DOXYGEN + + /** \internal Copies the coefficient at position (row,col) of other into *this. + * + * This method is overridden in SwapWrapper, allowing swap() assignments to share 99% of their code + * with usual assignments. + * + * Outside of this internal usage, this method has probably no usefulness. It is hidden in the public API dox. + */ + + template + EIGEN_STRONG_INLINE void copyCoeff(Index row, Index col, const DenseBase& other) + { + eigen_internal_assert(row >= 0 && row < rows() + && col >= 0 && col < cols()); + derived().coeffRef(row, col) = other.derived().coeff(row, col); + } + + /** \internal Copies the coefficient at the given index of other into *this. + * + * This method is overridden in SwapWrapper, allowing swap() assignments to share 99% of their code + * with usual assignments. + * + * Outside of this internal usage, this method has probably no usefulness. It is hidden in the public API dox. + */ + + template + EIGEN_STRONG_INLINE void copyCoeff(Index index, const DenseBase& other) + { + eigen_internal_assert(index >= 0 && index < size()); + derived().coeffRef(index) = other.derived().coeff(index); + } + + + template + EIGEN_STRONG_INLINE void copyCoeffByOuterInner(Index outer, Index inner, const DenseBase& other) + { + const Index row = rowIndexByOuterInner(outer,inner); + const Index col = colIndexByOuterInner(outer,inner); + // derived() is important here: copyCoeff() may be reimplemented in Derived! + derived().copyCoeff(row, col, other); + } + + /** \internal Copies the packet at position (row,col) of other into *this. + * + * This method is overridden in SwapWrapper, allowing swap() assignments to share 99% of their code + * with usual assignments. + * + * Outside of this internal usage, this method has probably no usefulness. It is hidden in the public API dox. + */ + + template + EIGEN_STRONG_INLINE void copyPacket(Index row, Index col, const DenseBase& other) + { + eigen_internal_assert(row >= 0 && row < rows() + && col >= 0 && col < cols()); + derived().template writePacket(row, col, + other.derived().template packet(row, col)); + } + + /** \internal Copies the packet at the given index of other into *this. + * + * This method is overridden in SwapWrapper, allowing swap() assignments to share 99% of their code + * with usual assignments. + * + * Outside of this internal usage, this method has probably no usefulness. It is hidden in the public API dox. + */ + + template + EIGEN_STRONG_INLINE void copyPacket(Index index, const DenseBase& other) + { + eigen_internal_assert(index >= 0 && index < size()); + derived().template writePacket(index, + other.derived().template packet(index)); + } + + /** \internal */ + template + EIGEN_STRONG_INLINE void copyPacketByOuterInner(Index outer, Index inner, const DenseBase& other) + { + const Index row = rowIndexByOuterInner(outer,inner); + const Index col = colIndexByOuterInner(outer,inner); + // derived() is important here: copyCoeff() may be reimplemented in Derived! + derived().template copyPacket< OtherDerived, StoreMode, LoadMode>(row, col, other); + } +#endif + +}; + +/** \brief Base class providing direct read-only coefficient access to matrices and arrays. + * \ingroup Core_Module + * \tparam Derived Type of the derived class + * \tparam #DirectAccessors Constant indicating direct access + * + * This class defines functions to work with strides which can be used to access entries directly. This class + * inherits DenseCoeffsBase which defines functions to access entries read-only using + * \c operator() . + * + * \sa \ref TopicClassHierarchy + */ +template +class DenseCoeffsBase : public DenseCoeffsBase +{ + public: + + typedef DenseCoeffsBase Base; + typedef typename internal::traits::Index Index; + typedef typename internal::traits::Scalar Scalar; + typedef typename NumTraits::Real RealScalar; + + using Base::rows; + using Base::cols; + using Base::size; + using Base::derived; + + /** \returns the pointer increment between two consecutive elements within a slice in the inner direction. + * + * \sa outerStride(), rowStride(), colStride() + */ + inline Index innerStride() const + { + return derived().innerStride(); + } + + /** \returns the pointer increment between two consecutive inner slices (for example, between two consecutive columns + * in a column-major matrix). + * + * \sa innerStride(), rowStride(), colStride() + */ + inline Index outerStride() const + { + return derived().outerStride(); + } + + // FIXME shall we remove it ? + inline Index stride() const + { + return Derived::IsVectorAtCompileTime ? innerStride() : outerStride(); + } + + /** \returns the pointer increment between two consecutive rows. + * + * \sa innerStride(), outerStride(), colStride() + */ + inline Index rowStride() const + { + return Derived::IsRowMajor ? outerStride() : innerStride(); + } + + /** \returns the pointer increment between two consecutive columns. + * + * \sa innerStride(), outerStride(), rowStride() + */ + inline Index colStride() const + { + return Derived::IsRowMajor ? innerStride() : outerStride(); + } +}; + +/** \brief Base class providing direct read/write coefficient access to matrices and arrays. + * \ingroup Core_Module + * \tparam Derived Type of the derived class + * \tparam #DirectWriteAccessors Constant indicating direct access + * + * This class defines functions to work with strides which can be used to access entries directly. This class + * inherits DenseCoeffsBase which defines functions to access entries read/write using + * \c operator(). + * + * \sa \ref TopicClassHierarchy + */ +template +class DenseCoeffsBase + : public DenseCoeffsBase +{ + public: + + typedef DenseCoeffsBase Base; + typedef typename internal::traits::Index Index; + typedef typename internal::traits::Scalar Scalar; + typedef typename NumTraits::Real RealScalar; + + using Base::rows; + using Base::cols; + using Base::size; + using Base::derived; + + /** \returns the pointer increment between two consecutive elements within a slice in the inner direction. + * + * \sa outerStride(), rowStride(), colStride() + */ + inline Index innerStride() const + { + return derived().innerStride(); + } + + /** \returns the pointer increment between two consecutive inner slices (for example, between two consecutive columns + * in a column-major matrix). + * + * \sa innerStride(), rowStride(), colStride() + */ + inline Index outerStride() const + { + return derived().outerStride(); + } + + // FIXME shall we remove it ? + inline Index stride() const + { + return Derived::IsVectorAtCompileTime ? innerStride() : outerStride(); + } + + /** \returns the pointer increment between two consecutive rows. + * + * \sa innerStride(), outerStride(), colStride() + */ + inline Index rowStride() const + { + return Derived::IsRowMajor ? outerStride() : innerStride(); + } + + /** \returns the pointer increment between two consecutive columns. + * + * \sa innerStride(), outerStride(), rowStride() + */ + inline Index colStride() const + { + return Derived::IsRowMajor ? innerStride() : outerStride(); + } +}; + +namespace internal { + +template +struct first_aligned_impl +{ + static inline typename Derived::Index run(const Derived&) + { return 0; } +}; + +template +struct first_aligned_impl +{ + static inline typename Derived::Index run(const Derived& m) + { + return internal::first_aligned(&m.const_cast_derived().coeffRef(0,0), m.size()); + } +}; + +/** \internal \returns the index of the first element of the array that is well aligned for vectorization. + * + * There is also the variant first_aligned(const Scalar*, Integer) defined in Memory.h. See it for more + * documentation. + */ +template +static inline typename Derived::Index first_aligned(const Derived& m) +{ + return first_aligned_impl + + ::run(m); +} + +template::ret> +struct inner_stride_at_compile_time +{ + enum { ret = traits::InnerStrideAtCompileTime }; +}; + +template +struct inner_stride_at_compile_time +{ + enum { ret = 0 }; +}; + +template::ret> +struct outer_stride_at_compile_time +{ + enum { ret = traits::OuterStrideAtCompileTime }; +}; + +template +struct outer_stride_at_compile_time +{ + enum { ret = 0 }; +}; + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_DENSECOEFFSBASE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/DenseStorage.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/DenseStorage.h new file mode 100644 index 00000000..568493cb --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/DenseStorage.h @@ -0,0 +1,434 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008 Gael Guennebaud +// Copyright (C) 2006-2009 Benoit Jacob +// Copyright (C) 2010 Hauke Heibel +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_MATRIXSTORAGE_H +#define EIGEN_MATRIXSTORAGE_H + +#ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN + #define EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN EIGEN_DENSE_STORAGE_CTOR_PLUGIN; +#else + #define EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN +#endif + +namespace Eigen { + +namespace internal { + +struct constructor_without_unaligned_array_assert {}; + +template void check_static_allocation_size() +{ + // if EIGEN_STACK_ALLOCATION_LIMIT is defined to 0, then no limit + #if EIGEN_STACK_ALLOCATION_LIMIT + EIGEN_STATIC_ASSERT(Size * sizeof(T) <= EIGEN_STACK_ALLOCATION_LIMIT, OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG); + #endif +} + +/** \internal + * Static array. If the MatrixOrArrayOptions require auto-alignment, the array will be automatically aligned: + * to 16 bytes boundary if the total size is a multiple of 16 bytes. + */ +template +struct plain_array +{ + T array[Size]; + + plain_array() + { + check_static_allocation_size(); + } + + plain_array(constructor_without_unaligned_array_assert) + { + check_static_allocation_size(); + } +}; + +#if defined(EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT) + #define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask) +#elif EIGEN_GNUC_AT_LEAST(4,7) + // GCC 4.7 is too aggressive in its optimizations and remove the alignement test based on the fact the array is declared to be aligned. + // See this bug report: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53900 + // Hiding the origin of the array pointer behind a function argument seems to do the trick even if the function is inlined: + template + EIGEN_ALWAYS_INLINE PtrType eigen_unaligned_array_assert_workaround_gcc47(PtrType array) { return array; } + #define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask) \ + eigen_assert((reinterpret_cast(eigen_unaligned_array_assert_workaround_gcc47(array)) & sizemask) == 0 \ + && "this assertion is explained here: " \ + "http://eigen.tuxfamily.org/dox-devel/group__TopicUnalignedArrayAssert.html" \ + " **** READ THIS WEB PAGE !!! ****"); +#else + #define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask) \ + eigen_assert((reinterpret_cast(array) & sizemask) == 0 \ + && "this assertion is explained here: " \ + "http://eigen.tuxfamily.org/dox-devel/group__TopicUnalignedArrayAssert.html" \ + " **** READ THIS WEB PAGE !!! ****"); +#endif + +template +struct plain_array +{ + EIGEN_USER_ALIGN16 T array[Size]; + + plain_array() + { + EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(0xf); + check_static_allocation_size(); + } + + plain_array(constructor_without_unaligned_array_assert) + { + check_static_allocation_size(); + } +}; + +template +struct plain_array +{ + EIGEN_USER_ALIGN16 T array[1]; + plain_array() {} + plain_array(constructor_without_unaligned_array_assert) {} +}; + +} // end namespace internal + +/** \internal + * + * \class DenseStorage + * \ingroup Core_Module + * + * \brief Stores the data of a matrix + * + * This class stores the data of fixed-size, dynamic-size or mixed matrices + * in a way as compact as possible. + * + * \sa Matrix + */ +template class DenseStorage; + +// purely fixed-size matrix +template class DenseStorage +{ + internal::plain_array m_data; + public: + DenseStorage() {} + DenseStorage(internal::constructor_without_unaligned_array_assert) + : m_data(internal::constructor_without_unaligned_array_assert()) {} + DenseStorage(const DenseStorage& other) : m_data(other.m_data) {} + DenseStorage& operator=(const DenseStorage& other) + { + if (this != &other) m_data = other.m_data; + return *this; + } + DenseStorage(DenseIndex,DenseIndex,DenseIndex) {} + void swap(DenseStorage& other) { std::swap(m_data,other.m_data); } + static DenseIndex rows(void) {return _Rows;} + static DenseIndex cols(void) {return _Cols;} + void conservativeResize(DenseIndex,DenseIndex,DenseIndex) {} + void resize(DenseIndex,DenseIndex,DenseIndex) {} + const T *data() const { return m_data.array; } + T *data() { return m_data.array; } +}; + +// null matrix +template class DenseStorage +{ + public: + DenseStorage() {} + DenseStorage(internal::constructor_without_unaligned_array_assert) {} + DenseStorage(const DenseStorage&) {} + DenseStorage& operator=(const DenseStorage&) { return *this; } + DenseStorage(DenseIndex,DenseIndex,DenseIndex) {} + void swap(DenseStorage& ) {} + static DenseIndex rows(void) {return _Rows;} + static DenseIndex cols(void) {return _Cols;} + void conservativeResize(DenseIndex,DenseIndex,DenseIndex) {} + void resize(DenseIndex,DenseIndex,DenseIndex) {} + const T *data() const { return 0; } + T *data() { return 0; } +}; + +// more specializations for null matrices; these are necessary to resolve ambiguities +template class DenseStorage +: public DenseStorage { }; + +template class DenseStorage +: public DenseStorage { }; + +template class DenseStorage +: public DenseStorage { }; + +// dynamic-size matrix with fixed-size storage +template class DenseStorage +{ + internal::plain_array m_data; + DenseIndex m_rows; + DenseIndex m_cols; + public: + DenseStorage() : m_rows(0), m_cols(0) {} + DenseStorage(internal::constructor_without_unaligned_array_assert) + : m_data(internal::constructor_without_unaligned_array_assert()), m_rows(0), m_cols(0) {} + DenseStorage(const DenseStorage& other) : m_data(other.m_data), m_rows(other.m_rows), m_cols(other.m_cols) {} + DenseStorage& operator=(const DenseStorage& other) + { + if (this != &other) + { + m_data = other.m_data; + m_rows = other.m_rows; + m_cols = other.m_cols; + } + return *this; + } + DenseStorage(DenseIndex, DenseIndex nbRows, DenseIndex nbCols) : m_rows(nbRows), m_cols(nbCols) {} + void swap(DenseStorage& other) + { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); std::swap(m_cols,other.m_cols); } + DenseIndex rows() const {return m_rows;} + DenseIndex cols() const {return m_cols;} + void conservativeResize(DenseIndex, DenseIndex nbRows, DenseIndex nbCols) { m_rows = nbRows; m_cols = nbCols; } + void resize(DenseIndex, DenseIndex nbRows, DenseIndex nbCols) { m_rows = nbRows; m_cols = nbCols; } + const T *data() const { return m_data.array; } + T *data() { return m_data.array; } +}; + +// dynamic-size matrix with fixed-size storage and fixed width +template class DenseStorage +{ + internal::plain_array m_data; + DenseIndex m_rows; + public: + DenseStorage() : m_rows(0) {} + DenseStorage(internal::constructor_without_unaligned_array_assert) + : m_data(internal::constructor_without_unaligned_array_assert()), m_rows(0) {} + DenseStorage(const DenseStorage& other) : m_data(other.m_data), m_rows(other.m_rows) {} + DenseStorage& operator=(const DenseStorage& other) + { + if (this != &other) + { + m_data = other.m_data; + m_rows = other.m_rows; + } + return *this; + } + DenseStorage(DenseIndex, DenseIndex nbRows, DenseIndex) : m_rows(nbRows) {} + void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); } + DenseIndex rows(void) const {return m_rows;} + DenseIndex cols(void) const {return _Cols;} + void conservativeResize(DenseIndex, DenseIndex nbRows, DenseIndex) { m_rows = nbRows; } + void resize(DenseIndex, DenseIndex nbRows, DenseIndex) { m_rows = nbRows; } + const T *data() const { return m_data.array; } + T *data() { return m_data.array; } +}; + +// dynamic-size matrix with fixed-size storage and fixed height +template class DenseStorage +{ + internal::plain_array m_data; + DenseIndex m_cols; + public: + DenseStorage() : m_cols(0) {} + DenseStorage(internal::constructor_without_unaligned_array_assert) + : m_data(internal::constructor_without_unaligned_array_assert()), m_cols(0) {} + DenseStorage(const DenseStorage& other) : m_data(other.m_data), m_cols(other.m_cols) {} + DenseStorage& operator=(const DenseStorage& other) + { + if (this != &other) + { + m_data = other.m_data; + m_cols = other.m_cols; + } + return *this; + } + DenseStorage(DenseIndex, DenseIndex, DenseIndex nbCols) : m_cols(nbCols) {} + void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); } + DenseIndex rows(void) const {return _Rows;} + DenseIndex cols(void) const {return m_cols;} + void conservativeResize(DenseIndex, DenseIndex, DenseIndex nbCols) { m_cols = nbCols; } + void resize(DenseIndex, DenseIndex, DenseIndex nbCols) { m_cols = nbCols; } + const T *data() const { return m_data.array; } + T *data() { return m_data.array; } +}; + +// purely dynamic matrix. +template class DenseStorage +{ + T *m_data; + DenseIndex m_rows; + DenseIndex m_cols; + public: + DenseStorage() : m_data(0), m_rows(0), m_cols(0) {} + DenseStorage(internal::constructor_without_unaligned_array_assert) + : m_data(0), m_rows(0), m_cols(0) {} + DenseStorage(DenseIndex size, DenseIndex nbRows, DenseIndex nbCols) + : m_data(internal::conditional_aligned_new_auto(size)), m_rows(nbRows), m_cols(nbCols) + { EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN } +#ifdef EIGEN_HAVE_RVALUE_REFERENCES + DenseStorage(DenseStorage&& other) + : m_data(std::move(other.m_data)) + , m_rows(std::move(other.m_rows)) + , m_cols(std::move(other.m_cols)) + { + other.m_data = nullptr; + } + DenseStorage& operator=(DenseStorage&& other) + { + using std::swap; + swap(m_data, other.m_data); + swap(m_rows, other.m_rows); + swap(m_cols, other.m_cols); + return *this; + } +#endif + ~DenseStorage() { internal::conditional_aligned_delete_auto(m_data, m_rows*m_cols); } + void swap(DenseStorage& other) + { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); std::swap(m_cols,other.m_cols); } + DenseIndex rows(void) const {return m_rows;} + DenseIndex cols(void) const {return m_cols;} + void conservativeResize(DenseIndex size, DenseIndex nbRows, DenseIndex nbCols) + { + m_data = internal::conditional_aligned_realloc_new_auto(m_data, size, m_rows*m_cols); + m_rows = nbRows; + m_cols = nbCols; + } + void resize(DenseIndex size, DenseIndex nbRows, DenseIndex nbCols) + { + if(size != m_rows*m_cols) + { + internal::conditional_aligned_delete_auto(m_data, m_rows*m_cols); + if (size) + m_data = internal::conditional_aligned_new_auto(size); + else + m_data = 0; + EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN + } + m_rows = nbRows; + m_cols = nbCols; + } + const T *data() const { return m_data; } + T *data() { return m_data; } + private: + DenseStorage(const DenseStorage&); + DenseStorage& operator=(const DenseStorage&); +}; + +// matrix with dynamic width and fixed height (so that matrix has dynamic size). +template class DenseStorage +{ + T *m_data; + DenseIndex m_cols; + public: + DenseStorage() : m_data(0), m_cols(0) {} + DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_cols(0) {} + DenseStorage(DenseIndex size, DenseIndex, DenseIndex nbCols) : m_data(internal::conditional_aligned_new_auto(size)), m_cols(nbCols) + { EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN } +#ifdef EIGEN_HAVE_RVALUE_REFERENCES + DenseStorage(DenseStorage&& other) + : m_data(std::move(other.m_data)) + , m_cols(std::move(other.m_cols)) + { + other.m_data = nullptr; + } + DenseStorage& operator=(DenseStorage&& other) + { + using std::swap; + swap(m_data, other.m_data); + swap(m_cols, other.m_cols); + return *this; + } +#endif + ~DenseStorage() { internal::conditional_aligned_delete_auto(m_data, _Rows*m_cols); } + void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); } + static DenseIndex rows(void) {return _Rows;} + DenseIndex cols(void) const {return m_cols;} + void conservativeResize(DenseIndex size, DenseIndex, DenseIndex nbCols) + { + m_data = internal::conditional_aligned_realloc_new_auto(m_data, size, _Rows*m_cols); + m_cols = nbCols; + } + EIGEN_STRONG_INLINE void resize(DenseIndex size, DenseIndex, DenseIndex nbCols) + { + if(size != _Rows*m_cols) + { + internal::conditional_aligned_delete_auto(m_data, _Rows*m_cols); + if (size) + m_data = internal::conditional_aligned_new_auto(size); + else + m_data = 0; + EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN + } + m_cols = nbCols; + } + const T *data() const { return m_data; } + T *data() { return m_data; } + private: + DenseStorage(const DenseStorage&); + DenseStorage& operator=(const DenseStorage&); +}; + +// matrix with dynamic height and fixed width (so that matrix has dynamic size). +template class DenseStorage +{ + T *m_data; + DenseIndex m_rows; + public: + DenseStorage() : m_data(0), m_rows(0) {} + DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_rows(0) {} + DenseStorage(DenseIndex size, DenseIndex nbRows, DenseIndex) : m_data(internal::conditional_aligned_new_auto(size)), m_rows(nbRows) + { EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN } +#ifdef EIGEN_HAVE_RVALUE_REFERENCES + DenseStorage(DenseStorage&& other) + : m_data(std::move(other.m_data)) + , m_rows(std::move(other.m_rows)) + { + other.m_data = nullptr; + } + DenseStorage& operator=(DenseStorage&& other) + { + using std::swap; + swap(m_data, other.m_data); + swap(m_rows, other.m_rows); + return *this; + } +#endif + ~DenseStorage() { internal::conditional_aligned_delete_auto(m_data, _Cols*m_rows); } + void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); } + DenseIndex rows(void) const {return m_rows;} + static DenseIndex cols(void) {return _Cols;} + void conservativeResize(DenseIndex size, DenseIndex nbRows, DenseIndex) + { + m_data = internal::conditional_aligned_realloc_new_auto(m_data, size, m_rows*_Cols); + m_rows = nbRows; + } + EIGEN_STRONG_INLINE void resize(DenseIndex size, DenseIndex nbRows, DenseIndex) + { + if(size != m_rows*_Cols) + { + internal::conditional_aligned_delete_auto(m_data, _Cols*m_rows); + if (size) + m_data = internal::conditional_aligned_new_auto(size); + else + m_data = 0; + EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN + } + m_rows = nbRows; + } + const T *data() const { return m_data; } + T *data() { return m_data; } + private: + DenseStorage(const DenseStorage&); + DenseStorage& operator=(const DenseStorage&); +}; + +} // end namespace Eigen + +#endif // EIGEN_MATRIX_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/Diagonal.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/Diagonal.h new file mode 100644 index 00000000..68cf6d4b --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/Diagonal.h @@ -0,0 +1,237 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2007-2009 Benoit Jacob +// Copyright (C) 2009-2010 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_DIAGONAL_H +#define EIGEN_DIAGONAL_H + +namespace Eigen { + +/** \class Diagonal + * \ingroup Core_Module + * + * \brief Expression of a diagonal/subdiagonal/superdiagonal in a matrix + * + * \param MatrixType the type of the object in which we are taking a sub/main/super diagonal + * \param DiagIndex the index of the sub/super diagonal. The default is 0 and it means the main diagonal. + * A positive value means a superdiagonal, a negative value means a subdiagonal. + * You can also use Dynamic so the index can be set at runtime. + * + * The matrix is not required to be square. + * + * This class represents an expression of the main diagonal, or any sub/super diagonal + * of a square matrix. It is the return type of MatrixBase::diagonal() and MatrixBase::diagonal(Index) and most of the + * time this is the only way it is used. + * + * \sa MatrixBase::diagonal(), MatrixBase::diagonal(Index) + */ + +namespace internal { +template +struct traits > + : traits +{ + typedef typename nested::type MatrixTypeNested; + typedef typename remove_reference::type _MatrixTypeNested; + typedef typename MatrixType::StorageKind StorageKind; + enum { + RowsAtCompileTime = (int(DiagIndex) == DynamicIndex || int(MatrixType::SizeAtCompileTime) == Dynamic) ? Dynamic + : (EIGEN_PLAIN_ENUM_MIN(MatrixType::RowsAtCompileTime - EIGEN_PLAIN_ENUM_MAX(-DiagIndex, 0), + MatrixType::ColsAtCompileTime - EIGEN_PLAIN_ENUM_MAX( DiagIndex, 0))), + ColsAtCompileTime = 1, + MaxRowsAtCompileTime = int(MatrixType::MaxSizeAtCompileTime) == Dynamic ? Dynamic + : DiagIndex == DynamicIndex ? EIGEN_SIZE_MIN_PREFER_FIXED(MatrixType::MaxRowsAtCompileTime, + MatrixType::MaxColsAtCompileTime) + : (EIGEN_PLAIN_ENUM_MIN(MatrixType::MaxRowsAtCompileTime - EIGEN_PLAIN_ENUM_MAX(-DiagIndex, 0), + MatrixType::MaxColsAtCompileTime - EIGEN_PLAIN_ENUM_MAX( DiagIndex, 0))), + MaxColsAtCompileTime = 1, + MaskLvalueBit = is_lvalue::value ? LvalueBit : 0, + Flags = (unsigned int)_MatrixTypeNested::Flags & (HereditaryBits | LinearAccessBit | MaskLvalueBit | DirectAccessBit) & ~RowMajorBit, + CoeffReadCost = _MatrixTypeNested::CoeffReadCost, + MatrixTypeOuterStride = outer_stride_at_compile_time::ret, + InnerStrideAtCompileTime = MatrixTypeOuterStride == Dynamic ? Dynamic : MatrixTypeOuterStride+1, + OuterStrideAtCompileTime = 0 + }; +}; +} + +template class Diagonal + : public internal::dense_xpr_base< Diagonal >::type +{ + public: + + enum { DiagIndex = _DiagIndex }; + typedef typename internal::dense_xpr_base::type Base; + EIGEN_DENSE_PUBLIC_INTERFACE(Diagonal) + + inline Diagonal(MatrixType& matrix, Index a_index = DiagIndex) : m_matrix(matrix), m_index(a_index) {} + + EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Diagonal) + + inline Index rows() const + { return m_index.value()<0 ? (std::min)(m_matrix.cols(),m_matrix.rows()+m_index.value()) : (std::min)(m_matrix.rows(),m_matrix.cols()-m_index.value()); } + + inline Index cols() const { return 1; } + + inline Index innerStride() const + { + return m_matrix.outerStride() + 1; + } + + inline Index outerStride() const + { + return 0; + } + + typedef typename internal::conditional< + internal::is_lvalue::value, + Scalar, + const Scalar + >::type ScalarWithConstIfNotLvalue; + + inline ScalarWithConstIfNotLvalue* data() { return &(m_matrix.const_cast_derived().coeffRef(rowOffset(), colOffset())); } + inline const Scalar* data() const { return &(m_matrix.const_cast_derived().coeffRef(rowOffset(), colOffset())); } + + inline Scalar& coeffRef(Index row, Index) + { + EIGEN_STATIC_ASSERT_LVALUE(MatrixType) + return m_matrix.const_cast_derived().coeffRef(row+rowOffset(), row+colOffset()); + } + + inline const Scalar& coeffRef(Index row, Index) const + { + return m_matrix.const_cast_derived().coeffRef(row+rowOffset(), row+colOffset()); + } + + inline CoeffReturnType coeff(Index row, Index) const + { + return m_matrix.coeff(row+rowOffset(), row+colOffset()); + } + + inline Scalar& coeffRef(Index idx) + { + EIGEN_STATIC_ASSERT_LVALUE(MatrixType) + return m_matrix.const_cast_derived().coeffRef(idx+rowOffset(), idx+colOffset()); + } + + inline const Scalar& coeffRef(Index idx) const + { + return m_matrix.const_cast_derived().coeffRef(idx+rowOffset(), idx+colOffset()); + } + + inline CoeffReturnType coeff(Index idx) const + { + return m_matrix.coeff(idx+rowOffset(), idx+colOffset()); + } + + const typename internal::remove_all::type& + nestedExpression() const + { + return m_matrix; + } + + int index() const + { + return m_index.value(); + } + + protected: + typename MatrixType::Nested m_matrix; + const internal::variable_if_dynamicindex m_index; + + private: + // some compilers may fail to optimize std::max etc in case of compile-time constants... + EIGEN_STRONG_INLINE Index absDiagIndex() const { return m_index.value()>0 ? m_index.value() : -m_index.value(); } + EIGEN_STRONG_INLINE Index rowOffset() const { return m_index.value()>0 ? 0 : -m_index.value(); } + EIGEN_STRONG_INLINE Index colOffset() const { return m_index.value()>0 ? m_index.value() : 0; } + // triger a compile time error is someone try to call packet + template typename MatrixType::PacketReturnType packet(Index) const; + template typename MatrixType::PacketReturnType packet(Index,Index) const; +}; + +/** \returns an expression of the main diagonal of the matrix \c *this + * + * \c *this is not required to be square. + * + * Example: \include MatrixBase_diagonal.cpp + * Output: \verbinclude MatrixBase_diagonal.out + * + * \sa class Diagonal */ +template +inline typename MatrixBase::DiagonalReturnType +MatrixBase::diagonal() +{ + return derived(); +} + +/** This is the const version of diagonal(). */ +template +inline typename MatrixBase::ConstDiagonalReturnType +MatrixBase::diagonal() const +{ + return ConstDiagonalReturnType(derived()); +} + +/** \returns an expression of the \a DiagIndex-th sub or super diagonal of the matrix \c *this + * + * \c *this is not required to be square. + * + * The template parameter \a DiagIndex represent a super diagonal if \a DiagIndex > 0 + * and a sub diagonal otherwise. \a DiagIndex == 0 is equivalent to the main diagonal. + * + * Example: \include MatrixBase_diagonal_int.cpp + * Output: \verbinclude MatrixBase_diagonal_int.out + * + * \sa MatrixBase::diagonal(), class Diagonal */ +template +inline typename MatrixBase::DiagonalDynamicIndexReturnType +MatrixBase::diagonal(Index index) +{ + return DiagonalDynamicIndexReturnType(derived(), index); +} + +/** This is the const version of diagonal(Index). */ +template +inline typename MatrixBase::ConstDiagonalDynamicIndexReturnType +MatrixBase::diagonal(Index index) const +{ + return ConstDiagonalDynamicIndexReturnType(derived(), index); +} + +/** \returns an expression of the \a DiagIndex-th sub or super diagonal of the matrix \c *this + * + * \c *this is not required to be square. + * + * The template parameter \a DiagIndex represent a super diagonal if \a DiagIndex > 0 + * and a sub diagonal otherwise. \a DiagIndex == 0 is equivalent to the main diagonal. + * + * Example: \include MatrixBase_diagonal_template_int.cpp + * Output: \verbinclude MatrixBase_diagonal_template_int.out + * + * \sa MatrixBase::diagonal(), class Diagonal */ +template +template +inline typename MatrixBase::template DiagonalIndexReturnType::Type +MatrixBase::diagonal() +{ + return derived(); +} + +/** This is the const version of diagonal(). */ +template +template +inline typename MatrixBase::template ConstDiagonalIndexReturnType::Type +MatrixBase::diagonal() const +{ + return derived(); +} + +} // end namespace Eigen + +#endif // EIGEN_DIAGONAL_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/DiagonalMatrix.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/DiagonalMatrix.h new file mode 100644 index 00000000..e6c220f4 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/DiagonalMatrix.h @@ -0,0 +1,313 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2009 Gael Guennebaud +// Copyright (C) 2007-2009 Benoit Jacob +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_DIAGONALMATRIX_H +#define EIGEN_DIAGONALMATRIX_H + +namespace Eigen { + +#ifndef EIGEN_PARSED_BY_DOXYGEN +template +class DiagonalBase : public EigenBase +{ + public: + typedef typename internal::traits::DiagonalVectorType DiagonalVectorType; + typedef typename DiagonalVectorType::Scalar Scalar; + typedef typename DiagonalVectorType::RealScalar RealScalar; + typedef typename internal::traits::StorageKind StorageKind; + typedef typename internal::traits::Index Index; + + enum { + RowsAtCompileTime = DiagonalVectorType::SizeAtCompileTime, + ColsAtCompileTime = DiagonalVectorType::SizeAtCompileTime, + MaxRowsAtCompileTime = DiagonalVectorType::MaxSizeAtCompileTime, + MaxColsAtCompileTime = DiagonalVectorType::MaxSizeAtCompileTime, + IsVectorAtCompileTime = 0, + Flags = 0 + }; + + typedef Matrix DenseMatrixType; + typedef DenseMatrixType DenseType; + typedef DiagonalMatrix PlainObject; + + inline const Derived& derived() const { return *static_cast(this); } + inline Derived& derived() { return *static_cast(this); } + + DenseMatrixType toDenseMatrix() const { return derived(); } + template + void evalTo(MatrixBase &other) const; + template + void addTo(MatrixBase &other) const + { other.diagonal() += diagonal(); } + template + void subTo(MatrixBase &other) const + { other.diagonal() -= diagonal(); } + + inline const DiagonalVectorType& diagonal() const { return derived().diagonal(); } + inline DiagonalVectorType& diagonal() { return derived().diagonal(); } + + inline Index rows() const { return diagonal().size(); } + inline Index cols() const { return diagonal().size(); } + + /** \returns the diagonal matrix product of \c *this by the matrix \a matrix. + */ + template + const DiagonalProduct + operator*(const MatrixBase &matrix) const + { + return DiagonalProduct(matrix.derived(), derived()); + } + + inline const DiagonalWrapper, const DiagonalVectorType> > + inverse() const + { + return diagonal().cwiseInverse(); + } + + inline const DiagonalWrapper, const DiagonalVectorType> > + operator*(const Scalar& scalar) const + { + return diagonal() * scalar; + } + friend inline const DiagonalWrapper, const DiagonalVectorType> > + operator*(const Scalar& scalar, const DiagonalBase& other) + { + return other.diagonal() * scalar; + } + + #ifdef EIGEN2_SUPPORT + template + bool isApprox(const DiagonalBase& other, typename NumTraits::Real precision = NumTraits::dummy_precision()) const + { + return diagonal().isApprox(other.diagonal(), precision); + } + template + bool isApprox(const MatrixBase& other, typename NumTraits::Real precision = NumTraits::dummy_precision()) const + { + return toDenseMatrix().isApprox(other, precision); + } + #endif +}; + +template +template +void DiagonalBase::evalTo(MatrixBase &other) const +{ + other.setZero(); + other.diagonal() = diagonal(); +} +#endif + +/** \class DiagonalMatrix + * \ingroup Core_Module + * + * \brief Represents a diagonal matrix with its storage + * + * \param _Scalar the type of coefficients + * \param SizeAtCompileTime the dimension of the matrix, or Dynamic + * \param MaxSizeAtCompileTime the dimension of the matrix, or Dynamic. This parameter is optional and defaults + * to SizeAtCompileTime. Most of the time, you do not need to specify it. + * + * \sa class DiagonalWrapper + */ + +namespace internal { +template +struct traits > + : traits > +{ + typedef Matrix<_Scalar,SizeAtCompileTime,1,0,MaxSizeAtCompileTime,1> DiagonalVectorType; + typedef Dense StorageKind; + typedef DenseIndex Index; + enum { + Flags = LvalueBit + }; +}; +} +template +class DiagonalMatrix + : public DiagonalBase > +{ + public: + #ifndef EIGEN_PARSED_BY_DOXYGEN + typedef typename internal::traits::DiagonalVectorType DiagonalVectorType; + typedef const DiagonalMatrix& Nested; + typedef _Scalar Scalar; + typedef typename internal::traits::StorageKind StorageKind; + typedef typename internal::traits::Index Index; + #endif + + protected: + + DiagonalVectorType m_diagonal; + + public: + + /** const version of diagonal(). */ + inline const DiagonalVectorType& diagonal() const { return m_diagonal; } + /** \returns a reference to the stored vector of diagonal coefficients. */ + inline DiagonalVectorType& diagonal() { return m_diagonal; } + + /** Default constructor without initialization */ + inline DiagonalMatrix() {} + + /** Constructs a diagonal matrix with given dimension */ + inline DiagonalMatrix(Index dim) : m_diagonal(dim) {} + + /** 2D constructor. */ + inline DiagonalMatrix(const Scalar& x, const Scalar& y) : m_diagonal(x,y) {} + + /** 3D constructor. */ + inline DiagonalMatrix(const Scalar& x, const Scalar& y, const Scalar& z) : m_diagonal(x,y,z) {} + + /** Copy constructor. */ + template + inline DiagonalMatrix(const DiagonalBase& other) : m_diagonal(other.diagonal()) {} + + #ifndef EIGEN_PARSED_BY_DOXYGEN + /** copy constructor. prevent a default copy constructor from hiding the other templated constructor */ + inline DiagonalMatrix(const DiagonalMatrix& other) : m_diagonal(other.diagonal()) {} + #endif + + /** generic constructor from expression of the diagonal coefficients */ + template + explicit inline DiagonalMatrix(const MatrixBase& other) : m_diagonal(other) + {} + + /** Copy operator. */ + template + DiagonalMatrix& operator=(const DiagonalBase& other) + { + m_diagonal = other.diagonal(); + return *this; + } + + #ifndef EIGEN_PARSED_BY_DOXYGEN + /** This is a special case of the templated operator=. Its purpose is to + * prevent a default operator= from hiding the templated operator=. + */ + DiagonalMatrix& operator=(const DiagonalMatrix& other) + { + m_diagonal = other.diagonal(); + return *this; + } + #endif + + /** Resizes to given size. */ + inline void resize(Index size) { m_diagonal.resize(size); } + /** Sets all coefficients to zero. */ + inline void setZero() { m_diagonal.setZero(); } + /** Resizes and sets all coefficients to zero. */ + inline void setZero(Index size) { m_diagonal.setZero(size); } + /** Sets this matrix to be the identity matrix of the current size. */ + inline void setIdentity() { m_diagonal.setOnes(); } + /** Sets this matrix to be the identity matrix of the given size. */ + inline void setIdentity(Index size) { m_diagonal.setOnes(size); } +}; + +/** \class DiagonalWrapper + * \ingroup Core_Module + * + * \brief Expression of a diagonal matrix + * + * \param _DiagonalVectorType the type of the vector of diagonal coefficients + * + * This class is an expression of a diagonal matrix, but not storing its own vector of diagonal coefficients, + * instead wrapping an existing vector expression. It is the return type of MatrixBase::asDiagonal() + * and most of the time this is the only way that it is used. + * + * \sa class DiagonalMatrix, class DiagonalBase, MatrixBase::asDiagonal() + */ + +namespace internal { +template +struct traits > +{ + typedef _DiagonalVectorType DiagonalVectorType; + typedef typename DiagonalVectorType::Scalar Scalar; + typedef typename DiagonalVectorType::Index Index; + typedef typename DiagonalVectorType::StorageKind StorageKind; + enum { + RowsAtCompileTime = DiagonalVectorType::SizeAtCompileTime, + ColsAtCompileTime = DiagonalVectorType::SizeAtCompileTime, + MaxRowsAtCompileTime = DiagonalVectorType::SizeAtCompileTime, + MaxColsAtCompileTime = DiagonalVectorType::SizeAtCompileTime, + Flags = traits::Flags & LvalueBit + }; +}; +} + +template +class DiagonalWrapper + : public DiagonalBase >, internal::no_assignment_operator +{ + public: + #ifndef EIGEN_PARSED_BY_DOXYGEN + typedef _DiagonalVectorType DiagonalVectorType; + typedef DiagonalWrapper Nested; + #endif + + /** Constructor from expression of diagonal coefficients to wrap. */ + inline DiagonalWrapper(DiagonalVectorType& a_diagonal) : m_diagonal(a_diagonal) {} + + /** \returns a const reference to the wrapped expression of diagonal coefficients. */ + const DiagonalVectorType& diagonal() const { return m_diagonal; } + + protected: + typename DiagonalVectorType::Nested m_diagonal; +}; + +/** \returns a pseudo-expression of a diagonal matrix with *this as vector of diagonal coefficients + * + * \only_for_vectors + * + * Example: \include MatrixBase_asDiagonal.cpp + * Output: \verbinclude MatrixBase_asDiagonal.out + * + * \sa class DiagonalWrapper, class DiagonalMatrix, diagonal(), isDiagonal() + **/ +template +inline const DiagonalWrapper +MatrixBase::asDiagonal() const +{ + return derived(); +} + +/** \returns true if *this is approximately equal to a diagonal matrix, + * within the precision given by \a prec. + * + * Example: \include MatrixBase_isDiagonal.cpp + * Output: \verbinclude MatrixBase_isDiagonal.out + * + * \sa asDiagonal() + */ +template +bool MatrixBase::isDiagonal(const RealScalar& prec) const +{ + using std::abs; + if(cols() != rows()) return false; + RealScalar maxAbsOnDiagonal = static_cast(-1); + for(Index j = 0; j < cols(); ++j) + { + RealScalar absOnDiagonal = abs(coeff(j,j)); + if(absOnDiagonal > maxAbsOnDiagonal) maxAbsOnDiagonal = absOnDiagonal; + } + for(Index j = 0; j < cols(); ++j) + for(Index i = 0; i < j; ++i) + { + if(!internal::isMuchSmallerThan(coeff(i, j), maxAbsOnDiagonal, prec)) return false; + if(!internal::isMuchSmallerThan(coeff(j, i), maxAbsOnDiagonal, prec)) return false; + } + return true; +} + +} // end namespace Eigen + +#endif // EIGEN_DIAGONALMATRIX_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/DiagonalProduct.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/DiagonalProduct.h new file mode 100644 index 00000000..cc6b536e --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/DiagonalProduct.h @@ -0,0 +1,131 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008 Gael Guennebaud +// Copyright (C) 2007-2009 Benoit Jacob +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_DIAGONALPRODUCT_H +#define EIGEN_DIAGONALPRODUCT_H + +namespace Eigen { + +namespace internal { +template +struct traits > + : traits +{ + typedef typename scalar_product_traits::ReturnType Scalar; + enum { + RowsAtCompileTime = MatrixType::RowsAtCompileTime, + ColsAtCompileTime = MatrixType::ColsAtCompileTime, + MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime, + MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime, + + _StorageOrder = MatrixType::Flags & RowMajorBit ? RowMajor : ColMajor, + _ScalarAccessOnDiag = !((int(_StorageOrder) == ColMajor && int(ProductOrder) == OnTheLeft) + ||(int(_StorageOrder) == RowMajor && int(ProductOrder) == OnTheRight)), + _SameTypes = is_same::value, + // FIXME currently we need same types, but in the future the next rule should be the one + //_Vectorizable = bool(int(MatrixType::Flags)&PacketAccessBit) && ((!_PacketOnDiag) || (_SameTypes && bool(int(DiagonalType::DiagonalVectorType::Flags)&PacketAccessBit))), + _Vectorizable = bool(int(MatrixType::Flags)&PacketAccessBit) && _SameTypes && (_ScalarAccessOnDiag || (bool(int(DiagonalType::DiagonalVectorType::Flags)&PacketAccessBit))), + _LinearAccessMask = (RowsAtCompileTime==1 || ColsAtCompileTime==1) ? LinearAccessBit : 0, + + Flags = ((HereditaryBits|_LinearAccessMask|AlignedBit) & (unsigned int)(MatrixType::Flags)) | (_Vectorizable ? PacketAccessBit : 0),//(int(MatrixType::Flags)&int(DiagonalType::DiagonalVectorType::Flags)&AlignedBit), + Cost0 = EIGEN_ADD_COST(NumTraits::MulCost, MatrixType::CoeffReadCost), + CoeffReadCost = EIGEN_ADD_COST(Cost0,DiagonalType::DiagonalVectorType::CoeffReadCost) + }; +}; +} + +template +class DiagonalProduct : internal::no_assignment_operator, + public MatrixBase > +{ + public: + + typedef MatrixBase Base; + EIGEN_DENSE_PUBLIC_INTERFACE(DiagonalProduct) + + inline DiagonalProduct(const MatrixType& matrix, const DiagonalType& diagonal) + : m_matrix(matrix), m_diagonal(diagonal) + { + eigen_assert(diagonal.diagonal().size() == (ProductOrder == OnTheLeft ? matrix.rows() : matrix.cols())); + } + + EIGEN_STRONG_INLINE Index rows() const { return m_matrix.rows(); } + EIGEN_STRONG_INLINE Index cols() const { return m_matrix.cols(); } + + EIGEN_STRONG_INLINE const Scalar coeff(Index row, Index col) const + { + return m_diagonal.diagonal().coeff(ProductOrder == OnTheLeft ? row : col) * m_matrix.coeff(row, col); + } + + EIGEN_STRONG_INLINE const Scalar coeff(Index idx) const + { + enum { + StorageOrder = int(MatrixType::Flags) & RowMajorBit ? RowMajor : ColMajor + }; + return coeff(int(StorageOrder)==ColMajor?idx:0,int(StorageOrder)==ColMajor?0:idx); + } + + template + EIGEN_STRONG_INLINE PacketScalar packet(Index row, Index col) const + { + enum { + StorageOrder = Flags & RowMajorBit ? RowMajor : ColMajor + }; + const Index indexInDiagonalVector = ProductOrder == OnTheLeft ? row : col; + return packet_impl(row,col,indexInDiagonalVector,typename internal::conditional< + ((int(StorageOrder) == RowMajor && int(ProductOrder) == OnTheLeft) + ||(int(StorageOrder) == ColMajor && int(ProductOrder) == OnTheRight)), internal::true_type, internal::false_type>::type()); + } + + template + EIGEN_STRONG_INLINE PacketScalar packet(Index idx) const + { + enum { + StorageOrder = int(MatrixType::Flags) & RowMajorBit ? RowMajor : ColMajor + }; + return packet(int(StorageOrder)==ColMajor?idx:0,int(StorageOrder)==ColMajor?0:idx); + } + + protected: + template + EIGEN_STRONG_INLINE PacketScalar packet_impl(Index row, Index col, Index id, internal::true_type) const + { + return internal::pmul(m_matrix.template packet(row, col), + internal::pset1(m_diagonal.diagonal().coeff(id))); + } + + template + EIGEN_STRONG_INLINE PacketScalar packet_impl(Index row, Index col, Index id, internal::false_type) const + { + enum { + InnerSize = (MatrixType::Flags & RowMajorBit) ? MatrixType::ColsAtCompileTime : MatrixType::RowsAtCompileTime, + DiagonalVectorPacketLoadMode = (LoadMode == Aligned && (((InnerSize%16) == 0) || (int(DiagonalType::DiagonalVectorType::Flags)&AlignedBit)==AlignedBit) ? Aligned : Unaligned) + }; + return internal::pmul(m_matrix.template packet(row, col), + m_diagonal.diagonal().template packet(id)); + } + + typename MatrixType::Nested m_matrix; + typename DiagonalType::Nested m_diagonal; +}; + +/** \returns the diagonal matrix product of \c *this by the diagonal matrix \a diagonal. + */ +template +template +inline const DiagonalProduct +MatrixBase::operator*(const DiagonalBase &a_diagonal) const +{ + return DiagonalProduct(derived(), a_diagonal.derived()); +} + +} // end namespace Eigen + +#endif // EIGEN_DIAGONALPRODUCT_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/Dot.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/Dot.h new file mode 100644 index 00000000..9d7651f1 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/Dot.h @@ -0,0 +1,263 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2006-2008, 2010 Benoit Jacob +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_DOT_H +#define EIGEN_DOT_H + +namespace Eigen { + +namespace internal { + +// helper function for dot(). The problem is that if we put that in the body of dot(), then upon calling dot +// with mismatched types, the compiler emits errors about failing to instantiate cwiseProduct BEFORE +// looking at the static assertions. Thus this is a trick to get better compile errors. +template +struct dot_nocheck +{ + typedef typename scalar_product_traits::Scalar,typename traits::Scalar>::ReturnType ResScalar; + static inline ResScalar run(const MatrixBase& a, const MatrixBase& b) + { + return a.template binaryExpr::Scalar,typename traits::Scalar> >(b).sum(); + } +}; + +template +struct dot_nocheck +{ + typedef typename scalar_product_traits::Scalar,typename traits::Scalar>::ReturnType ResScalar; + static inline ResScalar run(const MatrixBase& a, const MatrixBase& b) + { + return a.transpose().template binaryExpr::Scalar,typename traits::Scalar> >(b).sum(); + } +}; + +} // end namespace internal + +/** \returns the dot product of *this with other. + * + * \only_for_vectors + * + * \note If the scalar type is complex numbers, then this function returns the hermitian + * (sesquilinear) dot product, conjugate-linear in the first variable and linear in the + * second variable. + * + * \sa squaredNorm(), norm() + */ +template +template +typename internal::scalar_product_traits::Scalar,typename internal::traits::Scalar>::ReturnType +MatrixBase::dot(const MatrixBase& other) const +{ + EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) + EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived) + EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(Derived,OtherDerived) + typedef internal::scalar_conj_product_op func; + EIGEN_CHECK_BINARY_COMPATIBILIY(func,Scalar,typename OtherDerived::Scalar); + + eigen_assert(size() == other.size()); + + return internal::dot_nocheck::run(*this, other); +} + +#ifdef EIGEN2_SUPPORT +/** \returns the dot product of *this with other, with the Eigen2 convention that the dot product is linear in the first variable + * (conjugating the second variable). Of course this only makes a difference in the complex case. + * + * This method is only available in EIGEN2_SUPPORT mode. + * + * \only_for_vectors + * + * \sa dot() + */ +template +template +typename internal::traits::Scalar +MatrixBase::eigen2_dot(const MatrixBase& other) const +{ + EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) + EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived) + EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(Derived,OtherDerived) + EIGEN_STATIC_ASSERT((internal::is_same::value), + YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) + + eigen_assert(size() == other.size()); + + return internal::dot_nocheck::run(other,*this); +} +#endif + + +//---------- implementation of L2 norm and related functions ---------- + +/** \returns, for vectors, the squared \em l2 norm of \c *this, and for matrices the Frobenius norm. + * In both cases, it consists in the sum of the square of all the matrix entries. + * For vectors, this is also equals to the dot product of \c *this with itself. + * + * \sa dot(), norm() + */ +template +EIGEN_STRONG_INLINE typename NumTraits::Scalar>::Real MatrixBase::squaredNorm() const +{ + return numext::real((*this).cwiseAbs2().sum()); +} + +/** \returns, for vectors, the \em l2 norm of \c *this, and for matrices the Frobenius norm. + * In both cases, it consists in the square root of the sum of the square of all the matrix entries. + * For vectors, this is also equals to the square root of the dot product of \c *this with itself. + * + * \sa dot(), squaredNorm() + */ +template +inline typename NumTraits::Scalar>::Real MatrixBase::norm() const +{ + using std::sqrt; + return sqrt(squaredNorm()); +} + +/** \returns an expression of the quotient of *this by its own norm. + * + * \only_for_vectors + * + * \sa norm(), normalize() + */ +template +inline const typename MatrixBase::PlainObject +MatrixBase::normalized() const +{ + typedef typename internal::nested::type Nested; + typedef typename internal::remove_reference::type _Nested; + _Nested n(derived()); + return n / n.norm(); +} + +/** Normalizes the vector, i.e. divides it by its own norm. + * + * \only_for_vectors + * + * \sa norm(), normalized() + */ +template +inline void MatrixBase::normalize() +{ + *this /= norm(); +} + +//---------- implementation of other norms ---------- + +namespace internal { + +template +struct lpNorm_selector +{ + typedef typename NumTraits::Scalar>::Real RealScalar; + static inline RealScalar run(const MatrixBase& m) + { + using std::pow; + return pow(m.cwiseAbs().array().pow(p).sum(), RealScalar(1)/p); + } +}; + +template +struct lpNorm_selector +{ + static inline typename NumTraits::Scalar>::Real run(const MatrixBase& m) + { + return m.cwiseAbs().sum(); + } +}; + +template +struct lpNorm_selector +{ + static inline typename NumTraits::Scalar>::Real run(const MatrixBase& m) + { + return m.norm(); + } +}; + +template +struct lpNorm_selector +{ + static inline typename NumTraits::Scalar>::Real run(const MatrixBase& m) + { + return m.cwiseAbs().maxCoeff(); + } +}; + +} // end namespace internal + +/** \returns the \f$ \ell^p \f$ norm of *this, that is, returns the p-th root of the sum of the p-th powers of the absolute values + * of the coefficients of *this. If \a p is the special value \a Eigen::Infinity, this function returns the \f$ \ell^\infty \f$ + * norm, that is the maximum of the absolute values of the coefficients of *this. + * + * \sa norm() + */ +template +template +inline typename NumTraits::Scalar>::Real +MatrixBase::lpNorm() const +{ + return internal::lpNorm_selector::run(*this); +} + +//---------- implementation of isOrthogonal / isUnitary ---------- + +/** \returns true if *this is approximately orthogonal to \a other, + * within the precision given by \a prec. + * + * Example: \include MatrixBase_isOrthogonal.cpp + * Output: \verbinclude MatrixBase_isOrthogonal.out + */ +template +template +bool MatrixBase::isOrthogonal +(const MatrixBase& other, const RealScalar& prec) const +{ + typename internal::nested::type nested(derived()); + typename internal::nested::type otherNested(other.derived()); + return numext::abs2(nested.dot(otherNested)) <= prec * prec * nested.squaredNorm() * otherNested.squaredNorm(); +} + +/** \returns true if *this is approximately an unitary matrix, + * within the precision given by \a prec. In the case where the \a Scalar + * type is real numbers, a unitary matrix is an orthogonal matrix, whence the name. + * + * \note This can be used to check whether a family of vectors forms an orthonormal basis. + * Indeed, \c m.isUnitary() returns true if and only if the columns (equivalently, the rows) of m form an + * orthonormal basis. + * + * Example: \include MatrixBase_isUnitary.cpp + * Output: \verbinclude MatrixBase_isUnitary.out + */ +template +bool MatrixBase::isUnitary(const RealScalar& prec) const +{ + typename Derived::Nested nested(derived()); + for(Index i = 0; i < cols(); ++i) + { + if(!internal::isApprox(nested.col(i).squaredNorm(), static_cast(1), prec)) + return false; + for(Index j = 0; j < i; ++j) + if(!internal::isMuchSmallerThan(nested.col(i).dot(nested.col(j)), static_cast(1), prec)) + return false; + } + return true; +} + +} // end namespace Eigen + +#endif // EIGEN_DOT_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/EigenBase.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/EigenBase.h new file mode 100644 index 00000000..fadb4585 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/EigenBase.h @@ -0,0 +1,131 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2009 Benoit Jacob +// Copyright (C) 2009 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_EIGENBASE_H +#define EIGEN_EIGENBASE_H + +namespace Eigen { + +/** Common base class for all classes T such that MatrixBase has an operator=(T) and a constructor MatrixBase(T). + * + * In other words, an EigenBase object is an object that can be copied into a MatrixBase. + * + * Besides MatrixBase-derived classes, this also includes special matrix classes such as diagonal matrices, etc. + * + * Notice that this class is trivial, it is only used to disambiguate overloaded functions. + * + * \sa \ref TopicClassHierarchy + */ +template struct EigenBase +{ +// typedef typename internal::plain_matrix_type::type PlainObject; + + typedef typename internal::traits::StorageKind StorageKind; + typedef typename internal::traits::Index Index; + + /** \returns a reference to the derived object */ + Derived& derived() { return *static_cast(this); } + /** \returns a const reference to the derived object */ + const Derived& derived() const { return *static_cast(this); } + + inline Derived& const_cast_derived() const + { return *static_cast(const_cast(this)); } + inline const Derived& const_derived() const + { return *static_cast(this); } + + /** \returns the number of rows. \sa cols(), RowsAtCompileTime */ + inline Index rows() const { return derived().rows(); } + /** \returns the number of columns. \sa rows(), ColsAtCompileTime*/ + inline Index cols() const { return derived().cols(); } + /** \returns the number of coefficients, which is rows()*cols(). + * \sa rows(), cols(), SizeAtCompileTime. */ + inline Index size() const { return rows() * cols(); } + + /** \internal Don't use it, but do the equivalent: \code dst = *this; \endcode */ + template inline void evalTo(Dest& dst) const + { derived().evalTo(dst); } + + /** \internal Don't use it, but do the equivalent: \code dst += *this; \endcode */ + template inline void addTo(Dest& dst) const + { + // This is the default implementation, + // derived class can reimplement it in a more optimized way. + typename Dest::PlainObject res(rows(),cols()); + evalTo(res); + dst += res; + } + + /** \internal Don't use it, but do the equivalent: \code dst -= *this; \endcode */ + template inline void subTo(Dest& dst) const + { + // This is the default implementation, + // derived class can reimplement it in a more optimized way. + typename Dest::PlainObject res(rows(),cols()); + evalTo(res); + dst -= res; + } + + /** \internal Don't use it, but do the equivalent: \code dst.applyOnTheRight(*this); \endcode */ + template inline void applyThisOnTheRight(Dest& dst) const + { + // This is the default implementation, + // derived class can reimplement it in a more optimized way. + dst = dst * this->derived(); + } + + /** \internal Don't use it, but do the equivalent: \code dst.applyOnTheLeft(*this); \endcode */ + template inline void applyThisOnTheLeft(Dest& dst) const + { + // This is the default implementation, + // derived class can reimplement it in a more optimized way. + dst = this->derived() * dst; + } + +}; + +/*************************************************************************** +* Implementation of matrix base methods +***************************************************************************/ + +/** \brief Copies the generic expression \a other into *this. + * + * \details The expression must provide a (templated) evalTo(Derived& dst) const + * function which does the actual job. In practice, this allows any user to write + * its own special matrix without having to modify MatrixBase + * + * \returns a reference to *this. + */ +template +template +Derived& DenseBase::operator=(const EigenBase &other) +{ + other.derived().evalTo(derived()); + return derived(); +} + +template +template +Derived& DenseBase::operator+=(const EigenBase &other) +{ + other.derived().addTo(derived()); + return derived(); +} + +template +template +Derived& DenseBase::operator-=(const EigenBase &other) +{ + other.derived().subTo(derived()); + return derived(); +} + +} // end namespace Eigen + +#endif // EIGEN_EIGENBASE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/Flagged.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/Flagged.h new file mode 100644 index 00000000..1f2955fc --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/Flagged.h @@ -0,0 +1,140 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008 Benoit Jacob +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_FLAGGED_H +#define EIGEN_FLAGGED_H + +namespace Eigen { + +/** \class Flagged + * \ingroup Core_Module + * + * \brief Expression with modified flags + * + * \param ExpressionType the type of the object of which we are modifying the flags + * \param Added the flags added to the expression + * \param Removed the flags removed from the expression (has priority over Added). + * + * This class represents an expression whose flags have been modified. + * It is the return type of MatrixBase::flagged() + * and most of the time this is the only way it is used. + * + * \sa MatrixBase::flagged() + */ + +namespace internal { +template +struct traits > : traits +{ + enum { Flags = (ExpressionType::Flags | Added) & ~Removed }; +}; +} + +template class Flagged + : public MatrixBase > +{ + public: + + typedef MatrixBase Base; + + EIGEN_DENSE_PUBLIC_INTERFACE(Flagged) + typedef typename internal::conditional::ret, + ExpressionType, const ExpressionType&>::type ExpressionTypeNested; + typedef typename ExpressionType::InnerIterator InnerIterator; + + inline Flagged(const ExpressionType& matrix) : m_matrix(matrix) {} + + inline Index rows() const { return m_matrix.rows(); } + inline Index cols() const { return m_matrix.cols(); } + inline Index outerStride() const { return m_matrix.outerStride(); } + inline Index innerStride() const { return m_matrix.innerStride(); } + + inline CoeffReturnType coeff(Index row, Index col) const + { + return m_matrix.coeff(row, col); + } + + inline CoeffReturnType coeff(Index index) const + { + return m_matrix.coeff(index); + } + + inline const Scalar& coeffRef(Index row, Index col) const + { + return m_matrix.const_cast_derived().coeffRef(row, col); + } + + inline const Scalar& coeffRef(Index index) const + { + return m_matrix.const_cast_derived().coeffRef(index); + } + + inline Scalar& coeffRef(Index row, Index col) + { + return m_matrix.const_cast_derived().coeffRef(row, col); + } + + inline Scalar& coeffRef(Index index) + { + return m_matrix.const_cast_derived().coeffRef(index); + } + + template + inline const PacketScalar packet(Index row, Index col) const + { + return m_matrix.template packet(row, col); + } + + template + inline void writePacket(Index row, Index col, const PacketScalar& x) + { + m_matrix.const_cast_derived().template writePacket(row, col, x); + } + + template + inline const PacketScalar packet(Index index) const + { + return m_matrix.template packet(index); + } + + template + inline void writePacket(Index index, const PacketScalar& x) + { + m_matrix.const_cast_derived().template writePacket(index, x); + } + + const ExpressionType& _expression() const { return m_matrix; } + + template + typename ExpressionType::PlainObject solveTriangular(const MatrixBase& other) const; + + template + void solveTriangularInPlace(const MatrixBase& other) const; + + protected: + ExpressionTypeNested m_matrix; +}; + +/** \returns an expression of *this with added and removed flags + * + * This is mostly for internal use. + * + * \sa class Flagged + */ +template +template +inline const Flagged +DenseBase::flagged() const +{ + return derived(); +} + +} // end namespace Eigen + +#endif // EIGEN_FLAGGED_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/ForceAlignedAccess.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/ForceAlignedAccess.h new file mode 100644 index 00000000..807c7a29 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/ForceAlignedAccess.h @@ -0,0 +1,146 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2009-2010 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_FORCEALIGNEDACCESS_H +#define EIGEN_FORCEALIGNEDACCESS_H + +namespace Eigen { + +/** \class ForceAlignedAccess + * \ingroup Core_Module + * + * \brief Enforce aligned packet loads and stores regardless of what is requested + * + * \param ExpressionType the type of the object of which we are forcing aligned packet access + * + * This class is the return type of MatrixBase::forceAlignedAccess() + * and most of the time this is the only way it is used. + * + * \sa MatrixBase::forceAlignedAccess() + */ + +namespace internal { +template +struct traits > : public traits +{}; +} + +template class ForceAlignedAccess + : public internal::dense_xpr_base< ForceAlignedAccess >::type +{ + public: + + typedef typename internal::dense_xpr_base::type Base; + EIGEN_DENSE_PUBLIC_INTERFACE(ForceAlignedAccess) + + inline ForceAlignedAccess(const ExpressionType& matrix) : m_expression(matrix) {} + + inline Index rows() const { return m_expression.rows(); } + inline Index cols() const { return m_expression.cols(); } + inline Index outerStride() const { return m_expression.outerStride(); } + inline Index innerStride() const { return m_expression.innerStride(); } + + inline const CoeffReturnType coeff(Index row, Index col) const + { + return m_expression.coeff(row, col); + } + + inline Scalar& coeffRef(Index row, Index col) + { + return m_expression.const_cast_derived().coeffRef(row, col); + } + + inline const CoeffReturnType coeff(Index index) const + { + return m_expression.coeff(index); + } + + inline Scalar& coeffRef(Index index) + { + return m_expression.const_cast_derived().coeffRef(index); + } + + template + inline const PacketScalar packet(Index row, Index col) const + { + return m_expression.template packet(row, col); + } + + template + inline void writePacket(Index row, Index col, const PacketScalar& x) + { + m_expression.const_cast_derived().template writePacket(row, col, x); + } + + template + inline const PacketScalar packet(Index index) const + { + return m_expression.template packet(index); + } + + template + inline void writePacket(Index index, const PacketScalar& x) + { + m_expression.const_cast_derived().template writePacket(index, x); + } + + operator const ExpressionType&() const { return m_expression; } + + protected: + const ExpressionType& m_expression; + + private: + ForceAlignedAccess& operator=(const ForceAlignedAccess&); +}; + +/** \returns an expression of *this with forced aligned access + * \sa forceAlignedAccessIf(),class ForceAlignedAccess + */ +template +inline const ForceAlignedAccess +MatrixBase::forceAlignedAccess() const +{ + return ForceAlignedAccess(derived()); +} + +/** \returns an expression of *this with forced aligned access + * \sa forceAlignedAccessIf(), class ForceAlignedAccess + */ +template +inline ForceAlignedAccess +MatrixBase::forceAlignedAccess() +{ + return ForceAlignedAccess(derived()); +} + +/** \returns an expression of *this with forced aligned access if \a Enable is true. + * \sa forceAlignedAccess(), class ForceAlignedAccess + */ +template +template +inline typename internal::add_const_on_value_type,Derived&>::type>::type +MatrixBase::forceAlignedAccessIf() const +{ + return derived(); +} + +/** \returns an expression of *this with forced aligned access if \a Enable is true. + * \sa forceAlignedAccess(), class ForceAlignedAccess + */ +template +template +inline typename internal::conditional,Derived&>::type +MatrixBase::forceAlignedAccessIf() +{ + return derived(); +} + +} // end namespace Eigen + +#endif // EIGEN_FORCEALIGNEDACCESS_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/Functors.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/Functors.h new file mode 100644 index 00000000..5f14c658 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/Functors.h @@ -0,0 +1,1026 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008-2010 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_FUNCTORS_H +#define EIGEN_FUNCTORS_H + +namespace Eigen { + +namespace internal { + +// associative functors: + +/** \internal + * \brief Template functor to compute the sum of two scalars + * + * \sa class CwiseBinaryOp, MatrixBase::operator+, class VectorwiseOp, MatrixBase::sum() + */ +template struct scalar_sum_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_sum_op) + EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a + b; } + template + EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const + { return internal::padd(a,b); } + template + EIGEN_STRONG_INLINE const Scalar predux(const Packet& a) const + { return internal::predux(a); } +}; +template +struct functor_traits > { + enum { + Cost = NumTraits::AddCost, + PacketAccess = packet_traits::HasAdd + }; +}; + +/** \internal + * \brief Template functor to compute the product of two scalars + * + * \sa class CwiseBinaryOp, Cwise::operator*(), class VectorwiseOp, MatrixBase::redux() + */ +template struct scalar_product_op { + enum { + // TODO vectorize mixed product + Vectorizable = is_same::value && packet_traits::HasMul && packet_traits::HasMul + }; + typedef typename scalar_product_traits::ReturnType result_type; + EIGEN_EMPTY_STRUCT_CTOR(scalar_product_op) + EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a * b; } + template + EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const + { return internal::pmul(a,b); } + template + EIGEN_STRONG_INLINE const result_type predux(const Packet& a) const + { return internal::predux_mul(a); } +}; +template +struct functor_traits > { + enum { + Cost = (NumTraits::MulCost + NumTraits::MulCost)/2, // rough estimate! + PacketAccess = scalar_product_op::Vectorizable + }; +}; + +/** \internal + * \brief Template functor to compute the conjugate product of two scalars + * + * This is a short cut for conj(x) * y which is needed for optimization purpose; in Eigen2 support mode, this becomes x * conj(y) + */ +template struct scalar_conj_product_op { + + enum { + Conj = NumTraits::IsComplex + }; + + typedef typename scalar_product_traits::ReturnType result_type; + + EIGEN_EMPTY_STRUCT_CTOR(scalar_conj_product_op) + EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const + { return conj_helper().pmul(a,b); } + + template + EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const + { return conj_helper().pmul(a,b); } +}; +template +struct functor_traits > { + enum { + Cost = NumTraits::MulCost, + PacketAccess = internal::is_same::value && packet_traits::HasMul + }; +}; + +/** \internal + * \brief Template functor to compute the min of two scalars + * + * \sa class CwiseBinaryOp, MatrixBase::cwiseMin, class VectorwiseOp, MatrixBase::minCoeff() + */ +template struct scalar_min_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_min_op) + EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { using std::min; return (min)(a, b); } + template + EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const + { return internal::pmin(a,b); } + template + EIGEN_STRONG_INLINE const Scalar predux(const Packet& a) const + { return internal::predux_min(a); } +}; +template +struct functor_traits > { + enum { + Cost = NumTraits::AddCost, + PacketAccess = packet_traits::HasMin + }; +}; + +/** \internal + * \brief Template functor to compute the max of two scalars + * + * \sa class CwiseBinaryOp, MatrixBase::cwiseMax, class VectorwiseOp, MatrixBase::maxCoeff() + */ +template struct scalar_max_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_max_op) + EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { using std::max; return (max)(a, b); } + template + EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const + { return internal::pmax(a,b); } + template + EIGEN_STRONG_INLINE const Scalar predux(const Packet& a) const + { return internal::predux_max(a); } +}; +template +struct functor_traits > { + enum { + Cost = NumTraits::AddCost, + PacketAccess = packet_traits::HasMax + }; +}; + +/** \internal + * \brief Template functor to compute the hypot of two scalars + * + * \sa MatrixBase::stableNorm(), class Redux + */ +template struct scalar_hypot_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_hypot_op) +// typedef typename NumTraits::Real result_type; + EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& _x, const Scalar& _y) const + { + using std::max; + using std::min; + using std::sqrt; + Scalar p = (max)(_x, _y); + Scalar q = (min)(_x, _y); + Scalar qp = q/p; + return p * sqrt(Scalar(1) + qp*qp); + } +}; +template +struct functor_traits > { + enum { Cost = 5 * NumTraits::MulCost, PacketAccess=0 }; +}; + +/** \internal + * \brief Template functor to compute the pow of two scalars + */ +template struct scalar_binary_pow_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_binary_pow_op) + inline Scalar operator() (const Scalar& a, const OtherScalar& b) const { return numext::pow(a, b); } +}; +template +struct functor_traits > { + enum { Cost = 5 * NumTraits::MulCost, PacketAccess = false }; +}; + +// other binary functors: + +/** \internal + * \brief Template functor to compute the difference of two scalars + * + * \sa class CwiseBinaryOp, MatrixBase::operator- + */ +template struct scalar_difference_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_difference_op) + EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a - b; } + template + EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const + { return internal::psub(a,b); } +}; +template +struct functor_traits > { + enum { + Cost = NumTraits::AddCost, + PacketAccess = packet_traits::HasSub + }; +}; + +/** \internal + * \brief Template functor to compute the quotient of two scalars + * + * \sa class CwiseBinaryOp, Cwise::operator/() + */ +template struct scalar_quotient_op { + enum { + // TODO vectorize mixed product + Vectorizable = is_same::value && packet_traits::HasDiv && packet_traits::HasDiv + }; + typedef typename scalar_product_traits::ReturnType result_type; + EIGEN_EMPTY_STRUCT_CTOR(scalar_quotient_op) + EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a / b; } + template + EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const + { return internal::pdiv(a,b); } +}; +template +struct functor_traits > { + enum { + Cost = (NumTraits::MulCost + NumTraits::MulCost), // rough estimate! + PacketAccess = scalar_quotient_op::Vectorizable + }; +}; + + + +/** \internal + * \brief Template functor to compute the and of two booleans + * + * \sa class CwiseBinaryOp, ArrayBase::operator&& + */ +struct scalar_boolean_and_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_boolean_and_op) + EIGEN_STRONG_INLINE bool operator() (const bool& a, const bool& b) const { return a && b; } +}; +template<> struct functor_traits { + enum { + Cost = NumTraits::AddCost, + PacketAccess = false + }; +}; + +/** \internal + * \brief Template functor to compute the or of two booleans + * + * \sa class CwiseBinaryOp, ArrayBase::operator|| + */ +struct scalar_boolean_or_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_boolean_or_op) + EIGEN_STRONG_INLINE bool operator() (const bool& a, const bool& b) const { return a || b; } +}; +template<> struct functor_traits { + enum { + Cost = NumTraits::AddCost, + PacketAccess = false + }; +}; + +/** \internal + * \brief Template functors for comparison of two scalars + * \todo Implement packet-comparisons + */ +template struct scalar_cmp_op; + +template +struct functor_traits > { + enum { + Cost = NumTraits::AddCost, + PacketAccess = false + }; +}; + +template +struct result_of(Scalar,Scalar)> { + typedef bool type; +}; + + +template struct scalar_cmp_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op) + EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return a==b;} +}; +template struct scalar_cmp_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op) + EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return a struct scalar_cmp_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op) + EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return a<=b;} +}; +template struct scalar_cmp_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op) + EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return !(a<=b || b<=a);} +}; +template struct scalar_cmp_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op) + EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return a!=b;} +}; + +// unary functors: + +/** \internal + * \brief Template functor to compute the opposite of a scalar + * + * \sa class CwiseUnaryOp, MatrixBase::operator- + */ +template struct scalar_opposite_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_opposite_op) + EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return -a; } + template + EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const + { return internal::pnegate(a); } +}; +template +struct functor_traits > +{ enum { + Cost = NumTraits::AddCost, + PacketAccess = packet_traits::HasNegate }; +}; + +/** \internal + * \brief Template functor to compute the absolute value of a scalar + * + * \sa class CwiseUnaryOp, Cwise::abs + */ +template struct scalar_abs_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_abs_op) + typedef typename NumTraits::Real result_type; + EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { using std::abs; return abs(a); } + template + EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const + { return internal::pabs(a); } +}; +template +struct functor_traits > +{ + enum { + Cost = NumTraits::AddCost, + PacketAccess = packet_traits::HasAbs + }; +}; + +/** \internal + * \brief Template functor to compute the squared absolute value of a scalar + * + * \sa class CwiseUnaryOp, Cwise::abs2 + */ +template struct scalar_abs2_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_abs2_op) + typedef typename NumTraits::Real result_type; + EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return numext::abs2(a); } + template + EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const + { return internal::pmul(a,a); } +}; +template +struct functor_traits > +{ enum { Cost = NumTraits::MulCost, PacketAccess = packet_traits::HasAbs2 }; }; + +/** \internal + * \brief Template functor to compute the conjugate of a complex value + * + * \sa class CwiseUnaryOp, MatrixBase::conjugate() + */ +template struct scalar_conjugate_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_conjugate_op) + EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { using numext::conj; return conj(a); } + template + EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const { return internal::pconj(a); } +}; +template +struct functor_traits > +{ + enum { + Cost = NumTraits::IsComplex ? NumTraits::AddCost : 0, + PacketAccess = packet_traits::HasConj + }; +}; + +/** \internal + * \brief Template functor to cast a scalar to another type + * + * \sa class CwiseUnaryOp, MatrixBase::cast() + */ +template +struct scalar_cast_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_cast_op) + typedef NewType result_type; + EIGEN_STRONG_INLINE const NewType operator() (const Scalar& a) const { return cast(a); } +}; +template +struct functor_traits > +{ enum { Cost = is_same::value ? 0 : NumTraits::AddCost, PacketAccess = false }; }; + +/** \internal + * \brief Template functor to extract the real part of a complex + * + * \sa class CwiseUnaryOp, MatrixBase::real() + */ +template +struct scalar_real_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_real_op) + typedef typename NumTraits::Real result_type; + EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return numext::real(a); } +}; +template +struct functor_traits > +{ enum { Cost = 0, PacketAccess = false }; }; + +/** \internal + * \brief Template functor to extract the imaginary part of a complex + * + * \sa class CwiseUnaryOp, MatrixBase::imag() + */ +template +struct scalar_imag_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_imag_op) + typedef typename NumTraits::Real result_type; + EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return numext::imag(a); } +}; +template +struct functor_traits > +{ enum { Cost = 0, PacketAccess = false }; }; + +/** \internal + * \brief Template functor to extract the real part of a complex as a reference + * + * \sa class CwiseUnaryOp, MatrixBase::real() + */ +template +struct scalar_real_ref_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_real_ref_op) + typedef typename NumTraits::Real result_type; + EIGEN_STRONG_INLINE result_type& operator() (const Scalar& a) const { return numext::real_ref(*const_cast(&a)); } +}; +template +struct functor_traits > +{ enum { Cost = 0, PacketAccess = false }; }; + +/** \internal + * \brief Template functor to extract the imaginary part of a complex as a reference + * + * \sa class CwiseUnaryOp, MatrixBase::imag() + */ +template +struct scalar_imag_ref_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_imag_ref_op) + typedef typename NumTraits::Real result_type; + EIGEN_STRONG_INLINE result_type& operator() (const Scalar& a) const { return numext::imag_ref(*const_cast(&a)); } +}; +template +struct functor_traits > +{ enum { Cost = 0, PacketAccess = false }; }; + +/** \internal + * + * \brief Template functor to compute the exponential of a scalar + * + * \sa class CwiseUnaryOp, Cwise::exp() + */ +template struct scalar_exp_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_exp_op) + inline const Scalar operator() (const Scalar& a) const { using std::exp; return exp(a); } + typedef typename packet_traits::type Packet; + inline Packet packetOp(const Packet& a) const { return internal::pexp(a); } +}; +template +struct functor_traits > +{ enum { Cost = 5 * NumTraits::MulCost, PacketAccess = packet_traits::HasExp }; }; + +/** \internal + * + * \brief Template functor to compute the logarithm of a scalar + * + * \sa class CwiseUnaryOp, Cwise::log() + */ +template struct scalar_log_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_log_op) + inline const Scalar operator() (const Scalar& a) const { using std::log; return log(a); } + typedef typename packet_traits::type Packet; + inline Packet packetOp(const Packet& a) const { return internal::plog(a); } +}; +template +struct functor_traits > +{ enum { Cost = 5 * NumTraits::MulCost, PacketAccess = packet_traits::HasLog }; }; + +/** \internal + * \brief Template functor to multiply a scalar by a fixed other one + * + * \sa class CwiseUnaryOp, MatrixBase::operator*, MatrixBase::operator/ + */ +/* NOTE why doing the pset1() in packetOp *is* an optimization ? + * indeed it seems better to declare m_other as a Packet and do the pset1() once + * in the constructor. However, in practice: + * - GCC does not like m_other as a Packet and generate a load every time it needs it + * - on the other hand GCC is able to moves the pset1() outside the loop :) + * - simpler code ;) + * (ICC and gcc 4.4 seems to perform well in both cases, the issue is visible with y = a*x + b*y) + */ +template +struct scalar_multiple_op { + typedef typename packet_traits::type Packet; + // FIXME default copy constructors seems bugged with std::complex<> + EIGEN_STRONG_INLINE scalar_multiple_op(const scalar_multiple_op& other) : m_other(other.m_other) { } + EIGEN_STRONG_INLINE scalar_multiple_op(const Scalar& other) : m_other(other) { } + EIGEN_STRONG_INLINE Scalar operator() (const Scalar& a) const { return a * m_other; } + EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const + { return internal::pmul(a, pset1(m_other)); } + typename add_const_on_value_type::Nested>::type m_other; +}; +template +struct functor_traits > +{ enum { Cost = NumTraits::MulCost, PacketAccess = packet_traits::HasMul }; }; + +template +struct scalar_multiple2_op { + typedef typename scalar_product_traits::ReturnType result_type; + EIGEN_STRONG_INLINE scalar_multiple2_op(const scalar_multiple2_op& other) : m_other(other.m_other) { } + EIGEN_STRONG_INLINE scalar_multiple2_op(const Scalar2& other) : m_other(other) { } + EIGEN_STRONG_INLINE result_type operator() (const Scalar1& a) const { return a * m_other; } + typename add_const_on_value_type::Nested>::type m_other; +}; +template +struct functor_traits > +{ enum { Cost = NumTraits::MulCost, PacketAccess = false }; }; + +/** \internal + * \brief Template functor to divide a scalar by a fixed other one + * + * This functor is used to implement the quotient of a matrix by + * a scalar where the scalar type is not necessarily a floating point type. + * + * \sa class CwiseUnaryOp, MatrixBase::operator/ + */ +template +struct scalar_quotient1_op { + typedef typename packet_traits::type Packet; + // FIXME default copy constructors seems bugged with std::complex<> + EIGEN_STRONG_INLINE scalar_quotient1_op(const scalar_quotient1_op& other) : m_other(other.m_other) { } + EIGEN_STRONG_INLINE scalar_quotient1_op(const Scalar& other) : m_other(other) {} + EIGEN_STRONG_INLINE Scalar operator() (const Scalar& a) const { return a / m_other; } + EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const + { return internal::pdiv(a, pset1(m_other)); } + typename add_const_on_value_type::Nested>::type m_other; +}; +template +struct functor_traits > +{ enum { Cost = 2 * NumTraits::MulCost, PacketAccess = packet_traits::HasDiv }; }; + +// nullary functors + +template +struct scalar_constant_op { + typedef typename packet_traits::type Packet; + EIGEN_STRONG_INLINE scalar_constant_op(const scalar_constant_op& other) : m_other(other.m_other) { } + EIGEN_STRONG_INLINE scalar_constant_op(const Scalar& other) : m_other(other) { } + template + EIGEN_STRONG_INLINE const Scalar operator() (Index, Index = 0) const { return m_other; } + template + EIGEN_STRONG_INLINE const Packet packetOp(Index, Index = 0) const { return internal::pset1(m_other); } + const Scalar m_other; +}; +template +struct functor_traits > +// FIXME replace this packet test by a safe one +{ enum { Cost = 1, PacketAccess = packet_traits::Vectorizable, IsRepeatable = true }; }; + +template struct scalar_identity_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_identity_op) + template + EIGEN_STRONG_INLINE const Scalar operator() (Index row, Index col) const { return row==col ? Scalar(1) : Scalar(0); } +}; +template +struct functor_traits > +{ enum { Cost = NumTraits::AddCost, PacketAccess = false, IsRepeatable = true }; }; + +template struct linspaced_op_impl; + +// linear access for packet ops: +// 1) initialization +// base = [low, ..., low] + ([step, ..., step] * [-size, ..., 0]) +// 2) each step (where size is 1 for coeff access or PacketSize for packet access) +// base += [size*step, ..., size*step] +// +// TODO: Perhaps it's better to initialize lazily (so not in the constructor but in packetOp) +// in order to avoid the padd() in operator() ? +template +struct linspaced_op_impl +{ + typedef typename packet_traits::type Packet; + + linspaced_op_impl(const Scalar& low, const Scalar& step) : + m_low(low), m_step(step), + m_packetStep(pset1(packet_traits::size*step)), + m_base(padd(pset1(low), pmul(pset1(step),plset(-packet_traits::size)))) {} + + template + EIGEN_STRONG_INLINE const Scalar operator() (Index i) const + { + m_base = padd(m_base, pset1(m_step)); + return m_low+Scalar(i)*m_step; + } + + template + EIGEN_STRONG_INLINE const Packet packetOp(Index) const { return m_base = padd(m_base,m_packetStep); } + + const Scalar m_low; + const Scalar m_step; + const Packet m_packetStep; + mutable Packet m_base; +}; + +// random access for packet ops: +// 1) each step +// [low, ..., low] + ( [step, ..., step] * ( [i, ..., i] + [0, ..., size] ) ) +template +struct linspaced_op_impl +{ + typedef typename packet_traits::type Packet; + + linspaced_op_impl(const Scalar& low, const Scalar& step) : + m_low(low), m_step(step), + m_lowPacket(pset1(m_low)), m_stepPacket(pset1(m_step)), m_interPacket(plset(0)) {} + + template + EIGEN_STRONG_INLINE const Scalar operator() (Index i) const { return m_low+i*m_step; } + + template + EIGEN_STRONG_INLINE const Packet packetOp(Index i) const + { return internal::padd(m_lowPacket, pmul(m_stepPacket, padd(pset1(Scalar(i)),m_interPacket))); } + + const Scalar m_low; + const Scalar m_step; + const Packet m_lowPacket; + const Packet m_stepPacket; + const Packet m_interPacket; +}; + +// ----- Linspace functor ---------------------------------------------------------------- + +// Forward declaration (we default to random access which does not really give +// us a speed gain when using packet access but it allows to use the functor in +// nested expressions). +template struct linspaced_op; +template struct functor_traits< linspaced_op > +{ enum { Cost = 1, PacketAccess = packet_traits::HasSetLinear, IsRepeatable = true }; }; +template struct linspaced_op +{ + typedef typename packet_traits::type Packet; + linspaced_op(const Scalar& low, const Scalar& high, DenseIndex num_steps) : impl((num_steps==1 ? high : low), (num_steps==1 ? Scalar() : (high-low)/Scalar(num_steps-1))) {} + + template + EIGEN_STRONG_INLINE const Scalar operator() (Index i) const { return impl(i); } + + // We need this function when assigning e.g. a RowVectorXd to a MatrixXd since + // there row==0 and col is used for the actual iteration. + template + EIGEN_STRONG_INLINE const Scalar operator() (Index row, Index col) const + { + eigen_assert(col==0 || row==0); + return impl(col + row); + } + + template + EIGEN_STRONG_INLINE const Packet packetOp(Index i) const { return impl.packetOp(i); } + + // We need this function when assigning e.g. a RowVectorXd to a MatrixXd since + // there row==0 and col is used for the actual iteration. + template + EIGEN_STRONG_INLINE const Packet packetOp(Index row, Index col) const + { + eigen_assert(col==0 || row==0); + return impl.packetOp(col + row); + } + + // This proxy object handles the actual required temporaries, the different + // implementations (random vs. sequential access) as well as the + // correct piping to size 2/4 packet operations. + const linspaced_op_impl impl; +}; + +// all functors allow linear access, except scalar_identity_op. So we fix here a quick meta +// to indicate whether a functor allows linear access, just always answering 'yes' except for +// scalar_identity_op. +// FIXME move this to functor_traits adding a functor_default +template struct functor_has_linear_access { enum { ret = 1 }; }; +template struct functor_has_linear_access > { enum { ret = 0 }; }; + +// In Eigen, any binary op (Product, CwiseBinaryOp) require the Lhs and Rhs to have the same scalar type, except for multiplication +// where the mixing of different types is handled by scalar_product_traits +// In particular, real * complex is allowed. +// FIXME move this to functor_traits adding a functor_default +template struct functor_is_product_like { enum { ret = 0 }; }; +template struct functor_is_product_like > { enum { ret = 1 }; }; +template struct functor_is_product_like > { enum { ret = 1 }; }; +template struct functor_is_product_like > { enum { ret = 1 }; }; + + +/** \internal + * \brief Template functor to add a scalar to a fixed other one + * \sa class CwiseUnaryOp, Array::operator+ + */ +/* If you wonder why doing the pset1() in packetOp() is an optimization check scalar_multiple_op */ +template +struct scalar_add_op { + typedef typename packet_traits::type Packet; + // FIXME default copy constructors seems bugged with std::complex<> + inline scalar_add_op(const scalar_add_op& other) : m_other(other.m_other) { } + inline scalar_add_op(const Scalar& other) : m_other(other) { } + inline Scalar operator() (const Scalar& a) const { return a + m_other; } + inline const Packet packetOp(const Packet& a) const + { return internal::padd(a, pset1(m_other)); } + const Scalar m_other; +}; +template +struct functor_traits > +{ enum { Cost = NumTraits::AddCost, PacketAccess = packet_traits::HasAdd }; }; + +/** \internal + * \brief Template functor to compute the square root of a scalar + * \sa class CwiseUnaryOp, Cwise::sqrt() + */ +template struct scalar_sqrt_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_sqrt_op) + inline const Scalar operator() (const Scalar& a) const { using std::sqrt; return sqrt(a); } + typedef typename packet_traits::type Packet; + inline Packet packetOp(const Packet& a) const { return internal::psqrt(a); } +}; +template +struct functor_traits > +{ enum { + Cost = 5 * NumTraits::MulCost, + PacketAccess = packet_traits::HasSqrt + }; +}; + +/** \internal + * \brief Template functor to compute the cosine of a scalar + * \sa class CwiseUnaryOp, ArrayBase::cos() + */ +template struct scalar_cos_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_cos_op) + inline Scalar operator() (const Scalar& a) const { using std::cos; return cos(a); } + typedef typename packet_traits::type Packet; + inline Packet packetOp(const Packet& a) const { return internal::pcos(a); } +}; +template +struct functor_traits > +{ + enum { + Cost = 5 * NumTraits::MulCost, + PacketAccess = packet_traits::HasCos + }; +}; + +/** \internal + * \brief Template functor to compute the sine of a scalar + * \sa class CwiseUnaryOp, ArrayBase::sin() + */ +template struct scalar_sin_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_sin_op) + inline const Scalar operator() (const Scalar& a) const { using std::sin; return sin(a); } + typedef typename packet_traits::type Packet; + inline Packet packetOp(const Packet& a) const { return internal::psin(a); } +}; +template +struct functor_traits > +{ + enum { + Cost = 5 * NumTraits::MulCost, + PacketAccess = packet_traits::HasSin + }; +}; + + +/** \internal + * \brief Template functor to compute the tan of a scalar + * \sa class CwiseUnaryOp, ArrayBase::tan() + */ +template struct scalar_tan_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_tan_op) + inline const Scalar operator() (const Scalar& a) const { using std::tan; return tan(a); } + typedef typename packet_traits::type Packet; + inline Packet packetOp(const Packet& a) const { return internal::ptan(a); } +}; +template +struct functor_traits > +{ + enum { + Cost = 5 * NumTraits::MulCost, + PacketAccess = packet_traits::HasTan + }; +}; + +/** \internal + * \brief Template functor to compute the arc cosine of a scalar + * \sa class CwiseUnaryOp, ArrayBase::acos() + */ +template struct scalar_acos_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_acos_op) + inline const Scalar operator() (const Scalar& a) const { using std::acos; return acos(a); } + typedef typename packet_traits::type Packet; + inline Packet packetOp(const Packet& a) const { return internal::pacos(a); } +}; +template +struct functor_traits > +{ + enum { + Cost = 5 * NumTraits::MulCost, + PacketAccess = packet_traits::HasACos + }; +}; + +/** \internal + * \brief Template functor to compute the arc sine of a scalar + * \sa class CwiseUnaryOp, ArrayBase::asin() + */ +template struct scalar_asin_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_asin_op) + inline const Scalar operator() (const Scalar& a) const { using std::asin; return asin(a); } + typedef typename packet_traits::type Packet; + inline Packet packetOp(const Packet& a) const { return internal::pasin(a); } +}; +template +struct functor_traits > +{ + enum { + Cost = 5 * NumTraits::MulCost, + PacketAccess = packet_traits::HasASin + }; +}; + +/** \internal + * \brief Template functor to raise a scalar to a power + * \sa class CwiseUnaryOp, Cwise::pow + */ +template +struct scalar_pow_op { + // FIXME default copy constructors seems bugged with std::complex<> + inline scalar_pow_op(const scalar_pow_op& other) : m_exponent(other.m_exponent) { } + inline scalar_pow_op(const Scalar& exponent) : m_exponent(exponent) {} + inline Scalar operator() (const Scalar& a) const { return numext::pow(a, m_exponent); } + const Scalar m_exponent; +}; +template +struct functor_traits > +{ enum { Cost = 5 * NumTraits::MulCost, PacketAccess = false }; }; + +/** \internal + * \brief Template functor to compute the quotient between a scalar and array entries. + * \sa class CwiseUnaryOp, Cwise::inverse() + */ +template +struct scalar_inverse_mult_op { + scalar_inverse_mult_op(const Scalar& other) : m_other(other) {} + inline Scalar operator() (const Scalar& a) const { return m_other / a; } + template + inline const Packet packetOp(const Packet& a) const + { return internal::pdiv(pset1(m_other),a); } + Scalar m_other; +}; + +/** \internal + * \brief Template functor to compute the inverse of a scalar + * \sa class CwiseUnaryOp, Cwise::inverse() + */ +template +struct scalar_inverse_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_inverse_op) + inline Scalar operator() (const Scalar& a) const { return Scalar(1)/a; } + template + inline const Packet packetOp(const Packet& a) const + { return internal::pdiv(pset1(Scalar(1)),a); } +}; +template +struct functor_traits > +{ enum { Cost = NumTraits::MulCost, PacketAccess = packet_traits::HasDiv }; }; + +/** \internal + * \brief Template functor to compute the square of a scalar + * \sa class CwiseUnaryOp, Cwise::square() + */ +template +struct scalar_square_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_square_op) + inline Scalar operator() (const Scalar& a) const { return a*a; } + template + inline const Packet packetOp(const Packet& a) const + { return internal::pmul(a,a); } +}; +template +struct functor_traits > +{ enum { Cost = NumTraits::MulCost, PacketAccess = packet_traits::HasMul }; }; + +/** \internal + * \brief Template functor to compute the cube of a scalar + * \sa class CwiseUnaryOp, Cwise::cube() + */ +template +struct scalar_cube_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_cube_op) + inline Scalar operator() (const Scalar& a) const { return a*a*a; } + template + inline const Packet packetOp(const Packet& a) const + { return internal::pmul(a,pmul(a,a)); } +}; +template +struct functor_traits > +{ enum { Cost = 2*NumTraits::MulCost, PacketAccess = packet_traits::HasMul }; }; + +// default functor traits for STL functors: + +template +struct functor_traits > +{ enum { Cost = NumTraits::MulCost, PacketAccess = false }; }; + +template +struct functor_traits > +{ enum { Cost = NumTraits::MulCost, PacketAccess = false }; }; + +template +struct functor_traits > +{ enum { Cost = NumTraits::AddCost, PacketAccess = false }; }; + +template +struct functor_traits > +{ enum { Cost = NumTraits::AddCost, PacketAccess = false }; }; + +template +struct functor_traits > +{ enum { Cost = NumTraits::AddCost, PacketAccess = false }; }; + +template +struct functor_traits > +{ enum { Cost = 1, PacketAccess = false }; }; + +template +struct functor_traits > +{ enum { Cost = 1, PacketAccess = false }; }; + +template +struct functor_traits > +{ enum { Cost = 1, PacketAccess = false }; }; + +template +struct functor_traits > +{ enum { Cost = 1, PacketAccess = false }; }; + +template +struct functor_traits > +{ enum { Cost = 1, PacketAccess = false }; }; + +template +struct functor_traits > +{ enum { Cost = 1, PacketAccess = false }; }; + +template +struct functor_traits > +{ enum { Cost = 1, PacketAccess = false }; }; + +template +struct functor_traits > +{ enum { Cost = 1, PacketAccess = false }; }; + +template +struct functor_traits > +{ enum { Cost = 1, PacketAccess = false }; }; + +template +struct functor_traits > +{ enum { Cost = functor_traits::Cost, PacketAccess = false }; }; + +template +struct functor_traits > +{ enum { Cost = functor_traits::Cost, PacketAccess = false }; }; + +template +struct functor_traits > +{ enum { Cost = 1 + functor_traits::Cost, PacketAccess = false }; }; + +template +struct functor_traits > +{ enum { Cost = 1 + functor_traits::Cost, PacketAccess = false }; }; + +#ifdef EIGEN_STDEXT_SUPPORT + +template +struct functor_traits > +{ enum { Cost = 0, PacketAccess = false }; }; + +template +struct functor_traits > +{ enum { Cost = 0, PacketAccess = false }; }; + +template +struct functor_traits > > +{ enum { Cost = 0, PacketAccess = false }; }; + +template +struct functor_traits > > +{ enum { Cost = 0, PacketAccess = false }; }; + +template +struct functor_traits > +{ enum { Cost = functor_traits::Cost + functor_traits::Cost, PacketAccess = false }; }; + +template +struct functor_traits > +{ enum { Cost = functor_traits::Cost + functor_traits::Cost + functor_traits::Cost, PacketAccess = false }; }; + +#endif // EIGEN_STDEXT_SUPPORT + +// allow to add new functors and specializations of functor_traits from outside Eigen. +// this macro is really needed because functor_traits must be specialized after it is declared but before it is used... +#ifdef EIGEN_FUNCTORS_PLUGIN +#include EIGEN_FUNCTORS_PLUGIN +#endif + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_FUNCTORS_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/Fuzzy.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/Fuzzy.h new file mode 100644 index 00000000..fe63bd29 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/Fuzzy.h @@ -0,0 +1,150 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2006-2008 Benoit Jacob +// Copyright (C) 2008 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_FUZZY_H +#define EIGEN_FUZZY_H + +namespace Eigen { + +namespace internal +{ + +template::IsInteger> +struct isApprox_selector +{ + static bool run(const Derived& x, const OtherDerived& y, const typename Derived::RealScalar& prec) + { + using std::min; + typename internal::nested::type nested(x); + typename internal::nested::type otherNested(y); + return (nested - otherNested).cwiseAbs2().sum() <= prec * prec * (min)(nested.cwiseAbs2().sum(), otherNested.cwiseAbs2().sum()); + } +}; + +template +struct isApprox_selector +{ + static bool run(const Derived& x, const OtherDerived& y, const typename Derived::RealScalar&) + { + return x.matrix() == y.matrix(); + } +}; + +template::IsInteger> +struct isMuchSmallerThan_object_selector +{ + static bool run(const Derived& x, const OtherDerived& y, const typename Derived::RealScalar& prec) + { + return x.cwiseAbs2().sum() <= numext::abs2(prec) * y.cwiseAbs2().sum(); + } +}; + +template +struct isMuchSmallerThan_object_selector +{ + static bool run(const Derived& x, const OtherDerived&, const typename Derived::RealScalar&) + { + return x.matrix() == Derived::Zero(x.rows(), x.cols()).matrix(); + } +}; + +template::IsInteger> +struct isMuchSmallerThan_scalar_selector +{ + static bool run(const Derived& x, const typename Derived::RealScalar& y, const typename Derived::RealScalar& prec) + { + return x.cwiseAbs2().sum() <= numext::abs2(prec * y); + } +}; + +template +struct isMuchSmallerThan_scalar_selector +{ + static bool run(const Derived& x, const typename Derived::RealScalar&, const typename Derived::RealScalar&) + { + return x.matrix() == Derived::Zero(x.rows(), x.cols()).matrix(); + } +}; + +} // end namespace internal + + +/** \returns \c true if \c *this is approximately equal to \a other, within the precision + * determined by \a prec. + * + * \note The fuzzy compares are done multiplicatively. Two vectors \f$ v \f$ and \f$ w \f$ + * are considered to be approximately equal within precision \f$ p \f$ if + * \f[ \Vert v - w \Vert \leqslant p\,\min(\Vert v\Vert, \Vert w\Vert). \f] + * For matrices, the comparison is done using the Hilbert-Schmidt norm (aka Frobenius norm + * L2 norm). + * + * \note Because of the multiplicativeness of this comparison, one can't use this function + * to check whether \c *this is approximately equal to the zero matrix or vector. + * Indeed, \c isApprox(zero) returns false unless \c *this itself is exactly the zero matrix + * or vector. If you want to test whether \c *this is zero, use internal::isMuchSmallerThan(const + * RealScalar&, RealScalar) instead. + * + * \sa internal::isMuchSmallerThan(const RealScalar&, RealScalar) const + */ +template +template +bool DenseBase::isApprox( + const DenseBase& other, + const RealScalar& prec +) const +{ + return internal::isApprox_selector::run(derived(), other.derived(), prec); +} + +/** \returns \c true if the norm of \c *this is much smaller than \a other, + * within the precision determined by \a prec. + * + * \note The fuzzy compares are done multiplicatively. A vector \f$ v \f$ is + * considered to be much smaller than \f$ x \f$ within precision \f$ p \f$ if + * \f[ \Vert v \Vert \leqslant p\,\vert x\vert. \f] + * + * For matrices, the comparison is done using the Hilbert-Schmidt norm. For this reason, + * the value of the reference scalar \a other should come from the Hilbert-Schmidt norm + * of a reference matrix of same dimensions. + * + * \sa isApprox(), isMuchSmallerThan(const DenseBase&, RealScalar) const + */ +template +bool DenseBase::isMuchSmallerThan( + const typename NumTraits::Real& other, + const RealScalar& prec +) const +{ + return internal::isMuchSmallerThan_scalar_selector::run(derived(), other, prec); +} + +/** \returns \c true if the norm of \c *this is much smaller than the norm of \a other, + * within the precision determined by \a prec. + * + * \note The fuzzy compares are done multiplicatively. A vector \f$ v \f$ is + * considered to be much smaller than a vector \f$ w \f$ within precision \f$ p \f$ if + * \f[ \Vert v \Vert \leqslant p\,\Vert w\Vert. \f] + * For matrices, the comparison is done using the Hilbert-Schmidt norm. + * + * \sa isApprox(), isMuchSmallerThan(const RealScalar&, RealScalar) const + */ +template +template +bool DenseBase::isMuchSmallerThan( + const DenseBase& other, + const RealScalar& prec +) const +{ + return internal::isMuchSmallerThan_object_selector::run(derived(), other.derived(), prec); +} + +} // end namespace Eigen + +#endif // EIGEN_FUZZY_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/GeneralProduct.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/GeneralProduct.h new file mode 100644 index 00000000..0eae5299 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/GeneralProduct.h @@ -0,0 +1,635 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2006-2008 Benoit Jacob +// Copyright (C) 2008-2011 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_GENERAL_PRODUCT_H +#define EIGEN_GENERAL_PRODUCT_H + +namespace Eigen { + +/** \class GeneralProduct + * \ingroup Core_Module + * + * \brief Expression of the product of two general matrices or vectors + * + * \param LhsNested the type used to store the left-hand side + * \param RhsNested the type used to store the right-hand side + * \param ProductMode the type of the product + * + * This class represents an expression of the product of two general matrices. + * We call a general matrix, a dense matrix with full storage. For instance, + * This excludes triangular, selfadjoint, and sparse matrices. + * It is the return type of the operator* between general matrices. Its template + * arguments are determined automatically by ProductReturnType. Therefore, + * GeneralProduct should never be used direclty. To determine the result type of a + * function which involves a matrix product, use ProductReturnType::Type. + * + * \sa ProductReturnType, MatrixBase::operator*(const MatrixBase&) + */ +template::value> +class GeneralProduct; + +enum { + Large = 2, + Small = 3 +}; + +namespace internal { + +template struct product_type_selector; + +template struct product_size_category +{ + enum { is_large = MaxSize == Dynamic || + Size >= EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD, + value = is_large ? Large + : Size == 1 ? 1 + : Small + }; +}; + +template struct product_type +{ + typedef typename remove_all::type _Lhs; + typedef typename remove_all::type _Rhs; + enum { + MaxRows = _Lhs::MaxRowsAtCompileTime, + Rows = _Lhs::RowsAtCompileTime, + MaxCols = _Rhs::MaxColsAtCompileTime, + Cols = _Rhs::ColsAtCompileTime, + MaxDepth = EIGEN_SIZE_MIN_PREFER_FIXED(_Lhs::MaxColsAtCompileTime, + _Rhs::MaxRowsAtCompileTime), + Depth = EIGEN_SIZE_MIN_PREFER_FIXED(_Lhs::ColsAtCompileTime, + _Rhs::RowsAtCompileTime), + LargeThreshold = EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD + }; + + // the splitting into different lines of code here, introducing the _select enums and the typedef below, + // is to work around an internal compiler error with gcc 4.1 and 4.2. +private: + enum { + rows_select = product_size_category::value, + cols_select = product_size_category::value, + depth_select = product_size_category::value + }; + typedef product_type_selector selector; + +public: + enum { + value = selector::ret + }; +#ifdef EIGEN_DEBUG_PRODUCT + static void debug() + { + EIGEN_DEBUG_VAR(Rows); + EIGEN_DEBUG_VAR(Cols); + EIGEN_DEBUG_VAR(Depth); + EIGEN_DEBUG_VAR(rows_select); + EIGEN_DEBUG_VAR(cols_select); + EIGEN_DEBUG_VAR(depth_select); + EIGEN_DEBUG_VAR(value); + } +#endif +}; + + +/* The following allows to select the kind of product at compile time + * based on the three dimensions of the product. + * This is a compile time mapping from {1,Small,Large}^3 -> {product types} */ +// FIXME I'm not sure the current mapping is the ideal one. +template struct product_type_selector { enum { ret = OuterProduct }; }; +template struct product_type_selector<1, 1, Depth> { enum { ret = InnerProduct }; }; +template<> struct product_type_selector<1, 1, 1> { enum { ret = InnerProduct }; }; +template<> struct product_type_selector { enum { ret = CoeffBasedProductMode }; }; +template<> struct product_type_selector<1, Small,Small> { enum { ret = CoeffBasedProductMode }; }; +template<> struct product_type_selector { enum { ret = CoeffBasedProductMode }; }; +template<> struct product_type_selector { enum { ret = LazyCoeffBasedProductMode }; }; +template<> struct product_type_selector { enum { ret = LazyCoeffBasedProductMode }; }; +template<> struct product_type_selector { enum { ret = LazyCoeffBasedProductMode }; }; +template<> struct product_type_selector<1, Large,Small> { enum { ret = CoeffBasedProductMode }; }; +template<> struct product_type_selector<1, Large,Large> { enum { ret = GemvProduct }; }; +template<> struct product_type_selector<1, Small,Large> { enum { ret = CoeffBasedProductMode }; }; +template<> struct product_type_selector { enum { ret = CoeffBasedProductMode }; }; +template<> struct product_type_selector { enum { ret = GemvProduct }; }; +template<> struct product_type_selector { enum { ret = CoeffBasedProductMode }; }; +template<> struct product_type_selector { enum { ret = GemmProduct }; }; +template<> struct product_type_selector { enum { ret = GemmProduct }; }; +template<> struct product_type_selector { enum { ret = GemmProduct }; }; +template<> struct product_type_selector { enum { ret = GemmProduct }; }; +template<> struct product_type_selector { enum { ret = GemmProduct }; }; +template<> struct product_type_selector { enum { ret = GemmProduct }; }; +template<> struct product_type_selector { enum { ret = GemmProduct }; }; + +} // end namespace internal + +/** \class ProductReturnType + * \ingroup Core_Module + * + * \brief Helper class to get the correct and optimized returned type of operator* + * + * \param Lhs the type of the left-hand side + * \param Rhs the type of the right-hand side + * \param ProductMode the type of the product (determined automatically by internal::product_mode) + * + * This class defines the typename Type representing the optimized product expression + * between two matrix expressions. In practice, using ProductReturnType::Type + * is the recommended way to define the result type of a function returning an expression + * which involve a matrix product. The class Product should never be + * used directly. + * + * \sa class Product, MatrixBase::operator*(const MatrixBase&) + */ +template +struct ProductReturnType +{ + // TODO use the nested type to reduce instanciations ???? +// typedef typename internal::nested::type LhsNested; +// typedef typename internal::nested::type RhsNested; + + typedef GeneralProduct Type; +}; + +template +struct ProductReturnType +{ + typedef typename internal::nested::type >::type LhsNested; + typedef typename internal::nested::type >::type RhsNested; + typedef CoeffBasedProduct Type; +}; + +template +struct ProductReturnType +{ + typedef typename internal::nested::type >::type LhsNested; + typedef typename internal::nested::type >::type RhsNested; + typedef CoeffBasedProduct Type; +}; + +// this is a workaround for sun CC +template +struct LazyProductReturnType : public ProductReturnType +{}; + +/*********************************************************************** +* Implementation of Inner Vector Vector Product +***********************************************************************/ + +// FIXME : maybe the "inner product" could return a Scalar +// instead of a 1x1 matrix ?? +// Pro: more natural for the user +// Cons: this could be a problem if in a meta unrolled algorithm a matrix-matrix +// product ends up to a row-vector times col-vector product... To tackle this use +// case, we could have a specialization for Block with: operator=(Scalar x); + +namespace internal { + +template +struct traits > + : traits::ReturnType,1,1> > +{}; + +} + +template +class GeneralProduct + : internal::no_assignment_operator, + public Matrix::ReturnType,1,1> +{ + typedef Matrix::ReturnType,1,1> Base; + public: + GeneralProduct(const Lhs& lhs, const Rhs& rhs) + { + EIGEN_STATIC_ASSERT((internal::is_same::value), + YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) + + Base::coeffRef(0,0) = (lhs.transpose().cwiseProduct(rhs)).sum(); + } + + /** Convertion to scalar */ + operator const typename Base::Scalar() const { + return Base::coeff(0,0); + } +}; + +/*********************************************************************** +* Implementation of Outer Vector Vector Product +***********************************************************************/ + +namespace internal { + +// Column major +template +EIGEN_DONT_INLINE void outer_product_selector_run(const ProductType& prod, Dest& dest, const Func& func, const false_type&) +{ + typedef typename Dest::Index Index; + // FIXME make sure lhs is sequentially stored + // FIXME not very good if rhs is real and lhs complex while alpha is real too + const Index cols = dest.cols(); + for (Index j=0; j +EIGEN_DONT_INLINE void outer_product_selector_run(const ProductType& prod, Dest& dest, const Func& func, const true_type&) { + typedef typename Dest::Index Index; + // FIXME make sure rhs is sequentially stored + // FIXME not very good if lhs is real and rhs complex while alpha is real too + const Index rows = dest.rows(); + for (Index i=0; i +struct traits > + : traits, Lhs, Rhs> > +{}; + +} + +template +class GeneralProduct + : public ProductBase, Lhs, Rhs> +{ + template struct is_row_major : internal::conditional<(int(T::Flags)&RowMajorBit), internal::true_type, internal::false_type>::type {}; + + public: + EIGEN_PRODUCT_PUBLIC_INTERFACE(GeneralProduct) + + GeneralProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs) + { + EIGEN_STATIC_ASSERT((internal::is_same::value), + YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) + } + + struct set { template void operator()(const Dst& dst, const Src& src) const { dst.const_cast_derived() = src; } }; + struct add { template void operator()(const Dst& dst, const Src& src) const { dst.const_cast_derived() += src; } }; + struct sub { template void operator()(const Dst& dst, const Src& src) const { dst.const_cast_derived() -= src; } }; + struct adds { + Scalar m_scale; + adds(const Scalar& s) : m_scale(s) {} + template void operator()(const Dst& dst, const Src& src) const { + dst.const_cast_derived() += m_scale * src; + } + }; + + template + inline void evalTo(Dest& dest) const { + internal::outer_product_selector_run(*this, dest, set(), is_row_major()); + } + + template + inline void addTo(Dest& dest) const { + internal::outer_product_selector_run(*this, dest, add(), is_row_major()); + } + + template + inline void subTo(Dest& dest) const { + internal::outer_product_selector_run(*this, dest, sub(), is_row_major()); + } + + template void scaleAndAddTo(Dest& dest, const Scalar& alpha) const + { + internal::outer_product_selector_run(*this, dest, adds(alpha), is_row_major()); + } +}; + +/*********************************************************************** +* Implementation of General Matrix Vector Product +***********************************************************************/ + +/* According to the shape/flags of the matrix we have to distinghish 3 different cases: + * 1 - the matrix is col-major, BLAS compatible and M is large => call fast BLAS-like colmajor routine + * 2 - the matrix is row-major, BLAS compatible and N is large => call fast BLAS-like rowmajor routine + * 3 - all other cases are handled using a simple loop along the outer-storage direction. + * Therefore we need a lower level meta selector. + * Furthermore, if the matrix is the rhs, then the product has to be transposed. + */ +namespace internal { + +template +struct traits > + : traits, Lhs, Rhs> > +{}; + +template +struct gemv_selector; + +} // end namespace internal + +template +class GeneralProduct + : public ProductBase, Lhs, Rhs> +{ + public: + EIGEN_PRODUCT_PUBLIC_INTERFACE(GeneralProduct) + + typedef typename Lhs::Scalar LhsScalar; + typedef typename Rhs::Scalar RhsScalar; + + GeneralProduct(const Lhs& a_lhs, const Rhs& a_rhs) : Base(a_lhs,a_rhs) + { +// EIGEN_STATIC_ASSERT((internal::is_same::value), +// YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) + } + + enum { Side = Lhs::IsVectorAtCompileTime ? OnTheLeft : OnTheRight }; + typedef typename internal::conditional::type MatrixType; + + template void scaleAndAddTo(Dest& dst, const Scalar& alpha) const + { + eigen_assert(m_lhs.rows() == dst.rows() && m_rhs.cols() == dst.cols()); + internal::gemv_selector::HasUsableDirectAccess)>::run(*this, dst, alpha); + } +}; + +namespace internal { + +// The vector is on the left => transposition +template +struct gemv_selector +{ + template + static void run(const ProductType& prod, Dest& dest, const typename ProductType::Scalar& alpha) + { + Transpose destT(dest); + enum { OtherStorageOrder = StorageOrder == RowMajor ? ColMajor : RowMajor }; + gemv_selector + ::run(GeneralProduct,Transpose, GemvProduct> + (prod.rhs().transpose(), prod.lhs().transpose()), destT, alpha); + } +}; + +template struct gemv_static_vector_if; + +template +struct gemv_static_vector_if +{ + EIGEN_STRONG_INLINE Scalar* data() { eigen_internal_assert(false && "should never be called"); return 0; } +}; + +template +struct gemv_static_vector_if +{ + EIGEN_STRONG_INLINE Scalar* data() { return 0; } +}; + +template +struct gemv_static_vector_if +{ + #if EIGEN_ALIGN_STATICALLY + internal::plain_array m_data; + EIGEN_STRONG_INLINE Scalar* data() { return m_data.array; } + #else + // Some architectures cannot align on the stack, + // => let's manually enforce alignment by allocating more data and return the address of the first aligned element. + enum { + ForceAlignment = internal::packet_traits::Vectorizable, + PacketSize = internal::packet_traits::size + }; + internal::plain_array m_data; + EIGEN_STRONG_INLINE Scalar* data() { + return ForceAlignment + ? reinterpret_cast((reinterpret_cast(m_data.array) & ~(size_t(15))) + 16) + : m_data.array; + } + #endif +}; + +template<> struct gemv_selector +{ + template + static inline void run(const ProductType& prod, Dest& dest, const typename ProductType::Scalar& alpha) + { + typedef typename ProductType::Index Index; + typedef typename ProductType::LhsScalar LhsScalar; + typedef typename ProductType::RhsScalar RhsScalar; + typedef typename ProductType::Scalar ResScalar; + typedef typename ProductType::RealScalar RealScalar; + typedef typename ProductType::ActualLhsType ActualLhsType; + typedef typename ProductType::ActualRhsType ActualRhsType; + typedef typename ProductType::LhsBlasTraits LhsBlasTraits; + typedef typename ProductType::RhsBlasTraits RhsBlasTraits; + typedef Map, Aligned> MappedDest; + + ActualLhsType actualLhs = LhsBlasTraits::extract(prod.lhs()); + ActualRhsType actualRhs = RhsBlasTraits::extract(prod.rhs()); + + ResScalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(prod.lhs()) + * RhsBlasTraits::extractScalarFactor(prod.rhs()); + + enum { + // FIXME find a way to allow an inner stride on the result if packet_traits::size==1 + // on, the other hand it is good for the cache to pack the vector anyways... + EvalToDestAtCompileTime = Dest::InnerStrideAtCompileTime==1, + ComplexByReal = (NumTraits::IsComplex) && (!NumTraits::IsComplex), + MightCannotUseDest = (Dest::InnerStrideAtCompileTime!=1) || ComplexByReal + }; + + gemv_static_vector_if static_dest; + + bool alphaIsCompatible = (!ComplexByReal) || (numext::imag(actualAlpha)==RealScalar(0)); + bool evalToDest = EvalToDestAtCompileTime && alphaIsCompatible; + + RhsScalar compatibleAlpha = get_factor::run(actualAlpha); + + ei_declare_aligned_stack_constructed_variable(ResScalar,actualDestPtr,dest.size(), + evalToDest ? dest.data() : static_dest.data()); + + if(!evalToDest) + { + #ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN + int size = dest.size(); + EIGEN_DENSE_STORAGE_CTOR_PLUGIN + #endif + if(!alphaIsCompatible) + { + MappedDest(actualDestPtr, dest.size()).setZero(); + compatibleAlpha = RhsScalar(1); + } + else + MappedDest(actualDestPtr, dest.size()) = dest; + } + + general_matrix_vector_product + ::run( + actualLhs.rows(), actualLhs.cols(), + actualLhs.data(), actualLhs.outerStride(), + actualRhs.data(), actualRhs.innerStride(), + actualDestPtr, 1, + compatibleAlpha); + + if (!evalToDest) + { + if(!alphaIsCompatible) + dest += actualAlpha * MappedDest(actualDestPtr, dest.size()); + else + dest = MappedDest(actualDestPtr, dest.size()); + } + } +}; + +template<> struct gemv_selector +{ + template + static void run(const ProductType& prod, Dest& dest, const typename ProductType::Scalar& alpha) + { + typedef typename ProductType::LhsScalar LhsScalar; + typedef typename ProductType::RhsScalar RhsScalar; + typedef typename ProductType::Scalar ResScalar; + typedef typename ProductType::Index Index; + typedef typename ProductType::ActualLhsType ActualLhsType; + typedef typename ProductType::ActualRhsType ActualRhsType; + typedef typename ProductType::_ActualRhsType _ActualRhsType; + typedef typename ProductType::LhsBlasTraits LhsBlasTraits; + typedef typename ProductType::RhsBlasTraits RhsBlasTraits; + + typename add_const::type actualLhs = LhsBlasTraits::extract(prod.lhs()); + typename add_const::type actualRhs = RhsBlasTraits::extract(prod.rhs()); + + ResScalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(prod.lhs()) + * RhsBlasTraits::extractScalarFactor(prod.rhs()); + + enum { + // FIXME find a way to allow an inner stride on the result if packet_traits::size==1 + // on, the other hand it is good for the cache to pack the vector anyways... + DirectlyUseRhs = _ActualRhsType::InnerStrideAtCompileTime==1 + }; + + gemv_static_vector_if static_rhs; + + ei_declare_aligned_stack_constructed_variable(RhsScalar,actualRhsPtr,actualRhs.size(), + DirectlyUseRhs ? const_cast(actualRhs.data()) : static_rhs.data()); + + if(!DirectlyUseRhs) + { + #ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN + int size = actualRhs.size(); + EIGEN_DENSE_STORAGE_CTOR_PLUGIN + #endif + Map(actualRhsPtr, actualRhs.size()) = actualRhs; + } + + general_matrix_vector_product + ::run( + actualLhs.rows(), actualLhs.cols(), + actualLhs.data(), actualLhs.outerStride(), + actualRhsPtr, 1, + dest.data(), dest.innerStride(), + actualAlpha); + } +}; + +template<> struct gemv_selector +{ + template + static void run(const ProductType& prod, Dest& dest, const typename ProductType::Scalar& alpha) + { + typedef typename Dest::Index Index; + // TODO makes sure dest is sequentially stored in memory, otherwise use a temp + const Index size = prod.rhs().rows(); + for(Index k=0; k struct gemv_selector +{ + template + static void run(const ProductType& prod, Dest& dest, const typename ProductType::Scalar& alpha) + { + typedef typename Dest::Index Index; + // TODO makes sure rhs is sequentially stored in memory, otherwise use a temp + const Index rows = prod.rows(); + for(Index i=0; i +template +inline const typename ProductReturnType::Type +MatrixBase::operator*(const MatrixBase &other) const +{ + // A note regarding the function declaration: In MSVC, this function will sometimes + // not be inlined since DenseStorage is an unwindable object for dynamic + // matrices and product types are holding a member to store the result. + // Thus it does not help tagging this function with EIGEN_STRONG_INLINE. + enum { + ProductIsValid = Derived::ColsAtCompileTime==Dynamic + || OtherDerived::RowsAtCompileTime==Dynamic + || int(Derived::ColsAtCompileTime)==int(OtherDerived::RowsAtCompileTime), + AreVectors = Derived::IsVectorAtCompileTime && OtherDerived::IsVectorAtCompileTime, + SameSizes = EIGEN_PREDICATE_SAME_MATRIX_SIZE(Derived,OtherDerived) + }; + // note to the lost user: + // * for a dot product use: v1.dot(v2) + // * for a coeff-wise product use: v1.cwiseProduct(v2) + EIGEN_STATIC_ASSERT(ProductIsValid || !(AreVectors && SameSizes), + INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS) + EIGEN_STATIC_ASSERT(ProductIsValid || !(SameSizes && !AreVectors), + INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION) + EIGEN_STATIC_ASSERT(ProductIsValid || SameSizes, INVALID_MATRIX_PRODUCT) +#ifdef EIGEN_DEBUG_PRODUCT + internal::product_type::debug(); +#endif + return typename ProductReturnType::Type(derived(), other.derived()); +} + +/** \returns an expression of the matrix product of \c *this and \a other without implicit evaluation. + * + * The returned product will behave like any other expressions: the coefficients of the product will be + * computed once at a time as requested. This might be useful in some extremely rare cases when only + * a small and no coherent fraction of the result's coefficients have to be computed. + * + * \warning This version of the matrix product can be much much slower. So use it only if you know + * what you are doing and that you measured a true speed improvement. + * + * \sa operator*(const MatrixBase&) + */ +template +template +const typename LazyProductReturnType::Type +MatrixBase::lazyProduct(const MatrixBase &other) const +{ + enum { + ProductIsValid = Derived::ColsAtCompileTime==Dynamic + || OtherDerived::RowsAtCompileTime==Dynamic + || int(Derived::ColsAtCompileTime)==int(OtherDerived::RowsAtCompileTime), + AreVectors = Derived::IsVectorAtCompileTime && OtherDerived::IsVectorAtCompileTime, + SameSizes = EIGEN_PREDICATE_SAME_MATRIX_SIZE(Derived,OtherDerived) + }; + // note to the lost user: + // * for a dot product use: v1.dot(v2) + // * for a coeff-wise product use: v1.cwiseProduct(v2) + EIGEN_STATIC_ASSERT(ProductIsValid || !(AreVectors && SameSizes), + INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS) + EIGEN_STATIC_ASSERT(ProductIsValid || !(SameSizes && !AreVectors), + INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION) + EIGEN_STATIC_ASSERT(ProductIsValid || SameSizes, INVALID_MATRIX_PRODUCT) + + return typename LazyProductReturnType::Type(derived(), other.derived()); +} + +} // end namespace Eigen + +#endif // EIGEN_PRODUCT_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/GenericPacketMath.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/GenericPacketMath.h new file mode 100644 index 00000000..5f783ebe --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/GenericPacketMath.h @@ -0,0 +1,350 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008 Gael Guennebaud +// Copyright (C) 2006-2008 Benoit Jacob +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_GENERIC_PACKET_MATH_H +#define EIGEN_GENERIC_PACKET_MATH_H + +namespace Eigen { + +namespace internal { + +/** \internal + * \file GenericPacketMath.h + * + * Default implementation for types not supported by the vectorization. + * In practice these functions are provided to make easier the writing + * of generic vectorized code. + */ + +#ifndef EIGEN_DEBUG_ALIGNED_LOAD +#define EIGEN_DEBUG_ALIGNED_LOAD +#endif + +#ifndef EIGEN_DEBUG_UNALIGNED_LOAD +#define EIGEN_DEBUG_UNALIGNED_LOAD +#endif + +#ifndef EIGEN_DEBUG_ALIGNED_STORE +#define EIGEN_DEBUG_ALIGNED_STORE +#endif + +#ifndef EIGEN_DEBUG_UNALIGNED_STORE +#define EIGEN_DEBUG_UNALIGNED_STORE +#endif + +struct default_packet_traits +{ + enum { + HasAdd = 1, + HasSub = 1, + HasMul = 1, + HasNegate = 1, + HasAbs = 1, + HasAbs2 = 1, + HasMin = 1, + HasMax = 1, + HasConj = 1, + HasSetLinear = 1, + + HasDiv = 0, + HasSqrt = 0, + HasExp = 0, + HasLog = 0, + HasPow = 0, + + HasSin = 0, + HasCos = 0, + HasTan = 0, + HasASin = 0, + HasACos = 0, + HasATan = 0 + }; +}; + +template struct packet_traits : default_packet_traits +{ + typedef T type; + enum { + Vectorizable = 0, + size = 1, + AlignedOnScalar = 0 + }; + enum { + HasAdd = 0, + HasSub = 0, + HasMul = 0, + HasNegate = 0, + HasAbs = 0, + HasAbs2 = 0, + HasMin = 0, + HasMax = 0, + HasConj = 0, + HasSetLinear = 0 + }; +}; + +/** \internal \returns a + b (coeff-wise) */ +template inline Packet +padd(const Packet& a, + const Packet& b) { return a+b; } + +/** \internal \returns a - b (coeff-wise) */ +template inline Packet +psub(const Packet& a, + const Packet& b) { return a-b; } + +/** \internal \returns -a (coeff-wise) */ +template inline Packet +pnegate(const Packet& a) { return -a; } + +/** \internal \returns conj(a) (coeff-wise) */ +template inline Packet +pconj(const Packet& a) { return numext::conj(a); } + +/** \internal \returns a * b (coeff-wise) */ +template inline Packet +pmul(const Packet& a, + const Packet& b) { return a*b; } + +/** \internal \returns a / b (coeff-wise) */ +template inline Packet +pdiv(const Packet& a, + const Packet& b) { return a/b; } + +/** \internal \returns the min of \a a and \a b (coeff-wise) */ +template inline Packet +pmin(const Packet& a, + const Packet& b) { using std::min; return (min)(a, b); } + +/** \internal \returns the max of \a a and \a b (coeff-wise) */ +template inline Packet +pmax(const Packet& a, + const Packet& b) { using std::max; return (max)(a, b); } + +/** \internal \returns the absolute value of \a a */ +template inline Packet +pabs(const Packet& a) { using std::abs; return abs(a); } + +/** \internal \returns the bitwise and of \a a and \a b */ +template inline Packet +pand(const Packet& a, const Packet& b) { return a & b; } + +/** \internal \returns the bitwise or of \a a and \a b */ +template inline Packet +por(const Packet& a, const Packet& b) { return a | b; } + +/** \internal \returns the bitwise xor of \a a and \a b */ +template inline Packet +pxor(const Packet& a, const Packet& b) { return a ^ b; } + +/** \internal \returns the bitwise andnot of \a a and \a b */ +template inline Packet +pandnot(const Packet& a, const Packet& b) { return a & (!b); } + +/** \internal \returns a packet version of \a *from, from must be 16 bytes aligned */ +template inline Packet +pload(const typename unpacket_traits::type* from) { return *from; } + +/** \internal \returns a packet version of \a *from, (un-aligned load) */ +template inline Packet +ploadu(const typename unpacket_traits::type* from) { return *from; } + +/** \internal \returns a packet with elements of \a *from duplicated. + * For instance, for a packet of 8 elements, 4 scalar will be read from \a *from and + * duplicated to form: {from[0],from[0],from[1],from[1],,from[2],from[2],,from[3],from[3]} + * Currently, this function is only used for scalar * complex products. + */ +template inline Packet +ploaddup(const typename unpacket_traits::type* from) { return *from; } + +/** \internal \returns a packet with constant coefficients \a a, e.g.: (a,a,a,a) */ +template inline Packet +pset1(const typename unpacket_traits::type& a) { return a; } + +/** \internal \brief Returns a packet with coefficients (a,a+1,...,a+packet_size-1). */ +template inline typename packet_traits::type +plset(const Scalar& a) { return a; } + +/** \internal copy the packet \a from to \a *to, \a to must be 16 bytes aligned */ +template inline void pstore(Scalar* to, const Packet& from) +{ (*to) = from; } + +/** \internal copy the packet \a from to \a *to, (un-aligned store) */ +template inline void pstoreu(Scalar* to, const Packet& from) +{ (*to) = from; } + +/** \internal tries to do cache prefetching of \a addr */ +template inline void prefetch(const Scalar* addr) +{ +#if !defined(_MSC_VER) +__builtin_prefetch(addr); +#endif +} + +/** \internal \returns the first element of a packet */ +template inline typename unpacket_traits::type pfirst(const Packet& a) +{ return a; } + +/** \internal \returns a packet where the element i contains the sum of the packet of \a vec[i] */ +template inline Packet +preduxp(const Packet* vecs) { return vecs[0]; } + +/** \internal \returns the sum of the elements of \a a*/ +template inline typename unpacket_traits::type predux(const Packet& a) +{ return a; } + +/** \internal \returns the product of the elements of \a a*/ +template inline typename unpacket_traits::type predux_mul(const Packet& a) +{ return a; } + +/** \internal \returns the min of the elements of \a a*/ +template inline typename unpacket_traits::type predux_min(const Packet& a) +{ return a; } + +/** \internal \returns the max of the elements of \a a*/ +template inline typename unpacket_traits::type predux_max(const Packet& a) +{ return a; } + +/** \internal \returns the reversed elements of \a a*/ +template inline Packet preverse(const Packet& a) +{ return a; } + + +/** \internal \returns \a a with real and imaginary part flipped (for complex type only) */ +template inline Packet pcplxflip(const Packet& a) +{ + // FIXME: uncomment the following in case we drop the internal imag and real functions. +// using std::imag; +// using std::real; + return Packet(imag(a),real(a)); +} + +/************************** +* Special math functions +***************************/ + +/** \internal \returns the sine of \a a (coeff-wise) */ +template EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS +Packet psin(const Packet& a) { using std::sin; return sin(a); } + +/** \internal \returns the cosine of \a a (coeff-wise) */ +template EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS +Packet pcos(const Packet& a) { using std::cos; return cos(a); } + +/** \internal \returns the tan of \a a (coeff-wise) */ +template EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS +Packet ptan(const Packet& a) { using std::tan; return tan(a); } + +/** \internal \returns the arc sine of \a a (coeff-wise) */ +template EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS +Packet pasin(const Packet& a) { using std::asin; return asin(a); } + +/** \internal \returns the arc cosine of \a a (coeff-wise) */ +template EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS +Packet pacos(const Packet& a) { using std::acos; return acos(a); } + +/** \internal \returns the exp of \a a (coeff-wise) */ +template EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS +Packet pexp(const Packet& a) { using std::exp; return exp(a); } + +/** \internal \returns the log of \a a (coeff-wise) */ +template EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS +Packet plog(const Packet& a) { using std::log; return log(a); } + +/** \internal \returns the square-root of \a a (coeff-wise) */ +template EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS +Packet psqrt(const Packet& a) { using std::sqrt; return sqrt(a); } + +/*************************************************************************** +* The following functions might not have to be overwritten for vectorized types +***************************************************************************/ + +/** \internal copy a packet with constant coeficient \a a (e.g., [a,a,a,a]) to \a *to. \a to must be 16 bytes aligned */ +// NOTE: this function must really be templated on the packet type (think about different packet types for the same scalar type) +template +inline void pstore1(typename unpacket_traits::type* to, const typename unpacket_traits::type& a) +{ + pstore(to, pset1(a)); +} + +/** \internal \returns a * b + c (coeff-wise) */ +template inline Packet +pmadd(const Packet& a, + const Packet& b, + const Packet& c) +{ return padd(pmul(a, b),c); } + +/** \internal \returns a packet version of \a *from. + * If LoadMode equals #Aligned, \a from must be 16 bytes aligned */ +template +inline Packet ploadt(const typename unpacket_traits::type* from) +{ + if(LoadMode == Aligned) + return pload(from); + else + return ploadu(from); +} + +/** \internal copy the packet \a from to \a *to. + * If StoreMode equals #Aligned, \a to must be 16 bytes aligned */ +template +inline void pstoret(Scalar* to, const Packet& from) +{ + if(LoadMode == Aligned) + pstore(to, from); + else + pstoreu(to, from); +} + +/** \internal default implementation of palign() allowing partial specialization */ +template +struct palign_impl +{ + // by default data are aligned, so there is nothing to be done :) + static inline void run(PacketType&, const PacketType&) {} +}; + +/** \internal update \a first using the concatenation of the packet_size minus \a Offset last elements + * of \a first and \a Offset first elements of \a second. + * + * This function is currently only used to optimize matrix-vector products on unligned matrices. + * It takes 2 packets that represent a contiguous memory array, and returns a packet starting + * at the position \a Offset. For instance, for packets of 4 elements, we have: + * Input: + * - first = {f0,f1,f2,f3} + * - second = {s0,s1,s2,s3} + * Output: + * - if Offset==0 then {f0,f1,f2,f3} + * - if Offset==1 then {f1,f2,f3,s0} + * - if Offset==2 then {f2,f3,s0,s1} + * - if Offset==3 then {f3,s0,s1,s3} + */ +template +inline void palign(PacketType& first, const PacketType& second) +{ + palign_impl::run(first,second); +} + +/*************************************************************************** +* Fast complex products (GCC generates a function call which is very slow) +***************************************************************************/ + +template<> inline std::complex pmul(const std::complex& a, const std::complex& b) +{ return std::complex(real(a)*real(b) - imag(a)*imag(b), imag(a)*real(b) + real(a)*imag(b)); } + +template<> inline std::complex pmul(const std::complex& a, const std::complex& b) +{ return std::complex(real(a)*real(b) - imag(a)*imag(b), imag(a)*real(b) + real(a)*imag(b)); } + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_GENERIC_PACKET_MATH_H + diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/GlobalFunctions.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/GlobalFunctions.h new file mode 100644 index 00000000..2acf9772 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/GlobalFunctions.h @@ -0,0 +1,92 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2010-2012 Gael Guennebaud +// Copyright (C) 2010 Benoit Jacob +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_GLOBAL_FUNCTIONS_H +#define EIGEN_GLOBAL_FUNCTIONS_H + +#define EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(NAME,FUNCTOR) \ + template \ + inline const Eigen::CwiseUnaryOp, const Derived> \ + NAME(const Eigen::ArrayBase& x) { \ + return x.derived(); \ + } + +#define EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(NAME,FUNCTOR) \ + \ + template \ + struct NAME##_retval > \ + { \ + typedef const Eigen::CwiseUnaryOp, const Derived> type; \ + }; \ + template \ + struct NAME##_impl > \ + { \ + static inline typename NAME##_retval >::type run(const Eigen::ArrayBase& x) \ + { \ + return x.derived(); \ + } \ + }; + + +namespace Eigen +{ + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(real,scalar_real_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(imag,scalar_imag_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(conj,scalar_conjugate_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(sin,scalar_sin_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(cos,scalar_cos_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(asin,scalar_asin_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(acos,scalar_acos_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(tan,scalar_tan_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(exp,scalar_exp_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(log,scalar_log_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(abs,scalar_abs_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(sqrt,scalar_sqrt_op) + + template + inline const Eigen::CwiseUnaryOp, const Derived> + pow(const Eigen::ArrayBase& x, const typename Derived::Scalar& exponent) { + return x.derived().pow(exponent); + } + + template + inline const Eigen::CwiseBinaryOp, const Derived, const Derived> + pow(const Eigen::ArrayBase& x, const Eigen::ArrayBase& exponents) + { + return Eigen::CwiseBinaryOp, const Derived, const Derived>( + x.derived(), + exponents.derived() + ); + } + + /** + * \brief Component-wise division of a scalar by array elements. + **/ + template + inline const Eigen::CwiseUnaryOp, const Derived> + operator/(const typename Derived::Scalar& s, const Eigen::ArrayBase& a) + { + return Eigen::CwiseUnaryOp, const Derived>( + a.derived(), + Eigen::internal::scalar_inverse_mult_op(s) + ); + } + + namespace internal + { + EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(real,scalar_real_op) + EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(imag,scalar_imag_op) + EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(abs2,scalar_abs2_op) + } +} + +// TODO: cleanly disable those functions that are not supported on Array (numext::real_ref, internal::random, internal::isApprox...) + +#endif // EIGEN_GLOBAL_FUNCTIONS_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/IO.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/IO.h new file mode 100644 index 00000000..8d4bc59e --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/IO.h @@ -0,0 +1,250 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2006-2008 Benoit Jacob +// Copyright (C) 2008 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_IO_H +#define EIGEN_IO_H + +namespace Eigen { + +enum { DontAlignCols = 1 }; +enum { StreamPrecision = -1, + FullPrecision = -2 }; + +namespace internal { +template +std::ostream & print_matrix(std::ostream & s, const Derived& _m, const IOFormat& fmt); +} + +/** \class IOFormat + * \ingroup Core_Module + * + * \brief Stores a set of parameters controlling the way matrices are printed + * + * List of available parameters: + * - \b precision number of digits for floating point values, or one of the special constants \c StreamPrecision and \c FullPrecision. + * The default is the special value \c StreamPrecision which means to use the + * stream's own precision setting, as set for instance using \c cout.precision(3). The other special value + * \c FullPrecision means that the number of digits will be computed to match the full precision of each floating-point + * type. + * - \b flags an OR-ed combination of flags, the default value is 0, the only currently available flag is \c DontAlignCols which + * allows to disable the alignment of columns, resulting in faster code. + * - \b coeffSeparator string printed between two coefficients of the same row + * - \b rowSeparator string printed between two rows + * - \b rowPrefix string printed at the beginning of each row + * - \b rowSuffix string printed at the end of each row + * - \b matPrefix string printed at the beginning of the matrix + * - \b matSuffix string printed at the end of the matrix + * + * Example: \include IOFormat.cpp + * Output: \verbinclude IOFormat.out + * + * \sa DenseBase::format(), class WithFormat + */ +struct IOFormat +{ + /** Default contructor, see class IOFormat for the meaning of the parameters */ + IOFormat(int _precision = StreamPrecision, int _flags = 0, + const std::string& _coeffSeparator = " ", + const std::string& _rowSeparator = "\n", const std::string& _rowPrefix="", const std::string& _rowSuffix="", + const std::string& _matPrefix="", const std::string& _matSuffix="") + : matPrefix(_matPrefix), matSuffix(_matSuffix), rowPrefix(_rowPrefix), rowSuffix(_rowSuffix), rowSeparator(_rowSeparator), + rowSpacer(""), coeffSeparator(_coeffSeparator), precision(_precision), flags(_flags) + { + int i = int(matSuffix.length())-1; + while (i>=0 && matSuffix[i]!='\n') + { + rowSpacer += ' '; + i--; + } + } + std::string matPrefix, matSuffix; + std::string rowPrefix, rowSuffix, rowSeparator, rowSpacer; + std::string coeffSeparator; + int precision; + int flags; +}; + +/** \class WithFormat + * \ingroup Core_Module + * + * \brief Pseudo expression providing matrix output with given format + * + * \param ExpressionType the type of the object on which IO stream operations are performed + * + * This class represents an expression with stream operators controlled by a given IOFormat. + * It is the return type of DenseBase::format() + * and most of the time this is the only way it is used. + * + * See class IOFormat for some examples. + * + * \sa DenseBase::format(), class IOFormat + */ +template +class WithFormat +{ + public: + + WithFormat(const ExpressionType& matrix, const IOFormat& format) + : m_matrix(matrix), m_format(format) + {} + + friend std::ostream & operator << (std::ostream & s, const WithFormat& wf) + { + return internal::print_matrix(s, wf.m_matrix.eval(), wf.m_format); + } + + protected: + const typename ExpressionType::Nested m_matrix; + IOFormat m_format; +}; + +/** \returns a WithFormat proxy object allowing to print a matrix the with given + * format \a fmt. + * + * See class IOFormat for some examples. + * + * \sa class IOFormat, class WithFormat + */ +template +inline const WithFormat +DenseBase::format(const IOFormat& fmt) const +{ + return WithFormat(derived(), fmt); +} + +namespace internal { + +template +struct significant_decimals_default_impl +{ + typedef typename NumTraits::Real RealScalar; + static inline int run() + { + using std::ceil; + using std::log; + return cast(ceil(-log(NumTraits::epsilon())/log(RealScalar(10)))); + } +}; + +template +struct significant_decimals_default_impl +{ + static inline int run() + { + return 0; + } +}; + +template +struct significant_decimals_impl + : significant_decimals_default_impl::IsInteger> +{}; + +/** \internal + * print the matrix \a _m to the output stream \a s using the output format \a fmt */ +template +std::ostream & print_matrix(std::ostream & s, const Derived& _m, const IOFormat& fmt) +{ + if(_m.size() == 0) + { + s << fmt.matPrefix << fmt.matSuffix; + return s; + } + + typename Derived::Nested m = _m; + typedef typename Derived::Scalar Scalar; + typedef typename Derived::Index Index; + + Index width = 0; + + std::streamsize explicit_precision; + if(fmt.precision == StreamPrecision) + { + explicit_precision = 0; + } + else if(fmt.precision == FullPrecision) + { + if (NumTraits::IsInteger) + { + explicit_precision = 0; + } + else + { + explicit_precision = significant_decimals_impl::run(); + } + } + else + { + explicit_precision = fmt.precision; + } + + std::streamsize old_precision = 0; + if(explicit_precision) old_precision = s.precision(explicit_precision); + + bool align_cols = !(fmt.flags & DontAlignCols); + if(align_cols) + { + // compute the largest width + for(Index j = 0; j < m.cols(); ++j) + for(Index i = 0; i < m.rows(); ++i) + { + std::stringstream sstr; + sstr.copyfmt(s); + sstr << m.coeff(i,j); + width = std::max(width, Index(sstr.str().length())); + } + } + s << fmt.matPrefix; + for(Index i = 0; i < m.rows(); ++i) + { + if (i) + s << fmt.rowSpacer; + s << fmt.rowPrefix; + if(width) s.width(width); + s << m.coeff(i, 0); + for(Index j = 1; j < m.cols(); ++j) + { + s << fmt.coeffSeparator; + if (width) s.width(width); + s << m.coeff(i, j); + } + s << fmt.rowSuffix; + if( i < m.rows() - 1) + s << fmt.rowSeparator; + } + s << fmt.matSuffix; + if(explicit_precision) s.precision(old_precision); + return s; +} + +} // end namespace internal + +/** \relates DenseBase + * + * Outputs the matrix, to the given stream. + * + * If you wish to print the matrix with a format different than the default, use DenseBase::format(). + * + * It is also possible to change the default format by defining EIGEN_DEFAULT_IO_FORMAT before including Eigen headers. + * If not defined, this will automatically be defined to Eigen::IOFormat(), that is the Eigen::IOFormat with default parameters. + * + * \sa DenseBase::format() + */ +template +std::ostream & operator << +(std::ostream & s, + const DenseBase & m) +{ + return internal::print_matrix(s, m.eval(), EIGEN_DEFAULT_IO_FORMAT); +} + +} // end namespace Eigen + +#endif // EIGEN_IO_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/Map.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/Map.h new file mode 100644 index 00000000..f804c89d --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/Map.h @@ -0,0 +1,192 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2007-2010 Benoit Jacob +// Copyright (C) 2008 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_MAP_H +#define EIGEN_MAP_H + +namespace Eigen { + +/** \class Map + * \ingroup Core_Module + * + * \brief A matrix or vector expression mapping an existing array of data. + * + * \tparam PlainObjectType the equivalent matrix type of the mapped data + * \tparam MapOptions specifies whether the pointer is \c #Aligned, or \c #Unaligned. + * The default is \c #Unaligned. + * \tparam StrideType optionally specifies strides. By default, Map assumes the memory layout + * of an ordinary, contiguous array. This can be overridden by specifying strides. + * The type passed here must be a specialization of the Stride template, see examples below. + * + * This class represents a matrix or vector expression mapping an existing array of data. + * It can be used to let Eigen interface without any overhead with non-Eigen data structures, + * such as plain C arrays or structures from other libraries. By default, it assumes that the + * data is laid out contiguously in memory. You can however override this by explicitly specifying + * inner and outer strides. + * + * Here's an example of simply mapping a contiguous array as a \ref TopicStorageOrders "column-major" matrix: + * \include Map_simple.cpp + * Output: \verbinclude Map_simple.out + * + * If you need to map non-contiguous arrays, you can do so by specifying strides: + * + * Here's an example of mapping an array as a vector, specifying an inner stride, that is, the pointer + * increment between two consecutive coefficients. Here, we're specifying the inner stride as a compile-time + * fixed value. + * \include Map_inner_stride.cpp + * Output: \verbinclude Map_inner_stride.out + * + * Here's an example of mapping an array while specifying an outer stride. Here, since we're mapping + * as a column-major matrix, 'outer stride' means the pointer increment between two consecutive columns. + * Here, we're specifying the outer stride as a runtime parameter. Note that here \c OuterStride<> is + * a short version of \c OuterStride because the default template parameter of OuterStride + * is \c Dynamic + * \include Map_outer_stride.cpp + * Output: \verbinclude Map_outer_stride.out + * + * For more details and for an example of specifying both an inner and an outer stride, see class Stride. + * + * \b Tip: to change the array of data mapped by a Map object, you can use the C++ + * placement new syntax: + * + * Example: \include Map_placement_new.cpp + * Output: \verbinclude Map_placement_new.out + * + * This class is the return type of PlainObjectBase::Map() but can also be used directly. + * + * \sa PlainObjectBase::Map(), \ref TopicStorageOrders + */ + +namespace internal { +template +struct traits > + : public traits +{ + typedef traits TraitsBase; + typedef typename PlainObjectType::Index Index; + typedef typename PlainObjectType::Scalar Scalar; + enum { + InnerStrideAtCompileTime = StrideType::InnerStrideAtCompileTime == 0 + ? int(PlainObjectType::InnerStrideAtCompileTime) + : int(StrideType::InnerStrideAtCompileTime), + OuterStrideAtCompileTime = StrideType::OuterStrideAtCompileTime == 0 + ? int(PlainObjectType::OuterStrideAtCompileTime) + : int(StrideType::OuterStrideAtCompileTime), + HasNoInnerStride = InnerStrideAtCompileTime == 1, + HasNoOuterStride = StrideType::OuterStrideAtCompileTime == 0, + HasNoStride = HasNoInnerStride && HasNoOuterStride, + IsAligned = bool(EIGEN_ALIGN) && ((int(MapOptions)&Aligned)==Aligned), + IsDynamicSize = PlainObjectType::SizeAtCompileTime==Dynamic, + KeepsPacketAccess = bool(HasNoInnerStride) + && ( bool(IsDynamicSize) + || HasNoOuterStride + || ( OuterStrideAtCompileTime!=Dynamic + && ((static_cast(sizeof(Scalar))*OuterStrideAtCompileTime)%16)==0 ) ), + Flags0 = TraitsBase::Flags & (~NestByRefBit), + Flags1 = IsAligned ? (int(Flags0) | AlignedBit) : (int(Flags0) & ~AlignedBit), + Flags2 = (bool(HasNoStride) || bool(PlainObjectType::IsVectorAtCompileTime)) + ? int(Flags1) : int(Flags1 & ~LinearAccessBit), + Flags3 = is_lvalue::value ? int(Flags2) : (int(Flags2) & ~LvalueBit), + Flags = KeepsPacketAccess ? int(Flags3) : (int(Flags3) & ~PacketAccessBit) + }; +private: + enum { Options }; // Expressions don't have Options +}; +} + +template class Map + : public MapBase > +{ + public: + + typedef MapBase Base; + EIGEN_DENSE_PUBLIC_INTERFACE(Map) + + typedef typename Base::PointerType PointerType; +#if EIGEN2_SUPPORT_STAGE <= STAGE30_FULL_EIGEN3_API + typedef const Scalar* PointerArgType; + inline PointerType cast_to_pointer_type(PointerArgType ptr) { return const_cast(ptr); } +#else + typedef PointerType PointerArgType; + inline PointerType cast_to_pointer_type(PointerArgType ptr) { return ptr; } +#endif + + inline Index innerStride() const + { + return StrideType::InnerStrideAtCompileTime != 0 ? m_stride.inner() : 1; + } + + inline Index outerStride() const + { + return StrideType::OuterStrideAtCompileTime != 0 ? m_stride.outer() + : IsVectorAtCompileTime ? this->size() + : int(Flags)&RowMajorBit ? this->cols() + : this->rows(); + } + + /** Constructor in the fixed-size case. + * + * \param dataPtr pointer to the array to map + * \param a_stride optional Stride object, passing the strides. + */ + inline Map(PointerArgType dataPtr, const StrideType& a_stride = StrideType()) + : Base(cast_to_pointer_type(dataPtr)), m_stride(a_stride) + { + PlainObjectType::Base::_check_template_params(); + } + + /** Constructor in the dynamic-size vector case. + * + * \param dataPtr pointer to the array to map + * \param a_size the size of the vector expression + * \param a_stride optional Stride object, passing the strides. + */ + inline Map(PointerArgType dataPtr, Index a_size, const StrideType& a_stride = StrideType()) + : Base(cast_to_pointer_type(dataPtr), a_size), m_stride(a_stride) + { + PlainObjectType::Base::_check_template_params(); + } + + /** Constructor in the dynamic-size matrix case. + * + * \param dataPtr pointer to the array to map + * \param nbRows the number of rows of the matrix expression + * \param nbCols the number of columns of the matrix expression + * \param a_stride optional Stride object, passing the strides. + */ + inline Map(PointerArgType dataPtr, Index nbRows, Index nbCols, const StrideType& a_stride = StrideType()) + : Base(cast_to_pointer_type(dataPtr), nbRows, nbCols), m_stride(a_stride) + { + PlainObjectType::Base::_check_template_params(); + } + + EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Map) + + protected: + StrideType m_stride; +}; + +template +inline Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> + ::Array(const Scalar *data) +{ + this->_set_noalias(Eigen::Map(data)); +} + +template +inline Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> + ::Matrix(const Scalar *data) +{ + this->_set_noalias(Eigen::Map(data)); +} + +} // end namespace Eigen + +#endif // EIGEN_MAP_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/MapBase.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/MapBase.h new file mode 100644 index 00000000..a9828f7f --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/MapBase.h @@ -0,0 +1,247 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2007-2010 Benoit Jacob +// Copyright (C) 2008 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_MAPBASE_H +#define EIGEN_MAPBASE_H + +#define EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived) \ + EIGEN_STATIC_ASSERT((int(internal::traits::Flags) & LinearAccessBit) || Derived::IsVectorAtCompileTime, \ + YOU_ARE_TRYING_TO_USE_AN_INDEX_BASED_ACCESSOR_ON_AN_EXPRESSION_THAT_DOES_NOT_SUPPORT_THAT) + +namespace Eigen { + +/** \class MapBase + * \ingroup Core_Module + * + * \brief Base class for Map and Block expression with direct access + * + * \sa class Map, class Block + */ +template class MapBase + : public internal::dense_xpr_base::type +{ + public: + + typedef typename internal::dense_xpr_base::type Base; + enum { + RowsAtCompileTime = internal::traits::RowsAtCompileTime, + ColsAtCompileTime = internal::traits::ColsAtCompileTime, + SizeAtCompileTime = Base::SizeAtCompileTime + }; + + typedef typename internal::traits::StorageKind StorageKind; + typedef typename internal::traits::Index Index; + typedef typename internal::traits::Scalar Scalar; + typedef typename internal::packet_traits::type PacketScalar; + typedef typename NumTraits::Real RealScalar; + typedef typename internal::conditional< + bool(internal::is_lvalue::value), + Scalar *, + const Scalar *>::type + PointerType; + + using Base::derived; +// using Base::RowsAtCompileTime; +// using Base::ColsAtCompileTime; +// using Base::SizeAtCompileTime; + using Base::MaxRowsAtCompileTime; + using Base::MaxColsAtCompileTime; + using Base::MaxSizeAtCompileTime; + using Base::IsVectorAtCompileTime; + using Base::Flags; + using Base::IsRowMajor; + + using Base::rows; + using Base::cols; + using Base::size; + using Base::coeff; + using Base::coeffRef; + using Base::lazyAssign; + using Base::eval; + + using Base::innerStride; + using Base::outerStride; + using Base::rowStride; + using Base::colStride; + + // bug 217 - compile error on ICC 11.1 + using Base::operator=; + + typedef typename Base::CoeffReturnType CoeffReturnType; + + inline Index rows() const { return m_rows.value(); } + inline Index cols() const { return m_cols.value(); } + + /** Returns a pointer to the first coefficient of the matrix or vector. + * + * \note When addressing this data, make sure to honor the strides returned by innerStride() and outerStride(). + * + * \sa innerStride(), outerStride() + */ + inline const Scalar* data() const { return m_data; } + + inline const Scalar& coeff(Index rowId, Index colId) const + { + return m_data[colId * colStride() + rowId * rowStride()]; + } + + inline const Scalar& coeff(Index index) const + { + EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived) + return m_data[index * innerStride()]; + } + + inline const Scalar& coeffRef(Index rowId, Index colId) const + { + return this->m_data[colId * colStride() + rowId * rowStride()]; + } + + inline const Scalar& coeffRef(Index index) const + { + EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived) + return this->m_data[index * innerStride()]; + } + + template + inline PacketScalar packet(Index rowId, Index colId) const + { + return internal::ploadt + (m_data + (colId * colStride() + rowId * rowStride())); + } + + template + inline PacketScalar packet(Index index) const + { + EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived) + return internal::ploadt(m_data + index * innerStride()); + } + + explicit inline MapBase(PointerType dataPtr) : m_data(dataPtr), m_rows(RowsAtCompileTime), m_cols(ColsAtCompileTime) + { + EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived) + checkSanity(); + } + + inline MapBase(PointerType dataPtr, Index vecSize) + : m_data(dataPtr), + m_rows(RowsAtCompileTime == Dynamic ? vecSize : Index(RowsAtCompileTime)), + m_cols(ColsAtCompileTime == Dynamic ? vecSize : Index(ColsAtCompileTime)) + { + EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) + eigen_assert(vecSize >= 0); + eigen_assert(dataPtr == 0 || SizeAtCompileTime == Dynamic || SizeAtCompileTime == vecSize); + checkSanity(); + } + + inline MapBase(PointerType dataPtr, Index nbRows, Index nbCols) + : m_data(dataPtr), m_rows(nbRows), m_cols(nbCols) + { + eigen_assert( (dataPtr == 0) + || ( nbRows >= 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == nbRows) + && nbCols >= 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == nbCols))); + checkSanity(); + } + + protected: + + void checkSanity() const + { + EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(internal::traits::Flags&PacketAccessBit, + internal::inner_stride_at_compile_time::ret==1), + PACKET_ACCESS_REQUIRES_TO_HAVE_INNER_STRIDE_FIXED_TO_1); + eigen_assert(EIGEN_IMPLIES(internal::traits::Flags&AlignedBit, (size_t(m_data) % 16) == 0) + && "input pointer is not aligned on a 16 byte boundary"); + } + + PointerType m_data; + const internal::variable_if_dynamic m_rows; + const internal::variable_if_dynamic m_cols; +}; + +template class MapBase + : public MapBase +{ + typedef MapBase ReadOnlyMapBase; + public: + + typedef MapBase Base; + + typedef typename Base::Scalar Scalar; + typedef typename Base::PacketScalar PacketScalar; + typedef typename Base::Index Index; + typedef typename Base::PointerType PointerType; + + using Base::derived; + using Base::rows; + using Base::cols; + using Base::size; + using Base::coeff; + using Base::coeffRef; + + using Base::innerStride; + using Base::outerStride; + using Base::rowStride; + using Base::colStride; + + typedef typename internal::conditional< + internal::is_lvalue::value, + Scalar, + const Scalar + >::type ScalarWithConstIfNotLvalue; + + inline const Scalar* data() const { return this->m_data; } + inline ScalarWithConstIfNotLvalue* data() { return this->m_data; } // no const-cast here so non-const-correct code will give a compile error + + inline ScalarWithConstIfNotLvalue& coeffRef(Index row, Index col) + { + return this->m_data[col * colStride() + row * rowStride()]; + } + + inline ScalarWithConstIfNotLvalue& coeffRef(Index index) + { + EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived) + return this->m_data[index * innerStride()]; + } + + template + inline void writePacket(Index row, Index col, const PacketScalar& val) + { + internal::pstoret + (this->m_data + (col * colStride() + row * rowStride()), val); + } + + template + inline void writePacket(Index index, const PacketScalar& val) + { + EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived) + internal::pstoret + (this->m_data + index * innerStride(), val); + } + + explicit inline MapBase(PointerType dataPtr) : Base(dataPtr) {} + inline MapBase(PointerType dataPtr, Index vecSize) : Base(dataPtr, vecSize) {} + inline MapBase(PointerType dataPtr, Index nbRows, Index nbCols) : Base(dataPtr, nbRows, nbCols) {} + + Derived& operator=(const MapBase& other) + { + ReadOnlyMapBase::Base::operator=(other); + return derived(); + } + + // In theory we could simply refer to Base:Base::operator=, but MSVC does not like Base::Base, + // see bugs 821 and 920. + using ReadOnlyMapBase::Base::operator=; +}; + +#undef EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS + +} // end namespace Eigen + +#endif // EIGEN_MAPBASE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/MathFunctions.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/MathFunctions.h new file mode 100644 index 00000000..adf2f9c5 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/MathFunctions.h @@ -0,0 +1,768 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2006-2010 Benoit Jacob +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_MATHFUNCTIONS_H +#define EIGEN_MATHFUNCTIONS_H + +namespace Eigen { + +namespace internal { + +/** \internal \struct global_math_functions_filtering_base + * + * What it does: + * Defines a typedef 'type' as follows: + * - if type T has a member typedef Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl, then + * global_math_functions_filtering_base::type is a typedef for it. + * - otherwise, global_math_functions_filtering_base::type is a typedef for T. + * + * How it's used: + * To allow to defined the global math functions (like sin...) in certain cases, like the Array expressions. + * When you do sin(array1+array2), the object array1+array2 has a complicated expression type, all what you want to know + * is that it inherits ArrayBase. So we implement a partial specialization of sin_impl for ArrayBase. + * So we must make sure to use sin_impl > and not sin_impl, otherwise our partial specialization + * won't be used. How does sin know that? That's exactly what global_math_functions_filtering_base tells it. + * + * How it's implemented: + * SFINAE in the style of enable_if. Highly susceptible of breaking compilers. With GCC, it sure does work, but if you replace + * the typename dummy by an integer template parameter, it doesn't work anymore! + */ + +template +struct global_math_functions_filtering_base +{ + typedef T type; +}; + +template struct always_void { typedef void type; }; + +template +struct global_math_functions_filtering_base + ::type + > +{ + typedef typename T::Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl type; +}; + +#define EIGEN_MATHFUNC_IMPL(func, scalar) Eigen::internal::func##_impl::type> +#define EIGEN_MATHFUNC_RETVAL(func, scalar) typename Eigen::internal::func##_retval::type>::type + +/**************************************************************************** +* Implementation of real * +****************************************************************************/ + +template::IsComplex> +struct real_default_impl +{ + typedef typename NumTraits::Real RealScalar; + static inline RealScalar run(const Scalar& x) + { + return x; + } +}; + +template +struct real_default_impl +{ + typedef typename NumTraits::Real RealScalar; + static inline RealScalar run(const Scalar& x) + { + using std::real; + return real(x); + } +}; + +template struct real_impl : real_default_impl {}; + +template +struct real_retval +{ + typedef typename NumTraits::Real type; +}; + + +/**************************************************************************** +* Implementation of imag * +****************************************************************************/ + +template::IsComplex> +struct imag_default_impl +{ + typedef typename NumTraits::Real RealScalar; + static inline RealScalar run(const Scalar&) + { + return RealScalar(0); + } +}; + +template +struct imag_default_impl +{ + typedef typename NumTraits::Real RealScalar; + static inline RealScalar run(const Scalar& x) + { + using std::imag; + return imag(x); + } +}; + +template struct imag_impl : imag_default_impl {}; + +template +struct imag_retval +{ + typedef typename NumTraits::Real type; +}; + +/**************************************************************************** +* Implementation of real_ref * +****************************************************************************/ + +template +struct real_ref_impl +{ + typedef typename NumTraits::Real RealScalar; + static inline RealScalar& run(Scalar& x) + { + return reinterpret_cast(&x)[0]; + } + static inline const RealScalar& run(const Scalar& x) + { + return reinterpret_cast(&x)[0]; + } +}; + +template +struct real_ref_retval +{ + typedef typename NumTraits::Real & type; +}; + +/**************************************************************************** +* Implementation of imag_ref * +****************************************************************************/ + +template +struct imag_ref_default_impl +{ + typedef typename NumTraits::Real RealScalar; + static inline RealScalar& run(Scalar& x) + { + return reinterpret_cast(&x)[1]; + } + static inline const RealScalar& run(const Scalar& x) + { + return reinterpret_cast(&x)[1]; + } +}; + +template +struct imag_ref_default_impl +{ + static inline Scalar run(Scalar&) + { + return Scalar(0); + } + static inline const Scalar run(const Scalar&) + { + return Scalar(0); + } +}; + +template +struct imag_ref_impl : imag_ref_default_impl::IsComplex> {}; + +template +struct imag_ref_retval +{ + typedef typename NumTraits::Real & type; +}; + +/**************************************************************************** +* Implementation of conj * +****************************************************************************/ + +template::IsComplex> +struct conj_impl +{ + static inline Scalar run(const Scalar& x) + { + return x; + } +}; + +template +struct conj_impl +{ + static inline Scalar run(const Scalar& x) + { + using std::conj; + return conj(x); + } +}; + +template +struct conj_retval +{ + typedef Scalar type; +}; + +/**************************************************************************** +* Implementation of abs2 * +****************************************************************************/ + +template +struct abs2_impl +{ + typedef typename NumTraits::Real RealScalar; + static inline RealScalar run(const Scalar& x) + { + return x*x; + } +}; + +template +struct abs2_impl > +{ + static inline RealScalar run(const std::complex& x) + { + return real(x)*real(x) + imag(x)*imag(x); + } +}; + +template +struct abs2_retval +{ + typedef typename NumTraits::Real type; +}; + +/**************************************************************************** +* Implementation of norm1 * +****************************************************************************/ + +template +struct norm1_default_impl +{ + typedef typename NumTraits::Real RealScalar; + static inline RealScalar run(const Scalar& x) + { + using std::abs; + return abs(real(x)) + abs(imag(x)); + } +}; + +template +struct norm1_default_impl +{ + static inline Scalar run(const Scalar& x) + { + using std::abs; + return abs(x); + } +}; + +template +struct norm1_impl : norm1_default_impl::IsComplex> {}; + +template +struct norm1_retval +{ + typedef typename NumTraits::Real type; +}; + +/**************************************************************************** +* Implementation of hypot * +****************************************************************************/ + +template +struct hypot_impl +{ + typedef typename NumTraits::Real RealScalar; + static inline RealScalar run(const Scalar& x, const Scalar& y) + { + using std::max; + using std::min; + using std::abs; + using std::sqrt; + RealScalar _x = abs(x); + RealScalar _y = abs(y); + RealScalar p = (max)(_x, _y); + if(p==RealScalar(0)) return RealScalar(0); + RealScalar q = (min)(_x, _y); + RealScalar qp = q/p; + return p * sqrt(RealScalar(1) + qp*qp); + } +}; + +template +struct hypot_retval +{ + typedef typename NumTraits::Real type; +}; + +/**************************************************************************** +* Implementation of cast * +****************************************************************************/ + +template +struct cast_impl +{ + static inline NewType run(const OldType& x) + { + return static_cast(x); + } +}; + +// here, for once, we're plainly returning NewType: we don't want cast to do weird things. + +template +inline NewType cast(const OldType& x) +{ + return cast_impl::run(x); +} + +/**************************************************************************** +* Implementation of atanh2 * +****************************************************************************/ + +template +struct atanh2_default_impl +{ + typedef Scalar retval; + typedef typename NumTraits::Real RealScalar; + static inline Scalar run(const Scalar& x, const Scalar& y) + { + using std::abs; + using std::log; + using std::sqrt; + Scalar z = x / y; + if (y == Scalar(0) || abs(z) > sqrt(NumTraits::epsilon())) + return RealScalar(0.5) * log((y + x) / (y - x)); + else + return z + z*z*z / RealScalar(3); + } +}; + +template +struct atanh2_default_impl +{ + static inline Scalar run(const Scalar&, const Scalar&) + { + EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar) + return Scalar(0); + } +}; + +template +struct atanh2_impl : atanh2_default_impl::IsInteger> {}; + +template +struct atanh2_retval +{ + typedef Scalar type; +}; + +/**************************************************************************** +* Implementation of pow * +****************************************************************************/ + +template +struct pow_default_impl +{ + typedef Scalar retval; + static inline Scalar run(const Scalar& x, const Scalar& y) + { + using std::pow; + return pow(x, y); + } +}; + +template +struct pow_default_impl +{ + static inline Scalar run(Scalar x, Scalar y) + { + Scalar res(1); + eigen_assert(!NumTraits::IsSigned || y >= 0); + if(y & 1) res *= x; + y >>= 1; + while(y) + { + x *= x; + if(y&1) res *= x; + y >>= 1; + } + return res; + } +}; + +template +struct pow_impl : pow_default_impl::IsInteger> {}; + +template +struct pow_retval +{ + typedef Scalar type; +}; + +/**************************************************************************** +* Implementation of random * +****************************************************************************/ + +template +struct random_default_impl {}; + +template +struct random_impl : random_default_impl::IsComplex, NumTraits::IsInteger> {}; + +template +struct random_retval +{ + typedef Scalar type; +}; + +template inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random(const Scalar& x, const Scalar& y); +template inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random(); + +template +struct random_default_impl +{ + static inline Scalar run(const Scalar& x, const Scalar& y) + { + return x + (y-x) * Scalar(std::rand()) / Scalar(RAND_MAX); + } + static inline Scalar run() + { + return run(Scalar(NumTraits::IsSigned ? -1 : 0), Scalar(1)); + } +}; + +enum { + floor_log2_terminate, + floor_log2_move_up, + floor_log2_move_down, + floor_log2_bogus +}; + +template struct floor_log2_selector +{ + enum { middle = (lower + upper) / 2, + value = (upper <= lower + 1) ? int(floor_log2_terminate) + : (n < (1 << middle)) ? int(floor_log2_move_down) + : (n==0) ? int(floor_log2_bogus) + : int(floor_log2_move_up) + }; +}; + +template::value> +struct floor_log2 {}; + +template +struct floor_log2 +{ + enum { value = floor_log2::middle>::value }; +}; + +template +struct floor_log2 +{ + enum { value = floor_log2::middle, upper>::value }; +}; + +template +struct floor_log2 +{ + enum { value = (n >= ((unsigned int)(1) << (lower+1))) ? lower+1 : lower }; +}; + +template +struct floor_log2 +{ + // no value, error at compile time +}; + +template +struct random_default_impl +{ + typedef typename NumTraits::NonInteger NonInteger; + + static inline Scalar run(const Scalar& x, const Scalar& y) + { + return x + Scalar((NonInteger(y)-x+1) * std::rand() / (RAND_MAX + NonInteger(1))); + } + + static inline Scalar run() + { +#ifdef EIGEN_MAKING_DOCS + return run(Scalar(NumTraits::IsSigned ? -10 : 0), Scalar(10)); +#else + enum { rand_bits = floor_log2<(unsigned int)(RAND_MAX)+1>::value, + scalar_bits = sizeof(Scalar) * CHAR_BIT, + shift = EIGEN_PLAIN_ENUM_MAX(0, int(rand_bits) - int(scalar_bits)), + offset = NumTraits::IsSigned ? (1 << (EIGEN_PLAIN_ENUM_MIN(rand_bits,scalar_bits)-1)) : 0 + }; + return Scalar((std::rand() >> shift) - offset); +#endif + } +}; + +template +struct random_default_impl +{ + static inline Scalar run(const Scalar& x, const Scalar& y) + { + return Scalar(random(real(x), real(y)), + random(imag(x), imag(y))); + } + static inline Scalar run() + { + typedef typename NumTraits::Real RealScalar; + return Scalar(random(), random()); + } +}; + +template +inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random(const Scalar& x, const Scalar& y) +{ + return EIGEN_MATHFUNC_IMPL(random, Scalar)::run(x, y); +} + +template +inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random() +{ + return EIGEN_MATHFUNC_IMPL(random, Scalar)::run(); +} + +} // end namespace internal + +/**************************************************************************** +* Generic math function * +****************************************************************************/ + +namespace numext { + +template +inline EIGEN_MATHFUNC_RETVAL(real, Scalar) real(const Scalar& x) +{ + return EIGEN_MATHFUNC_IMPL(real, Scalar)::run(x); +} + +template +inline typename internal::add_const_on_value_type< EIGEN_MATHFUNC_RETVAL(real_ref, Scalar) >::type real_ref(const Scalar& x) +{ + return internal::real_ref_impl::run(x); +} + +template +inline EIGEN_MATHFUNC_RETVAL(real_ref, Scalar) real_ref(Scalar& x) +{ + return EIGEN_MATHFUNC_IMPL(real_ref, Scalar)::run(x); +} + +template +inline EIGEN_MATHFUNC_RETVAL(imag, Scalar) imag(const Scalar& x) +{ + return EIGEN_MATHFUNC_IMPL(imag, Scalar)::run(x); +} + +template +inline typename internal::add_const_on_value_type< EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) >::type imag_ref(const Scalar& x) +{ + return internal::imag_ref_impl::run(x); +} + +template +inline EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) imag_ref(Scalar& x) +{ + return EIGEN_MATHFUNC_IMPL(imag_ref, Scalar)::run(x); +} + +template +inline EIGEN_MATHFUNC_RETVAL(conj, Scalar) conj(const Scalar& x) +{ + return EIGEN_MATHFUNC_IMPL(conj, Scalar)::run(x); +} + +template +inline EIGEN_MATHFUNC_RETVAL(abs2, Scalar) abs2(const Scalar& x) +{ + return EIGEN_MATHFUNC_IMPL(abs2, Scalar)::run(x); +} + +template +inline EIGEN_MATHFUNC_RETVAL(norm1, Scalar) norm1(const Scalar& x) +{ + return EIGEN_MATHFUNC_IMPL(norm1, Scalar)::run(x); +} + +template +inline EIGEN_MATHFUNC_RETVAL(hypot, Scalar) hypot(const Scalar& x, const Scalar& y) +{ + return EIGEN_MATHFUNC_IMPL(hypot, Scalar)::run(x, y); +} + +template +inline EIGEN_MATHFUNC_RETVAL(atanh2, Scalar) atanh2(const Scalar& x, const Scalar& y) +{ + return EIGEN_MATHFUNC_IMPL(atanh2, Scalar)::run(x, y); +} + +template +inline EIGEN_MATHFUNC_RETVAL(pow, Scalar) pow(const Scalar& x, const Scalar& y) +{ + return EIGEN_MATHFUNC_IMPL(pow, Scalar)::run(x, y); +} + +// std::isfinite is non standard, so let's define our own version, +// even though it is not very efficient. +template bool (isfinite)(const T& x) +{ + return x::highest() && x>NumTraits::lowest(); +} + +} // end namespace numext + +namespace internal { + +/**************************************************************************** +* Implementation of fuzzy comparisons * +****************************************************************************/ + +template +struct scalar_fuzzy_default_impl {}; + +template +struct scalar_fuzzy_default_impl +{ + typedef typename NumTraits::Real RealScalar; + template + static inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y, const RealScalar& prec) + { + using std::abs; + return abs(x) <= abs(y) * prec; + } + static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar& prec) + { + using std::min; + using std::abs; + return abs(x - y) <= (min)(abs(x), abs(y)) * prec; + } + static inline bool isApproxOrLessThan(const Scalar& x, const Scalar& y, const RealScalar& prec) + { + return x <= y || isApprox(x, y, prec); + } +}; + +template +struct scalar_fuzzy_default_impl +{ + typedef typename NumTraits::Real RealScalar; + template + static inline bool isMuchSmallerThan(const Scalar& x, const Scalar&, const RealScalar&) + { + return x == Scalar(0); + } + static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar&) + { + return x == y; + } + static inline bool isApproxOrLessThan(const Scalar& x, const Scalar& y, const RealScalar&) + { + return x <= y; + } +}; + +template +struct scalar_fuzzy_default_impl +{ + typedef typename NumTraits::Real RealScalar; + template + static inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y, const RealScalar& prec) + { + return numext::abs2(x) <= numext::abs2(y) * prec * prec; + } + static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar& prec) + { + using std::min; + return numext::abs2(x - y) <= (min)(numext::abs2(x), numext::abs2(y)) * prec * prec; + } +}; + +template +struct scalar_fuzzy_impl : scalar_fuzzy_default_impl::IsComplex, NumTraits::IsInteger> {}; + +template +inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y, + typename NumTraits::Real precision = NumTraits::dummy_precision()) +{ + return scalar_fuzzy_impl::template isMuchSmallerThan(x, y, precision); +} + +template +inline bool isApprox(const Scalar& x, const Scalar& y, + typename NumTraits::Real precision = NumTraits::dummy_precision()) +{ + return scalar_fuzzy_impl::isApprox(x, y, precision); +} + +template +inline bool isApproxOrLessThan(const Scalar& x, const Scalar& y, + typename NumTraits::Real precision = NumTraits::dummy_precision()) +{ + return scalar_fuzzy_impl::isApproxOrLessThan(x, y, precision); +} + +/****************************************** +*** The special case of the bool type *** +******************************************/ + +template<> struct random_impl +{ + static inline bool run() + { + return random(0,1)==0 ? false : true; + } +}; + +template<> struct scalar_fuzzy_impl +{ + typedef bool RealScalar; + + template + static inline bool isMuchSmallerThan(const bool& x, const bool&, const bool&) + { + return !x; + } + + static inline bool isApprox(bool x, bool y, bool) + { + return x == y; + } + + static inline bool isApproxOrLessThan(const bool& x, const bool& y, const bool&) + { + return (!x) || y; + } + +}; + + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_MATHFUNCTIONS_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/Matrix.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/Matrix.h new file mode 100644 index 00000000..02be142d --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/Matrix.h @@ -0,0 +1,420 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2006-2010 Benoit Jacob +// Copyright (C) 2008-2009 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_MATRIX_H +#define EIGEN_MATRIX_H + +namespace Eigen { + +/** \class Matrix + * \ingroup Core_Module + * + * \brief The matrix class, also used for vectors and row-vectors + * + * The %Matrix class is the work-horse for all \em dense (\ref dense "note") matrices and vectors within Eigen. + * Vectors are matrices with one column, and row-vectors are matrices with one row. + * + * The %Matrix class encompasses \em both fixed-size and dynamic-size objects (\ref fixedsize "note"). + * + * The first three template parameters are required: + * \tparam _Scalar \anchor matrix_tparam_scalar Numeric type, e.g. float, double, int or std::complex. + * User defined sclar types are supported as well (see \ref user_defined_scalars "here"). + * \tparam _Rows Number of rows, or \b Dynamic + * \tparam _Cols Number of columns, or \b Dynamic + * + * The remaining template parameters are optional -- in most cases you don't have to worry about them. + * \tparam _Options \anchor matrix_tparam_options A combination of either \b #RowMajor or \b #ColMajor, and of either + * \b #AutoAlign or \b #DontAlign. + * The former controls \ref TopicStorageOrders "storage order", and defaults to column-major. The latter controls alignment, which is required + * for vectorization. It defaults to aligning matrices except for fixed sizes that aren't a multiple of the packet size. + * \tparam _MaxRows Maximum number of rows. Defaults to \a _Rows (\ref maxrows "note"). + * \tparam _MaxCols Maximum number of columns. Defaults to \a _Cols (\ref maxrows "note"). + * + * Eigen provides a number of typedefs covering the usual cases. Here are some examples: + * + * \li \c Matrix2d is a 2x2 square matrix of doubles (\c Matrix) + * \li \c Vector4f is a vector of 4 floats (\c Matrix) + * \li \c RowVector3i is a row-vector of 3 ints (\c Matrix) + * + * \li \c MatrixXf is a dynamic-size matrix of floats (\c Matrix) + * \li \c VectorXf is a dynamic-size vector of floats (\c Matrix) + * + * \li \c Matrix2Xf is a partially fixed-size (dynamic-size) matrix of floats (\c Matrix) + * \li \c MatrixX3d is a partially dynamic-size (fixed-size) matrix of double (\c Matrix) + * + * See \link matrixtypedefs this page \endlink for a complete list of predefined \em %Matrix and \em Vector typedefs. + * + * You can access elements of vectors and matrices using normal subscripting: + * + * \code + * Eigen::VectorXd v(10); + * v[0] = 0.1; + * v[1] = 0.2; + * v(0) = 0.3; + * v(1) = 0.4; + * + * Eigen::MatrixXi m(10, 10); + * m(0, 1) = 1; + * m(0, 2) = 2; + * m(0, 3) = 3; + * \endcode + * + * This class can be extended with the help of the plugin mechanism described on the page + * \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_MATRIX_PLUGIN. + * + * Some notes: + * + *
+ *
\anchor dense Dense versus sparse:
+ *
This %Matrix class handles dense, not sparse matrices and vectors. For sparse matrices and vectors, see the Sparse module. + * + * Dense matrices and vectors are plain usual arrays of coefficients. All the coefficients are stored, in an ordinary contiguous array. + * This is unlike Sparse matrices and vectors where the coefficients are stored as a list of nonzero coefficients.
+ * + *
\anchor fixedsize Fixed-size versus dynamic-size:
+ *
Fixed-size means that the numbers of rows and columns are known are compile-time. In this case, Eigen allocates the array + * of coefficients as a fixed-size array, as a class member. This makes sense for very small matrices, typically up to 4x4, sometimes up + * to 16x16. Larger matrices should be declared as dynamic-size even if one happens to know their size at compile-time. + * + * Dynamic-size means that the numbers of rows or columns are not necessarily known at compile-time. In this case they are runtime + * variables, and the array of coefficients is allocated dynamically on the heap. + * + * Note that \em dense matrices, be they Fixed-size or Dynamic-size, do not expand dynamically in the sense of a std::map. + * If you want this behavior, see the Sparse module.
+ * + *
\anchor maxrows _MaxRows and _MaxCols:
+ *
In most cases, one just leaves these parameters to the default values. + * These parameters mean the maximum size of rows and columns that the matrix may have. They are useful in cases + * when the exact numbers of rows and columns are not known are compile-time, but it is known at compile-time that they cannot + * exceed a certain value. This happens when taking dynamic-size blocks inside fixed-size matrices: in this case _MaxRows and _MaxCols + * are the dimensions of the original matrix, while _Rows and _Cols are Dynamic.
+ *
+ * + * \see MatrixBase for the majority of the API methods for matrices, \ref TopicClassHierarchy, + * \ref TopicStorageOrders + */ + +namespace internal { +template +struct traits > +{ + typedef _Scalar Scalar; + typedef Dense StorageKind; + typedef DenseIndex Index; + typedef MatrixXpr XprKind; + enum { + RowsAtCompileTime = _Rows, + ColsAtCompileTime = _Cols, + MaxRowsAtCompileTime = _MaxRows, + MaxColsAtCompileTime = _MaxCols, + Flags = compute_matrix_flags<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::ret, + CoeffReadCost = NumTraits::ReadCost, + Options = _Options, + InnerStrideAtCompileTime = 1, + OuterStrideAtCompileTime = (Options&RowMajor) ? ColsAtCompileTime : RowsAtCompileTime + }; +}; +} + +template +class Matrix + : public PlainObjectBase > +{ + public: + + /** \brief Base class typedef. + * \sa PlainObjectBase + */ + typedef PlainObjectBase Base; + + enum { Options = _Options }; + + EIGEN_DENSE_PUBLIC_INTERFACE(Matrix) + + typedef typename Base::PlainObject PlainObject; + + using Base::base; + using Base::coeffRef; + + /** + * \brief Assigns matrices to each other. + * + * \note This is a special case of the templated operator=. Its purpose is + * to prevent a default operator= from hiding the templated operator=. + * + * \callgraph + */ + EIGEN_STRONG_INLINE Matrix& operator=(const Matrix& other) + { + return Base::_set(other); + } + + /** \internal + * \brief Copies the value of the expression \a other into \c *this with automatic resizing. + * + * *this might be resized to match the dimensions of \a other. If *this was a null matrix (not already initialized), + * it will be initialized. + * + * Note that copying a row-vector into a vector (and conversely) is allowed. + * The resizing, if any, is then done in the appropriate way so that row-vectors + * remain row-vectors and vectors remain vectors. + */ + template + EIGEN_STRONG_INLINE Matrix& operator=(const MatrixBase& other) + { + return Base::_set(other); + } + + /* Here, doxygen failed to copy the brief information when using \copydoc */ + + /** + * \brief Copies the generic expression \a other into *this. + * \copydetails DenseBase::operator=(const EigenBase &other) + */ + template + EIGEN_STRONG_INLINE Matrix& operator=(const EigenBase &other) + { + return Base::operator=(other); + } + + template + EIGEN_STRONG_INLINE Matrix& operator=(const ReturnByValue& func) + { + return Base::operator=(func); + } + + /** \brief Default constructor. + * + * For fixed-size matrices, does nothing. + * + * For dynamic-size matrices, creates an empty matrix of size 0. Does not allocate any array. Such a matrix + * is called a null matrix. This constructor is the unique way to create null matrices: resizing + * a matrix to 0 is not supported. + * + * \sa resize(Index,Index) + */ + EIGEN_STRONG_INLINE Matrix() : Base() + { + Base::_check_template_params(); + EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED + } + + // FIXME is it still needed + Matrix(internal::constructor_without_unaligned_array_assert) + : Base(internal::constructor_without_unaligned_array_assert()) + { Base::_check_template_params(); EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED } + +#ifdef EIGEN_HAVE_RVALUE_REFERENCES + Matrix(Matrix&& other) + : Base(std::move(other)) + { + Base::_check_template_params(); + if (RowsAtCompileTime!=Dynamic && ColsAtCompileTime!=Dynamic) + Base::_set_noalias(other); + } + Matrix& operator=(Matrix&& other) + { + other.swap(*this); + return *this; + } +#endif + + /** \brief Constructs a vector or row-vector with given dimension. \only_for_vectors + * + * Note that this is only useful for dynamic-size vectors. For fixed-size vectors, + * it is redundant to pass the dimension here, so it makes more sense to use the default + * constructor Matrix() instead. + */ + EIGEN_STRONG_INLINE explicit Matrix(Index dim) + : Base(dim, RowsAtCompileTime == 1 ? 1 : dim, ColsAtCompileTime == 1 ? 1 : dim) + { + Base::_check_template_params(); + EIGEN_STATIC_ASSERT_VECTOR_ONLY(Matrix) + eigen_assert(dim >= 0); + eigen_assert(SizeAtCompileTime == Dynamic || SizeAtCompileTime == dim); + EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED + } + + #ifndef EIGEN_PARSED_BY_DOXYGEN + template + EIGEN_STRONG_INLINE Matrix(const T0& x, const T1& y) + { + Base::_check_template_params(); + Base::template _init2(x, y); + } + #else + /** \brief Constructs an uninitialized matrix with \a rows rows and \a cols columns. + * + * This is useful for dynamic-size matrices. For fixed-size matrices, + * it is redundant to pass these parameters, so one should use the default constructor + * Matrix() instead. */ + Matrix(Index rows, Index cols); + /** \brief Constructs an initialized 2D vector with given coefficients */ + Matrix(const Scalar& x, const Scalar& y); + #endif + + /** \brief Constructs an initialized 3D vector with given coefficients */ + EIGEN_STRONG_INLINE Matrix(const Scalar& x, const Scalar& y, const Scalar& z) + { + Base::_check_template_params(); + EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Matrix, 3) + m_storage.data()[0] = x; + m_storage.data()[1] = y; + m_storage.data()[2] = z; + } + /** \brief Constructs an initialized 4D vector with given coefficients */ + EIGEN_STRONG_INLINE Matrix(const Scalar& x, const Scalar& y, const Scalar& z, const Scalar& w) + { + Base::_check_template_params(); + EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Matrix, 4) + m_storage.data()[0] = x; + m_storage.data()[1] = y; + m_storage.data()[2] = z; + m_storage.data()[3] = w; + } + + explicit Matrix(const Scalar *data); + + /** \brief Constructor copying the value of the expression \a other */ + template + EIGEN_STRONG_INLINE Matrix(const MatrixBase& other) + : Base(other.rows() * other.cols(), other.rows(), other.cols()) + { + // This test resides here, to bring the error messages closer to the user. Normally, these checks + // are performed deeply within the library, thus causing long and scary error traces. + EIGEN_STATIC_ASSERT((internal::is_same::value), + YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) + + Base::_check_template_params(); + Base::_set_noalias(other); + } + /** \brief Copy constructor */ + EIGEN_STRONG_INLINE Matrix(const Matrix& other) + : Base(other.rows() * other.cols(), other.rows(), other.cols()) + { + Base::_check_template_params(); + Base::_set_noalias(other); + } + /** \brief Copy constructor with in-place evaluation */ + template + EIGEN_STRONG_INLINE Matrix(const ReturnByValue& other) + { + Base::_check_template_params(); + Base::resize(other.rows(), other.cols()); + other.evalTo(*this); + } + + /** \brief Copy constructor for generic expressions. + * \sa MatrixBase::operator=(const EigenBase&) + */ + template + EIGEN_STRONG_INLINE Matrix(const EigenBase &other) + : Base(other.derived().rows() * other.derived().cols(), other.derived().rows(), other.derived().cols()) + { + Base::_check_template_params(); + Base::_resize_to_match(other); + // FIXME/CHECK: isn't *this = other.derived() more efficient. it allows to + // go for pure _set() implementations, right? + *this = other; + } + + /** \internal + * \brief Override MatrixBase::swap() since for dynamic-sized matrices + * of same type it is enough to swap the data pointers. + */ + template + void swap(MatrixBase const & other) + { this->_swap(other.derived()); } + + inline Index innerStride() const { return 1; } + inline Index outerStride() const { return this->innerSize(); } + + /////////// Geometry module /////////// + + template + explicit Matrix(const RotationBase& r); + template + Matrix& operator=(const RotationBase& r); + + #ifdef EIGEN2_SUPPORT + template + explicit Matrix(const eigen2_RotationBase& r); + template + Matrix& operator=(const eigen2_RotationBase& r); + #endif + + // allow to extend Matrix outside Eigen + #ifdef EIGEN_MATRIX_PLUGIN + #include EIGEN_MATRIX_PLUGIN + #endif + + protected: + template + friend struct internal::conservative_resize_like_impl; + + using Base::m_storage; +}; + +/** \defgroup matrixtypedefs Global matrix typedefs + * + * \ingroup Core_Module + * + * Eigen defines several typedef shortcuts for most common matrix and vector types. + * + * The general patterns are the following: + * + * \c MatrixSizeType where \c Size can be \c 2,\c 3,\c 4 for fixed size square matrices or \c X for dynamic size, + * and where \c Type can be \c i for integer, \c f for float, \c d for double, \c cf for complex float, \c cd + * for complex double. + * + * For example, \c Matrix3d is a fixed-size 3x3 matrix type of doubles, and \c MatrixXf is a dynamic-size matrix of floats. + * + * There are also \c VectorSizeType and \c RowVectorSizeType which are self-explanatory. For example, \c Vector4cf is + * a fixed-size vector of 4 complex floats. + * + * \sa class Matrix + */ + +#define EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, Size, SizeSuffix) \ +/** \ingroup matrixtypedefs */ \ +typedef Matrix Matrix##SizeSuffix##TypeSuffix; \ +/** \ingroup matrixtypedefs */ \ +typedef Matrix Vector##SizeSuffix##TypeSuffix; \ +/** \ingroup matrixtypedefs */ \ +typedef Matrix RowVector##SizeSuffix##TypeSuffix; + +#define EIGEN_MAKE_FIXED_TYPEDEFS(Type, TypeSuffix, Size) \ +/** \ingroup matrixtypedefs */ \ +typedef Matrix Matrix##Size##X##TypeSuffix; \ +/** \ingroup matrixtypedefs */ \ +typedef Matrix Matrix##X##Size##TypeSuffix; + +#define EIGEN_MAKE_TYPEDEFS_ALL_SIZES(Type, TypeSuffix) \ +EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, 2, 2) \ +EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, 3, 3) \ +EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, 4, 4) \ +EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, Dynamic, X) \ +EIGEN_MAKE_FIXED_TYPEDEFS(Type, TypeSuffix, 2) \ +EIGEN_MAKE_FIXED_TYPEDEFS(Type, TypeSuffix, 3) \ +EIGEN_MAKE_FIXED_TYPEDEFS(Type, TypeSuffix, 4) + +EIGEN_MAKE_TYPEDEFS_ALL_SIZES(int, i) +EIGEN_MAKE_TYPEDEFS_ALL_SIZES(float, f) +EIGEN_MAKE_TYPEDEFS_ALL_SIZES(double, d) +EIGEN_MAKE_TYPEDEFS_ALL_SIZES(std::complex, cf) +EIGEN_MAKE_TYPEDEFS_ALL_SIZES(std::complex, cd) + +#undef EIGEN_MAKE_TYPEDEFS_ALL_SIZES +#undef EIGEN_MAKE_TYPEDEFS +#undef EIGEN_MAKE_FIXED_TYPEDEFS + +} // end namespace Eigen + +#endif // EIGEN_MATRIX_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/MatrixBase.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/MatrixBase.h new file mode 100644 index 00000000..e83ef4dc --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/MatrixBase.h @@ -0,0 +1,563 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2006-2009 Benoit Jacob +// Copyright (C) 2008 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_MATRIXBASE_H +#define EIGEN_MATRIXBASE_H + +namespace Eigen { + +/** \class MatrixBase + * \ingroup Core_Module + * + * \brief Base class for all dense matrices, vectors, and expressions + * + * This class is the base that is inherited by all matrix, vector, and related expression + * types. Most of the Eigen API is contained in this class, and its base classes. Other important + * classes for the Eigen API are Matrix, and VectorwiseOp. + * + * Note that some methods are defined in other modules such as the \ref LU_Module LU module + * for all functions related to matrix inversions. + * + * \tparam Derived is the derived type, e.g. a matrix type, or an expression, etc. + * + * When writing a function taking Eigen objects as argument, if you want your function + * to take as argument any matrix, vector, or expression, just let it take a + * MatrixBase argument. As an example, here is a function printFirstRow which, given + * a matrix, vector, or expression \a x, prints the first row of \a x. + * + * \code + template + void printFirstRow(const Eigen::MatrixBase& x) + { + cout << x.row(0) << endl; + } + * \endcode + * + * This class can be extended with the help of the plugin mechanism described on the page + * \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_MATRIXBASE_PLUGIN. + * + * \sa \ref TopicClassHierarchy + */ +template class MatrixBase + : public DenseBase +{ + public: +#ifndef EIGEN_PARSED_BY_DOXYGEN + typedef MatrixBase StorageBaseType; + typedef typename internal::traits::StorageKind StorageKind; + typedef typename internal::traits::Index Index; + typedef typename internal::traits::Scalar Scalar; + typedef typename internal::packet_traits::type PacketScalar; + typedef typename NumTraits::Real RealScalar; + + typedef DenseBase Base; + using Base::RowsAtCompileTime; + using Base::ColsAtCompileTime; + using Base::SizeAtCompileTime; + using Base::MaxRowsAtCompileTime; + using Base::MaxColsAtCompileTime; + using Base::MaxSizeAtCompileTime; + using Base::IsVectorAtCompileTime; + using Base::Flags; + using Base::CoeffReadCost; + + using Base::derived; + using Base::const_cast_derived; + using Base::rows; + using Base::cols; + using Base::size; + using Base::coeff; + using Base::coeffRef; + using Base::lazyAssign; + using Base::eval; + using Base::operator+=; + using Base::operator-=; + using Base::operator*=; + using Base::operator/=; + + typedef typename Base::CoeffReturnType CoeffReturnType; + typedef typename Base::ConstTransposeReturnType ConstTransposeReturnType; + typedef typename Base::RowXpr RowXpr; + typedef typename Base::ColXpr ColXpr; +#endif // not EIGEN_PARSED_BY_DOXYGEN + + + +#ifndef EIGEN_PARSED_BY_DOXYGEN + /** type of the equivalent square matrix */ + typedef Matrix SquareMatrixType; +#endif // not EIGEN_PARSED_BY_DOXYGEN + + /** \returns the size of the main diagonal, which is min(rows(),cols()). + * \sa rows(), cols(), SizeAtCompileTime. */ + inline Index diagonalSize() const { return (std::min)(rows(),cols()); } + + /** \brief The plain matrix type corresponding to this expression. + * + * This is not necessarily exactly the return type of eval(). In the case of plain matrices, + * the return type of eval() is a const reference to a matrix, not a matrix! It is however guaranteed + * that the return type of eval() is either PlainObject or const PlainObject&. + */ + typedef Matrix::Scalar, + internal::traits::RowsAtCompileTime, + internal::traits::ColsAtCompileTime, + AutoAlign | (internal::traits::Flags&RowMajorBit ? RowMajor : ColMajor), + internal::traits::MaxRowsAtCompileTime, + internal::traits::MaxColsAtCompileTime + > PlainObject; + +#ifndef EIGEN_PARSED_BY_DOXYGEN + /** \internal Represents a matrix with all coefficients equal to one another*/ + typedef CwiseNullaryOp,Derived> ConstantReturnType; + /** \internal the return type of MatrixBase::adjoint() */ + typedef typename internal::conditional::IsComplex, + CwiseUnaryOp, ConstTransposeReturnType>, + ConstTransposeReturnType + >::type AdjointReturnType; + /** \internal Return type of eigenvalues() */ + typedef Matrix, internal::traits::ColsAtCompileTime, 1, ColMajor> EigenvaluesReturnType; + /** \internal the return type of identity */ + typedef CwiseNullaryOp,Derived> IdentityReturnType; + /** \internal the return type of unit vectors */ + typedef Block, SquareMatrixType>, + internal::traits::RowsAtCompileTime, + internal::traits::ColsAtCompileTime> BasisReturnType; +#endif // not EIGEN_PARSED_BY_DOXYGEN + +#define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::MatrixBase +# include "../plugins/CommonCwiseUnaryOps.h" +# include "../plugins/CommonCwiseBinaryOps.h" +# include "../plugins/MatrixCwiseUnaryOps.h" +# include "../plugins/MatrixCwiseBinaryOps.h" +# ifdef EIGEN_MATRIXBASE_PLUGIN +# include EIGEN_MATRIXBASE_PLUGIN +# endif +#undef EIGEN_CURRENT_STORAGE_BASE_CLASS + + /** Special case of the template operator=, in order to prevent the compiler + * from generating a default operator= (issue hit with g++ 4.1) + */ + Derived& operator=(const MatrixBase& other); + + // We cannot inherit here via Base::operator= since it is causing + // trouble with MSVC. + + template + Derived& operator=(const DenseBase& other); + + template + Derived& operator=(const EigenBase& other); + + template + Derived& operator=(const ReturnByValue& other); + + template + Derived& lazyAssign(const ProductBase& other); + + template + Derived& lazyAssign(const MatrixPowerProduct& other); + + template + Derived& operator+=(const MatrixBase& other); + template + Derived& operator-=(const MatrixBase& other); + + template + const typename ProductReturnType::Type + operator*(const MatrixBase &other) const; + + template + const typename LazyProductReturnType::Type + lazyProduct(const MatrixBase &other) const; + + template + Derived& operator*=(const EigenBase& other); + + template + void applyOnTheLeft(const EigenBase& other); + + template + void applyOnTheRight(const EigenBase& other); + + template + const DiagonalProduct + operator*(const DiagonalBase &diagonal) const; + + template + typename internal::scalar_product_traits::Scalar,typename internal::traits::Scalar>::ReturnType + dot(const MatrixBase& other) const; + + #ifdef EIGEN2_SUPPORT + template + Scalar eigen2_dot(const MatrixBase& other) const; + #endif + + RealScalar squaredNorm() const; + RealScalar norm() const; + RealScalar stableNorm() const; + RealScalar blueNorm() const; + RealScalar hypotNorm() const; + const PlainObject normalized() const; + void normalize(); + + const AdjointReturnType adjoint() const; + void adjointInPlace(); + + typedef Diagonal DiagonalReturnType; + DiagonalReturnType diagonal(); + typedef typename internal::add_const >::type ConstDiagonalReturnType; + ConstDiagonalReturnType diagonal() const; + + template struct DiagonalIndexReturnType { typedef Diagonal Type; }; + template struct ConstDiagonalIndexReturnType { typedef const Diagonal Type; }; + + template typename DiagonalIndexReturnType::Type diagonal(); + template typename ConstDiagonalIndexReturnType::Type diagonal() const; + + typedef Diagonal DiagonalDynamicIndexReturnType; + typedef typename internal::add_const >::type ConstDiagonalDynamicIndexReturnType; + + DiagonalDynamicIndexReturnType diagonal(Index index); + ConstDiagonalDynamicIndexReturnType diagonal(Index index) const; + + #ifdef EIGEN2_SUPPORT + template typename internal::eigen2_part_return_type::type part(); + template const typename internal::eigen2_part_return_type::type part() const; + + // huuuge hack. make Eigen2's matrix.part() work in eigen3. Problem: Diagonal is now a class template instead + // of an integer constant. Solution: overload the part() method template wrt template parameters list. + template class U> + const DiagonalWrapper part() const + { return diagonal().asDiagonal(); } + #endif // EIGEN2_SUPPORT + + template struct TriangularViewReturnType { typedef TriangularView Type; }; + template struct ConstTriangularViewReturnType { typedef const TriangularView Type; }; + + template typename TriangularViewReturnType::Type triangularView(); + template typename ConstTriangularViewReturnType::Type triangularView() const; + + template struct SelfAdjointViewReturnType { typedef SelfAdjointView Type; }; + template struct ConstSelfAdjointViewReturnType { typedef const SelfAdjointView Type; }; + + template typename SelfAdjointViewReturnType::Type selfadjointView(); + template typename ConstSelfAdjointViewReturnType::Type selfadjointView() const; + + const SparseView sparseView(const Scalar& m_reference = Scalar(0), + const typename NumTraits::Real& m_epsilon = NumTraits::dummy_precision()) const; + static const IdentityReturnType Identity(); + static const IdentityReturnType Identity(Index rows, Index cols); + static const BasisReturnType Unit(Index size, Index i); + static const BasisReturnType Unit(Index i); + static const BasisReturnType UnitX(); + static const BasisReturnType UnitY(); + static const BasisReturnType UnitZ(); + static const BasisReturnType UnitW(); + + const DiagonalWrapper asDiagonal() const; + const PermutationWrapper asPermutation() const; + + Derived& setIdentity(); + Derived& setIdentity(Index rows, Index cols); + + bool isIdentity(const RealScalar& prec = NumTraits::dummy_precision()) const; + bool isDiagonal(const RealScalar& prec = NumTraits::dummy_precision()) const; + + bool isUpperTriangular(const RealScalar& prec = NumTraits::dummy_precision()) const; + bool isLowerTriangular(const RealScalar& prec = NumTraits::dummy_precision()) const; + + template + bool isOrthogonal(const MatrixBase& other, + const RealScalar& prec = NumTraits::dummy_precision()) const; + bool isUnitary(const RealScalar& prec = NumTraits::dummy_precision()) const; + + /** \returns true if each coefficients of \c *this and \a other are all exactly equal. + * \warning When using floating point scalar values you probably should rather use a + * fuzzy comparison such as isApprox() + * \sa isApprox(), operator!= */ + template + inline bool operator==(const MatrixBase& other) const + { return cwiseEqual(other).all(); } + + /** \returns true if at least one pair of coefficients of \c *this and \a other are not exactly equal to each other. + * \warning When using floating point scalar values you probably should rather use a + * fuzzy comparison such as isApprox() + * \sa isApprox(), operator== */ + template + inline bool operator!=(const MatrixBase& other) const + { return cwiseNotEqual(other).any(); } + + NoAlias noalias(); + + inline const ForceAlignedAccess forceAlignedAccess() const; + inline ForceAlignedAccess forceAlignedAccess(); + template inline typename internal::add_const_on_value_type,Derived&>::type>::type forceAlignedAccessIf() const; + template inline typename internal::conditional,Derived&>::type forceAlignedAccessIf(); + + Scalar trace() const; + +/////////// Array module /////////// + + template RealScalar lpNorm() const; + + MatrixBase& matrix() { return *this; } + const MatrixBase& matrix() const { return *this; } + + /** \returns an \link Eigen::ArrayBase Array \endlink expression of this matrix + * \sa ArrayBase::matrix() */ + ArrayWrapper array() { return derived(); } + const ArrayWrapper array() const { return derived(); } + +/////////// LU module /////////// + + const FullPivLU fullPivLu() const; + const PartialPivLU partialPivLu() const; + + #if EIGEN2_SUPPORT_STAGE < STAGE20_RESOLVE_API_CONFLICTS + const LU lu() const; + #endif + + #ifdef EIGEN2_SUPPORT + const LU eigen2_lu() const; + #endif + + #if EIGEN2_SUPPORT_STAGE > STAGE20_RESOLVE_API_CONFLICTS + const PartialPivLU lu() const; + #endif + + #ifdef EIGEN2_SUPPORT + template + void computeInverse(MatrixBase *result) const { + *result = this->inverse(); + } + #endif + + const internal::inverse_impl inverse() const; + template + void computeInverseAndDetWithCheck( + ResultType& inverse, + typename ResultType::Scalar& determinant, + bool& invertible, + const RealScalar& absDeterminantThreshold = NumTraits::dummy_precision() + ) const; + template + void computeInverseWithCheck( + ResultType& inverse, + bool& invertible, + const RealScalar& absDeterminantThreshold = NumTraits::dummy_precision() + ) const; + Scalar determinant() const; + +/////////// Cholesky module /////////// + + const LLT llt() const; + const LDLT ldlt() const; + +/////////// QR module /////////// + + const HouseholderQR householderQr() const; + const ColPivHouseholderQR colPivHouseholderQr() const; + const FullPivHouseholderQR fullPivHouseholderQr() const; + + #ifdef EIGEN2_SUPPORT + const QR qr() const; + #endif + + EigenvaluesReturnType eigenvalues() const; + RealScalar operatorNorm() const; + +/////////// SVD module /////////// + + JacobiSVD jacobiSvd(unsigned int computationOptions = 0) const; + + #ifdef EIGEN2_SUPPORT + SVD svd() const; + #endif + +/////////// Geometry module /////////// + + #ifndef EIGEN_PARSED_BY_DOXYGEN + /// \internal helper struct to form the return type of the cross product + template struct cross_product_return_type { + typedef typename internal::scalar_product_traits::Scalar,typename internal::traits::Scalar>::ReturnType Scalar; + typedef Matrix type; + }; + #endif // EIGEN_PARSED_BY_DOXYGEN + template + typename cross_product_return_type::type + cross(const MatrixBase& other) const; + template + PlainObject cross3(const MatrixBase& other) const; + PlainObject unitOrthogonal(void) const; + Matrix eulerAngles(Index a0, Index a1, Index a2) const; + + #if EIGEN2_SUPPORT_STAGE > STAGE20_RESOLVE_API_CONFLICTS + ScalarMultipleReturnType operator*(const UniformScaling& s) const; + // put this as separate enum value to work around possible GCC 4.3 bug (?) + enum { HomogeneousReturnTypeDirection = ColsAtCompileTime==1?Vertical:Horizontal }; + typedef Homogeneous HomogeneousReturnType; + HomogeneousReturnType homogeneous() const; + #endif + + enum { + SizeMinusOne = SizeAtCompileTime==Dynamic ? Dynamic : SizeAtCompileTime-1 + }; + typedef Block::ColsAtCompileTime==1 ? SizeMinusOne : 1, + internal::traits::ColsAtCompileTime==1 ? 1 : SizeMinusOne> ConstStartMinusOne; + typedef CwiseUnaryOp::Scalar>, + const ConstStartMinusOne > HNormalizedReturnType; + + const HNormalizedReturnType hnormalized() const; + +////////// Householder module /////////// + + void makeHouseholderInPlace(Scalar& tau, RealScalar& beta); + template + void makeHouseholder(EssentialPart& essential, + Scalar& tau, RealScalar& beta) const; + template + void applyHouseholderOnTheLeft(const EssentialPart& essential, + const Scalar& tau, + Scalar* workspace); + template + void applyHouseholderOnTheRight(const EssentialPart& essential, + const Scalar& tau, + Scalar* workspace); + +///////// Jacobi module ///////// + + template + void applyOnTheLeft(Index p, Index q, const JacobiRotation& j); + template + void applyOnTheRight(Index p, Index q, const JacobiRotation& j); + +///////// SparseCore module ///////// + + template + EIGEN_STRONG_INLINE const typename SparseMatrixBase::template CwiseProductDenseReturnType::Type + cwiseProduct(const SparseMatrixBase &other) const + { + return other.cwiseProduct(derived()); + } + +///////// MatrixFunctions module ///////// + + typedef typename internal::stem_function::type StemFunction; + const MatrixExponentialReturnValue exp() const; + const MatrixFunctionReturnValue matrixFunction(StemFunction f) const; + const MatrixFunctionReturnValue cosh() const; + const MatrixFunctionReturnValue sinh() const; + const MatrixFunctionReturnValue cos() const; + const MatrixFunctionReturnValue sin() const; + const MatrixSquareRootReturnValue sqrt() const; + const MatrixLogarithmReturnValue log() const; + const MatrixPowerReturnValue pow(const RealScalar& p) const; + +#ifdef EIGEN2_SUPPORT + template + Derived& operator+=(const Flagged, 0, + EvalBeforeAssigningBit>& other); + + template + Derived& operator-=(const Flagged, 0, + EvalBeforeAssigningBit>& other); + + /** \deprecated because .lazy() is deprecated + * Overloaded for cache friendly product evaluation */ + template + Derived& lazyAssign(const Flagged& other) + { return lazyAssign(other._expression()); } + + template + const Flagged marked() const; + const Flagged lazy() const; + + inline const Cwise cwise() const; + inline Cwise cwise(); + + VectorBlock start(Index size); + const VectorBlock start(Index size) const; + VectorBlock end(Index size); + const VectorBlock end(Index size) const; + template VectorBlock start(); + template const VectorBlock start() const; + template VectorBlock end(); + template const VectorBlock end() const; + + Minor minor(Index row, Index col); + const Minor minor(Index row, Index col) const; +#endif + + protected: + MatrixBase() : Base() {} + + private: + explicit MatrixBase(int); + MatrixBase(int,int); + template explicit MatrixBase(const MatrixBase&); + protected: + // mixing arrays and matrices is not legal + template Derived& operator+=(const ArrayBase& ) + {EIGEN_STATIC_ASSERT(std::ptrdiff_t(sizeof(typename OtherDerived::Scalar))==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES); return *this;} + // mixing arrays and matrices is not legal + template Derived& operator-=(const ArrayBase& ) + {EIGEN_STATIC_ASSERT(std::ptrdiff_t(sizeof(typename OtherDerived::Scalar))==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES); return *this;} +}; + + +/*************************************************************************** +* Implementation of matrix base methods +***************************************************************************/ + +/** replaces \c *this by \c *this * \a other. + * + * \returns a reference to \c *this + * + * Example: \include MatrixBase_applyOnTheRight.cpp + * Output: \verbinclude MatrixBase_applyOnTheRight.out + */ +template +template +inline Derived& +MatrixBase::operator*=(const EigenBase &other) +{ + other.derived().applyThisOnTheRight(derived()); + return derived(); +} + +/** replaces \c *this by \c *this * \a other. It is equivalent to MatrixBase::operator*=(). + * + * Example: \include MatrixBase_applyOnTheRight.cpp + * Output: \verbinclude MatrixBase_applyOnTheRight.out + */ +template +template +inline void MatrixBase::applyOnTheRight(const EigenBase &other) +{ + other.derived().applyThisOnTheRight(derived()); +} + +/** replaces \c *this by \a other * \c *this. + * + * Example: \include MatrixBase_applyOnTheLeft.cpp + * Output: \verbinclude MatrixBase_applyOnTheLeft.out + */ +template +template +inline void MatrixBase::applyOnTheLeft(const EigenBase &other) +{ + other.derived().applyThisOnTheLeft(derived()); +} + +} // end namespace Eigen + +#endif // EIGEN_MATRIXBASE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/NestByValue.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/NestByValue.h new file mode 100644 index 00000000..a893b176 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/NestByValue.h @@ -0,0 +1,111 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008 Gael Guennebaud +// Copyright (C) 2006-2008 Benoit Jacob +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_NESTBYVALUE_H +#define EIGEN_NESTBYVALUE_H + +namespace Eigen { + +/** \class NestByValue + * \ingroup Core_Module + * + * \brief Expression which must be nested by value + * + * \param ExpressionType the type of the object of which we are requiring nesting-by-value + * + * This class is the return type of MatrixBase::nestByValue() + * and most of the time this is the only way it is used. + * + * \sa MatrixBase::nestByValue() + */ + +namespace internal { +template +struct traits > : public traits +{}; +} + +template class NestByValue + : public internal::dense_xpr_base< NestByValue >::type +{ + public: + + typedef typename internal::dense_xpr_base::type Base; + EIGEN_DENSE_PUBLIC_INTERFACE(NestByValue) + + inline NestByValue(const ExpressionType& matrix) : m_expression(matrix) {} + + inline Index rows() const { return m_expression.rows(); } + inline Index cols() const { return m_expression.cols(); } + inline Index outerStride() const { return m_expression.outerStride(); } + inline Index innerStride() const { return m_expression.innerStride(); } + + inline const CoeffReturnType coeff(Index row, Index col) const + { + return m_expression.coeff(row, col); + } + + inline Scalar& coeffRef(Index row, Index col) + { + return m_expression.const_cast_derived().coeffRef(row, col); + } + + inline const CoeffReturnType coeff(Index index) const + { + return m_expression.coeff(index); + } + + inline Scalar& coeffRef(Index index) + { + return m_expression.const_cast_derived().coeffRef(index); + } + + template + inline const PacketScalar packet(Index row, Index col) const + { + return m_expression.template packet(row, col); + } + + template + inline void writePacket(Index row, Index col, const PacketScalar& x) + { + m_expression.const_cast_derived().template writePacket(row, col, x); + } + + template + inline const PacketScalar packet(Index index) const + { + return m_expression.template packet(index); + } + + template + inline void writePacket(Index index, const PacketScalar& x) + { + m_expression.const_cast_derived().template writePacket(index, x); + } + + operator const ExpressionType&() const { return m_expression; } + + protected: + const ExpressionType m_expression; +}; + +/** \returns an expression of the temporary version of *this. + */ +template +inline const NestByValue +DenseBase::nestByValue() const +{ + return NestByValue(derived()); +} + +} // end namespace Eigen + +#endif // EIGEN_NESTBYVALUE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/NoAlias.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/NoAlias.h new file mode 100644 index 00000000..768bfb18 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/NoAlias.h @@ -0,0 +1,134 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2009 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_NOALIAS_H +#define EIGEN_NOALIAS_H + +namespace Eigen { + +/** \class NoAlias + * \ingroup Core_Module + * + * \brief Pseudo expression providing an operator = assuming no aliasing + * + * \param ExpressionType the type of the object on which to do the lazy assignment + * + * This class represents an expression with special assignment operators + * assuming no aliasing between the target expression and the source expression. + * More precisely it alloas to bypass the EvalBeforeAssignBit flag of the source expression. + * It is the return type of MatrixBase::noalias() + * and most of the time this is the only way it is used. + * + * \sa MatrixBase::noalias() + */ +template class StorageBase> +class NoAlias +{ + typedef typename ExpressionType::Scalar Scalar; + public: + NoAlias(ExpressionType& expression) : m_expression(expression) {} + + /** Behaves like MatrixBase::lazyAssign(other) + * \sa MatrixBase::lazyAssign() */ + template + EIGEN_STRONG_INLINE ExpressionType& operator=(const StorageBase& other) + { return internal::assign_selector::run(m_expression,other.derived()); } + + /** \sa MatrixBase::operator+= */ + template + EIGEN_STRONG_INLINE ExpressionType& operator+=(const StorageBase& other) + { + typedef SelfCwiseBinaryOp, ExpressionType, OtherDerived> SelfAdder; + SelfAdder tmp(m_expression); + typedef typename internal::nested::type OtherDerivedNested; + typedef typename internal::remove_all::type _OtherDerivedNested; + internal::assign_selector::run(tmp,OtherDerivedNested(other.derived())); + return m_expression; + } + + /** \sa MatrixBase::operator-= */ + template + EIGEN_STRONG_INLINE ExpressionType& operator-=(const StorageBase& other) + { + typedef SelfCwiseBinaryOp, ExpressionType, OtherDerived> SelfAdder; + SelfAdder tmp(m_expression); + typedef typename internal::nested::type OtherDerivedNested; + typedef typename internal::remove_all::type _OtherDerivedNested; + internal::assign_selector::run(tmp,OtherDerivedNested(other.derived())); + return m_expression; + } + +#ifndef EIGEN_PARSED_BY_DOXYGEN + template + EIGEN_STRONG_INLINE ExpressionType& operator+=(const ProductBase& other) + { other.derived().addTo(m_expression); return m_expression; } + + template + EIGEN_STRONG_INLINE ExpressionType& operator-=(const ProductBase& other) + { other.derived().subTo(m_expression); return m_expression; } + + template + EIGEN_STRONG_INLINE ExpressionType& operator+=(const CoeffBasedProduct& other) + { return m_expression.derived() += CoeffBasedProduct(other.lhs(), other.rhs()); } + + template + EIGEN_STRONG_INLINE ExpressionType& operator-=(const CoeffBasedProduct& other) + { return m_expression.derived() -= CoeffBasedProduct(other.lhs(), other.rhs()); } + + template + ExpressionType& operator=(const ReturnByValue& func) + { return m_expression = func; } +#endif + + ExpressionType& expression() const + { + return m_expression; + } + + protected: + ExpressionType& m_expression; +}; + +/** \returns a pseudo expression of \c *this with an operator= assuming + * no aliasing between \c *this and the source expression. + * + * More precisely, noalias() allows to bypass the EvalBeforeAssignBit flag. + * Currently, even though several expressions may alias, only product + * expressions have this flag. Therefore, noalias() is only usefull when + * the source expression contains a matrix product. + * + * Here are some examples where noalias is usefull: + * \code + * D.noalias() = A * B; + * D.noalias() += A.transpose() * B; + * D.noalias() -= 2 * A * B.adjoint(); + * \endcode + * + * On the other hand the following example will lead to a \b wrong result: + * \code + * A.noalias() = A * B; + * \endcode + * because the result matrix A is also an operand of the matrix product. Therefore, + * there is no alternative than evaluating A * B in a temporary, that is the default + * behavior when you write: + * \code + * A = A * B; + * \endcode + * + * \sa class NoAlias + */ +template +NoAlias MatrixBase::noalias() +{ + return derived(); +} + +} // end namespace Eigen + +#endif // EIGEN_NOALIAS_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/NumTraits.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/NumTraits.h new file mode 100644 index 00000000..bac9e50b --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/NumTraits.h @@ -0,0 +1,150 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2006-2010 Benoit Jacob +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_NUMTRAITS_H +#define EIGEN_NUMTRAITS_H + +namespace Eigen { + +/** \class NumTraits + * \ingroup Core_Module + * + * \brief Holds information about the various numeric (i.e. scalar) types allowed by Eigen. + * + * \param T the numeric type at hand + * + * This class stores enums, typedefs and static methods giving information about a numeric type. + * + * The provided data consists of: + * \li A typedef \a Real, giving the "real part" type of \a T. If \a T is already real, + * then \a Real is just a typedef to \a T. If \a T is \c std::complex then \a Real + * is a typedef to \a U. + * \li A typedef \a NonInteger, giving the type that should be used for operations producing non-integral values, + * such as quotients, square roots, etc. If \a T is a floating-point type, then this typedef just gives + * \a T again. Note however that many Eigen functions such as internal::sqrt simply refuse to + * take integers. Outside of a few cases, Eigen doesn't do automatic type promotion. Thus, this typedef is + * only intended as a helper for code that needs to explicitly promote types. + * \li A typedef \a Nested giving the type to use to nest a value inside of the expression tree. If you don't know what + * this means, just use \a T here. + * \li An enum value \a IsComplex. It is equal to 1 if \a T is a \c std::complex + * type, and to 0 otherwise. + * \li An enum value \a IsInteger. It is equal to \c 1 if \a T is an integer type such as \c int, + * and to \c 0 otherwise. + * \li Enum values ReadCost, AddCost and MulCost representing a rough estimate of the number of CPU cycles needed + * to by move / add / mul instructions respectively, assuming the data is already stored in CPU registers. + * Stay vague here. No need to do architecture-specific stuff. + * \li An enum value \a IsSigned. It is equal to \c 1 if \a T is a signed type and to 0 if \a T is unsigned. + * \li An enum value \a RequireInitialization. It is equal to \c 1 if the constructor of the numeric type \a T must + * be called, and to 0 if it is safe not to call it. Default is 0 if \a T is an arithmetic type, and 1 otherwise. + * \li An epsilon() function which, unlike std::numeric_limits::epsilon(), returns a \a Real instead of a \a T. + * \li A dummy_precision() function returning a weak epsilon value. It is mainly used as a default + * value by the fuzzy comparison operators. + * \li highest() and lowest() functions returning the highest and lowest possible values respectively. + */ + +template struct GenericNumTraits +{ + enum { + IsInteger = std::numeric_limits::is_integer, + IsSigned = std::numeric_limits::is_signed, + IsComplex = 0, + RequireInitialization = internal::is_arithmetic::value ? 0 : 1, + ReadCost = 1, + AddCost = 1, + MulCost = 1 + }; + + typedef T Real; + typedef typename internal::conditional< + IsInteger, + typename internal::conditional::type, + T + >::type NonInteger; + typedef T Nested; + + static inline Real epsilon() { return std::numeric_limits::epsilon(); } + static inline Real dummy_precision() + { + // make sure to override this for floating-point types + return Real(0); + } + static inline T highest() { return (std::numeric_limits::max)(); } + static inline T lowest() { return IsInteger ? (std::numeric_limits::min)() : (-(std::numeric_limits::max)()); } + +#ifdef EIGEN2_SUPPORT + enum { + HasFloatingPoint = !IsInteger + }; + typedef NonInteger FloatingPoint; +#endif +}; + +template struct NumTraits : GenericNumTraits +{}; + +template<> struct NumTraits + : GenericNumTraits +{ + static inline float dummy_precision() { return 1e-5f; } +}; + +template<> struct NumTraits : GenericNumTraits +{ + static inline double dummy_precision() { return 1e-12; } +}; + +template<> struct NumTraits + : GenericNumTraits +{ + static inline long double dummy_precision() { return 1e-15l; } +}; + +template struct NumTraits > + : GenericNumTraits > +{ + typedef _Real Real; + enum { + IsComplex = 1, + RequireInitialization = NumTraits<_Real>::RequireInitialization, + ReadCost = 2 * NumTraits<_Real>::ReadCost, + AddCost = 2 * NumTraits::AddCost, + MulCost = 4 * NumTraits::MulCost + 2 * NumTraits::AddCost + }; + + static inline Real epsilon() { return NumTraits::epsilon(); } + static inline Real dummy_precision() { return NumTraits::dummy_precision(); } +}; + +template +struct NumTraits > +{ + typedef Array ArrayType; + typedef typename NumTraits::Real RealScalar; + typedef Array Real; + typedef typename NumTraits::NonInteger NonIntegerScalar; + typedef Array NonInteger; + typedef ArrayType & Nested; + + enum { + IsComplex = NumTraits::IsComplex, + IsInteger = NumTraits::IsInteger, + IsSigned = NumTraits::IsSigned, + RequireInitialization = 1, + ReadCost = ArrayType::SizeAtCompileTime==Dynamic ? Dynamic : ArrayType::SizeAtCompileTime * NumTraits::ReadCost, + AddCost = ArrayType::SizeAtCompileTime==Dynamic ? Dynamic : ArrayType::SizeAtCompileTime * NumTraits::AddCost, + MulCost = ArrayType::SizeAtCompileTime==Dynamic ? Dynamic : ArrayType::SizeAtCompileTime * NumTraits::MulCost + }; + + static inline RealScalar epsilon() { return NumTraits::epsilon(); } + static inline RealScalar dummy_precision() { return NumTraits::dummy_precision(); } +}; + +} // end namespace Eigen + +#endif // EIGEN_NUMTRAITS_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/PermutationMatrix.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/PermutationMatrix.h new file mode 100644 index 00000000..85ffae26 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/PermutationMatrix.h @@ -0,0 +1,721 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2009 Benoit Jacob +// Copyright (C) 2009-2011 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_PERMUTATIONMATRIX_H +#define EIGEN_PERMUTATIONMATRIX_H + +namespace Eigen { + +template class PermutedImpl; + +/** \class PermutationBase + * \ingroup Core_Module + * + * \brief Base class for permutations + * + * \param Derived the derived class + * + * This class is the base class for all expressions representing a permutation matrix, + * internally stored as a vector of integers. + * The convention followed here is that if \f$ \sigma \f$ is a permutation, the corresponding permutation matrix + * \f$ P_\sigma \f$ is such that if \f$ (e_1,\ldots,e_p) \f$ is the canonical basis, we have: + * \f[ P_\sigma(e_i) = e_{\sigma(i)}. \f] + * This convention ensures that for any two permutations \f$ \sigma, \tau \f$, we have: + * \f[ P_{\sigma\circ\tau} = P_\sigma P_\tau. \f] + * + * Permutation matrices are square and invertible. + * + * Notice that in addition to the member functions and operators listed here, there also are non-member + * operator* to multiply any kind of permutation object with any kind of matrix expression (MatrixBase) + * on either side. + * + * \sa class PermutationMatrix, class PermutationWrapper + */ + +namespace internal { + +template +struct permut_matrix_product_retval; +template +struct permut_sparsematrix_product_retval; +enum PermPermProduct_t {PermPermProduct}; + +} // end namespace internal + +template +class PermutationBase : public EigenBase +{ + typedef internal::traits Traits; + typedef EigenBase Base; + public: + + #ifndef EIGEN_PARSED_BY_DOXYGEN + typedef typename Traits::IndicesType IndicesType; + enum { + Flags = Traits::Flags, + CoeffReadCost = Traits::CoeffReadCost, + RowsAtCompileTime = Traits::RowsAtCompileTime, + ColsAtCompileTime = Traits::ColsAtCompileTime, + MaxRowsAtCompileTime = Traits::MaxRowsAtCompileTime, + MaxColsAtCompileTime = Traits::MaxColsAtCompileTime + }; + typedef typename Traits::Scalar Scalar; + typedef typename Traits::Index Index; + typedef Matrix + DenseMatrixType; + typedef PermutationMatrix + PlainPermutationType; + using Base::derived; + #endif + + /** Copies the other permutation into *this */ + template + Derived& operator=(const PermutationBase& other) + { + indices() = other.indices(); + return derived(); + } + + /** Assignment from the Transpositions \a tr */ + template + Derived& operator=(const TranspositionsBase& tr) + { + setIdentity(tr.size()); + for(Index k=size()-1; k>=0; --k) + applyTranspositionOnTheRight(k,tr.coeff(k)); + return derived(); + } + + #ifndef EIGEN_PARSED_BY_DOXYGEN + /** This is a special case of the templated operator=. Its purpose is to + * prevent a default operator= from hiding the templated operator=. + */ + Derived& operator=(const PermutationBase& other) + { + indices() = other.indices(); + return derived(); + } + #endif + + /** \returns the number of rows */ + inline Index rows() const { return Index(indices().size()); } + + /** \returns the number of columns */ + inline Index cols() const { return Index(indices().size()); } + + /** \returns the size of a side of the respective square matrix, i.e., the number of indices */ + inline Index size() const { return Index(indices().size()); } + + #ifndef EIGEN_PARSED_BY_DOXYGEN + template + void evalTo(MatrixBase& other) const + { + other.setZero(); + for (int i=0; i=0 && j>=0 && i=0 && j>=0 && i inverse() const + { return derived(); } + /** \returns the tranpose permutation matrix. + * + * \note \note_try_to_help_rvo + */ + inline Transpose transpose() const + { return derived(); } + + /**** multiplication helpers to hopefully get RVO ****/ + + +#ifndef EIGEN_PARSED_BY_DOXYGEN + protected: + template + void assignTranspose(const PermutationBase& other) + { + for (int i=0; i + void assignProduct(const Lhs& lhs, const Rhs& rhs) + { + eigen_assert(lhs.cols() == rhs.rows()); + for (int i=0; i + inline PlainPermutationType operator*(const PermutationBase& other) const + { return PlainPermutationType(internal::PermPermProduct, derived(), other.derived()); } + + /** \returns the product of a permutation with another inverse permutation. + * + * \note \note_try_to_help_rvo + */ + template + inline PlainPermutationType operator*(const Transpose >& other) const + { return PlainPermutationType(internal::PermPermProduct, *this, other.eval()); } + + /** \returns the product of an inverse permutation with another permutation. + * + * \note \note_try_to_help_rvo + */ + template friend + inline PlainPermutationType operator*(const Transpose >& other, const PermutationBase& perm) + { return PlainPermutationType(internal::PermPermProduct, other.eval(), perm); } + + /** \returns the determinant of the permutation matrix, which is either 1 or -1 depending on the parity of the permutation. + * + * This function is O(\c n) procedure allocating a buffer of \c n booleans. + */ + Index determinant() const + { + Index res = 1; + Index n = size(); + Matrix mask(n); + mask.fill(false); + Index r = 0; + while(r < n) + { + // search for the next seed + while(r=n) + break; + // we got one, let's follow it until we are back to the seed + Index k0 = r++; + mask.coeffRef(k0) = true; + for(Index k=indices().coeff(k0); k!=k0; k=indices().coeff(k)) + { + mask.coeffRef(k) = true; + res = -res; + } + } + return res; + } + + protected: + +}; + +/** \class PermutationMatrix + * \ingroup Core_Module + * + * \brief Permutation matrix + * + * \param SizeAtCompileTime the number of rows/cols, or Dynamic + * \param MaxSizeAtCompileTime the maximum number of rows/cols, or Dynamic. This optional parameter defaults to SizeAtCompileTime. Most of the time, you should not have to specify it. + * \param IndexType the interger type of the indices + * + * This class represents a permutation matrix, internally stored as a vector of integers. + * + * \sa class PermutationBase, class PermutationWrapper, class DiagonalMatrix + */ + +namespace internal { +template +struct traits > + : traits > +{ + typedef IndexType Index; + typedef Matrix IndicesType; +}; +} + +template +class PermutationMatrix : public PermutationBase > +{ + typedef PermutationBase Base; + typedef internal::traits Traits; + public: + + #ifndef EIGEN_PARSED_BY_DOXYGEN + typedef typename Traits::IndicesType IndicesType; + #endif + + inline PermutationMatrix() + {} + + /** Constructs an uninitialized permutation matrix of given size. + */ + inline PermutationMatrix(int size) : m_indices(size) + {} + + /** Copy constructor. */ + template + inline PermutationMatrix(const PermutationBase& other) + : m_indices(other.indices()) {} + + #ifndef EIGEN_PARSED_BY_DOXYGEN + /** Standard copy constructor. Defined only to prevent a default copy constructor + * from hiding the other templated constructor */ + inline PermutationMatrix(const PermutationMatrix& other) : m_indices(other.indices()) {} + #endif + + /** Generic constructor from expression of the indices. The indices + * array has the meaning that the permutations sends each integer i to indices[i]. + * + * \warning It is your responsibility to check that the indices array that you passes actually + * describes a permutation, i.e., each value between 0 and n-1 occurs exactly once, where n is the + * array's size. + */ + template + explicit inline PermutationMatrix(const MatrixBase& a_indices) : m_indices(a_indices) + {} + + /** Convert the Transpositions \a tr to a permutation matrix */ + template + explicit PermutationMatrix(const TranspositionsBase& tr) + : m_indices(tr.size()) + { + *this = tr; + } + + /** Copies the other permutation into *this */ + template + PermutationMatrix& operator=(const PermutationBase& other) + { + m_indices = other.indices(); + return *this; + } + + /** Assignment from the Transpositions \a tr */ + template + PermutationMatrix& operator=(const TranspositionsBase& tr) + { + return Base::operator=(tr.derived()); + } + + #ifndef EIGEN_PARSED_BY_DOXYGEN + /** This is a special case of the templated operator=. Its purpose is to + * prevent a default operator= from hiding the templated operator=. + */ + PermutationMatrix& operator=(const PermutationMatrix& other) + { + m_indices = other.m_indices; + return *this; + } + #endif + + /** const version of indices(). */ + const IndicesType& indices() const { return m_indices; } + /** \returns a reference to the stored array representing the permutation. */ + IndicesType& indices() { return m_indices; } + + + /**** multiplication helpers to hopefully get RVO ****/ + +#ifndef EIGEN_PARSED_BY_DOXYGEN + template + PermutationMatrix(const Transpose >& other) + : m_indices(other.nestedPermutation().size()) + { + for (int i=0; i + PermutationMatrix(internal::PermPermProduct_t, const Lhs& lhs, const Rhs& rhs) + : m_indices(lhs.indices().size()) + { + Base::assignProduct(lhs,rhs); + } +#endif + + protected: + + IndicesType m_indices; +}; + + +namespace internal { +template +struct traits,_PacketAccess> > + : traits > +{ + typedef IndexType Index; + typedef Map, _PacketAccess> IndicesType; +}; +} + +template +class Map,_PacketAccess> + : public PermutationBase,_PacketAccess> > +{ + typedef PermutationBase Base; + typedef internal::traits Traits; + public: + + #ifndef EIGEN_PARSED_BY_DOXYGEN + typedef typename Traits::IndicesType IndicesType; + typedef typename IndicesType::Scalar Index; + #endif + + inline Map(const Index* indicesPtr) + : m_indices(indicesPtr) + {} + + inline Map(const Index* indicesPtr, Index size) + : m_indices(indicesPtr,size) + {} + + /** Copies the other permutation into *this */ + template + Map& operator=(const PermutationBase& other) + { return Base::operator=(other.derived()); } + + /** Assignment from the Transpositions \a tr */ + template + Map& operator=(const TranspositionsBase& tr) + { return Base::operator=(tr.derived()); } + + #ifndef EIGEN_PARSED_BY_DOXYGEN + /** This is a special case of the templated operator=. Its purpose is to + * prevent a default operator= from hiding the templated operator=. + */ + Map& operator=(const Map& other) + { + m_indices = other.m_indices; + return *this; + } + #endif + + /** const version of indices(). */ + const IndicesType& indices() const { return m_indices; } + /** \returns a reference to the stored array representing the permutation. */ + IndicesType& indices() { return m_indices; } + + protected: + + IndicesType m_indices; +}; + +/** \class PermutationWrapper + * \ingroup Core_Module + * + * \brief Class to view a vector of integers as a permutation matrix + * + * \param _IndicesType the type of the vector of integer (can be any compatible expression) + * + * This class allows to view any vector expression of integers as a permutation matrix. + * + * \sa class PermutationBase, class PermutationMatrix + */ + +struct PermutationStorage {}; + +template class TranspositionsWrapper; +namespace internal { +template +struct traits > +{ + typedef PermutationStorage StorageKind; + typedef typename _IndicesType::Scalar Scalar; + typedef typename _IndicesType::Scalar Index; + typedef _IndicesType IndicesType; + enum { + RowsAtCompileTime = _IndicesType::SizeAtCompileTime, + ColsAtCompileTime = _IndicesType::SizeAtCompileTime, + MaxRowsAtCompileTime = IndicesType::MaxRowsAtCompileTime, + MaxColsAtCompileTime = IndicesType::MaxColsAtCompileTime, + Flags = 0, + CoeffReadCost = _IndicesType::CoeffReadCost + }; +}; +} + +template +class PermutationWrapper : public PermutationBase > +{ + typedef PermutationBase Base; + typedef internal::traits Traits; + public: + + #ifndef EIGEN_PARSED_BY_DOXYGEN + typedef typename Traits::IndicesType IndicesType; + #endif + + inline PermutationWrapper(const IndicesType& a_indices) + : m_indices(a_indices) + {} + + /** const version of indices(). */ + const typename internal::remove_all::type& + indices() const { return m_indices; } + + protected: + + typename IndicesType::Nested m_indices; +}; + +/** \returns the matrix with the permutation applied to the columns. + */ +template +inline const internal::permut_matrix_product_retval +operator*(const MatrixBase& matrix, + const PermutationBase &permutation) +{ + return internal::permut_matrix_product_retval + + (permutation.derived(), matrix.derived()); +} + +/** \returns the matrix with the permutation applied to the rows. + */ +template +inline const internal::permut_matrix_product_retval + +operator*(const PermutationBase &permutation, + const MatrixBase& matrix) +{ + return internal::permut_matrix_product_retval + + (permutation.derived(), matrix.derived()); +} + +namespace internal { + +template +struct traits > +{ + typedef typename MatrixType::PlainObject ReturnType; +}; + +template +struct permut_matrix_product_retval + : public ReturnByValue > +{ + typedef typename remove_all::type MatrixTypeNestedCleaned; + typedef typename MatrixType::Index Index; + + permut_matrix_product_retval(const PermutationType& perm, const MatrixType& matrix) + : m_permutation(perm), m_matrix(matrix) + {} + + inline Index rows() const { return m_matrix.rows(); } + inline Index cols() const { return m_matrix.cols(); } + + template inline void evalTo(Dest& dst) const + { + const Index n = Side==OnTheLeft ? rows() : cols(); + // FIXME we need an is_same for expression that is not sensitive to constness. For instance + // is_same_xpr, Block >::value should be true. + if( is_same::value + && blas_traits::HasUsableDirectAccess + && blas_traits::HasUsableDirectAccess + && extract_data(dst) == extract_data(m_matrix)) + { + // apply the permutation inplace + Matrix mask(m_permutation.size()); + mask.fill(false); + Index r = 0; + while(r < m_permutation.size()) + { + // search for the next seed + while(r=m_permutation.size()) + break; + // we got one, let's follow it until we are back to the seed + Index k0 = r++; + Index kPrev = k0; + mask.coeffRef(k0) = true; + for(Index k=m_permutation.indices().coeff(k0); k!=k0; k=m_permutation.indices().coeff(k)) + { + Block(dst, k) + .swap(Block + (dst,((Side==OnTheLeft) ^ Transposed) ? k0 : kPrev)); + + mask.coeffRef(k) = true; + kPrev = k; + } + } + } + else + { + for(int i = 0; i < n; ++i) + { + Block + (dst, ((Side==OnTheLeft) ^ Transposed) ? m_permutation.indices().coeff(i) : i) + + = + + Block + (m_matrix, ((Side==OnTheRight) ^ Transposed) ? m_permutation.indices().coeff(i) : i); + } + } + } + + protected: + const PermutationType& m_permutation; + typename MatrixType::Nested m_matrix; +}; + +/* Template partial specialization for transposed/inverse permutations */ + +template +struct traits > > + : traits +{}; + +} // end namespace internal + +template +class Transpose > + : public EigenBase > > +{ + typedef Derived PermutationType; + typedef typename PermutationType::IndicesType IndicesType; + typedef typename PermutationType::PlainPermutationType PlainPermutationType; + public: + + #ifndef EIGEN_PARSED_BY_DOXYGEN + typedef internal::traits Traits; + typedef typename Derived::DenseMatrixType DenseMatrixType; + enum { + Flags = Traits::Flags, + CoeffReadCost = Traits::CoeffReadCost, + RowsAtCompileTime = Traits::RowsAtCompileTime, + ColsAtCompileTime = Traits::ColsAtCompileTime, + MaxRowsAtCompileTime = Traits::MaxRowsAtCompileTime, + MaxColsAtCompileTime = Traits::MaxColsAtCompileTime + }; + typedef typename Traits::Scalar Scalar; + #endif + + Transpose(const PermutationType& p) : m_permutation(p) {} + + inline int rows() const { return m_permutation.rows(); } + inline int cols() const { return m_permutation.cols(); } + + #ifndef EIGEN_PARSED_BY_DOXYGEN + template + void evalTo(MatrixBase& other) const + { + other.setZero(); + for (int i=0; i friend + inline const internal::permut_matrix_product_retval + operator*(const MatrixBase& matrix, const Transpose& trPerm) + { + return internal::permut_matrix_product_retval(trPerm.m_permutation, matrix.derived()); + } + + /** \returns the matrix with the inverse permutation applied to the rows. + */ + template + inline const internal::permut_matrix_product_retval + operator*(const MatrixBase& matrix) const + { + return internal::permut_matrix_product_retval(m_permutation, matrix.derived()); + } + + const PermutationType& nestedPermutation() const { return m_permutation; } + + protected: + const PermutationType& m_permutation; +}; + +template +const PermutationWrapper MatrixBase::asPermutation() const +{ + return derived(); +} + +} // end namespace Eigen + +#endif // EIGEN_PERMUTATIONMATRIX_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/PlainObjectBase.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/PlainObjectBase.h new file mode 100644 index 00000000..a4e4af4a --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/PlainObjectBase.h @@ -0,0 +1,822 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008-2009 Gael Guennebaud +// Copyright (C) 2006-2008 Benoit Jacob +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_DENSESTORAGEBASE_H +#define EIGEN_DENSESTORAGEBASE_H + +#if defined(EIGEN_INITIALIZE_MATRICES_BY_ZERO) +# define EIGEN_INITIALIZE_COEFFS +# define EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED for(int i=0;i::quiet_NaN(); +#else +# undef EIGEN_INITIALIZE_COEFFS +# define EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED +#endif + +namespace Eigen { + +namespace internal { + +template struct check_rows_cols_for_overflow { + template + static EIGEN_ALWAYS_INLINE void run(Index, Index) + { + } +}; + +template<> struct check_rows_cols_for_overflow { + template + static EIGEN_ALWAYS_INLINE void run(Index rows, Index cols) + { + // http://hg.mozilla.org/mozilla-central/file/6c8a909977d3/xpcom/ds/CheckedInt.h#l242 + // we assume Index is signed + Index max_index = (size_t(1) << (8 * sizeof(Index) - 1)) - 1; // assume Index is signed + bool error = (rows == 0 || cols == 0) ? false + : (rows > max_index / cols); + if (error) + throw_std_bad_alloc(); + } +}; + +template +struct conservative_resize_like_impl; + +template struct matrix_swap_impl; + +} // end namespace internal + +/** \class PlainObjectBase + * \brief %Dense storage base class for matrices and arrays. + * + * This class can be extended with the help of the plugin mechanism described on the page + * \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_PLAINOBJECTBASE_PLUGIN. + * + * \sa \ref TopicClassHierarchy + */ +#ifdef EIGEN_PARSED_BY_DOXYGEN +namespace internal { + +// this is a warkaround to doxygen not being able to understand the inheritence logic +// when it is hidden by the dense_xpr_base helper struct. +template struct dense_xpr_base_dispatcher_for_doxygen;// : public MatrixBase {}; +/** This class is just a workaround for Doxygen and it does not not actually exist. */ +template +struct dense_xpr_base_dispatcher_for_doxygen > + : public MatrixBase > {}; +/** This class is just a workaround for Doxygen and it does not not actually exist. */ +template +struct dense_xpr_base_dispatcher_for_doxygen > + : public ArrayBase > {}; + +} // namespace internal + +template +class PlainObjectBase : public internal::dense_xpr_base_dispatcher_for_doxygen +#else +template +class PlainObjectBase : public internal::dense_xpr_base::type +#endif +{ + public: + enum { Options = internal::traits::Options }; + typedef typename internal::dense_xpr_base::type Base; + + typedef typename internal::traits::StorageKind StorageKind; + typedef typename internal::traits::Index Index; + typedef typename internal::traits::Scalar Scalar; + typedef typename internal::packet_traits::type PacketScalar; + typedef typename NumTraits::Real RealScalar; + typedef Derived DenseType; + + using Base::RowsAtCompileTime; + using Base::ColsAtCompileTime; + using Base::SizeAtCompileTime; + using Base::MaxRowsAtCompileTime; + using Base::MaxColsAtCompileTime; + using Base::MaxSizeAtCompileTime; + using Base::IsVectorAtCompileTime; + using Base::Flags; + + template friend class Eigen::Map; + friend class Eigen::Map; + typedef Eigen::Map MapType; + friend class Eigen::Map; + typedef const Eigen::Map ConstMapType; + friend class Eigen::Map; + typedef Eigen::Map AlignedMapType; + friend class Eigen::Map; + typedef const Eigen::Map ConstAlignedMapType; + template struct StridedMapType { typedef Eigen::Map type; }; + template struct StridedConstMapType { typedef Eigen::Map type; }; + template struct StridedAlignedMapType { typedef Eigen::Map type; }; + template struct StridedConstAlignedMapType { typedef Eigen::Map type; }; + + protected: + DenseStorage m_storage; + + public: + enum { NeedsToAlign = SizeAtCompileTime != Dynamic && (internal::traits::Flags & AlignedBit) != 0 }; + EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign) + + Base& base() { return *static_cast(this); } + const Base& base() const { return *static_cast(this); } + + EIGEN_STRONG_INLINE Index rows() const { return m_storage.rows(); } + EIGEN_STRONG_INLINE Index cols() const { return m_storage.cols(); } + + EIGEN_STRONG_INLINE const Scalar& coeff(Index rowId, Index colId) const + { + if(Flags & RowMajorBit) + return m_storage.data()[colId + rowId * m_storage.cols()]; + else // column-major + return m_storage.data()[rowId + colId * m_storage.rows()]; + } + + EIGEN_STRONG_INLINE const Scalar& coeff(Index index) const + { + return m_storage.data()[index]; + } + + EIGEN_STRONG_INLINE Scalar& coeffRef(Index rowId, Index colId) + { + if(Flags & RowMajorBit) + return m_storage.data()[colId + rowId * m_storage.cols()]; + else // column-major + return m_storage.data()[rowId + colId * m_storage.rows()]; + } + + EIGEN_STRONG_INLINE Scalar& coeffRef(Index index) + { + return m_storage.data()[index]; + } + + EIGEN_STRONG_INLINE const Scalar& coeffRef(Index rowId, Index colId) const + { + if(Flags & RowMajorBit) + return m_storage.data()[colId + rowId * m_storage.cols()]; + else // column-major + return m_storage.data()[rowId + colId * m_storage.rows()]; + } + + EIGEN_STRONG_INLINE const Scalar& coeffRef(Index index) const + { + return m_storage.data()[index]; + } + + /** \internal */ + template + EIGEN_STRONG_INLINE PacketScalar packet(Index rowId, Index colId) const + { + return internal::ploadt + (m_storage.data() + (Flags & RowMajorBit + ? colId + rowId * m_storage.cols() + : rowId + colId * m_storage.rows())); + } + + /** \internal */ + template + EIGEN_STRONG_INLINE PacketScalar packet(Index index) const + { + return internal::ploadt(m_storage.data() + index); + } + + /** \internal */ + template + EIGEN_STRONG_INLINE void writePacket(Index rowId, Index colId, const PacketScalar& val) + { + internal::pstoret + (m_storage.data() + (Flags & RowMajorBit + ? colId + rowId * m_storage.cols() + : rowId + colId * m_storage.rows()), val); + } + + /** \internal */ + template + EIGEN_STRONG_INLINE void writePacket(Index index, const PacketScalar& val) + { + internal::pstoret(m_storage.data() + index, val); + } + + /** \returns a const pointer to the data array of this matrix */ + EIGEN_STRONG_INLINE const Scalar *data() const + { return m_storage.data(); } + + /** \returns a pointer to the data array of this matrix */ + EIGEN_STRONG_INLINE Scalar *data() + { return m_storage.data(); } + + /** Resizes \c *this to a \a rows x \a cols matrix. + * + * This method is intended for dynamic-size matrices, although it is legal to call it on any + * matrix as long as fixed dimensions are left unchanged. If you only want to change the number + * of rows and/or of columns, you can use resize(NoChange_t, Index), resize(Index, NoChange_t). + * + * If the current number of coefficients of \c *this exactly matches the + * product \a rows * \a cols, then no memory allocation is performed and + * the current values are left unchanged. In all other cases, including + * shrinking, the data is reallocated and all previous values are lost. + * + * Example: \include Matrix_resize_int_int.cpp + * Output: \verbinclude Matrix_resize_int_int.out + * + * \sa resize(Index) for vectors, resize(NoChange_t, Index), resize(Index, NoChange_t) + */ + EIGEN_STRONG_INLINE void resize(Index nbRows, Index nbCols) + { + eigen_assert( EIGEN_IMPLIES(RowsAtCompileTime!=Dynamic,nbRows==RowsAtCompileTime) + && EIGEN_IMPLIES(ColsAtCompileTime!=Dynamic,nbCols==ColsAtCompileTime) + && EIGEN_IMPLIES(RowsAtCompileTime==Dynamic && MaxRowsAtCompileTime!=Dynamic,nbRows<=MaxRowsAtCompileTime) + && EIGEN_IMPLIES(ColsAtCompileTime==Dynamic && MaxColsAtCompileTime!=Dynamic,nbCols<=MaxColsAtCompileTime) + && nbRows>=0 && nbCols>=0 && "Invalid sizes when resizing a matrix or array."); + internal::check_rows_cols_for_overflow::run(nbRows, nbCols); + #ifdef EIGEN_INITIALIZE_COEFFS + Index size = nbRows*nbCols; + bool size_changed = size != this->size(); + m_storage.resize(size, nbRows, nbCols); + if(size_changed) EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED + #else + internal::check_rows_cols_for_overflow::run(nbRows, nbCols); + m_storage.resize(nbRows*nbCols, nbRows, nbCols); + #endif + } + + /** Resizes \c *this to a vector of length \a size + * + * \only_for_vectors. This method does not work for + * partially dynamic matrices when the static dimension is anything other + * than 1. For example it will not work with Matrix. + * + * Example: \include Matrix_resize_int.cpp + * Output: \verbinclude Matrix_resize_int.out + * + * \sa resize(Index,Index), resize(NoChange_t, Index), resize(Index, NoChange_t) + */ + inline void resize(Index size) + { + EIGEN_STATIC_ASSERT_VECTOR_ONLY(PlainObjectBase) + eigen_assert(((SizeAtCompileTime == Dynamic && (MaxSizeAtCompileTime==Dynamic || size<=MaxSizeAtCompileTime)) || SizeAtCompileTime == size) && size>=0); + #ifdef EIGEN_INITIALIZE_COEFFS + bool size_changed = size != this->size(); + #endif + if(RowsAtCompileTime == 1) + m_storage.resize(size, 1, size); + else + m_storage.resize(size, size, 1); + #ifdef EIGEN_INITIALIZE_COEFFS + if(size_changed) EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED + #endif + } + + /** Resizes the matrix, changing only the number of columns. For the parameter of type NoChange_t, just pass the special value \c NoChange + * as in the example below. + * + * Example: \include Matrix_resize_NoChange_int.cpp + * Output: \verbinclude Matrix_resize_NoChange_int.out + * + * \sa resize(Index,Index) + */ + inline void resize(NoChange_t, Index nbCols) + { + resize(rows(), nbCols); + } + + /** Resizes the matrix, changing only the number of rows. For the parameter of type NoChange_t, just pass the special value \c NoChange + * as in the example below. + * + * Example: \include Matrix_resize_int_NoChange.cpp + * Output: \verbinclude Matrix_resize_int_NoChange.out + * + * \sa resize(Index,Index) + */ + inline void resize(Index nbRows, NoChange_t) + { + resize(nbRows, cols()); + } + + /** Resizes \c *this to have the same dimensions as \a other. + * Takes care of doing all the checking that's needed. + * + * Note that copying a row-vector into a vector (and conversely) is allowed. + * The resizing, if any, is then done in the appropriate way so that row-vectors + * remain row-vectors and vectors remain vectors. + */ + template + EIGEN_STRONG_INLINE void resizeLike(const EigenBase& _other) + { + const OtherDerived& other = _other.derived(); + internal::check_rows_cols_for_overflow::run(other.rows(), other.cols()); + const Index othersize = other.rows()*other.cols(); + if(RowsAtCompileTime == 1) + { + eigen_assert(other.rows() == 1 || other.cols() == 1); + resize(1, othersize); + } + else if(ColsAtCompileTime == 1) + { + eigen_assert(other.rows() == 1 || other.cols() == 1); + resize(othersize, 1); + } + else resize(other.rows(), other.cols()); + } + + /** Resizes the matrix to \a rows x \a cols while leaving old values untouched. + * + * The method is intended for matrices of dynamic size. If you only want to change the number + * of rows and/or of columns, you can use conservativeResize(NoChange_t, Index) or + * conservativeResize(Index, NoChange_t). + * + * Matrices are resized relative to the top-left element. In case values need to be + * appended to the matrix they will be uninitialized. + */ + EIGEN_STRONG_INLINE void conservativeResize(Index nbRows, Index nbCols) + { + internal::conservative_resize_like_impl::run(*this, nbRows, nbCols); + } + + /** Resizes the matrix to \a rows x \a cols while leaving old values untouched. + * + * As opposed to conservativeResize(Index rows, Index cols), this version leaves + * the number of columns unchanged. + * + * In case the matrix is growing, new rows will be uninitialized. + */ + EIGEN_STRONG_INLINE void conservativeResize(Index nbRows, NoChange_t) + { + // Note: see the comment in conservativeResize(Index,Index) + conservativeResize(nbRows, cols()); + } + + /** Resizes the matrix to \a rows x \a cols while leaving old values untouched. + * + * As opposed to conservativeResize(Index rows, Index cols), this version leaves + * the number of rows unchanged. + * + * In case the matrix is growing, new columns will be uninitialized. + */ + EIGEN_STRONG_INLINE void conservativeResize(NoChange_t, Index nbCols) + { + // Note: see the comment in conservativeResize(Index,Index) + conservativeResize(rows(), nbCols); + } + + /** Resizes the vector to \a size while retaining old values. + * + * \only_for_vectors. This method does not work for + * partially dynamic matrices when the static dimension is anything other + * than 1. For example it will not work with Matrix. + * + * When values are appended, they will be uninitialized. + */ + EIGEN_STRONG_INLINE void conservativeResize(Index size) + { + internal::conservative_resize_like_impl::run(*this, size); + } + + /** Resizes the matrix to \a rows x \a cols of \c other, while leaving old values untouched. + * + * The method is intended for matrices of dynamic size. If you only want to change the number + * of rows and/or of columns, you can use conservativeResize(NoChange_t, Index) or + * conservativeResize(Index, NoChange_t). + * + * Matrices are resized relative to the top-left element. In case values need to be + * appended to the matrix they will copied from \c other. + */ + template + EIGEN_STRONG_INLINE void conservativeResizeLike(const DenseBase& other) + { + internal::conservative_resize_like_impl::run(*this, other); + } + + /** This is a special case of the templated operator=. Its purpose is to + * prevent a default operator= from hiding the templated operator=. + */ + EIGEN_STRONG_INLINE Derived& operator=(const PlainObjectBase& other) + { + return _set(other); + } + + /** \sa MatrixBase::lazyAssign() */ + template + EIGEN_STRONG_INLINE Derived& lazyAssign(const DenseBase& other) + { + _resize_to_match(other); + return Base::lazyAssign(other.derived()); + } + + template + EIGEN_STRONG_INLINE Derived& operator=(const ReturnByValue& func) + { + resize(func.rows(), func.cols()); + return Base::operator=(func); + } + + EIGEN_STRONG_INLINE PlainObjectBase() : m_storage() + { +// _check_template_params(); +// EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED + } + +#ifndef EIGEN_PARSED_BY_DOXYGEN + // FIXME is it still needed ? + /** \internal */ + PlainObjectBase(internal::constructor_without_unaligned_array_assert) + : m_storage(internal::constructor_without_unaligned_array_assert()) + { +// _check_template_params(); EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED + } +#endif + +#ifdef EIGEN_HAVE_RVALUE_REFERENCES + PlainObjectBase(PlainObjectBase&& other) + : m_storage( std::move(other.m_storage) ) + { + } + + PlainObjectBase& operator=(PlainObjectBase&& other) + { + using std::swap; + swap(m_storage, other.m_storage); + return *this; + } +#endif + + /** Copy constructor */ + EIGEN_STRONG_INLINE PlainObjectBase(const PlainObjectBase& other) + : m_storage() + { + _check_template_params(); + lazyAssign(other); + } + + template + EIGEN_STRONG_INLINE PlainObjectBase(const DenseBase &other) + : m_storage() + { + _check_template_params(); + lazyAssign(other); + } + + EIGEN_STRONG_INLINE PlainObjectBase(Index a_size, Index nbRows, Index nbCols) + : m_storage(a_size, nbRows, nbCols) + { +// _check_template_params(); +// EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED + } + + /** \copydoc MatrixBase::operator=(const EigenBase&) + */ + template + EIGEN_STRONG_INLINE Derived& operator=(const EigenBase &other) + { + _resize_to_match(other); + Base::operator=(other.derived()); + return this->derived(); + } + + /** \sa MatrixBase::operator=(const EigenBase&) */ + template + EIGEN_STRONG_INLINE PlainObjectBase(const EigenBase &other) + : m_storage(other.derived().rows() * other.derived().cols(), other.derived().rows(), other.derived().cols()) + { + _check_template_params(); + internal::check_rows_cols_for_overflow::run(other.derived().rows(), other.derived().cols()); + Base::operator=(other.derived()); + } + + /** \name Map + * These are convenience functions returning Map objects. The Map() static functions return unaligned Map objects, + * while the AlignedMap() functions return aligned Map objects and thus should be called only with 16-byte-aligned + * \a data pointers. + * + * \see class Map + */ + //@{ + static inline ConstMapType Map(const Scalar* data) + { return ConstMapType(data); } + static inline MapType Map(Scalar* data) + { return MapType(data); } + static inline ConstMapType Map(const Scalar* data, Index size) + { return ConstMapType(data, size); } + static inline MapType Map(Scalar* data, Index size) + { return MapType(data, size); } + static inline ConstMapType Map(const Scalar* data, Index rows, Index cols) + { return ConstMapType(data, rows, cols); } + static inline MapType Map(Scalar* data, Index rows, Index cols) + { return MapType(data, rows, cols); } + + static inline ConstAlignedMapType MapAligned(const Scalar* data) + { return ConstAlignedMapType(data); } + static inline AlignedMapType MapAligned(Scalar* data) + { return AlignedMapType(data); } + static inline ConstAlignedMapType MapAligned(const Scalar* data, Index size) + { return ConstAlignedMapType(data, size); } + static inline AlignedMapType MapAligned(Scalar* data, Index size) + { return AlignedMapType(data, size); } + static inline ConstAlignedMapType MapAligned(const Scalar* data, Index rows, Index cols) + { return ConstAlignedMapType(data, rows, cols); } + static inline AlignedMapType MapAligned(Scalar* data, Index rows, Index cols) + { return AlignedMapType(data, rows, cols); } + + template + static inline typename StridedConstMapType >::type Map(const Scalar* data, const Stride& stride) + { return typename StridedConstMapType >::type(data, stride); } + template + static inline typename StridedMapType >::type Map(Scalar* data, const Stride& stride) + { return typename StridedMapType >::type(data, stride); } + template + static inline typename StridedConstMapType >::type Map(const Scalar* data, Index size, const Stride& stride) + { return typename StridedConstMapType >::type(data, size, stride); } + template + static inline typename StridedMapType >::type Map(Scalar* data, Index size, const Stride& stride) + { return typename StridedMapType >::type(data, size, stride); } + template + static inline typename StridedConstMapType >::type Map(const Scalar* data, Index rows, Index cols, const Stride& stride) + { return typename StridedConstMapType >::type(data, rows, cols, stride); } + template + static inline typename StridedMapType >::type Map(Scalar* data, Index rows, Index cols, const Stride& stride) + { return typename StridedMapType >::type(data, rows, cols, stride); } + + template + static inline typename StridedConstAlignedMapType >::type MapAligned(const Scalar* data, const Stride& stride) + { return typename StridedConstAlignedMapType >::type(data, stride); } + template + static inline typename StridedAlignedMapType >::type MapAligned(Scalar* data, const Stride& stride) + { return typename StridedAlignedMapType >::type(data, stride); } + template + static inline typename StridedConstAlignedMapType >::type MapAligned(const Scalar* data, Index size, const Stride& stride) + { return typename StridedConstAlignedMapType >::type(data, size, stride); } + template + static inline typename StridedAlignedMapType >::type MapAligned(Scalar* data, Index size, const Stride& stride) + { return typename StridedAlignedMapType >::type(data, size, stride); } + template + static inline typename StridedConstAlignedMapType >::type MapAligned(const Scalar* data, Index rows, Index cols, const Stride& stride) + { return typename StridedConstAlignedMapType >::type(data, rows, cols, stride); } + template + static inline typename StridedAlignedMapType >::type MapAligned(Scalar* data, Index rows, Index cols, const Stride& stride) + { return typename StridedAlignedMapType >::type(data, rows, cols, stride); } + //@} + + using Base::setConstant; + Derived& setConstant(Index size, const Scalar& value); + Derived& setConstant(Index rows, Index cols, const Scalar& value); + + using Base::setZero; + Derived& setZero(Index size); + Derived& setZero(Index rows, Index cols); + + using Base::setOnes; + Derived& setOnes(Index size); + Derived& setOnes(Index rows, Index cols); + + using Base::setRandom; + Derived& setRandom(Index size); + Derived& setRandom(Index rows, Index cols); + + #ifdef EIGEN_PLAINOBJECTBASE_PLUGIN + #include EIGEN_PLAINOBJECTBASE_PLUGIN + #endif + + protected: + /** \internal Resizes *this in preparation for assigning \a other to it. + * Takes care of doing all the checking that's needed. + * + * Note that copying a row-vector into a vector (and conversely) is allowed. + * The resizing, if any, is then done in the appropriate way so that row-vectors + * remain row-vectors and vectors remain vectors. + */ + template + EIGEN_STRONG_INLINE void _resize_to_match(const EigenBase& other) + { + #ifdef EIGEN_NO_AUTOMATIC_RESIZING + eigen_assert((this->size()==0 || (IsVectorAtCompileTime ? (this->size() == other.size()) + : (rows() == other.rows() && cols() == other.cols()))) + && "Size mismatch. Automatic resizing is disabled because EIGEN_NO_AUTOMATIC_RESIZING is defined"); + EIGEN_ONLY_USED_FOR_DEBUG(other); + if(this->size()==0) + resizeLike(other); + #else + resizeLike(other); + #endif + } + + /** + * \brief Copies the value of the expression \a other into \c *this with automatic resizing. + * + * *this might be resized to match the dimensions of \a other. If *this was a null matrix (not already initialized), + * it will be initialized. + * + * Note that copying a row-vector into a vector (and conversely) is allowed. + * The resizing, if any, is then done in the appropriate way so that row-vectors + * remain row-vectors and vectors remain vectors. + * + * \sa operator=(const MatrixBase&), _set_noalias() + * + * \internal + */ + template + EIGEN_STRONG_INLINE Derived& _set(const DenseBase& other) + { + _set_selector(other.derived(), typename internal::conditional(int(OtherDerived::Flags) & EvalBeforeAssigningBit), internal::true_type, internal::false_type>::type()); + return this->derived(); + } + + template + EIGEN_STRONG_INLINE void _set_selector(const OtherDerived& other, const internal::true_type&) { _set_noalias(other.eval()); } + + template + EIGEN_STRONG_INLINE void _set_selector(const OtherDerived& other, const internal::false_type&) { _set_noalias(other); } + + /** \internal Like _set() but additionally makes the assumption that no aliasing effect can happen (which + * is the case when creating a new matrix) so one can enforce lazy evaluation. + * + * \sa operator=(const MatrixBase&), _set() + */ + template + EIGEN_STRONG_INLINE Derived& _set_noalias(const DenseBase& other) + { + // I don't think we need this resize call since the lazyAssign will anyways resize + // and lazyAssign will be called by the assign selector. + //_resize_to_match(other); + // the 'false' below means to enforce lazy evaluation. We don't use lazyAssign() because + // it wouldn't allow to copy a row-vector into a column-vector. + return internal::assign_selector::run(this->derived(), other.derived()); + } + + template + EIGEN_STRONG_INLINE void _init2(Index nbRows, Index nbCols, typename internal::enable_if::type* = 0) + { + EIGEN_STATIC_ASSERT(bool(NumTraits::IsInteger) && + bool(NumTraits::IsInteger), + FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED) + resize(nbRows,nbCols); + } + template + EIGEN_STRONG_INLINE void _init2(const Scalar& val0, const Scalar& val1, typename internal::enable_if::type* = 0) + { + EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 2) + m_storage.data()[0] = val0; + m_storage.data()[1] = val1; + } + + template + friend struct internal::matrix_swap_impl; + + /** \internal generic implementation of swap for dense storage since for dynamic-sized matrices of same type it is enough to swap the + * data pointers. + */ + template + void _swap(DenseBase const & other) + { + enum { SwapPointers = internal::is_same::value && Base::SizeAtCompileTime==Dynamic }; + internal::matrix_swap_impl::run(this->derived(), other.const_cast_derived()); + } + + public: +#ifndef EIGEN_PARSED_BY_DOXYGEN + static EIGEN_STRONG_INLINE void _check_template_params() + { + EIGEN_STATIC_ASSERT((EIGEN_IMPLIES(MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1, (Options&RowMajor)==RowMajor) + && EIGEN_IMPLIES(MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1, (Options&RowMajor)==0) + && ((RowsAtCompileTime == Dynamic) || (RowsAtCompileTime >= 0)) + && ((ColsAtCompileTime == Dynamic) || (ColsAtCompileTime >= 0)) + && ((MaxRowsAtCompileTime == Dynamic) || (MaxRowsAtCompileTime >= 0)) + && ((MaxColsAtCompileTime == Dynamic) || (MaxColsAtCompileTime >= 0)) + && (MaxRowsAtCompileTime == RowsAtCompileTime || RowsAtCompileTime==Dynamic) + && (MaxColsAtCompileTime == ColsAtCompileTime || ColsAtCompileTime==Dynamic) + && (Options & (DontAlign|RowMajor)) == Options), + INVALID_MATRIX_TEMPLATE_PARAMETERS) + } +#endif + +private: + enum { ThisConstantIsPrivateInPlainObjectBase }; +}; + +namespace internal { + +template +struct conservative_resize_like_impl +{ + typedef typename Derived::Index Index; + static void run(DenseBase& _this, Index rows, Index cols) + { + if (_this.rows() == rows && _this.cols() == cols) return; + EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived) + + if ( ( Derived::IsRowMajor && _this.cols() == cols) || // row-major and we change only the number of rows + (!Derived::IsRowMajor && _this.rows() == rows) ) // column-major and we change only the number of columns + { + internal::check_rows_cols_for_overflow::run(rows, cols); + _this.derived().m_storage.conservativeResize(rows*cols,rows,cols); + } + else + { + // The storage order does not allow us to use reallocation. + typename Derived::PlainObject tmp(rows,cols); + const Index common_rows = (std::min)(rows, _this.rows()); + const Index common_cols = (std::min)(cols, _this.cols()); + tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols); + _this.derived().swap(tmp); + } + } + + static void run(DenseBase& _this, const DenseBase& other) + { + if (_this.rows() == other.rows() && _this.cols() == other.cols()) return; + + // Note: Here is space for improvement. Basically, for conservativeResize(Index,Index), + // neither RowsAtCompileTime or ColsAtCompileTime must be Dynamic. If only one of the + // dimensions is dynamic, one could use either conservativeResize(Index rows, NoChange_t) or + // conservativeResize(NoChange_t, Index cols). For these methods new static asserts like + // EIGEN_STATIC_ASSERT_DYNAMIC_ROWS and EIGEN_STATIC_ASSERT_DYNAMIC_COLS would be good. + EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived) + EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(OtherDerived) + + if ( ( Derived::IsRowMajor && _this.cols() == other.cols()) || // row-major and we change only the number of rows + (!Derived::IsRowMajor && _this.rows() == other.rows()) ) // column-major and we change only the number of columns + { + const Index new_rows = other.rows() - _this.rows(); + const Index new_cols = other.cols() - _this.cols(); + _this.derived().m_storage.conservativeResize(other.size(),other.rows(),other.cols()); + if (new_rows>0) + _this.bottomRightCorner(new_rows, other.cols()) = other.bottomRows(new_rows); + else if (new_cols>0) + _this.bottomRightCorner(other.rows(), new_cols) = other.rightCols(new_cols); + } + else + { + // The storage order does not allow us to use reallocation. + typename Derived::PlainObject tmp(other); + const Index common_rows = (std::min)(tmp.rows(), _this.rows()); + const Index common_cols = (std::min)(tmp.cols(), _this.cols()); + tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols); + _this.derived().swap(tmp); + } + } +}; + +// Here, the specialization for vectors inherits from the general matrix case +// to allow calling .conservativeResize(rows,cols) on vectors. +template +struct conservative_resize_like_impl + : conservative_resize_like_impl +{ + using conservative_resize_like_impl::run; + + typedef typename Derived::Index Index; + static void run(DenseBase& _this, Index size) + { + const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : size; + const Index new_cols = Derived::RowsAtCompileTime==1 ? size : 1; + _this.derived().m_storage.conservativeResize(size,new_rows,new_cols); + } + + static void run(DenseBase& _this, const DenseBase& other) + { + if (_this.rows() == other.rows() && _this.cols() == other.cols()) return; + + const Index num_new_elements = other.size() - _this.size(); + + const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : other.rows(); + const Index new_cols = Derived::RowsAtCompileTime==1 ? other.cols() : 1; + _this.derived().m_storage.conservativeResize(other.size(),new_rows,new_cols); + + if (num_new_elements > 0) + _this.tail(num_new_elements) = other.tail(num_new_elements); + } +}; + +template +struct matrix_swap_impl +{ + static inline void run(MatrixTypeA& a, MatrixTypeB& b) + { + a.base().swap(b); + } +}; + +template +struct matrix_swap_impl +{ + static inline void run(MatrixTypeA& a, MatrixTypeB& b) + { + static_cast(a).m_storage.swap(static_cast(b).m_storage); + } +}; + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_DENSESTORAGEBASE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/ProductBase.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/ProductBase.h new file mode 100644 index 00000000..cf74470a --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/ProductBase.h @@ -0,0 +1,290 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2009-2010 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_PRODUCTBASE_H +#define EIGEN_PRODUCTBASE_H + +namespace Eigen { + +/** \class ProductBase + * \ingroup Core_Module + * + */ + +namespace internal { +template +struct traits > +{ + typedef MatrixXpr XprKind; + typedef typename remove_all<_Lhs>::type Lhs; + typedef typename remove_all<_Rhs>::type Rhs; + typedef typename scalar_product_traits::ReturnType Scalar; + typedef typename promote_storage_type::StorageKind, + typename traits::StorageKind>::ret StorageKind; + typedef typename promote_index_type::Index, + typename traits::Index>::type Index; + enum { + RowsAtCompileTime = traits::RowsAtCompileTime, + ColsAtCompileTime = traits::ColsAtCompileTime, + MaxRowsAtCompileTime = traits::MaxRowsAtCompileTime, + MaxColsAtCompileTime = traits::MaxColsAtCompileTime, + Flags = (MaxRowsAtCompileTime==1 ? RowMajorBit : 0) + | EvalBeforeNestingBit | EvalBeforeAssigningBit | NestByRefBit, + // Note that EvalBeforeNestingBit and NestByRefBit + // are not used in practice because nested is overloaded for products + CoeffReadCost = 0 // FIXME why is it needed ? + }; +}; +} + +#define EIGEN_PRODUCT_PUBLIC_INTERFACE(Derived) \ + typedef ProductBase Base; \ + EIGEN_DENSE_PUBLIC_INTERFACE(Derived) \ + typedef typename Base::LhsNested LhsNested; \ + typedef typename Base::_LhsNested _LhsNested; \ + typedef typename Base::LhsBlasTraits LhsBlasTraits; \ + typedef typename Base::ActualLhsType ActualLhsType; \ + typedef typename Base::_ActualLhsType _ActualLhsType; \ + typedef typename Base::RhsNested RhsNested; \ + typedef typename Base::_RhsNested _RhsNested; \ + typedef typename Base::RhsBlasTraits RhsBlasTraits; \ + typedef typename Base::ActualRhsType ActualRhsType; \ + typedef typename Base::_ActualRhsType _ActualRhsType; \ + using Base::m_lhs; \ + using Base::m_rhs; + +template +class ProductBase : public MatrixBase +{ + public: + typedef MatrixBase Base; + EIGEN_DENSE_PUBLIC_INTERFACE(ProductBase) + + typedef typename Lhs::Nested LhsNested; + typedef typename internal::remove_all::type _LhsNested; + typedef internal::blas_traits<_LhsNested> LhsBlasTraits; + typedef typename LhsBlasTraits::DirectLinearAccessType ActualLhsType; + typedef typename internal::remove_all::type _ActualLhsType; + typedef typename internal::traits::Scalar LhsScalar; + + typedef typename Rhs::Nested RhsNested; + typedef typename internal::remove_all::type _RhsNested; + typedef internal::blas_traits<_RhsNested> RhsBlasTraits; + typedef typename RhsBlasTraits::DirectLinearAccessType ActualRhsType; + typedef typename internal::remove_all::type _ActualRhsType; + typedef typename internal::traits::Scalar RhsScalar; + + // Diagonal of a product: no need to evaluate the arguments because they are going to be evaluated only once + typedef CoeffBasedProduct FullyLazyCoeffBaseProductType; + + public: + +#ifndef EIGEN_NO_MALLOC + typedef typename Base::PlainObject BasePlainObject; + typedef Matrix DynPlainObject; + typedef typename internal::conditional<(BasePlainObject::SizeAtCompileTime==Dynamic) || (BasePlainObject::SizeAtCompileTime*int(sizeof(Scalar)) < int(EIGEN_STACK_ALLOCATION_LIMIT)), + BasePlainObject, DynPlainObject>::type PlainObject; +#else + typedef typename Base::PlainObject PlainObject; +#endif + + ProductBase(const Lhs& a_lhs, const Rhs& a_rhs) + : m_lhs(a_lhs), m_rhs(a_rhs) + { + eigen_assert(a_lhs.cols() == a_rhs.rows() + && "invalid matrix product" + && "if you wanted a coeff-wise or a dot product use the respective explicit functions"); + } + + inline Index rows() const { return m_lhs.rows(); } + inline Index cols() const { return m_rhs.cols(); } + + template + inline void evalTo(Dest& dst) const { dst.setZero(); scaleAndAddTo(dst,Scalar(1)); } + + template + inline void addTo(Dest& dst) const { scaleAndAddTo(dst,Scalar(1)); } + + template + inline void subTo(Dest& dst) const { scaleAndAddTo(dst,Scalar(-1)); } + + template + inline void scaleAndAddTo(Dest& dst, const Scalar& alpha) const { derived().scaleAndAddTo(dst,alpha); } + + const _LhsNested& lhs() const { return m_lhs; } + const _RhsNested& rhs() const { return m_rhs; } + + // Implicit conversion to the nested type (trigger the evaluation of the product) + operator const PlainObject& () const + { + m_result.resize(m_lhs.rows(), m_rhs.cols()); + derived().evalTo(m_result); + return m_result; + } + + const Diagonal diagonal() const + { return FullyLazyCoeffBaseProductType(m_lhs, m_rhs); } + + template + const Diagonal diagonal() const + { return FullyLazyCoeffBaseProductType(m_lhs, m_rhs); } + + const Diagonal diagonal(Index index) const + { return FullyLazyCoeffBaseProductType(m_lhs, m_rhs).diagonal(index); } + + // restrict coeff accessors to 1x1 expressions. No need to care about mutators here since this isnt a Lvalue expression + typename Base::CoeffReturnType coeff(Index row, Index col) const + { +#ifdef EIGEN2_SUPPORT + return lhs().row(row).cwiseProduct(rhs().col(col).transpose()).sum(); +#else + EIGEN_STATIC_ASSERT_SIZE_1x1(Derived) + eigen_assert(this->rows() == 1 && this->cols() == 1); + Matrix result = *this; + return result.coeff(row,col); +#endif + } + + typename Base::CoeffReturnType coeff(Index i) const + { + EIGEN_STATIC_ASSERT_SIZE_1x1(Derived) + eigen_assert(this->rows() == 1 && this->cols() == 1); + Matrix result = *this; + return result.coeff(i); + } + + const Scalar& coeffRef(Index row, Index col) const + { + EIGEN_STATIC_ASSERT_SIZE_1x1(Derived) + eigen_assert(this->rows() == 1 && this->cols() == 1); + return derived().coeffRef(row,col); + } + + const Scalar& coeffRef(Index i) const + { + EIGEN_STATIC_ASSERT_SIZE_1x1(Derived) + eigen_assert(this->rows() == 1 && this->cols() == 1); + return derived().coeffRef(i); + } + + protected: + + LhsNested m_lhs; + RhsNested m_rhs; + + mutable PlainObject m_result; +}; + +// here we need to overload the nested rule for products +// such that the nested type is a const reference to a plain matrix +namespace internal { +template +struct nested, N, PlainObject> +{ + typedef typename GeneralProduct::PlainObject const& type; +}; +template +struct nested, N, PlainObject> +{ + typedef typename GeneralProduct::PlainObject const& type; +}; +} + +template +class ScaledProduct; + +// Note that these two operator* functions are not defined as member +// functions of ProductBase, because, otherwise we would have to +// define all overloads defined in MatrixBase. Furthermore, Using +// "using Base::operator*" would not work with MSVC. +// +// Also note that here we accept any compatible scalar types +template +const ScaledProduct +operator*(const ProductBase& prod, const typename Derived::Scalar& x) +{ return ScaledProduct(prod.derived(), x); } + +template +typename internal::enable_if::value, + const ScaledProduct >::type +operator*(const ProductBase& prod, const typename Derived::RealScalar& x) +{ return ScaledProduct(prod.derived(), x); } + + +template +const ScaledProduct +operator*(const typename Derived::Scalar& x,const ProductBase& prod) +{ return ScaledProduct(prod.derived(), x); } + +template +typename internal::enable_if::value, + const ScaledProduct >::type +operator*(const typename Derived::RealScalar& x,const ProductBase& prod) +{ return ScaledProduct(prod.derived(), x); } + +namespace internal { +template +struct traits > + : traits, + typename NestedProduct::_LhsNested, + typename NestedProduct::_RhsNested> > +{ + typedef typename traits::StorageKind StorageKind; +}; +} + +template +class ScaledProduct + : public ProductBase, + typename NestedProduct::_LhsNested, + typename NestedProduct::_RhsNested> +{ + public: + typedef ProductBase, + typename NestedProduct::_LhsNested, + typename NestedProduct::_RhsNested> Base; + typedef typename Base::Scalar Scalar; + typedef typename Base::PlainObject PlainObject; +// EIGEN_PRODUCT_PUBLIC_INTERFACE(ScaledProduct) + + ScaledProduct(const NestedProduct& prod, const Scalar& x) + : Base(prod.lhs(),prod.rhs()), m_prod(prod), m_alpha(x) {} + + template + inline void evalTo(Dest& dst) const { dst.setZero(); scaleAndAddTo(dst, Scalar(1)); } + + template + inline void addTo(Dest& dst) const { scaleAndAddTo(dst, Scalar(1)); } + + template + inline void subTo(Dest& dst) const { scaleAndAddTo(dst, Scalar(-1)); } + + template + inline void scaleAndAddTo(Dest& dst, const Scalar& a_alpha) const { m_prod.derived().scaleAndAddTo(dst,a_alpha * m_alpha); } + + const Scalar& alpha() const { return m_alpha; } + + protected: + const NestedProduct& m_prod; + Scalar m_alpha; +}; + +/** \internal + * Overloaded to perform an efficient C = (A*B).lazy() */ +template +template +Derived& MatrixBase::lazyAssign(const ProductBase& other) +{ + other.derived().evalTo(derived()); + return derived(); +} + +} // end namespace Eigen + +#endif // EIGEN_PRODUCTBASE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/Random.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/Random.h new file mode 100644 index 00000000..480fea40 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/Random.h @@ -0,0 +1,152 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_RANDOM_H +#define EIGEN_RANDOM_H + +namespace Eigen { + +namespace internal { + +template struct scalar_random_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_random_op) + template + inline const Scalar operator() (Index, Index = 0) const { return random(); } +}; + +template +struct functor_traits > +{ enum { Cost = 5 * NumTraits::MulCost, PacketAccess = false, IsRepeatable = false }; }; + +} // end namespace internal + +/** \returns a random matrix expression + * + * The parameters \a rows and \a cols are the number of rows and of columns of + * the returned matrix. Must be compatible with this MatrixBase type. + * + * This variant is meant to be used for dynamic-size matrix types. For fixed-size types, + * it is redundant to pass \a rows and \a cols as arguments, so Random() should be used + * instead. + * + * Example: \include MatrixBase_random_int_int.cpp + * Output: \verbinclude MatrixBase_random_int_int.out + * + * This expression has the "evaluate before nesting" flag so that it will be evaluated into + * a temporary matrix whenever it is nested in a larger expression. This prevents unexpected + * behavior with expressions involving random matrices. + * + * \sa MatrixBase::setRandom(), MatrixBase::Random(Index), MatrixBase::Random() + */ +template +inline const CwiseNullaryOp::Scalar>, Derived> +DenseBase::Random(Index rows, Index cols) +{ + return NullaryExpr(rows, cols, internal::scalar_random_op()); +} + +/** \returns a random vector expression + * + * The parameter \a size is the size of the returned vector. + * Must be compatible with this MatrixBase type. + * + * \only_for_vectors + * + * This variant is meant to be used for dynamic-size vector types. For fixed-size types, + * it is redundant to pass \a size as argument, so Random() should be used + * instead. + * + * Example: \include MatrixBase_random_int.cpp + * Output: \verbinclude MatrixBase_random_int.out + * + * This expression has the "evaluate before nesting" flag so that it will be evaluated into + * a temporary vector whenever it is nested in a larger expression. This prevents unexpected + * behavior with expressions involving random matrices. + * + * \sa MatrixBase::setRandom(), MatrixBase::Random(Index,Index), MatrixBase::Random() + */ +template +inline const CwiseNullaryOp::Scalar>, Derived> +DenseBase::Random(Index size) +{ + return NullaryExpr(size, internal::scalar_random_op()); +} + +/** \returns a fixed-size random matrix or vector expression + * + * This variant is only for fixed-size MatrixBase types. For dynamic-size types, you + * need to use the variants taking size arguments. + * + * Example: \include MatrixBase_random.cpp + * Output: \verbinclude MatrixBase_random.out + * + * This expression has the "evaluate before nesting" flag so that it will be evaluated into + * a temporary matrix whenever it is nested in a larger expression. This prevents unexpected + * behavior with expressions involving random matrices. + * + * \sa MatrixBase::setRandom(), MatrixBase::Random(Index,Index), MatrixBase::Random(Index) + */ +template +inline const CwiseNullaryOp::Scalar>, Derived> +DenseBase::Random() +{ + return NullaryExpr(RowsAtCompileTime, ColsAtCompileTime, internal::scalar_random_op()); +} + +/** Sets all coefficients in this expression to random values. + * + * Example: \include MatrixBase_setRandom.cpp + * Output: \verbinclude MatrixBase_setRandom.out + * + * \sa class CwiseNullaryOp, setRandom(Index), setRandom(Index,Index) + */ +template +inline Derived& DenseBase::setRandom() +{ + return *this = Random(rows(), cols()); +} + +/** Resizes to the given \a newSize, and sets all coefficients in this expression to random values. + * + * \only_for_vectors + * + * Example: \include Matrix_setRandom_int.cpp + * Output: \verbinclude Matrix_setRandom_int.out + * + * \sa MatrixBase::setRandom(), setRandom(Index,Index), class CwiseNullaryOp, MatrixBase::Random() + */ +template +EIGEN_STRONG_INLINE Derived& +PlainObjectBase::setRandom(Index newSize) +{ + resize(newSize); + return setRandom(); +} + +/** Resizes to the given size, and sets all coefficients in this expression to random values. + * + * \param nbRows the new number of rows + * \param nbCols the new number of columns + * + * Example: \include Matrix_setRandom_int_int.cpp + * Output: \verbinclude Matrix_setRandom_int_int.out + * + * \sa MatrixBase::setRandom(), setRandom(Index), class CwiseNullaryOp, MatrixBase::Random() + */ +template +EIGEN_STRONG_INLINE Derived& +PlainObjectBase::setRandom(Index nbRows, Index nbCols) +{ + resize(nbRows, nbCols); + return setRandom(); +} + +} // end namespace Eigen + +#endif // EIGEN_RANDOM_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/Redux.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/Redux.h new file mode 100644 index 00000000..9b8662a6 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/Redux.h @@ -0,0 +1,409 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008 Gael Guennebaud +// Copyright (C) 2006-2008 Benoit Jacob +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_REDUX_H +#define EIGEN_REDUX_H + +namespace Eigen { + +namespace internal { + +// TODO +// * implement other kind of vectorization +// * factorize code + +/*************************************************************************** +* Part 1 : the logic deciding a strategy for vectorization and unrolling +***************************************************************************/ + +template +struct redux_traits +{ +public: + enum { + PacketSize = packet_traits::size, + InnerMaxSize = int(Derived::IsRowMajor) + ? Derived::MaxColsAtCompileTime + : Derived::MaxRowsAtCompileTime + }; + + enum { + MightVectorize = (int(Derived::Flags)&ActualPacketAccessBit) + && (functor_traits::PacketAccess), + MayLinearVectorize = MightVectorize && (int(Derived::Flags)&LinearAccessBit), + MaySliceVectorize = MightVectorize && int(InnerMaxSize)>=3*PacketSize + }; + +public: + enum { + Traversal = int(MayLinearVectorize) ? int(LinearVectorizedTraversal) + : int(MaySliceVectorize) ? int(SliceVectorizedTraversal) + : int(DefaultTraversal) + }; + +public: + enum { + Cost = ( Derived::SizeAtCompileTime == Dynamic + || Derived::CoeffReadCost == Dynamic + || (Derived::SizeAtCompileTime!=1 && functor_traits::Cost == Dynamic) + ) ? Dynamic + : Derived::SizeAtCompileTime * Derived::CoeffReadCost + + (Derived::SizeAtCompileTime-1) * functor_traits::Cost, + UnrollingLimit = EIGEN_UNROLLING_LIMIT * (int(Traversal) == int(DefaultTraversal) ? 1 : int(PacketSize)) + }; + +public: + enum { + Unrolling = Cost != Dynamic && Cost <= UnrollingLimit + ? CompleteUnrolling + : NoUnrolling + }; +}; + +/*************************************************************************** +* Part 2 : unrollers +***************************************************************************/ + +/*** no vectorization ***/ + +template +struct redux_novec_unroller +{ + enum { + HalfLength = Length/2 + }; + + typedef typename Derived::Scalar Scalar; + + static EIGEN_STRONG_INLINE Scalar run(const Derived &mat, const Func& func) + { + return func(redux_novec_unroller::run(mat,func), + redux_novec_unroller::run(mat,func)); + } +}; + +template +struct redux_novec_unroller +{ + enum { + outer = Start / Derived::InnerSizeAtCompileTime, + inner = Start % Derived::InnerSizeAtCompileTime + }; + + typedef typename Derived::Scalar Scalar; + + static EIGEN_STRONG_INLINE Scalar run(const Derived &mat, const Func&) + { + return mat.coeffByOuterInner(outer, inner); + } +}; + +// This is actually dead code and will never be called. It is required +// to prevent false warnings regarding failed inlining though +// for 0 length run() will never be called at all. +template +struct redux_novec_unroller +{ + typedef typename Derived::Scalar Scalar; + static EIGEN_STRONG_INLINE Scalar run(const Derived&, const Func&) { return Scalar(); } +}; + +/*** vectorization ***/ + +template +struct redux_vec_unroller +{ + enum { + PacketSize = packet_traits::size, + HalfLength = Length/2 + }; + + typedef typename Derived::Scalar Scalar; + typedef typename packet_traits::type PacketScalar; + + static EIGEN_STRONG_INLINE PacketScalar run(const Derived &mat, const Func& func) + { + return func.packetOp( + redux_vec_unroller::run(mat,func), + redux_vec_unroller::run(mat,func) ); + } +}; + +template +struct redux_vec_unroller +{ + enum { + index = Start * packet_traits::size, + outer = index / int(Derived::InnerSizeAtCompileTime), + inner = index % int(Derived::InnerSizeAtCompileTime), + alignment = (Derived::Flags & AlignedBit) ? Aligned : Unaligned + }; + + typedef typename Derived::Scalar Scalar; + typedef typename packet_traits::type PacketScalar; + + static EIGEN_STRONG_INLINE PacketScalar run(const Derived &mat, const Func&) + { + return mat.template packetByOuterInner(outer, inner); + } +}; + +/*************************************************************************** +* Part 3 : implementation of all cases +***************************************************************************/ + +template::Traversal, + int Unrolling = redux_traits::Unrolling +> +struct redux_impl; + +template +struct redux_impl +{ + typedef typename Derived::Scalar Scalar; + typedef typename Derived::Index Index; + static EIGEN_STRONG_INLINE Scalar run(const Derived& mat, const Func& func) + { + eigen_assert(mat.rows()>0 && mat.cols()>0 && "you are using an empty matrix"); + Scalar res; + res = mat.coeffByOuterInner(0, 0); + for(Index i = 1; i < mat.innerSize(); ++i) + res = func(res, mat.coeffByOuterInner(0, i)); + for(Index i = 1; i < mat.outerSize(); ++i) + for(Index j = 0; j < mat.innerSize(); ++j) + res = func(res, mat.coeffByOuterInner(i, j)); + return res; + } +}; + +template +struct redux_impl + : public redux_novec_unroller +{}; + +template +struct redux_impl +{ + typedef typename Derived::Scalar Scalar; + typedef typename packet_traits::type PacketScalar; + typedef typename Derived::Index Index; + + static Scalar run(const Derived& mat, const Func& func) + { + const Index size = mat.size(); + eigen_assert(size && "you are using an empty matrix"); + const Index packetSize = packet_traits::size; + const Index alignedStart = internal::first_aligned(mat); + enum { + alignment = bool(Derived::Flags & DirectAccessBit) || bool(Derived::Flags & AlignedBit) + ? Aligned : Unaligned + }; + const Index alignedSize2 = ((size-alignedStart)/(2*packetSize))*(2*packetSize); + const Index alignedSize = ((size-alignedStart)/(packetSize))*(packetSize); + const Index alignedEnd2 = alignedStart + alignedSize2; + const Index alignedEnd = alignedStart + alignedSize; + Scalar res; + if(alignedSize) + { + PacketScalar packet_res0 = mat.template packet(alignedStart); + if(alignedSize>packetSize) // we have at least two packets to partly unroll the loop + { + PacketScalar packet_res1 = mat.template packet(alignedStart+packetSize); + for(Index index = alignedStart + 2*packetSize; index < alignedEnd2; index += 2*packetSize) + { + packet_res0 = func.packetOp(packet_res0, mat.template packet(index)); + packet_res1 = func.packetOp(packet_res1, mat.template packet(index+packetSize)); + } + + packet_res0 = func.packetOp(packet_res0,packet_res1); + if(alignedEnd>alignedEnd2) + packet_res0 = func.packetOp(packet_res0, mat.template packet(alignedEnd2)); + } + res = func.predux(packet_res0); + + for(Index index = 0; index < alignedStart; ++index) + res = func(res,mat.coeff(index)); + + for(Index index = alignedEnd; index < size; ++index) + res = func(res,mat.coeff(index)); + } + else // too small to vectorize anything. + // since this is dynamic-size hence inefficient anyway for such small sizes, don't try to optimize. + { + res = mat.coeff(0); + for(Index index = 1; index < size; ++index) + res = func(res,mat.coeff(index)); + } + + return res; + } +}; + +// NOTE: for SliceVectorizedTraversal we simply bypass unrolling +template +struct redux_impl +{ + typedef typename Derived::Scalar Scalar; + typedef typename packet_traits::type PacketScalar; + typedef typename Derived::Index Index; + + static Scalar run(const Derived& mat, const Func& func) + { + eigen_assert(mat.rows()>0 && mat.cols()>0 && "you are using an empty matrix"); + const Index innerSize = mat.innerSize(); + const Index outerSize = mat.outerSize(); + enum { + packetSize = packet_traits::size + }; + const Index packetedInnerSize = ((innerSize)/packetSize)*packetSize; + Scalar res; + if(packetedInnerSize) + { + PacketScalar packet_res = mat.template packet(0,0); + for(Index j=0; j(j,i)); + + res = func.predux(packet_res); + for(Index j=0; j::run(mat, func); + } + + return res; + } +}; + +template +struct redux_impl +{ + typedef typename Derived::Scalar Scalar; + typedef typename packet_traits::type PacketScalar; + enum { + PacketSize = packet_traits::size, + Size = Derived::SizeAtCompileTime, + VectorizedSize = (Size / PacketSize) * PacketSize + }; + static EIGEN_STRONG_INLINE Scalar run(const Derived& mat, const Func& func) + { + eigen_assert(mat.rows()>0 && mat.cols()>0 && "you are using an empty matrix"); + Scalar res = func.predux(redux_vec_unroller::run(mat,func)); + if (VectorizedSize != Size) + res = func(res,redux_novec_unroller::run(mat,func)); + return res; + } +}; + +} // end namespace internal + +/*************************************************************************** +* Part 4 : public API +***************************************************************************/ + + +/** \returns the result of a full redux operation on the whole matrix or vector using \a func + * + * The template parameter \a BinaryOp is the type of the functor \a func which must be + * an associative operator. Both current STL and TR1 functor styles are handled. + * + * \sa DenseBase::sum(), DenseBase::minCoeff(), DenseBase::maxCoeff(), MatrixBase::colwise(), MatrixBase::rowwise() + */ +template +template +EIGEN_STRONG_INLINE typename internal::result_of::Scalar)>::type +DenseBase::redux(const Func& func) const +{ + typedef typename internal::remove_all::type ThisNested; + return internal::redux_impl + ::run(derived(), func); +} + +/** \returns the minimum of all coefficients of \c *this. + * \warning the result is undefined if \c *this contains NaN. + */ +template +EIGEN_STRONG_INLINE typename internal::traits::Scalar +DenseBase::minCoeff() const +{ + return this->redux(Eigen::internal::scalar_min_op()); +} + +/** \returns the maximum of all coefficients of \c *this. + * \warning the result is undefined if \c *this contains NaN. + */ +template +EIGEN_STRONG_INLINE typename internal::traits::Scalar +DenseBase::maxCoeff() const +{ + return this->redux(Eigen::internal::scalar_max_op()); +} + +/** \returns the sum of all coefficients of *this + * + * \sa trace(), prod(), mean() + */ +template +EIGEN_STRONG_INLINE typename internal::traits::Scalar +DenseBase::sum() const +{ + if(SizeAtCompileTime==0 || (SizeAtCompileTime==Dynamic && size()==0)) + return Scalar(0); + return this->redux(Eigen::internal::scalar_sum_op()); +} + +/** \returns the mean of all coefficients of *this +* +* \sa trace(), prod(), sum() +*/ +template +EIGEN_STRONG_INLINE typename internal::traits::Scalar +DenseBase::mean() const +{ + return Scalar(this->redux(Eigen::internal::scalar_sum_op())) / Scalar(this->size()); +} + +/** \returns the product of all coefficients of *this + * + * Example: \include MatrixBase_prod.cpp + * Output: \verbinclude MatrixBase_prod.out + * + * \sa sum(), mean(), trace() + */ +template +EIGEN_STRONG_INLINE typename internal::traits::Scalar +DenseBase::prod() const +{ + if(SizeAtCompileTime==0 || (SizeAtCompileTime==Dynamic && size()==0)) + return Scalar(1); + return this->redux(Eigen::internal::scalar_product_op()); +} + +/** \returns the trace of \c *this, i.e. the sum of the coefficients on the main diagonal. + * + * \c *this can be any matrix, not necessarily square. + * + * \sa diagonal(), sum() + */ +template +EIGEN_STRONG_INLINE typename internal::traits::Scalar +MatrixBase::trace() const +{ + return derived().diagonal().sum(); +} + +} // end namespace Eigen + +#endif // EIGEN_REDUX_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/Ref.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/Ref.h new file mode 100644 index 00000000..7a3becaf --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/Ref.h @@ -0,0 +1,278 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2012 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_REF_H +#define EIGEN_REF_H + +namespace Eigen { + +template class RefBase; +template,OuterStride<> >::type > class Ref; + +/** \class Ref + * \ingroup Core_Module + * + * \brief A matrix or vector expression mapping an existing expressions + * + * \tparam PlainObjectType the equivalent matrix type of the mapped data + * \tparam Options specifies whether the pointer is \c #Aligned, or \c #Unaligned. + * The default is \c #Unaligned. + * \tparam StrideType optionally specifies strides. By default, Ref implies a contiguous storage along the inner dimension (inner stride==1), + * but accept a variable outer stride (leading dimension). + * This can be overridden by specifying strides. + * The type passed here must be a specialization of the Stride template, see examples below. + * + * This class permits to write non template functions taking Eigen's object as parameters while limiting the number of copies. + * A Ref<> object can represent either a const expression or a l-value: + * \code + * // in-out argument: + * void foo1(Ref x); + * + * // read-only const argument: + * void foo2(const Ref& x); + * \endcode + * + * In the in-out case, the input argument must satisfies the constraints of the actual Ref<> type, otherwise a compilation issue will be triggered. + * By default, a Ref can reference any dense vector expression of float having a contiguous memory layout. + * Likewise, a Ref can reference any column major dense matrix expression of float whose column's elements are contiguously stored with + * the possibility to have a constant space inbetween each column, i.e.: the inner stride mmust be equal to 1, but the outer-stride (or leading dimension), + * can be greater than the number of rows. + * + * In the const case, if the input expression does not match the above requirement, then it is evaluated into a temporary before being passed to the function. + * Here are some examples: + * \code + * MatrixXf A; + * VectorXf a; + * foo1(a.head()); // OK + * foo1(A.col()); // OK + * foo1(A.row()); // compilation error because here innerstride!=1 + * foo2(A.row()); // The row is copied into a contiguous temporary + * foo2(2*a); // The expression is evaluated into a temporary + * foo2(A.col().segment(2,4)); // No temporary + * \endcode + * + * The range of inputs that can be referenced without temporary can be enlarged using the last two template parameter. + * Here is an example accepting an innerstride!=1: + * \code + * // in-out argument: + * void foo3(Ref > x); + * foo3(A.row()); // OK + * \endcode + * The downside here is that the function foo3 might be significantly slower than foo1 because it won't be able to exploit vectorization, and will involved more + * expensive address computations even if the input is contiguously stored in memory. To overcome this issue, one might propose to overloads internally calling a + * template function, e.g.: + * \code + * // in the .h: + * void foo(const Ref& A); + * void foo(const Ref >& A); + * + * // in the .cpp: + * template void foo_impl(const TypeOfA& A) { + * ... // crazy code goes here + * } + * void foo(const Ref& A) { foo_impl(A); } + * void foo(const Ref >& A) { foo_impl(A); } + * \endcode + * + * + * \sa PlainObjectBase::Map(), \ref TopicStorageOrders + */ + +namespace internal { + +template +struct traits > + : public traits > +{ + typedef _PlainObjectType PlainObjectType; + typedef _StrideType StrideType; + enum { + Options = _Options, + Flags = traits >::Flags | NestByRefBit + }; + + template struct match { + enum { + HasDirectAccess = internal::has_direct_access::ret, + StorageOrderMatch = PlainObjectType::IsVectorAtCompileTime || Derived::IsVectorAtCompileTime || ((PlainObjectType::Flags&RowMajorBit)==(Derived::Flags&RowMajorBit)), + InnerStrideMatch = int(StrideType::InnerStrideAtCompileTime)==int(Dynamic) + || int(StrideType::InnerStrideAtCompileTime)==int(Derived::InnerStrideAtCompileTime) + || (int(StrideType::InnerStrideAtCompileTime)==0 && int(Derived::InnerStrideAtCompileTime)==1), + OuterStrideMatch = Derived::IsVectorAtCompileTime + || int(StrideType::OuterStrideAtCompileTime)==int(Dynamic) || int(StrideType::OuterStrideAtCompileTime)==int(Derived::OuterStrideAtCompileTime), + AlignmentMatch = (_Options!=Aligned) || ((PlainObjectType::Flags&AlignedBit)==0) || ((traits::Flags&AlignedBit)==AlignedBit), + ScalarTypeMatch = internal::is_same::value, + MatchAtCompileTime = HasDirectAccess && StorageOrderMatch && InnerStrideMatch && OuterStrideMatch && AlignmentMatch && ScalarTypeMatch + }; + typedef typename internal::conditional::type type; + }; + +}; + +template +struct traits > : public traits {}; + +} + +template class RefBase + : public MapBase +{ + typedef typename internal::traits::PlainObjectType PlainObjectType; + typedef typename internal::traits::StrideType StrideType; + +public: + + typedef MapBase Base; + EIGEN_DENSE_PUBLIC_INTERFACE(RefBase) + + inline Index innerStride() const + { + return StrideType::InnerStrideAtCompileTime != 0 ? m_stride.inner() : 1; + } + + inline Index outerStride() const + { + return StrideType::OuterStrideAtCompileTime != 0 ? m_stride.outer() + : IsVectorAtCompileTime ? this->size() + : int(Flags)&RowMajorBit ? this->cols() + : this->rows(); + } + + RefBase() + : Base(0,RowsAtCompileTime==Dynamic?0:RowsAtCompileTime,ColsAtCompileTime==Dynamic?0:ColsAtCompileTime), + // Stride<> does not allow default ctor for Dynamic strides, so let' initialize it with dummy values: + m_stride(StrideType::OuterStrideAtCompileTime==Dynamic?0:StrideType::OuterStrideAtCompileTime, + StrideType::InnerStrideAtCompileTime==Dynamic?0:StrideType::InnerStrideAtCompileTime) + {} + + EIGEN_INHERIT_ASSIGNMENT_OPERATORS(RefBase) + +protected: + + typedef Stride StrideBase; + + template + void construct(Expression& expr) + { + if(PlainObjectType::RowsAtCompileTime==1) + { + eigen_assert(expr.rows()==1 || expr.cols()==1); + ::new (static_cast(this)) Base(expr.data(), 1, expr.size()); + } + else if(PlainObjectType::ColsAtCompileTime==1) + { + eigen_assert(expr.rows()==1 || expr.cols()==1); + ::new (static_cast(this)) Base(expr.data(), expr.size(), 1); + } + else + ::new (static_cast(this)) Base(expr.data(), expr.rows(), expr.cols()); + + if(Expression::IsVectorAtCompileTime && (!PlainObjectType::IsVectorAtCompileTime) && ((Expression::Flags&RowMajorBit)!=(PlainObjectType::Flags&RowMajorBit))) + ::new (&m_stride) StrideBase(expr.innerStride(), StrideType::InnerStrideAtCompileTime==0?0:1); + else + ::new (&m_stride) StrideBase(StrideType::OuterStrideAtCompileTime==0?0:expr.outerStride(), + StrideType::InnerStrideAtCompileTime==0?0:expr.innerStride()); + } + + StrideBase m_stride; +}; + + +template class Ref + : public RefBase > +{ + private: + typedef internal::traits Traits; + template + inline Ref(const PlainObjectBase& expr, + typename internal::enable_if::MatchAtCompileTime),Derived>::type* = 0); + public: + + typedef RefBase Base; + EIGEN_DENSE_PUBLIC_INTERFACE(Ref) + + + #ifndef EIGEN_PARSED_BY_DOXYGEN + template + inline Ref(PlainObjectBase& expr, + typename internal::enable_if::MatchAtCompileTime),Derived>::type* = 0) + { + EIGEN_STATIC_ASSERT(static_cast(Traits::template match::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH); + Base::construct(expr.derived()); + } + template + inline Ref(const DenseBase& expr, + typename internal::enable_if::MatchAtCompileTime),Derived>::type* = 0) + #else + template + inline Ref(DenseBase& expr) + #endif + { + EIGEN_STATIC_ASSERT(static_cast(internal::is_lvalue::value), THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY); + EIGEN_STATIC_ASSERT(static_cast(Traits::template match::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH); + enum { THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY = Derived::ThisConstantIsPrivateInPlainObjectBase}; + Base::construct(expr.const_cast_derived()); + } + + EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Ref) + +}; + +// this is the const ref version +template class Ref + : public RefBase > +{ + typedef internal::traits Traits; + public: + + typedef RefBase Base; + EIGEN_DENSE_PUBLIC_INTERFACE(Ref) + + template + inline Ref(const DenseBase& expr, + typename internal::enable_if::ScalarTypeMatch),Derived>::type* = 0) + { +// std::cout << match_helper::HasDirectAccess << "," << match_helper::OuterStrideMatch << "," << match_helper::InnerStrideMatch << "\n"; +// std::cout << int(StrideType::OuterStrideAtCompileTime) << " - " << int(Derived::OuterStrideAtCompileTime) << "\n"; +// std::cout << int(StrideType::InnerStrideAtCompileTime) << " - " << int(Derived::InnerStrideAtCompileTime) << "\n"; + construct(expr.derived(), typename Traits::template match::type()); + } + + inline Ref(const Ref& other) : Base(other) { + // copy constructor shall not copy the m_object, to avoid unnecessary malloc and copy + } + + template + inline Ref(const RefBase& other) { + construct(other.derived(), typename Traits::template match::type()); + } + + protected: + + template + void construct(const Expression& expr,internal::true_type) + { + Base::construct(expr); + } + + template + void construct(const Expression& expr, internal::false_type) + { + m_object.lazyAssign(expr); + Base::construct(m_object); + } + + protected: + TPlainObjectType m_object; +}; + +} // end namespace Eigen + +#endif // EIGEN_REF_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/Replicate.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/Replicate.h new file mode 100644 index 00000000..ac4537c1 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/Replicate.h @@ -0,0 +1,177 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2009-2010 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_REPLICATE_H +#define EIGEN_REPLICATE_H + +namespace Eigen { + +/** + * \class Replicate + * \ingroup Core_Module + * + * \brief Expression of the multiple replication of a matrix or vector + * + * \param MatrixType the type of the object we are replicating + * + * This class represents an expression of the multiple replication of a matrix or vector. + * It is the return type of DenseBase::replicate() and most of the time + * this is the only way it is used. + * + * \sa DenseBase::replicate() + */ + +namespace internal { +template +struct traits > + : traits +{ + typedef typename MatrixType::Scalar Scalar; + typedef typename traits::StorageKind StorageKind; + typedef typename traits::XprKind XprKind; + enum { + Factor = (RowFactor==Dynamic || ColFactor==Dynamic) ? Dynamic : RowFactor*ColFactor + }; + typedef typename nested::type MatrixTypeNested; + typedef typename remove_reference::type _MatrixTypeNested; + enum { + RowsAtCompileTime = RowFactor==Dynamic || int(MatrixType::RowsAtCompileTime)==Dynamic + ? Dynamic + : RowFactor * MatrixType::RowsAtCompileTime, + ColsAtCompileTime = ColFactor==Dynamic || int(MatrixType::ColsAtCompileTime)==Dynamic + ? Dynamic + : ColFactor * MatrixType::ColsAtCompileTime, + //FIXME we don't propagate the max sizes !!! + MaxRowsAtCompileTime = RowsAtCompileTime, + MaxColsAtCompileTime = ColsAtCompileTime, + IsRowMajor = MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1 ? 1 + : MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1 ? 0 + : (MatrixType::Flags & RowMajorBit) ? 1 : 0, + Flags = (_MatrixTypeNested::Flags & HereditaryBits & ~RowMajorBit) | (IsRowMajor ? RowMajorBit : 0), + CoeffReadCost = _MatrixTypeNested::CoeffReadCost + }; +}; +} + +template class Replicate + : public internal::dense_xpr_base< Replicate >::type +{ + typedef typename internal::traits::MatrixTypeNested MatrixTypeNested; + typedef typename internal::traits::_MatrixTypeNested _MatrixTypeNested; + public: + + typedef typename internal::dense_xpr_base::type Base; + EIGEN_DENSE_PUBLIC_INTERFACE(Replicate) + + template + inline explicit Replicate(const OriginalMatrixType& a_matrix) + : m_matrix(a_matrix), m_rowFactor(RowFactor), m_colFactor(ColFactor) + { + EIGEN_STATIC_ASSERT((internal::is_same::type,OriginalMatrixType>::value), + THE_MATRIX_OR_EXPRESSION_THAT_YOU_PASSED_DOES_NOT_HAVE_THE_EXPECTED_TYPE) + eigen_assert(RowFactor!=Dynamic && ColFactor!=Dynamic); + } + + template + inline Replicate(const OriginalMatrixType& a_matrix, Index rowFactor, Index colFactor) + : m_matrix(a_matrix), m_rowFactor(rowFactor), m_colFactor(colFactor) + { + EIGEN_STATIC_ASSERT((internal::is_same::type,OriginalMatrixType>::value), + THE_MATRIX_OR_EXPRESSION_THAT_YOU_PASSED_DOES_NOT_HAVE_THE_EXPECTED_TYPE) + } + + inline Index rows() const { return m_matrix.rows() * m_rowFactor.value(); } + inline Index cols() const { return m_matrix.cols() * m_colFactor.value(); } + + inline Scalar coeff(Index rowId, Index colId) const + { + // try to avoid using modulo; this is a pure optimization strategy + const Index actual_row = internal::traits::RowsAtCompileTime==1 ? 0 + : RowFactor==1 ? rowId + : rowId%m_matrix.rows(); + const Index actual_col = internal::traits::ColsAtCompileTime==1 ? 0 + : ColFactor==1 ? colId + : colId%m_matrix.cols(); + + return m_matrix.coeff(actual_row, actual_col); + } + template + inline PacketScalar packet(Index rowId, Index colId) const + { + const Index actual_row = internal::traits::RowsAtCompileTime==1 ? 0 + : RowFactor==1 ? rowId + : rowId%m_matrix.rows(); + const Index actual_col = internal::traits::ColsAtCompileTime==1 ? 0 + : ColFactor==1 ? colId + : colId%m_matrix.cols(); + + return m_matrix.template packet(actual_row, actual_col); + } + + const _MatrixTypeNested& nestedExpression() const + { + return m_matrix; + } + + protected: + MatrixTypeNested m_matrix; + const internal::variable_if_dynamic m_rowFactor; + const internal::variable_if_dynamic m_colFactor; +}; + +/** + * \return an expression of the replication of \c *this + * + * Example: \include MatrixBase_replicate.cpp + * Output: \verbinclude MatrixBase_replicate.out + * + * \sa VectorwiseOp::replicate(), DenseBase::replicate(Index,Index), class Replicate + */ +template +template +const Replicate +DenseBase::replicate() const +{ + return Replicate(derived()); +} + +/** + * \return an expression of the replication of \c *this + * + * Example: \include MatrixBase_replicate_int_int.cpp + * Output: \verbinclude MatrixBase_replicate_int_int.out + * + * \sa VectorwiseOp::replicate(), DenseBase::replicate(), class Replicate + */ +template +const typename DenseBase::ReplicateReturnType +DenseBase::replicate(Index rowFactor,Index colFactor) const +{ + return Replicate(derived(),rowFactor,colFactor); +} + +/** + * \return an expression of the replication of each column (or row) of \c *this + * + * Example: \include DirectionWise_replicate_int.cpp + * Output: \verbinclude DirectionWise_replicate_int.out + * + * \sa VectorwiseOp::replicate(), DenseBase::replicate(), class Replicate + */ +template +const typename VectorwiseOp::ReplicateReturnType +VectorwiseOp::replicate(Index factor) const +{ + return typename VectorwiseOp::ReplicateReturnType + (_expression(),Direction==Vertical?factor:1,Direction==Horizontal?factor:1); +} + +} // end namespace Eigen + +#endif // EIGEN_REPLICATE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/ReturnByValue.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/ReturnByValue.h new file mode 100644 index 00000000..f635598d --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/ReturnByValue.h @@ -0,0 +1,99 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2009-2010 Gael Guennebaud +// Copyright (C) 2009-2010 Benoit Jacob +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_RETURNBYVALUE_H +#define EIGEN_RETURNBYVALUE_H + +namespace Eigen { + +/** \class ReturnByValue + * \ingroup Core_Module + * + */ + +namespace internal { + +template +struct traits > + : public traits::ReturnType> +{ + enum { + // We're disabling the DirectAccess because e.g. the constructor of + // the Block-with-DirectAccess expression requires to have a coeffRef method. + // Also, we don't want to have to implement the stride stuff. + Flags = (traits::ReturnType>::Flags + | EvalBeforeNestingBit) & ~DirectAccessBit + }; +}; + +/* The ReturnByValue object doesn't even have a coeff() method. + * So the only way that nesting it in an expression can work, is by evaluating it into a plain matrix. + * So internal::nested always gives the plain return matrix type. + * + * FIXME: I don't understand why we need this specialization: isn't this taken care of by the EvalBeforeNestingBit ?? + */ +template +struct nested, n, PlainObject> +{ + typedef typename traits::ReturnType type; +}; + +} // end namespace internal + +template class ReturnByValue + : internal::no_assignment_operator, public internal::dense_xpr_base< ReturnByValue >::type +{ + public: + typedef typename internal::traits::ReturnType ReturnType; + + typedef typename internal::dense_xpr_base::type Base; + EIGEN_DENSE_PUBLIC_INTERFACE(ReturnByValue) + + template + inline void evalTo(Dest& dst) const + { static_cast(this)->evalTo(dst); } + inline Index rows() const { return static_cast(this)->rows(); } + inline Index cols() const { return static_cast(this)->cols(); } + +#ifndef EIGEN_PARSED_BY_DOXYGEN +#define Unusable YOU_ARE_TRYING_TO_ACCESS_A_SINGLE_COEFFICIENT_IN_A_SPECIAL_EXPRESSION_WHERE_THAT_IS_NOT_ALLOWED_BECAUSE_THAT_WOULD_BE_INEFFICIENT + class Unusable{ + Unusable(const Unusable&) {} + Unusable& operator=(const Unusable&) {return *this;} + }; + const Unusable& coeff(Index) const { return *reinterpret_cast(this); } + const Unusable& coeff(Index,Index) const { return *reinterpret_cast(this); } + Unusable& coeffRef(Index) { return *reinterpret_cast(this); } + Unusable& coeffRef(Index,Index) { return *reinterpret_cast(this); } + template Unusable& packet(Index) const; + template Unusable& packet(Index, Index) const; +#endif +}; + +template +template +Derived& DenseBase::operator=(const ReturnByValue& other) +{ + other.evalTo(derived()); + return derived(); +} + +template +template +Derived& DenseBase::lazyAssign(const ReturnByValue& other) +{ + other.evalTo(derived()); + return derived(); +} + + +} // end namespace Eigen + +#endif // EIGEN_RETURNBYVALUE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/Reverse.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/Reverse.h new file mode 100644 index 00000000..e30ae3d2 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/Reverse.h @@ -0,0 +1,224 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2006-2008 Benoit Jacob +// Copyright (C) 2009 Ricard Marxer +// Copyright (C) 2009-2010 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_REVERSE_H +#define EIGEN_REVERSE_H + +namespace Eigen { + +/** \class Reverse + * \ingroup Core_Module + * + * \brief Expression of the reverse of a vector or matrix + * + * \param MatrixType the type of the object of which we are taking the reverse + * + * This class represents an expression of the reverse of a vector. + * It is the return type of MatrixBase::reverse() and VectorwiseOp::reverse() + * and most of the time this is the only way it is used. + * + * \sa MatrixBase::reverse(), VectorwiseOp::reverse() + */ + +namespace internal { + +template +struct traits > + : traits +{ + typedef typename MatrixType::Scalar Scalar; + typedef typename traits::StorageKind StorageKind; + typedef typename traits::XprKind XprKind; + typedef typename nested::type MatrixTypeNested; + typedef typename remove_reference::type _MatrixTypeNested; + enum { + RowsAtCompileTime = MatrixType::RowsAtCompileTime, + ColsAtCompileTime = MatrixType::ColsAtCompileTime, + MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime, + MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime, + + // let's enable LinearAccess only with vectorization because of the product overhead + LinearAccess = ( (Direction==BothDirections) && (int(_MatrixTypeNested::Flags)&PacketAccessBit) ) + ? LinearAccessBit : 0, + + Flags = int(_MatrixTypeNested::Flags) & (HereditaryBits | LvalueBit | PacketAccessBit | LinearAccess), + + CoeffReadCost = _MatrixTypeNested::CoeffReadCost + }; +}; + +template struct reverse_packet_cond +{ + static inline PacketScalar run(const PacketScalar& x) { return preverse(x); } +}; + +template struct reverse_packet_cond +{ + static inline PacketScalar run(const PacketScalar& x) { return x; } +}; + +} // end namespace internal + +template class Reverse + : public internal::dense_xpr_base< Reverse >::type +{ + public: + + typedef typename internal::dense_xpr_base::type Base; + EIGEN_DENSE_PUBLIC_INTERFACE(Reverse) + using Base::IsRowMajor; + + // next line is necessary because otherwise const version of operator() + // is hidden by non-const version defined in this file + using Base::operator(); + + protected: + enum { + PacketSize = internal::packet_traits::size, + IsColMajor = !IsRowMajor, + ReverseRow = (Direction == Vertical) || (Direction == BothDirections), + ReverseCol = (Direction == Horizontal) || (Direction == BothDirections), + OffsetRow = ReverseRow && IsColMajor ? PacketSize : 1, + OffsetCol = ReverseCol && IsRowMajor ? PacketSize : 1, + ReversePacket = (Direction == BothDirections) + || ((Direction == Vertical) && IsColMajor) + || ((Direction == Horizontal) && IsRowMajor) + }; + typedef internal::reverse_packet_cond reverse_packet; + public: + + inline Reverse(const MatrixType& matrix) : m_matrix(matrix) { } + + EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Reverse) + + inline Index rows() const { return m_matrix.rows(); } + inline Index cols() const { return m_matrix.cols(); } + + inline Index innerStride() const + { + return -m_matrix.innerStride(); + } + + inline Scalar& operator()(Index row, Index col) + { + eigen_assert(row >= 0 && row < rows() && col >= 0 && col < cols()); + return coeffRef(row, col); + } + + inline Scalar& coeffRef(Index row, Index col) + { + return m_matrix.const_cast_derived().coeffRef(ReverseRow ? m_matrix.rows() - row - 1 : row, + ReverseCol ? m_matrix.cols() - col - 1 : col); + } + + inline CoeffReturnType coeff(Index row, Index col) const + { + return m_matrix.coeff(ReverseRow ? m_matrix.rows() - row - 1 : row, + ReverseCol ? m_matrix.cols() - col - 1 : col); + } + + inline CoeffReturnType coeff(Index index) const + { + return m_matrix.coeff(m_matrix.size() - index - 1); + } + + inline Scalar& coeffRef(Index index) + { + return m_matrix.const_cast_derived().coeffRef(m_matrix.size() - index - 1); + } + + inline Scalar& operator()(Index index) + { + eigen_assert(index >= 0 && index < m_matrix.size()); + return coeffRef(index); + } + + template + inline const PacketScalar packet(Index row, Index col) const + { + return reverse_packet::run(m_matrix.template packet( + ReverseRow ? m_matrix.rows() - row - OffsetRow : row, + ReverseCol ? m_matrix.cols() - col - OffsetCol : col)); + } + + template + inline void writePacket(Index row, Index col, const PacketScalar& x) + { + m_matrix.const_cast_derived().template writePacket( + ReverseRow ? m_matrix.rows() - row - OffsetRow : row, + ReverseCol ? m_matrix.cols() - col - OffsetCol : col, + reverse_packet::run(x)); + } + + template + inline const PacketScalar packet(Index index) const + { + return internal::preverse(m_matrix.template packet( m_matrix.size() - index - PacketSize )); + } + + template + inline void writePacket(Index index, const PacketScalar& x) + { + m_matrix.const_cast_derived().template writePacket(m_matrix.size() - index - PacketSize, internal::preverse(x)); + } + + const typename internal::remove_all::type& + nestedExpression() const + { + return m_matrix; + } + + protected: + typename MatrixType::Nested m_matrix; +}; + +/** \returns an expression of the reverse of *this. + * + * Example: \include MatrixBase_reverse.cpp + * Output: \verbinclude MatrixBase_reverse.out + * + */ +template +inline typename DenseBase::ReverseReturnType +DenseBase::reverse() +{ + return derived(); +} + +/** This is the const version of reverse(). */ +template +inline const typename DenseBase::ConstReverseReturnType +DenseBase::reverse() const +{ + return derived(); +} + +/** This is the "in place" version of reverse: it reverses \c *this. + * + * In most cases it is probably better to simply use the reversed expression + * of a matrix. However, when reversing the matrix data itself is really needed, + * then this "in-place" version is probably the right choice because it provides + * the following additional features: + * - less error prone: doing the same operation with .reverse() requires special care: + * \code m = m.reverse().eval(); \endcode + * - this API allows to avoid creating a temporary (the current implementation creates a temporary, but that could be avoided using swap) + * - it allows future optimizations (cache friendliness, etc.) + * + * \sa reverse() */ +template +inline void DenseBase::reverseInPlace() +{ + derived() = derived().reverse().eval(); +} + +} // end namespace Eigen + +#endif // EIGEN_REVERSE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/Select.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/Select.h new file mode 100644 index 00000000..87993bbb --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/Select.h @@ -0,0 +1,162 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008-2010 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_SELECT_H +#define EIGEN_SELECT_H + +namespace Eigen { + +/** \class Select + * \ingroup Core_Module + * + * \brief Expression of a coefficient wise version of the C++ ternary operator ?: + * + * \param ConditionMatrixType the type of the \em condition expression which must be a boolean matrix + * \param ThenMatrixType the type of the \em then expression + * \param ElseMatrixType the type of the \em else expression + * + * This class represents an expression of a coefficient wise version of the C++ ternary operator ?:. + * It is the return type of DenseBase::select() and most of the time this is the only way it is used. + * + * \sa DenseBase::select(const DenseBase&, const DenseBase&) const + */ + +namespace internal { +template +struct traits > + : traits +{ + typedef typename traits::Scalar Scalar; + typedef Dense StorageKind; + typedef typename traits::XprKind XprKind; + typedef typename ConditionMatrixType::Nested ConditionMatrixNested; + typedef typename ThenMatrixType::Nested ThenMatrixNested; + typedef typename ElseMatrixType::Nested ElseMatrixNested; + enum { + RowsAtCompileTime = ConditionMatrixType::RowsAtCompileTime, + ColsAtCompileTime = ConditionMatrixType::ColsAtCompileTime, + MaxRowsAtCompileTime = ConditionMatrixType::MaxRowsAtCompileTime, + MaxColsAtCompileTime = ConditionMatrixType::MaxColsAtCompileTime, + Flags = (unsigned int)ThenMatrixType::Flags & ElseMatrixType::Flags & HereditaryBits, + CoeffReadCost = traits::type>::CoeffReadCost + + EIGEN_SIZE_MAX(traits::type>::CoeffReadCost, + traits::type>::CoeffReadCost) + }; +}; +} + +template +class Select : internal::no_assignment_operator, + public internal::dense_xpr_base< Select >::type +{ + public: + + typedef typename internal::dense_xpr_base::type Base; - EIGEN_DENSE_PUBLIC_INTERFACE(Select) - - Select(const ConditionMatrixType& a_conditionMatrix, - const ThenMatrixType& a_thenMatrix, - const ElseMatrixType& a_elseMatrix) - : m_condition(a_conditionMatrix), m_then(a_thenMatrix), m_else(a_elseMatrix) - { - eigen_assert(m_condition.rows() == m_then.rows() && m_condition.rows() == m_else.rows()); - eigen_assert(m_condition.cols() == m_then.cols() && m_condition.cols() == m_else.cols()); - } - - Index rows() const { return m_condition.rows(); } - Index cols() const { return m_condition.cols(); } - - const Scalar coeff(Index i, Index j) const - { - if (m_condition.coeff(i,j)) - return m_then.coeff(i,j); - else - return m_else.coeff(i,j); - } - - const Scalar coeff(Index i) const - { - if (m_condition.coeff(i)) - return m_then.coeff(i); - else - return m_else.coeff(i); - } - - const ConditionMatrixType& conditionMatrix() const - { - return m_condition; - } - - const ThenMatrixType& thenMatrix() const - { - return m_then; - } - - const ElseMatrixType& elseMatrix() const - { - return m_else; - } - - protected: - typename ConditionMatrixType::Nested m_condition; - typename ThenMatrixType::Nested m_then; - typename ElseMatrixType::Nested m_else; -}; - - -/** \returns a matrix where each coefficient (i,j) is equal to \a thenMatrix(i,j) - * if \c *this(i,j), and \a elseMatrix(i,j) otherwise. - * - * Example: \include MatrixBase_select.cpp - * Output: \verbinclude MatrixBase_select.out - * - * \sa class Select - */ -template -template -inline const Select -DenseBase::select(const DenseBase& thenMatrix, - const DenseBase& elseMatrix) const -{ - return Select(derived(), thenMatrix.derived(), elseMatrix.derived()); -} - -/** Version of DenseBase::select(const DenseBase&, const DenseBase&) with - * the \em else expression being a scalar value. - * - * \sa DenseBase::select(const DenseBase&, const DenseBase&) const, class Select - */ -template -template -inline const Select -DenseBase::select(const DenseBase& thenMatrix, - const typename ThenDerived::Scalar& elseScalar) const -{ - return Select( - derived(), thenMatrix.derived(), ThenDerived::Constant(rows(),cols(),elseScalar)); -} - -/** Version of DenseBase::select(const DenseBase&, const DenseBase&) with - * the \em then expression being a scalar value. - * - * \sa DenseBase::select(const DenseBase&, const DenseBase&) const, class Select - */ -template -template -inline const Select -DenseBase::select(const typename ElseDerived::Scalar& thenScalar, - const DenseBase& elseMatrix) const -{ - return Select( - derived(), ElseDerived::Constant(rows(),cols(),thenScalar), elseMatrix.derived()); -} - -} // end namespace Eigen - -#endif // EIGEN_SELECT_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/SelfAdjointView.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/SelfAdjointView.h deleted file mode 100644 index 6fa7cd15..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Core/SelfAdjointView.h +++ /dev/null @@ -1,314 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2009 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_SELFADJOINTMATRIX_H -#define EIGEN_SELFADJOINTMATRIX_H - -namespace Eigen { - -/** \class SelfAdjointView - * \ingroup Core_Module - * - * - * \brief Expression of a selfadjoint matrix from a triangular part of a dense matrix - * - * \param MatrixType the type of the dense matrix storing the coefficients - * \param TriangularPart can be either \c #Lower or \c #Upper - * - * This class is an expression of a sefladjoint matrix from a triangular part of a matrix - * with given dense storage of the coefficients. It is the return type of MatrixBase::selfadjointView() - * and most of the time this is the only way that it is used. - * - * \sa class TriangularBase, MatrixBase::selfadjointView() - */ - -namespace internal { -template -struct traits > : traits -{ - typedef typename nested::type MatrixTypeNested; - typedef typename remove_all::type MatrixTypeNestedCleaned; - typedef MatrixType ExpressionType; - typedef typename MatrixType::PlainObject DenseMatrixType; - enum { - Mode = UpLo | SelfAdjoint, - Flags = MatrixTypeNestedCleaned::Flags & (HereditaryBits) - & (~(PacketAccessBit | DirectAccessBit | LinearAccessBit)), // FIXME these flags should be preserved - CoeffReadCost = MatrixTypeNestedCleaned::CoeffReadCost - }; -}; -} - -template -struct SelfadjointProductMatrix; - -// FIXME could also be called SelfAdjointWrapper to be consistent with DiagonalWrapper ?? -template class SelfAdjointView - : public TriangularBase > -{ - public: - - typedef TriangularBase Base; - typedef typename internal::traits::MatrixTypeNested MatrixTypeNested; - typedef typename internal::traits::MatrixTypeNestedCleaned MatrixTypeNestedCleaned; - - /** \brief The type of coefficients in this matrix */ - typedef typename internal::traits::Scalar Scalar; - - typedef typename MatrixType::Index Index; - - enum { - Mode = internal::traits::Mode - }; - typedef typename MatrixType::PlainObject PlainObject; - - inline SelfAdjointView(MatrixType& matrix) : m_matrix(matrix) - {} - - inline Index rows() const { return m_matrix.rows(); } - inline Index cols() const { return m_matrix.cols(); } - inline Index outerStride() const { return m_matrix.outerStride(); } - inline Index innerStride() const { return m_matrix.innerStride(); } - - /** \sa MatrixBase::coeff() - * \warning the coordinates must fit into the referenced triangular part - */ - inline Scalar coeff(Index row, Index col) const - { - Base::check_coordinates_internal(row, col); - return m_matrix.coeff(row, col); - } - - /** \sa MatrixBase::coeffRef() - * \warning the coordinates must fit into the referenced triangular part - */ - inline Scalar& coeffRef(Index row, Index col) - { - Base::check_coordinates_internal(row, col); - return m_matrix.const_cast_derived().coeffRef(row, col); - } - - /** \internal */ - const MatrixTypeNestedCleaned& _expression() const { return m_matrix; } - - const MatrixTypeNestedCleaned& nestedExpression() const { return m_matrix; } - MatrixTypeNestedCleaned& nestedExpression() { return *const_cast(&m_matrix); } - - /** Efficient self-adjoint matrix times vector/matrix product */ - template - SelfadjointProductMatrix - operator*(const MatrixBase& rhs) const - { - return SelfadjointProductMatrix - - (m_matrix, rhs.derived()); - } - - /** Efficient vector/matrix times self-adjoint matrix product */ - template friend - SelfadjointProductMatrix - operator*(const MatrixBase& lhs, const SelfAdjointView& rhs) - { - return SelfadjointProductMatrix - - (lhs.derived(),rhs.m_matrix); - } - - /** Perform a symmetric rank 2 update of the selfadjoint matrix \c *this: - * \f$ this = this + \alpha u v^* + conj(\alpha) v u^* \f$ - * \returns a reference to \c *this - * - * The vectors \a u and \c v \b must be column vectors, however they can be - * a adjoint expression without any overhead. Only the meaningful triangular - * part of the matrix is updated, the rest is left unchanged. - * - * \sa rankUpdate(const MatrixBase&, Scalar) - */ - template - SelfAdjointView& rankUpdate(const MatrixBase& u, const MatrixBase& v, const Scalar& alpha = Scalar(1)); - - /** Perform a symmetric rank K update of the selfadjoint matrix \c *this: - * \f$ this = this + \alpha ( u u^* ) \f$ where \a u is a vector or matrix. - * - * \returns a reference to \c *this - * - * Note that to perform \f$ this = this + \alpha ( u^* u ) \f$ you can simply - * call this function with u.adjoint(). - * - * \sa rankUpdate(const MatrixBase&, const MatrixBase&, Scalar) - */ - template - SelfAdjointView& rankUpdate(const MatrixBase& u, const Scalar& alpha = Scalar(1)); - -/////////// Cholesky module /////////// - - const LLT llt() const; - const LDLT ldlt() const; - -/////////// Eigenvalue module /////////// - - /** Real part of #Scalar */ - typedef typename NumTraits::Real RealScalar; - /** Return type of eigenvalues() */ - typedef Matrix::ColsAtCompileTime, 1> EigenvaluesReturnType; - - EigenvaluesReturnType eigenvalues() const; - RealScalar operatorNorm() const; - - #ifdef EIGEN2_SUPPORT - template - SelfAdjointView& operator=(const MatrixBase& other) - { - enum { - OtherPart = UpLo == Upper ? StrictlyLower : StrictlyUpper - }; - m_matrix.const_cast_derived().template triangularView() = other; - m_matrix.const_cast_derived().template triangularView() = other.adjoint(); - return *this; - } - template - SelfAdjointView& operator=(const TriangularView& other) - { - enum { - OtherPart = UpLo == Upper ? StrictlyLower : StrictlyUpper - }; - m_matrix.const_cast_derived().template triangularView() = other.toDenseMatrix(); - m_matrix.const_cast_derived().template triangularView() = other.toDenseMatrix().adjoint(); - return *this; - } - #endif - - protected: - MatrixTypeNested m_matrix; -}; - - -// template -// internal::selfadjoint_matrix_product_returntype > -// operator*(const MatrixBase& lhs, const SelfAdjointView& rhs) -// { -// return internal::matrix_selfadjoint_product_returntype >(lhs.derived(),rhs); -// } - -// selfadjoint to dense matrix - -namespace internal { - -template -struct triangular_assignment_selector -{ - enum { - col = (UnrollCount-1) / Derived1::RowsAtCompileTime, - row = (UnrollCount-1) % Derived1::RowsAtCompileTime - }; - - static inline void run(Derived1 &dst, const Derived2 &src) - { - triangular_assignment_selector::run(dst, src); - - if(row == col) - dst.coeffRef(row, col) = numext::real(src.coeff(row, col)); - else if(row < col) - dst.coeffRef(col, row) = numext::conj(dst.coeffRef(row, col) = src.coeff(row, col)); - } -}; - -template -struct triangular_assignment_selector -{ - static inline void run(Derived1 &, const Derived2 &) {} -}; - -template -struct triangular_assignment_selector -{ - enum { - col = (UnrollCount-1) / Derived1::RowsAtCompileTime, - row = (UnrollCount-1) % Derived1::RowsAtCompileTime - }; - - static inline void run(Derived1 &dst, const Derived2 &src) - { - triangular_assignment_selector::run(dst, src); - - if(row == col) - dst.coeffRef(row, col) = numext::real(src.coeff(row, col)); - else if(row > col) - dst.coeffRef(col, row) = numext::conj(dst.coeffRef(row, col) = src.coeff(row, col)); - } -}; - -template -struct triangular_assignment_selector -{ - static inline void run(Derived1 &, const Derived2 &) {} -}; - -template -struct triangular_assignment_selector -{ - typedef typename Derived1::Index Index; - static inline void run(Derived1 &dst, const Derived2 &src) - { - for(Index j = 0; j < dst.cols(); ++j) - { - for(Index i = 0; i < j; ++i) - { - dst.copyCoeff(i, j, src); - dst.coeffRef(j,i) = numext::conj(dst.coeff(i,j)); - } - dst.copyCoeff(j, j, src); - } - } -}; - -template -struct triangular_assignment_selector -{ - static inline void run(Derived1 &dst, const Derived2 &src) - { - typedef typename Derived1::Index Index; - for(Index i = 0; i < dst.rows(); ++i) - { - for(Index j = 0; j < i; ++j) - { - dst.copyCoeff(i, j, src); - dst.coeffRef(j,i) = numext::conj(dst.coeff(i,j)); - } - dst.copyCoeff(i, i, src); - } - } -}; - -} // end namespace internal - -/*************************************************************************** -* Implementation of MatrixBase methods -***************************************************************************/ - -template -template -typename MatrixBase::template ConstSelfAdjointViewReturnType::Type -MatrixBase::selfadjointView() const -{ - return derived(); -} - -template -template -typename MatrixBase::template SelfAdjointViewReturnType::Type -MatrixBase::selfadjointView() -{ - return derived(); -} - -} // end namespace Eigen - -#endif // EIGEN_SELFADJOINTMATRIX_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/SelfCwiseBinaryOp.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/SelfCwiseBinaryOp.h deleted file mode 100644 index 0956475a..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Core/SelfCwiseBinaryOp.h +++ /dev/null @@ -1,191 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2009-2010 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_SELFCWISEBINARYOP_H -#define EIGEN_SELFCWISEBINARYOP_H - -namespace Eigen { - -/** \class SelfCwiseBinaryOp - * \ingroup Core_Module - * - * \internal - * - * \brief Internal helper class for optimizing operators like +=, -= - * - * This is a pseudo expression class re-implementing the copyCoeff/copyPacket - * method to directly performs a +=/-= operations in an optimal way. In particular, - * this allows to make sure that the input/output data are loaded only once using - * aligned packet loads. - * - * \sa class SwapWrapper for a similar trick. - */ - -namespace internal { -template -struct traits > - : traits > -{ - enum { - // Note that it is still a good idea to preserve the DirectAccessBit - // so that assign can correctly align the data. - Flags = traits >::Flags | (Lhs::Flags&DirectAccessBit) | (Lhs::Flags&LvalueBit), - OuterStrideAtCompileTime = Lhs::OuterStrideAtCompileTime, - InnerStrideAtCompileTime = Lhs::InnerStrideAtCompileTime - }; -}; -} - -template class SelfCwiseBinaryOp - : public internal::dense_xpr_base< SelfCwiseBinaryOp >::type -{ - public: - - typedef typename internal::dense_xpr_base::type Base; - EIGEN_DENSE_PUBLIC_INTERFACE(SelfCwiseBinaryOp) - - typedef typename internal::packet_traits::type Packet; - - inline SelfCwiseBinaryOp(Lhs& xpr, const BinaryOp& func = BinaryOp()) : m_matrix(xpr), m_functor(func) {} - - inline Index rows() const { return m_matrix.rows(); } - inline Index cols() const { return m_matrix.cols(); } - inline Index outerStride() const { return m_matrix.outerStride(); } - inline Index innerStride() const { return m_matrix.innerStride(); } - inline const Scalar* data() const { return m_matrix.data(); } - - // note that this function is needed by assign to correctly align loads/stores - // TODO make Assign use .data() - inline Scalar& coeffRef(Index row, Index col) - { - EIGEN_STATIC_ASSERT_LVALUE(Lhs) - return m_matrix.const_cast_derived().coeffRef(row, col); - } - inline const Scalar& coeffRef(Index row, Index col) const - { - return m_matrix.coeffRef(row, col); - } - - // note that this function is needed by assign to correctly align loads/stores - // TODO make Assign use .data() - inline Scalar& coeffRef(Index index) - { - EIGEN_STATIC_ASSERT_LVALUE(Lhs) - return m_matrix.const_cast_derived().coeffRef(index); - } - inline const Scalar& coeffRef(Index index) const - { - return m_matrix.const_cast_derived().coeffRef(index); - } - - template - void copyCoeff(Index row, Index col, const DenseBase& other) - { - OtherDerived& _other = other.const_cast_derived(); - eigen_internal_assert(row >= 0 && row < rows() - && col >= 0 && col < cols()); - Scalar& tmp = m_matrix.coeffRef(row,col); - tmp = m_functor(tmp, _other.coeff(row,col)); - } - - template - void copyCoeff(Index index, const DenseBase& other) - { - OtherDerived& _other = other.const_cast_derived(); - eigen_internal_assert(index >= 0 && index < m_matrix.size()); - Scalar& tmp = m_matrix.coeffRef(index); - tmp = m_functor(tmp, _other.coeff(index)); - } - - template - void copyPacket(Index row, Index col, const DenseBase& other) - { - OtherDerived& _other = other.const_cast_derived(); - eigen_internal_assert(row >= 0 && row < rows() - && col >= 0 && col < cols()); - m_matrix.template writePacket(row, col, - m_functor.packetOp(m_matrix.template packet(row, col),_other.template packet(row, col)) ); - } - - template - void copyPacket(Index index, const DenseBase& other) - { - OtherDerived& _other = other.const_cast_derived(); - eigen_internal_assert(index >= 0 && index < m_matrix.size()); - m_matrix.template writePacket(index, - m_functor.packetOp(m_matrix.template packet(index),_other.template packet(index)) ); - } - - // reimplement lazyAssign to handle complex *= real - // see CwiseBinaryOp ctor for details - template - EIGEN_STRONG_INLINE SelfCwiseBinaryOp& lazyAssign(const DenseBase& rhs) - { - EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Lhs,RhsDerived) - EIGEN_CHECK_BINARY_COMPATIBILIY(BinaryOp,typename Lhs::Scalar,typename RhsDerived::Scalar); - - #ifdef EIGEN_DEBUG_ASSIGN - internal::assign_traits::debug(); - #endif - eigen_assert(rows() == rhs.rows() && cols() == rhs.cols()); - internal::assign_impl::run(*this,rhs.derived()); - #ifndef EIGEN_NO_DEBUG - this->checkTransposeAliasing(rhs.derived()); - #endif - return *this; - } - - // overloaded to honor evaluation of special matrices - // maybe another solution would be to not use SelfCwiseBinaryOp - // at first... - SelfCwiseBinaryOp& operator=(const Rhs& _rhs) - { - typename internal::nested::type rhs(_rhs); - return Base::operator=(rhs); - } - - Lhs& expression() const - { - return m_matrix; - } - - const BinaryOp& functor() const - { - return m_functor; - } - - protected: - Lhs& m_matrix; - const BinaryOp& m_functor; - - private: - SelfCwiseBinaryOp& operator=(const SelfCwiseBinaryOp&); -}; - -template -inline Derived& DenseBase::operator*=(const Scalar& other) -{ - typedef typename Derived::PlainObject PlainObject; - SelfCwiseBinaryOp, Derived, typename PlainObject::ConstantReturnType> tmp(derived()); - tmp = PlainObject::Constant(rows(),cols(),other); - return derived(); -} - -template -inline Derived& DenseBase::operator/=(const Scalar& other) -{ - typedef typename Derived::PlainObject PlainObject; - SelfCwiseBinaryOp, Derived, typename PlainObject::ConstantReturnType> tmp(derived()); - tmp = PlainObject::Constant(rows(),cols(), other); - return derived(); -} - -} // end namespace Eigen - -#endif // EIGEN_SELFCWISEBINARYOP_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/SolveTriangular.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/SolveTriangular.h deleted file mode 100644 index ef17f288..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Core/SolveTriangular.h +++ /dev/null @@ -1,260 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2009 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_SOLVETRIANGULAR_H -#define EIGEN_SOLVETRIANGULAR_H - -namespace Eigen { - -namespace internal { - -// Forward declarations: -// The following two routines are implemented in the products/TriangularSolver*.h files -template -struct triangular_solve_vector; - -template -struct triangular_solve_matrix; - -// small helper struct extracting some traits on the underlying solver operation -template -class trsolve_traits -{ - private: - enum { - RhsIsVectorAtCompileTime = (Side==OnTheLeft ? Rhs::ColsAtCompileTime : Rhs::RowsAtCompileTime)==1 - }; - public: - enum { - Unrolling = (RhsIsVectorAtCompileTime && Rhs::SizeAtCompileTime != Dynamic && Rhs::SizeAtCompileTime <= 8) - ? CompleteUnrolling : NoUnrolling, - RhsVectors = RhsIsVectorAtCompileTime ? 1 : Dynamic - }; -}; - -template::Unrolling, - int RhsVectors = trsolve_traits::RhsVectors - > -struct triangular_solver_selector; - -template -struct triangular_solver_selector -{ - typedef typename Lhs::Scalar LhsScalar; - typedef typename Rhs::Scalar RhsScalar; - typedef blas_traits LhsProductTraits; - typedef typename LhsProductTraits::ExtractType ActualLhsType; - typedef Map, Aligned> MappedRhs; - static void run(const Lhs& lhs, Rhs& rhs) - { - ActualLhsType actualLhs = LhsProductTraits::extract(lhs); - - // FIXME find a way to allow an inner stride if packet_traits::size==1 - - bool useRhsDirectly = Rhs::InnerStrideAtCompileTime==1 || rhs.innerStride()==1; - - ei_declare_aligned_stack_constructed_variable(RhsScalar,actualRhs,rhs.size(), - (useRhsDirectly ? rhs.data() : 0)); - - if(!useRhsDirectly) - MappedRhs(actualRhs,rhs.size()) = rhs; - - triangular_solve_vector - ::run(actualLhs.cols(), actualLhs.data(), actualLhs.outerStride(), actualRhs); - - if(!useRhsDirectly) - rhs = MappedRhs(actualRhs, rhs.size()); - } -}; - -// the rhs is a matrix -template -struct triangular_solver_selector -{ - typedef typename Rhs::Scalar Scalar; - typedef typename Rhs::Index Index; - typedef blas_traits LhsProductTraits; - typedef typename LhsProductTraits::DirectLinearAccessType ActualLhsType; - - static void run(const Lhs& lhs, Rhs& rhs) - { - typename internal::add_const_on_value_type::type actualLhs = LhsProductTraits::extract(lhs); - - const Index size = lhs.rows(); - const Index othersize = Side==OnTheLeft? rhs.cols() : rhs.rows(); - - typedef internal::gemm_blocking_space<(Rhs::Flags&RowMajorBit) ? RowMajor : ColMajor,Scalar,Scalar, - Rhs::MaxRowsAtCompileTime, Rhs::MaxColsAtCompileTime, Lhs::MaxRowsAtCompileTime,4> BlockingType; - - BlockingType blocking(rhs.rows(), rhs.cols(), size); - - triangular_solve_matrix - ::run(size, othersize, &actualLhs.coeffRef(0,0), actualLhs.outerStride(), &rhs.coeffRef(0,0), rhs.outerStride(), blocking); - } -}; - -/*************************************************************************** -* meta-unrolling implementation -***************************************************************************/ - -template -struct triangular_solver_unroller; - -template -struct triangular_solver_unroller { - enum { - IsLower = ((Mode&Lower)==Lower), - I = IsLower ? Index : Size - Index - 1, - S = IsLower ? 0 : I+1 - }; - static void run(const Lhs& lhs, Rhs& rhs) - { - if (Index>0) - rhs.coeffRef(I) -= lhs.row(I).template segment(S).transpose() - .cwiseProduct(rhs.template segment(S)).sum(); - - if(!(Mode & UnitDiag)) - rhs.coeffRef(I) /= lhs.coeff(I,I); - - triangular_solver_unroller::run(lhs,rhs); - } -}; - -template -struct triangular_solver_unroller { - static void run(const Lhs&, Rhs&) {} -}; - -template -struct triangular_solver_selector { - static void run(const Lhs& lhs, Rhs& rhs) - { triangular_solver_unroller::run(lhs,rhs); } -}; - -template -struct triangular_solver_selector { - static void run(const Lhs& lhs, Rhs& rhs) - { - Transpose trLhs(lhs); - Transpose trRhs(rhs); - - triangular_solver_unroller,Transpose, - ((Mode&Upper)==Upper ? Lower : Upper) | (Mode&UnitDiag), - 0,Rhs::SizeAtCompileTime>::run(trLhs,trRhs); - } -}; - -} // end namespace internal - -/*************************************************************************** -* TriangularView methods -***************************************************************************/ - -/** "in-place" version of TriangularView::solve() where the result is written in \a other - * - * \warning The parameter is only marked 'const' to make the C++ compiler accept a temporary expression here. - * This function will const_cast it, so constness isn't honored here. - * - * See TriangularView:solve() for the details. - */ -template -template -void TriangularView::solveInPlace(const MatrixBase& _other) const -{ - OtherDerived& other = _other.const_cast_derived(); - eigen_assert( cols() == rows() && ((Side==OnTheLeft && cols() == other.rows()) || (Side==OnTheRight && cols() == other.cols())) ); - eigen_assert((!(Mode & ZeroDiag)) && bool(Mode & (Upper|Lower))); - - enum { copy = internal::traits::Flags & RowMajorBit && OtherDerived::IsVectorAtCompileTime }; - typedef typename internal::conditional::type, OtherDerived&>::type OtherCopy; - OtherCopy otherCopy(other); - - internal::triangular_solver_selector::type, - Side, Mode>::run(nestedExpression(), otherCopy); - - if (copy) - other = otherCopy; -} - -/** \returns the product of the inverse of \c *this with \a other, \a *this being triangular. - * - * This function computes the inverse-matrix matrix product inverse(\c *this) * \a other if - * \a Side==OnTheLeft (the default), or the right-inverse-multiply \a other * inverse(\c *this) if - * \a Side==OnTheRight. - * - * The matrix \c *this must be triangular and invertible (i.e., all the coefficients of the - * diagonal must be non zero). It works as a forward (resp. backward) substitution if \c *this - * is an upper (resp. lower) triangular matrix. - * - * Example: \include MatrixBase_marked.cpp - * Output: \verbinclude MatrixBase_marked.out - * - * This function returns an expression of the inverse-multiply and can works in-place if it is assigned - * to the same matrix or vector \a other. - * - * For users coming from BLAS, this function (and more specifically solveInPlace()) offer - * all the operations supported by the \c *TRSV and \c *TRSM BLAS routines. - * - * \sa TriangularView::solveInPlace() - */ -template -template -const internal::triangular_solve_retval,Other> -TriangularView::solve(const MatrixBase& other) const -{ - return internal::triangular_solve_retval(*this, other.derived()); -} - -namespace internal { - - -template -struct traits > -{ - typedef typename internal::plain_matrix_type_column_major::type ReturnType; -}; - -template struct triangular_solve_retval - : public ReturnByValue > -{ - typedef typename remove_all::type RhsNestedCleaned; - typedef ReturnByValue Base; - typedef typename Base::Index Index; - - triangular_solve_retval(const TriangularType& tri, const Rhs& rhs) - : m_triangularMatrix(tri), m_rhs(rhs) - {} - - inline Index rows() const { return m_rhs.rows(); } - inline Index cols() const { return m_rhs.cols(); } - - template inline void evalTo(Dest& dst) const - { - if(!(is_same::value && extract_data(dst) == extract_data(m_rhs))) - dst = m_rhs; - m_triangularMatrix.template solveInPlace(dst); - } - - protected: - const TriangularType& m_triangularMatrix; - typename Rhs::Nested m_rhs; -}; - -} // namespace internal - -} // end namespace Eigen - -#endif // EIGEN_SOLVETRIANGULAR_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/StableNorm.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/StableNorm.h deleted file mode 100644 index 389d9427..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Core/StableNorm.h +++ /dev/null @@ -1,203 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2009 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_STABLENORM_H -#define EIGEN_STABLENORM_H - -namespace Eigen { - -namespace internal { - -template -inline void stable_norm_kernel(const ExpressionType& bl, Scalar& ssq, Scalar& scale, Scalar& invScale) -{ - using std::max; - Scalar maxCoeff = bl.cwiseAbs().maxCoeff(); - - if (maxCoeff>scale) - { - ssq = ssq * numext::abs2(scale/maxCoeff); - Scalar tmp = Scalar(1)/maxCoeff; - if(tmp > NumTraits::highest()) - { - invScale = NumTraits::highest(); - scale = Scalar(1)/invScale; - } - else - { - scale = maxCoeff; - invScale = tmp; - } - } - - // TODO if the maxCoeff is much much smaller than the current scale, - // then we can neglect this sub vector - if(scale>Scalar(0)) // if scale==0, then bl is 0 - ssq += (bl*invScale).squaredNorm(); -} - -template -inline typename NumTraits::Scalar>::Real -blueNorm_impl(const EigenBase& _vec) -{ - typedef typename Derived::RealScalar RealScalar; - typedef typename Derived::Index Index; - using std::pow; - using std::min; - using std::max; - using std::sqrt; - using std::abs; - const Derived& vec(_vec.derived()); - static bool initialized = false; - static RealScalar b1, b2, s1m, s2m, overfl, rbig, relerr; - if(!initialized) - { - int ibeta, it, iemin, iemax, iexp; - RealScalar eps; - // This program calculates the machine-dependent constants - // bl, b2, slm, s2m, relerr overfl - // from the "basic" machine-dependent numbers - // nbig, ibeta, it, iemin, iemax, rbig. - // The following define the basic machine-dependent constants. - // For portability, the PORT subprograms "ilmaeh" and "rlmach" - // are used. For any specific computer, each of the assignment - // statements can be replaced - ibeta = std::numeric_limits::radix; // base for floating-point numbers - it = std::numeric_limits::digits; // number of base-beta digits in mantissa - iemin = std::numeric_limits::min_exponent; // minimum exponent - iemax = std::numeric_limits::max_exponent; // maximum exponent - rbig = (std::numeric_limits::max)(); // largest floating-point number - - iexp = -((1-iemin)/2); - b1 = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp))); // lower boundary of midrange - iexp = (iemax + 1 - it)/2; - b2 = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp))); // upper boundary of midrange - - iexp = (2-iemin)/2; - s1m = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp))); // scaling factor for lower range - iexp = - ((iemax+it)/2); - s2m = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp))); // scaling factor for upper range - - overfl = rbig*s2m; // overflow boundary for abig - eps = RealScalar(pow(double(ibeta), 1-it)); - relerr = sqrt(eps); // tolerance for neglecting asml - initialized = true; - } - Index n = vec.size(); - RealScalar ab2 = b2 / RealScalar(n); - RealScalar asml = RealScalar(0); - RealScalar amed = RealScalar(0); - RealScalar abig = RealScalar(0); - for(typename Derived::InnerIterator it(vec, 0); it; ++it) - { - RealScalar ax = abs(it.value()); - if(ax > ab2) abig += numext::abs2(ax*s2m); - else if(ax < b1) asml += numext::abs2(ax*s1m); - else amed += numext::abs2(ax); - } - if(abig > RealScalar(0)) - { - abig = sqrt(abig); - if(abig > overfl) - { - return rbig; - } - if(amed > RealScalar(0)) - { - abig = abig/s2m; - amed = sqrt(amed); - } - else - return abig/s2m; - } - else if(asml > RealScalar(0)) - { - if (amed > RealScalar(0)) - { - abig = sqrt(amed); - amed = sqrt(asml) / s1m; - } - else - return sqrt(asml)/s1m; - } - else - return sqrt(amed); - asml = (min)(abig, amed); - abig = (max)(abig, amed); - if(asml <= abig*relerr) - return abig; - else - return abig * sqrt(RealScalar(1) + numext::abs2(asml/abig)); -} - -} // end namespace internal - -/** \returns the \em l2 norm of \c *this avoiding underflow and overflow. - * This version use a blockwise two passes algorithm: - * 1 - find the absolute largest coefficient \c s - * 2 - compute \f$ s \Vert \frac{*this}{s} \Vert \f$ in a standard way - * - * For architecture/scalar types supporting vectorization, this version - * is faster than blueNorm(). Otherwise the blueNorm() is much faster. - * - * \sa norm(), blueNorm(), hypotNorm() - */ -template -inline typename NumTraits::Scalar>::Real -MatrixBase::stableNorm() const -{ - using std::min; - using std::sqrt; - const Index blockSize = 4096; - RealScalar scale(0); - RealScalar invScale(1); - RealScalar ssq(0); // sum of square - enum { - Alignment = (int(Flags)&DirectAccessBit) || (int(Flags)&AlignedBit) ? 1 : 0 - }; - Index n = size(); - Index bi = internal::first_aligned(derived()); - if (bi>0) - internal::stable_norm_kernel(this->head(bi), ssq, scale, invScale); - for (; bisegment(bi,(min)(blockSize, n - bi)).template forceAlignedAccessIf(), ssq, scale, invScale); - return scale * sqrt(ssq); -} - -/** \returns the \em l2 norm of \c *this using the Blue's algorithm. - * A Portable Fortran Program to Find the Euclidean Norm of a Vector, - * ACM TOMS, Vol 4, Issue 1, 1978. - * - * For architecture/scalar types without vectorization, this version - * is much faster than stableNorm(). Otherwise the stableNorm() is faster. - * - * \sa norm(), stableNorm(), hypotNorm() - */ -template -inline typename NumTraits::Scalar>::Real -MatrixBase::blueNorm() const -{ - return internal::blueNorm_impl(*this); -} - -/** \returns the \em l2 norm of \c *this avoiding undeflow and overflow. - * This version use a concatenation of hypot() calls, and it is very slow. - * - * \sa norm(), stableNorm() - */ -template -inline typename NumTraits::Scalar>::Real -MatrixBase::hypotNorm() const -{ - return this->cwiseAbs().redux(internal::scalar_hypot_op()); -} - -} // end namespace Eigen - -#endif // EIGEN_STABLENORM_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/Stride.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/Stride.h deleted file mode 100644 index 1e3f5fe9..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Core/Stride.h +++ /dev/null @@ -1,108 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2010 Benoit Jacob -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_STRIDE_H -#define EIGEN_STRIDE_H - -namespace Eigen { - -/** \class Stride - * \ingroup Core_Module - * - * \brief Holds strides information for Map - * - * This class holds the strides information for mapping arrays with strides with class Map. - * - * It holds two values: the inner stride and the outer stride. - * - * The inner stride is the pointer increment between two consecutive entries within a given row of a - * row-major matrix or within a given column of a column-major matrix. - * - * The outer stride is the pointer increment between two consecutive rows of a row-major matrix or - * between two consecutive columns of a column-major matrix. - * - * These two values can be passed either at compile-time as template parameters, or at runtime as - * arguments to the constructor. - * - * Indeed, this class takes two template parameters: - * \param _OuterStrideAtCompileTime the outer stride, or Dynamic if you want to specify it at runtime. - * \param _InnerStrideAtCompileTime the inner stride, or Dynamic if you want to specify it at runtime. - * - * Here is an example: - * \include Map_general_stride.cpp - * Output: \verbinclude Map_general_stride.out - * - * \sa class InnerStride, class OuterStride, \ref TopicStorageOrders - */ -template -class Stride -{ - public: - typedef DenseIndex Index; - enum { - InnerStrideAtCompileTime = _InnerStrideAtCompileTime, - OuterStrideAtCompileTime = _OuterStrideAtCompileTime - }; - - /** Default constructor, for use when strides are fixed at compile time */ - Stride() - : m_outer(OuterStrideAtCompileTime), m_inner(InnerStrideAtCompileTime) - { - eigen_assert(InnerStrideAtCompileTime != Dynamic && OuterStrideAtCompileTime != Dynamic); - } - - /** Constructor allowing to pass the strides at runtime */ - Stride(Index outerStride, Index innerStride) - : m_outer(outerStride), m_inner(innerStride) - { - eigen_assert(innerStride>=0 && outerStride>=0); - } - - /** Copy constructor */ - Stride(const Stride& other) - : m_outer(other.outer()), m_inner(other.inner()) - {} - - /** \returns the outer stride */ - inline Index outer() const { return m_outer.value(); } - /** \returns the inner stride */ - inline Index inner() const { return m_inner.value(); } - - protected: - internal::variable_if_dynamic m_outer; - internal::variable_if_dynamic m_inner; -}; - -/** \brief Convenience specialization of Stride to specify only an inner stride - * See class Map for some examples */ -template -class InnerStride : public Stride<0, Value> -{ - typedef Stride<0, Value> Base; - public: - typedef DenseIndex Index; - InnerStride() : Base() {} - InnerStride(Index v) : Base(0, v) {} -}; - -/** \brief Convenience specialization of Stride to specify only an outer stride - * See class Map for some examples */ -template -class OuterStride : public Stride -{ - typedef Stride Base; - public: - typedef DenseIndex Index; - OuterStride() : Base() {} - OuterStride(Index v) : Base(v,0) {} -}; - -} // end namespace Eigen - -#endif // EIGEN_STRIDE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/Swap.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/Swap.h deleted file mode 100644 index bf58bd59..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Core/Swap.h +++ /dev/null @@ -1,126 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2006-2008 Benoit Jacob -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_SWAP_H -#define EIGEN_SWAP_H - -namespace Eigen { - -/** \class SwapWrapper - * \ingroup Core_Module - * - * \internal - * - * \brief Internal helper class for swapping two expressions - */ -namespace internal { -template -struct traits > : traits {}; -} - -template class SwapWrapper - : public internal::dense_xpr_base >::type -{ - public: - - typedef typename internal::dense_xpr_base::type Base; - EIGEN_DENSE_PUBLIC_INTERFACE(SwapWrapper) - typedef typename internal::packet_traits::type Packet; - - inline SwapWrapper(ExpressionType& xpr) : m_expression(xpr) {} - - inline Index rows() const { return m_expression.rows(); } - inline Index cols() const { return m_expression.cols(); } - inline Index outerStride() const { return m_expression.outerStride(); } - inline Index innerStride() const { return m_expression.innerStride(); } - - typedef typename internal::conditional< - internal::is_lvalue::value, - Scalar, - const Scalar - >::type ScalarWithConstIfNotLvalue; - - inline ScalarWithConstIfNotLvalue* data() { return m_expression.data(); } - inline const Scalar* data() const { return m_expression.data(); } - - inline Scalar& coeffRef(Index rowId, Index colId) - { - return m_expression.const_cast_derived().coeffRef(rowId, colId); - } - - inline Scalar& coeffRef(Index index) - { - return m_expression.const_cast_derived().coeffRef(index); - } - - inline Scalar& coeffRef(Index rowId, Index colId) const - { - return m_expression.coeffRef(rowId, colId); - } - - inline Scalar& coeffRef(Index index) const - { - return m_expression.coeffRef(index); - } - - template - void copyCoeff(Index rowId, Index colId, const DenseBase& other) - { - OtherDerived& _other = other.const_cast_derived(); - eigen_internal_assert(rowId >= 0 && rowId < rows() - && colId >= 0 && colId < cols()); - Scalar tmp = m_expression.coeff(rowId, colId); - m_expression.coeffRef(rowId, colId) = _other.coeff(rowId, colId); - _other.coeffRef(rowId, colId) = tmp; - } - - template - void copyCoeff(Index index, const DenseBase& other) - { - OtherDerived& _other = other.const_cast_derived(); - eigen_internal_assert(index >= 0 && index < m_expression.size()); - Scalar tmp = m_expression.coeff(index); - m_expression.coeffRef(index) = _other.coeff(index); - _other.coeffRef(index) = tmp; - } - - template - void copyPacket(Index rowId, Index colId, const DenseBase& other) - { - OtherDerived& _other = other.const_cast_derived(); - eigen_internal_assert(rowId >= 0 && rowId < rows() - && colId >= 0 && colId < cols()); - Packet tmp = m_expression.template packet(rowId, colId); - m_expression.template writePacket(rowId, colId, - _other.template packet(rowId, colId) - ); - _other.template writePacket(rowId, colId, tmp); - } - - template - void copyPacket(Index index, const DenseBase& other) - { - OtherDerived& _other = other.const_cast_derived(); - eigen_internal_assert(index >= 0 && index < m_expression.size()); - Packet tmp = m_expression.template packet(index); - m_expression.template writePacket(index, - _other.template packet(index) - ); - _other.template writePacket(index, tmp); - } - - ExpressionType& expression() const { return m_expression; } - - protected: - ExpressionType& m_expression; -}; - -} // end namespace Eigen - -#endif // EIGEN_SWAP_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/Transpose.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/Transpose.h deleted file mode 100644 index 22096ea2..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Core/Transpose.h +++ /dev/null @@ -1,419 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2006-2008 Benoit Jacob -// Copyright (C) 2009-2010 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_TRANSPOSE_H -#define EIGEN_TRANSPOSE_H - -namespace Eigen { - -/** \class Transpose - * \ingroup Core_Module - * - * \brief Expression of the transpose of a matrix - * - * \param MatrixType the type of the object of which we are taking the transpose - * - * This class represents an expression of the transpose of a matrix. - * It is the return type of MatrixBase::transpose() and MatrixBase::adjoint() - * and most of the time this is the only way it is used. - * - * \sa MatrixBase::transpose(), MatrixBase::adjoint() - */ - -namespace internal { -template -struct traits > : traits -{ - typedef typename MatrixType::Scalar Scalar; - typedef typename nested::type MatrixTypeNested; - typedef typename remove_reference::type MatrixTypeNestedPlain; - typedef typename traits::StorageKind StorageKind; - typedef typename traits::XprKind XprKind; - enum { - RowsAtCompileTime = MatrixType::ColsAtCompileTime, - ColsAtCompileTime = MatrixType::RowsAtCompileTime, - MaxRowsAtCompileTime = MatrixType::MaxColsAtCompileTime, - MaxColsAtCompileTime = MatrixType::MaxRowsAtCompileTime, - FlagsLvalueBit = is_lvalue::value ? LvalueBit : 0, - Flags0 = MatrixTypeNestedPlain::Flags & ~(LvalueBit | NestByRefBit), - Flags1 = Flags0 | FlagsLvalueBit, - Flags = Flags1 ^ RowMajorBit, - CoeffReadCost = MatrixTypeNestedPlain::CoeffReadCost, - InnerStrideAtCompileTime = inner_stride_at_compile_time::ret, - OuterStrideAtCompileTime = outer_stride_at_compile_time::ret - }; -}; -} - -template class TransposeImpl; - -template class Transpose - : public TransposeImpl::StorageKind> -{ - public: - - typedef typename TransposeImpl::StorageKind>::Base Base; - EIGEN_GENERIC_PUBLIC_INTERFACE(Transpose) - - inline Transpose(MatrixType& a_matrix) : m_matrix(a_matrix) {} - - EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Transpose) - - inline Index rows() const { return m_matrix.cols(); } - inline Index cols() const { return m_matrix.rows(); } - - /** \returns the nested expression */ - const typename internal::remove_all::type& - nestedExpression() const { return m_matrix; } - - /** \returns the nested expression */ - typename internal::remove_all::type& - nestedExpression() { return m_matrix.const_cast_derived(); } - - protected: - typename MatrixType::Nested m_matrix; -}; - -namespace internal { - -template::ret> -struct TransposeImpl_base -{ - typedef typename dense_xpr_base >::type type; -}; - -template -struct TransposeImpl_base -{ - typedef typename dense_xpr_base >::type type; -}; - -} // end namespace internal - -template class TransposeImpl - : public internal::TransposeImpl_base::type -{ - public: - - typedef typename internal::TransposeImpl_base::type Base; - EIGEN_DENSE_PUBLIC_INTERFACE(Transpose) - EIGEN_INHERIT_ASSIGNMENT_OPERATORS(TransposeImpl) - - inline Index innerStride() const { return derived().nestedExpression().innerStride(); } - inline Index outerStride() const { return derived().nestedExpression().outerStride(); } - - typedef typename internal::conditional< - internal::is_lvalue::value, - Scalar, - const Scalar - >::type ScalarWithConstIfNotLvalue; - - inline ScalarWithConstIfNotLvalue* data() { return derived().nestedExpression().data(); } - inline const Scalar* data() const { return derived().nestedExpression().data(); } - - inline ScalarWithConstIfNotLvalue& coeffRef(Index rowId, Index colId) - { - EIGEN_STATIC_ASSERT_LVALUE(MatrixType) - return derived().nestedExpression().const_cast_derived().coeffRef(colId, rowId); - } - - inline ScalarWithConstIfNotLvalue& coeffRef(Index index) - { - EIGEN_STATIC_ASSERT_LVALUE(MatrixType) - return derived().nestedExpression().const_cast_derived().coeffRef(index); - } - - inline const Scalar& coeffRef(Index rowId, Index colId) const - { - return derived().nestedExpression().coeffRef(colId, rowId); - } - - inline const Scalar& coeffRef(Index index) const - { - return derived().nestedExpression().coeffRef(index); - } - - inline CoeffReturnType coeff(Index rowId, Index colId) const - { - return derived().nestedExpression().coeff(colId, rowId); - } - - inline CoeffReturnType coeff(Index index) const - { - return derived().nestedExpression().coeff(index); - } - - template - inline const PacketScalar packet(Index rowId, Index colId) const - { - return derived().nestedExpression().template packet(colId, rowId); - } - - template - inline void writePacket(Index rowId, Index colId, const PacketScalar& x) - { - derived().nestedExpression().const_cast_derived().template writePacket(colId, rowId, x); - } - - template - inline const PacketScalar packet(Index index) const - { - return derived().nestedExpression().template packet(index); - } - - template - inline void writePacket(Index index, const PacketScalar& x) - { - derived().nestedExpression().const_cast_derived().template writePacket(index, x); - } -}; - -/** \returns an expression of the transpose of *this. - * - * Example: \include MatrixBase_transpose.cpp - * Output: \verbinclude MatrixBase_transpose.out - * - * \warning If you want to replace a matrix by its own transpose, do \b NOT do this: - * \code - * m = m.transpose(); // bug!!! caused by aliasing effect - * \endcode - * Instead, use the transposeInPlace() method: - * \code - * m.transposeInPlace(); - * \endcode - * which gives Eigen good opportunities for optimization, or alternatively you can also do: - * \code - * m = m.transpose().eval(); - * \endcode - * - * \sa transposeInPlace(), adjoint() */ -template -inline Transpose -DenseBase::transpose() -{ - return derived(); -} - -/** This is the const version of transpose(). - * - * Make sure you read the warning for transpose() ! - * - * \sa transposeInPlace(), adjoint() */ -template -inline typename DenseBase::ConstTransposeReturnType -DenseBase::transpose() const -{ - return ConstTransposeReturnType(derived()); -} - -/** \returns an expression of the adjoint (i.e. conjugate transpose) of *this. - * - * Example: \include MatrixBase_adjoint.cpp - * Output: \verbinclude MatrixBase_adjoint.out - * - * \warning If you want to replace a matrix by its own adjoint, do \b NOT do this: - * \code - * m = m.adjoint(); // bug!!! caused by aliasing effect - * \endcode - * Instead, use the adjointInPlace() method: - * \code - * m.adjointInPlace(); - * \endcode - * which gives Eigen good opportunities for optimization, or alternatively you can also do: - * \code - * m = m.adjoint().eval(); - * \endcode - * - * \sa adjointInPlace(), transpose(), conjugate(), class Transpose, class internal::scalar_conjugate_op */ -template -inline const typename MatrixBase::AdjointReturnType -MatrixBase::adjoint() const -{ - return this->transpose(); // in the complex case, the .conjugate() is be implicit here - // due to implicit conversion to return type -} - -/*************************************************************************** -* "in place" transpose implementation -***************************************************************************/ - -namespace internal { - -template -struct inplace_transpose_selector; - -template -struct inplace_transpose_selector { // square matrix - static void run(MatrixType& m) { - m.matrix().template triangularView().swap(m.matrix().transpose()); - } -}; - -template -struct inplace_transpose_selector { // non square matrix - static void run(MatrixType& m) { - if (m.rows()==m.cols()) - m.matrix().template triangularView().swap(m.matrix().transpose()); - else - m = m.transpose().eval(); - } -}; - -} // end namespace internal - -/** This is the "in place" version of transpose(): it replaces \c *this by its own transpose. - * Thus, doing - * \code - * m.transposeInPlace(); - * \endcode - * has the same effect on m as doing - * \code - * m = m.transpose().eval(); - * \endcode - * and is faster and also safer because in the latter line of code, forgetting the eval() results - * in a bug caused by \ref TopicAliasing "aliasing". - * - * Notice however that this method is only useful if you want to replace a matrix by its own transpose. - * If you just need the transpose of a matrix, use transpose(). - * - * \note if the matrix is not square, then \c *this must be a resizable matrix. - * This excludes (non-square) fixed-size matrices, block-expressions and maps. - * - * \sa transpose(), adjoint(), adjointInPlace() */ -template -inline void DenseBase::transposeInPlace() -{ - eigen_assert((rows() == cols() || (RowsAtCompileTime == Dynamic && ColsAtCompileTime == Dynamic)) - && "transposeInPlace() called on a non-square non-resizable matrix"); - internal::inplace_transpose_selector::run(derived()); -} - -/*************************************************************************** -* "in place" adjoint implementation -***************************************************************************/ - -/** This is the "in place" version of adjoint(): it replaces \c *this by its own transpose. - * Thus, doing - * \code - * m.adjointInPlace(); - * \endcode - * has the same effect on m as doing - * \code - * m = m.adjoint().eval(); - * \endcode - * and is faster and also safer because in the latter line of code, forgetting the eval() results - * in a bug caused by aliasing. - * - * Notice however that this method is only useful if you want to replace a matrix by its own adjoint. - * If you just need the adjoint of a matrix, use adjoint(). - * - * \note if the matrix is not square, then \c *this must be a resizable matrix. - * This excludes (non-square) fixed-size matrices, block-expressions and maps. - * - * \sa transpose(), adjoint(), transposeInPlace() */ -template -inline void MatrixBase::adjointInPlace() -{ - derived() = adjoint().eval(); -} - -#ifndef EIGEN_NO_DEBUG - -// The following is to detect aliasing problems in most common cases. - -namespace internal { - -template -struct blas_traits > - : blas_traits -{ - typedef SelfCwiseBinaryOp XprType; - static inline const XprType extract(const XprType& x) { return x; } -}; - -template -struct check_transpose_aliasing_compile_time_selector -{ - enum { ret = bool(blas_traits::IsTransposed) != DestIsTransposed }; -}; - -template -struct check_transpose_aliasing_compile_time_selector > -{ - enum { ret = bool(blas_traits::IsTransposed) != DestIsTransposed - || bool(blas_traits::IsTransposed) != DestIsTransposed - }; -}; - -template -struct check_transpose_aliasing_run_time_selector -{ - static bool run(const Scalar* dest, const OtherDerived& src) - { - return (bool(blas_traits::IsTransposed) != DestIsTransposed) && (dest!=0 && dest==(const Scalar*)extract_data(src)); - } -}; - -template -struct check_transpose_aliasing_run_time_selector > -{ - static bool run(const Scalar* dest, const CwiseBinaryOp& src) - { - return ((blas_traits::IsTransposed != DestIsTransposed) && (dest!=0 && dest==(const Scalar*)extract_data(src.lhs()))) - || ((blas_traits::IsTransposed != DestIsTransposed) && (dest!=0 && dest==(const Scalar*)extract_data(src.rhs()))); - } -}; - -// the following selector, checkTransposeAliasing_impl, based on MightHaveTransposeAliasing, -// is because when the condition controlling the assert is known at compile time, ICC emits a warning. -// This is actually a good warning: in expressions that don't have any transposing, the condition is -// known at compile time to be false, and using that, we can avoid generating the code of the assert again -// and again for all these expressions that don't need it. - -template::IsTransposed,OtherDerived>::ret - > -struct checkTransposeAliasing_impl -{ - static void run(const Derived& dst, const OtherDerived& other) - { - eigen_assert((!check_transpose_aliasing_run_time_selector - ::IsTransposed,OtherDerived> - ::run(extract_data(dst), other)) - && "aliasing detected during transposition, use transposeInPlace() " - "or evaluate the rhs into a temporary using .eval()"); - - } -}; - -template -struct checkTransposeAliasing_impl -{ - static void run(const Derived&, const OtherDerived&) - { - } -}; - -} // end namespace internal - -template -template -void DenseBase::checkTransposeAliasing(const OtherDerived& other) const -{ - internal::checkTransposeAliasing_impl::run(derived(), other); -} -#endif - -} // end namespace Eigen - -#endif // EIGEN_TRANSPOSE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/Transpositions.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/Transpositions.h deleted file mode 100644 index e4ba0756..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Core/Transpositions.h +++ /dev/null @@ -1,436 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2010-2011 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_TRANSPOSITIONS_H -#define EIGEN_TRANSPOSITIONS_H - -namespace Eigen { - -/** \class Transpositions - * \ingroup Core_Module - * - * \brief Represents a sequence of transpositions (row/column interchange) - * - * \param SizeAtCompileTime the number of transpositions, or Dynamic - * \param MaxSizeAtCompileTime the maximum number of transpositions, or Dynamic. This optional parameter defaults to SizeAtCompileTime. Most of the time, you should not have to specify it. - * - * This class represents a permutation transformation as a sequence of \em n transpositions - * \f$[T_{n-1} \ldots T_{i} \ldots T_{0}]\f$. It is internally stored as a vector of integers \c indices. - * Each transposition \f$ T_{i} \f$ applied on the left of a matrix (\f$ T_{i} M\f$) interchanges - * the rows \c i and \c indices[i] of the matrix \c M. - * A transposition applied on the right (e.g., \f$ M T_{i}\f$) yields a column interchange. - * - * Compared to the class PermutationMatrix, such a sequence of transpositions is what is - * computed during a decomposition with pivoting, and it is faster when applying the permutation in-place. - * - * To apply a sequence of transpositions to a matrix, simply use the operator * as in the following example: - * \code - * Transpositions tr; - * MatrixXf mat; - * mat = tr * mat; - * \endcode - * In this example, we detect that the matrix appears on both side, and so the transpositions - * are applied in-place without any temporary or extra copy. - * - * \sa class PermutationMatrix - */ - -namespace internal { -template struct transposition_matrix_product_retval; -} - -template -class TranspositionsBase -{ - typedef internal::traits Traits; - - public: - - typedef typename Traits::IndicesType IndicesType; - typedef typename IndicesType::Scalar Index; - - Derived& derived() { return *static_cast(this); } - const Derived& derived() const { return *static_cast(this); } - - /** Copies the \a other transpositions into \c *this */ - template - Derived& operator=(const TranspositionsBase& other) - { - indices() = other.indices(); - return derived(); - } - - #ifndef EIGEN_PARSED_BY_DOXYGEN - /** This is a special case of the templated operator=. Its purpose is to - * prevent a default operator= from hiding the templated operator=. - */ - Derived& operator=(const TranspositionsBase& other) - { - indices() = other.indices(); - return derived(); - } - #endif - - /** \returns the number of transpositions */ - inline Index size() const { return indices().size(); } - - /** Direct access to the underlying index vector */ - inline const Index& coeff(Index i) const { return indices().coeff(i); } - /** Direct access to the underlying index vector */ - inline Index& coeffRef(Index i) { return indices().coeffRef(i); } - /** Direct access to the underlying index vector */ - inline const Index& operator()(Index i) const { return indices()(i); } - /** Direct access to the underlying index vector */ - inline Index& operator()(Index i) { return indices()(i); } - /** Direct access to the underlying index vector */ - inline const Index& operator[](Index i) const { return indices()(i); } - /** Direct access to the underlying index vector */ - inline Index& operator[](Index i) { return indices()(i); } - - /** const version of indices(). */ - const IndicesType& indices() const { return derived().indices(); } - /** \returns a reference to the stored array representing the transpositions. */ - IndicesType& indices() { return derived().indices(); } - - /** Resizes to given size. */ - inline void resize(int newSize) - { - indices().resize(newSize); - } - - /** Sets \c *this to represents an identity transformation */ - void setIdentity() - { - for(int i = 0; i < indices().size(); ++i) - coeffRef(i) = i; - } - - // FIXME: do we want such methods ? - // might be usefull when the target matrix expression is complex, e.g.: - // object.matrix().block(..,..,..,..) = trans * object.matrix().block(..,..,..,..); - /* - template - void applyForwardToRows(MatrixType& mat) const - { - for(Index k=0 ; k - void applyBackwardToRows(MatrixType& mat) const - { - for(Index k=size()-1 ; k>=0 ; --k) - if(m_indices(k)!=k) - mat.row(k).swap(mat.row(m_indices(k))); - } - */ - - /** \returns the inverse transformation */ - inline Transpose inverse() const - { return Transpose(derived()); } - - /** \returns the tranpose transformation */ - inline Transpose transpose() const - { return Transpose(derived()); } - - protected: -}; - -namespace internal { -template -struct traits > -{ - typedef IndexType Index; - typedef Matrix IndicesType; -}; -} - -template -class Transpositions : public TranspositionsBase > -{ - typedef internal::traits Traits; - public: - - typedef TranspositionsBase Base; - typedef typename Traits::IndicesType IndicesType; - typedef typename IndicesType::Scalar Index; - - inline Transpositions() {} - - /** Copy constructor. */ - template - inline Transpositions(const TranspositionsBase& other) - : m_indices(other.indices()) {} - - #ifndef EIGEN_PARSED_BY_DOXYGEN - /** Standard copy constructor. Defined only to prevent a default copy constructor - * from hiding the other templated constructor */ - inline Transpositions(const Transpositions& other) : m_indices(other.indices()) {} - #endif - - /** Generic constructor from expression of the transposition indices. */ - template - explicit inline Transpositions(const MatrixBase& a_indices) : m_indices(a_indices) - {} - - /** Copies the \a other transpositions into \c *this */ - template - Transpositions& operator=(const TranspositionsBase& other) - { - return Base::operator=(other); - } - - #ifndef EIGEN_PARSED_BY_DOXYGEN - /** This is a special case of the templated operator=. Its purpose is to - * prevent a default operator= from hiding the templated operator=. - */ - Transpositions& operator=(const Transpositions& other) - { - m_indices = other.m_indices; - return *this; - } - #endif - - /** Constructs an uninitialized permutation matrix of given size. - */ - inline Transpositions(Index size) : m_indices(size) - {} - - /** const version of indices(). */ - const IndicesType& indices() const { return m_indices; } - /** \returns a reference to the stored array representing the transpositions. */ - IndicesType& indices() { return m_indices; } - - protected: - - IndicesType m_indices; -}; - - -namespace internal { -template -struct traits,_PacketAccess> > -{ - typedef IndexType Index; - typedef Map, _PacketAccess> IndicesType; -}; -} - -template -class Map,PacketAccess> - : public TranspositionsBase,PacketAccess> > -{ - typedef internal::traits Traits; - public: - - typedef TranspositionsBase Base; - typedef typename Traits::IndicesType IndicesType; - typedef typename IndicesType::Scalar Index; - - inline Map(const Index* indicesPtr) - : m_indices(indicesPtr) - {} - - inline Map(const Index* indicesPtr, Index size) - : m_indices(indicesPtr,size) - {} - - /** Copies the \a other transpositions into \c *this */ - template - Map& operator=(const TranspositionsBase& other) - { - return Base::operator=(other); - } - - #ifndef EIGEN_PARSED_BY_DOXYGEN - /** This is a special case of the templated operator=. Its purpose is to - * prevent a default operator= from hiding the templated operator=. - */ - Map& operator=(const Map& other) - { - m_indices = other.m_indices; - return *this; - } - #endif - - /** const version of indices(). */ - const IndicesType& indices() const { return m_indices; } - - /** \returns a reference to the stored array representing the transpositions. */ - IndicesType& indices() { return m_indices; } - - protected: - - IndicesType m_indices; -}; - -namespace internal { -template -struct traits > -{ - typedef typename _IndicesType::Scalar Index; - typedef _IndicesType IndicesType; -}; -} - -template -class TranspositionsWrapper - : public TranspositionsBase > -{ - typedef internal::traits Traits; - public: - - typedef TranspositionsBase Base; - typedef typename Traits::IndicesType IndicesType; - typedef typename IndicesType::Scalar Index; - - inline TranspositionsWrapper(IndicesType& a_indices) - : m_indices(a_indices) - {} - - /** Copies the \a other transpositions into \c *this */ - template - TranspositionsWrapper& operator=(const TranspositionsBase& other) - { - return Base::operator=(other); - } - - #ifndef EIGEN_PARSED_BY_DOXYGEN - /** This is a special case of the templated operator=. Its purpose is to - * prevent a default operator= from hiding the templated operator=. - */ - TranspositionsWrapper& operator=(const TranspositionsWrapper& other) - { - m_indices = other.m_indices; - return *this; - } - #endif - - /** const version of indices(). */ - const IndicesType& indices() const { return m_indices; } - - /** \returns a reference to the stored array representing the transpositions. */ - IndicesType& indices() { return m_indices; } - - protected: - - const typename IndicesType::Nested m_indices; -}; - -/** \returns the \a matrix with the \a transpositions applied to the columns. - */ -template -inline const internal::transposition_matrix_product_retval -operator*(const MatrixBase& matrix, - const TranspositionsBase &transpositions) -{ - return internal::transposition_matrix_product_retval - - (transpositions.derived(), matrix.derived()); -} - -/** \returns the \a matrix with the \a transpositions applied to the rows. - */ -template -inline const internal::transposition_matrix_product_retval - -operator*(const TranspositionsBase &transpositions, - const MatrixBase& matrix) -{ - return internal::transposition_matrix_product_retval - - (transpositions.derived(), matrix.derived()); -} - -namespace internal { - -template -struct traits > -{ - typedef typename MatrixType::PlainObject ReturnType; -}; - -template -struct transposition_matrix_product_retval - : public ReturnByValue > -{ - typedef typename remove_all::type MatrixTypeNestedCleaned; - typedef typename TranspositionType::Index Index; - - transposition_matrix_product_retval(const TranspositionType& tr, const MatrixType& matrix) - : m_transpositions(tr), m_matrix(matrix) - {} - - inline int rows() const { return m_matrix.rows(); } - inline int cols() const { return m_matrix.cols(); } - - template inline void evalTo(Dest& dst) const - { - const int size = m_transpositions.size(); - Index j = 0; - - if(!(is_same::value && extract_data(dst) == extract_data(m_matrix))) - dst = m_matrix; - - for(int k=(Transposed?size-1:0) ; Transposed?k>=0:k -class Transpose > -{ - typedef TranspositionsDerived TranspositionType; - typedef typename TranspositionType::IndicesType IndicesType; - public: - - Transpose(const TranspositionType& t) : m_transpositions(t) {} - - inline int size() const { return m_transpositions.size(); } - - /** \returns the \a matrix with the inverse transpositions applied to the columns. - */ - template friend - inline const internal::transposition_matrix_product_retval - operator*(const MatrixBase& matrix, const Transpose& trt) - { - return internal::transposition_matrix_product_retval(trt.m_transpositions, matrix.derived()); - } - - /** \returns the \a matrix with the inverse transpositions applied to the rows. - */ - template - inline const internal::transposition_matrix_product_retval - operator*(const MatrixBase& matrix) const - { - return internal::transposition_matrix_product_retval(m_transpositions, matrix.derived()); - } - - protected: - const TranspositionType& m_transpositions; -}; - -} // end namespace Eigen - -#endif // EIGEN_TRANSPOSITIONS_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/TriangularMatrix.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/TriangularMatrix.h deleted file mode 100644 index 4d65392c..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Core/TriangularMatrix.h +++ /dev/null @@ -1,839 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Benoit Jacob -// Copyright (C) 2008-2009 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_TRIANGULARMATRIX_H -#define EIGEN_TRIANGULARMATRIX_H - -namespace Eigen { - -namespace internal { - -template struct triangular_solve_retval; - -} - -/** \internal - * - * \class TriangularBase - * \ingroup Core_Module - * - * \brief Base class for triangular part in a matrix - */ -template class TriangularBase : public EigenBase -{ - public: - - enum { - Mode = internal::traits::Mode, - CoeffReadCost = internal::traits::CoeffReadCost, - RowsAtCompileTime = internal::traits::RowsAtCompileTime, - ColsAtCompileTime = internal::traits::ColsAtCompileTime, - MaxRowsAtCompileTime = internal::traits::MaxRowsAtCompileTime, - MaxColsAtCompileTime = internal::traits::MaxColsAtCompileTime - }; - typedef typename internal::traits::Scalar Scalar; - typedef typename internal::traits::StorageKind StorageKind; - typedef typename internal::traits::Index Index; - typedef typename internal::traits::DenseMatrixType DenseMatrixType; - typedef DenseMatrixType DenseType; - - inline TriangularBase() { eigen_assert(!((Mode&UnitDiag) && (Mode&ZeroDiag))); } - - inline Index rows() const { return derived().rows(); } - inline Index cols() const { return derived().cols(); } - inline Index outerStride() const { return derived().outerStride(); } - inline Index innerStride() const { return derived().innerStride(); } - - inline Scalar coeff(Index row, Index col) const { return derived().coeff(row,col); } - inline Scalar& coeffRef(Index row, Index col) { return derived().coeffRef(row,col); } - - /** \see MatrixBase::copyCoeff(row,col) - */ - template - EIGEN_STRONG_INLINE void copyCoeff(Index row, Index col, Other& other) - { - derived().coeffRef(row, col) = other.coeff(row, col); - } - - inline Scalar operator()(Index row, Index col) const - { - check_coordinates(row, col); - return coeff(row,col); - } - inline Scalar& operator()(Index row, Index col) - { - check_coordinates(row, col); - return coeffRef(row,col); - } - - #ifndef EIGEN_PARSED_BY_DOXYGEN - inline const Derived& derived() const { return *static_cast(this); } - inline Derived& derived() { return *static_cast(this); } - #endif // not EIGEN_PARSED_BY_DOXYGEN - - template - void evalTo(MatrixBase &other) const; - template - void evalToLazy(MatrixBase &other) const; - - DenseMatrixType toDenseMatrix() const - { - DenseMatrixType res(rows(), cols()); - evalToLazy(res); - return res; - } - - protected: - - void check_coordinates(Index row, Index col) const - { - EIGEN_ONLY_USED_FOR_DEBUG(row); - EIGEN_ONLY_USED_FOR_DEBUG(col); - eigen_assert(col>=0 && col=0 && row=row) - || (mode==Lower && col<=row) - || ((mode==StrictlyUpper || mode==UnitUpper) && col>row) - || ((mode==StrictlyLower || mode==UnitLower) && col -struct traits > : traits -{ - typedef typename nested::type MatrixTypeNested; - typedef typename remove_reference::type MatrixTypeNestedNonRef; - typedef typename remove_all::type MatrixTypeNestedCleaned; - typedef MatrixType ExpressionType; - typedef typename MatrixType::PlainObject DenseMatrixType; - enum { - Mode = _Mode, - Flags = (MatrixTypeNestedCleaned::Flags & (HereditaryBits) & (~(PacketAccessBit | DirectAccessBit | LinearAccessBit))) | Mode, - CoeffReadCost = MatrixTypeNestedCleaned::CoeffReadCost - }; -}; -} - -template -struct TriangularProduct; - -template class TriangularView - : public TriangularBase > -{ - public: - - typedef TriangularBase Base; - typedef typename internal::traits::Scalar Scalar; - - typedef _MatrixType MatrixType; - typedef typename internal::traits::DenseMatrixType DenseMatrixType; - typedef DenseMatrixType PlainObject; - - protected: - typedef typename internal::traits::MatrixTypeNested MatrixTypeNested; - typedef typename internal::traits::MatrixTypeNestedNonRef MatrixTypeNestedNonRef; - typedef typename internal::traits::MatrixTypeNestedCleaned MatrixTypeNestedCleaned; - - typedef typename internal::remove_all::type MatrixConjugateReturnType; - - public: - using Base::evalToLazy; - - - typedef typename internal::traits::StorageKind StorageKind; - typedef typename internal::traits::Index Index; - - enum { - Mode = _Mode, - TransposeMode = (Mode & Upper ? Lower : 0) - | (Mode & Lower ? Upper : 0) - | (Mode & (UnitDiag)) - | (Mode & (ZeroDiag)) - }; - - inline TriangularView(const MatrixType& matrix) : m_matrix(matrix) - {} - - inline Index rows() const { return m_matrix.rows(); } - inline Index cols() const { return m_matrix.cols(); } - inline Index outerStride() const { return m_matrix.outerStride(); } - inline Index innerStride() const { return m_matrix.innerStride(); } - - /** \sa MatrixBase::operator+=() */ - template TriangularView& operator+=(const DenseBase& other) { return *this = m_matrix + other.derived(); } - /** \sa MatrixBase::operator-=() */ - template TriangularView& operator-=(const DenseBase& other) { return *this = m_matrix - other.derived(); } - /** \sa MatrixBase::operator*=() */ - TriangularView& operator*=(const typename internal::traits::Scalar& other) { return *this = m_matrix * other; } - /** \sa MatrixBase::operator/=() */ - TriangularView& operator/=(const typename internal::traits::Scalar& other) { return *this = m_matrix / other; } - - /** \sa MatrixBase::fill() */ - void fill(const Scalar& value) { setConstant(value); } - /** \sa MatrixBase::setConstant() */ - TriangularView& setConstant(const Scalar& value) - { return *this = MatrixType::Constant(rows(), cols(), value); } - /** \sa MatrixBase::setZero() */ - TriangularView& setZero() { return setConstant(Scalar(0)); } - /** \sa MatrixBase::setOnes() */ - TriangularView& setOnes() { return setConstant(Scalar(1)); } - - /** \sa MatrixBase::coeff() - * \warning the coordinates must fit into the referenced triangular part - */ - inline Scalar coeff(Index row, Index col) const - { - Base::check_coordinates_internal(row, col); - return m_matrix.coeff(row, col); - } - - /** \sa MatrixBase::coeffRef() - * \warning the coordinates must fit into the referenced triangular part - */ - inline Scalar& coeffRef(Index row, Index col) - { - Base::check_coordinates_internal(row, col); - return m_matrix.const_cast_derived().coeffRef(row, col); - } - - const MatrixTypeNestedCleaned& nestedExpression() const { return m_matrix; } - MatrixTypeNestedCleaned& nestedExpression() { return *const_cast(&m_matrix); } - - /** Assigns a triangular matrix to a triangular part of a dense matrix */ - template - TriangularView& operator=(const TriangularBase& other); - - template - TriangularView& operator=(const MatrixBase& other); - - TriangularView& operator=(const TriangularView& other) - { return *this = other.nestedExpression(); } - - template - void lazyAssign(const TriangularBase& other); - - template - void lazyAssign(const MatrixBase& other); - - /** \sa MatrixBase::conjugate() */ - inline TriangularView conjugate() - { return m_matrix.conjugate(); } - /** \sa MatrixBase::conjugate() const */ - inline const TriangularView conjugate() const - { return m_matrix.conjugate(); } - - /** \sa MatrixBase::adjoint() const */ - inline const TriangularView adjoint() const - { return m_matrix.adjoint(); } - - /** \sa MatrixBase::transpose() */ - inline TriangularView,TransposeMode> transpose() - { - EIGEN_STATIC_ASSERT_LVALUE(MatrixType) - return m_matrix.const_cast_derived().transpose(); - } - /** \sa MatrixBase::transpose() const */ - inline const TriangularView,TransposeMode> transpose() const - { - return m_matrix.transpose(); - } - - /** Efficient triangular matrix times vector/matrix product */ - template - TriangularProduct - operator*(const MatrixBase& rhs) const - { - return TriangularProduct - - (m_matrix, rhs.derived()); - } - - /** Efficient vector/matrix times triangular matrix product */ - template friend - TriangularProduct - operator*(const MatrixBase& lhs, const TriangularView& rhs) - { - return TriangularProduct - - (lhs.derived(),rhs.m_matrix); - } - - #ifdef EIGEN2_SUPPORT - template - struct eigen2_product_return_type - { - typedef typename TriangularView::DenseMatrixType DenseMatrixType; - typedef typename OtherDerived::PlainObject::DenseType OtherPlainObject; - typedef typename ProductReturnType::Type ProdRetType; - typedef typename ProdRetType::PlainObject type; - }; - template - const typename eigen2_product_return_type::type - operator*(const EigenBase& rhs) const - { - typename OtherDerived::PlainObject::DenseType rhsPlainObject; - rhs.evalTo(rhsPlainObject); - return this->toDenseMatrix() * rhsPlainObject; - } - template - bool isApprox(const TriangularView& other, typename NumTraits::Real precision = NumTraits::dummy_precision()) const - { - return this->toDenseMatrix().isApprox(other.toDenseMatrix(), precision); - } - template - bool isApprox(const MatrixBase& other, typename NumTraits::Real precision = NumTraits::dummy_precision()) const - { - return this->toDenseMatrix().isApprox(other, precision); - } - #endif // EIGEN2_SUPPORT - - template - inline const internal::triangular_solve_retval - solve(const MatrixBase& other) const; - - template - void solveInPlace(const MatrixBase& other) const; - - template - inline const internal::triangular_solve_retval - solve(const MatrixBase& other) const - { return solve(other); } - - template - void solveInPlace(const MatrixBase& other) const - { return solveInPlace(other); } - - const SelfAdjointView selfadjointView() const - { - EIGEN_STATIC_ASSERT((Mode&UnitDiag)==0,PROGRAMMING_ERROR); - return SelfAdjointView(m_matrix); - } - SelfAdjointView selfadjointView() - { - EIGEN_STATIC_ASSERT((Mode&UnitDiag)==0,PROGRAMMING_ERROR); - return SelfAdjointView(m_matrix); - } - - template - void swap(TriangularBase const & other) - { - TriangularView,Mode>(const_cast(m_matrix)).lazyAssign(other.derived()); - } - - template - void swap(MatrixBase const & other) - { - SwapWrapper swaper(const_cast(m_matrix)); - TriangularView,Mode>(swaper).lazyAssign(other.derived()); - } - - Scalar determinant() const - { - if (Mode & UnitDiag) - return 1; - else if (Mode & ZeroDiag) - return 0; - else - return m_matrix.diagonal().prod(); - } - - // TODO simplify the following: - template - EIGEN_STRONG_INLINE TriangularView& operator=(const ProductBase& other) - { - setZero(); - return assignProduct(other.derived(),1); - } - - template - EIGEN_STRONG_INLINE TriangularView& operator+=(const ProductBase& other) - { - return assignProduct(other.derived(),1); - } - - template - EIGEN_STRONG_INLINE TriangularView& operator-=(const ProductBase& other) - { - return assignProduct(other.derived(),-1); - } - - - template - EIGEN_STRONG_INLINE TriangularView& operator=(const ScaledProduct& other) - { - setZero(); - return assignProduct(other.derived(),other.alpha()); - } - - template - EIGEN_STRONG_INLINE TriangularView& operator+=(const ScaledProduct& other) - { - return assignProduct(other.derived(),other.alpha()); - } - - template - EIGEN_STRONG_INLINE TriangularView& operator-=(const ScaledProduct& other) - { - return assignProduct(other.derived(),-other.alpha()); - } - - protected: - - template - EIGEN_STRONG_INLINE TriangularView& assignProduct(const ProductBase& prod, const Scalar& alpha); - - template - EIGEN_STRONG_INLINE TriangularView& assignProduct(const TriangularProduct& prod, const Scalar& alpha) - { - lazyAssign(alpha*prod.eval()); - return *this; - } - - MatrixTypeNested m_matrix; -}; - -/*************************************************************************** -* Implementation of triangular evaluation/assignment -***************************************************************************/ - -namespace internal { - -template -struct triangular_assignment_selector -{ - enum { - col = (UnrollCount-1) / Derived1::RowsAtCompileTime, - row = (UnrollCount-1) % Derived1::RowsAtCompileTime - }; - - typedef typename Derived1::Scalar Scalar; - - static inline void run(Derived1 &dst, const Derived2 &src) - { - triangular_assignment_selector::run(dst, src); - - eigen_assert( Mode == Upper || Mode == Lower - || Mode == StrictlyUpper || Mode == StrictlyLower - || Mode == UnitUpper || Mode == UnitLower); - if((Mode == Upper && row <= col) - || (Mode == Lower && row >= col) - || (Mode == StrictlyUpper && row < col) - || (Mode == StrictlyLower && row > col) - || (Mode == UnitUpper && row < col) - || (Mode == UnitLower && row > col)) - dst.copyCoeff(row, col, src); - else if(ClearOpposite) - { - if (Mode&UnitDiag && row==col) - dst.coeffRef(row, col) = Scalar(1); - else - dst.coeffRef(row, col) = Scalar(0); - } - } -}; - -// prevent buggy user code from causing an infinite recursion -template -struct triangular_assignment_selector -{ - static inline void run(Derived1 &, const Derived2 &) {} -}; - -template -struct triangular_assignment_selector -{ - typedef typename Derived1::Index Index; - typedef typename Derived1::Scalar Scalar; - static inline void run(Derived1 &dst, const Derived2 &src) - { - for(Index j = 0; j < dst.cols(); ++j) - { - Index maxi = (std::min)(j, dst.rows()-1); - for(Index i = 0; i <= maxi; ++i) - dst.copyCoeff(i, j, src); - if (ClearOpposite) - for(Index i = maxi+1; i < dst.rows(); ++i) - dst.coeffRef(i, j) = Scalar(0); - } - } -}; - -template -struct triangular_assignment_selector -{ - typedef typename Derived1::Index Index; - static inline void run(Derived1 &dst, const Derived2 &src) - { - for(Index j = 0; j < dst.cols(); ++j) - { - for(Index i = j; i < dst.rows(); ++i) - dst.copyCoeff(i, j, src); - Index maxi = (std::min)(j, dst.rows()); - if (ClearOpposite) - for(Index i = 0; i < maxi; ++i) - dst.coeffRef(i, j) = static_cast(0); - } - } -}; - -template -struct triangular_assignment_selector -{ - typedef typename Derived1::Index Index; - typedef typename Derived1::Scalar Scalar; - static inline void run(Derived1 &dst, const Derived2 &src) - { - for(Index j = 0; j < dst.cols(); ++j) - { - Index maxi = (std::min)(j, dst.rows()); - for(Index i = 0; i < maxi; ++i) - dst.copyCoeff(i, j, src); - if (ClearOpposite) - for(Index i = maxi; i < dst.rows(); ++i) - dst.coeffRef(i, j) = Scalar(0); - } - } -}; - -template -struct triangular_assignment_selector -{ - typedef typename Derived1::Index Index; - static inline void run(Derived1 &dst, const Derived2 &src) - { - for(Index j = 0; j < dst.cols(); ++j) - { - for(Index i = j+1; i < dst.rows(); ++i) - dst.copyCoeff(i, j, src); - Index maxi = (std::min)(j, dst.rows()-1); - if (ClearOpposite) - for(Index i = 0; i <= maxi; ++i) - dst.coeffRef(i, j) = static_cast(0); - } - } -}; - -template -struct triangular_assignment_selector -{ - typedef typename Derived1::Index Index; - static inline void run(Derived1 &dst, const Derived2 &src) - { - for(Index j = 0; j < dst.cols(); ++j) - { - Index maxi = (std::min)(j, dst.rows()); - for(Index i = 0; i < maxi; ++i) - dst.copyCoeff(i, j, src); - if (ClearOpposite) - { - for(Index i = maxi+1; i < dst.rows(); ++i) - dst.coeffRef(i, j) = 0; - } - } - dst.diagonal().setOnes(); - } -}; -template -struct triangular_assignment_selector -{ - typedef typename Derived1::Index Index; - static inline void run(Derived1 &dst, const Derived2 &src) - { - for(Index j = 0; j < dst.cols(); ++j) - { - Index maxi = (std::min)(j, dst.rows()); - for(Index i = maxi+1; i < dst.rows(); ++i) - dst.copyCoeff(i, j, src); - if (ClearOpposite) - { - for(Index i = 0; i < maxi; ++i) - dst.coeffRef(i, j) = 0; - } - } - dst.diagonal().setOnes(); - } -}; - -} // end namespace internal - -// FIXME should we keep that possibility -template -template -inline TriangularView& -TriangularView::operator=(const MatrixBase& other) -{ - if(OtherDerived::Flags & EvalBeforeAssigningBit) - { - typename internal::plain_matrix_type::type other_evaluated(other.rows(), other.cols()); - other_evaluated.template triangularView().lazyAssign(other.derived()); - lazyAssign(other_evaluated); - } - else - lazyAssign(other.derived()); - return *this; -} - -// FIXME should we keep that possibility -template -template -void TriangularView::lazyAssign(const MatrixBase& other) -{ - enum { - unroll = MatrixType::SizeAtCompileTime != Dynamic - && internal::traits::CoeffReadCost != Dynamic - && MatrixType::SizeAtCompileTime*internal::traits::CoeffReadCost/2 <= EIGEN_UNROLLING_LIMIT - }; - eigen_assert(m_matrix.rows() == other.rows() && m_matrix.cols() == other.cols()); - - internal::triangular_assignment_selector - ::run(m_matrix.const_cast_derived(), other.derived()); -} - - - -template -template -inline TriangularView& -TriangularView::operator=(const TriangularBase& other) -{ - eigen_assert(Mode == int(OtherDerived::Mode)); - if(internal::traits::Flags & EvalBeforeAssigningBit) - { - typename OtherDerived::DenseMatrixType other_evaluated(other.rows(), other.cols()); - other_evaluated.template triangularView().lazyAssign(other.derived().nestedExpression()); - lazyAssign(other_evaluated); - } - else - lazyAssign(other.derived().nestedExpression()); - return *this; -} - -template -template -void TriangularView::lazyAssign(const TriangularBase& other) -{ - enum { - unroll = MatrixType::SizeAtCompileTime != Dynamic - && internal::traits::CoeffReadCost != Dynamic - && MatrixType::SizeAtCompileTime * internal::traits::CoeffReadCost / 2 - <= EIGEN_UNROLLING_LIMIT - }; - eigen_assert(m_matrix.rows() == other.rows() && m_matrix.cols() == other.cols()); - - internal::triangular_assignment_selector - ::run(m_matrix.const_cast_derived(), other.derived().nestedExpression()); -} - -/*************************************************************************** -* Implementation of TriangularBase methods -***************************************************************************/ - -/** Assigns a triangular or selfadjoint matrix to a dense matrix. - * If the matrix is triangular, the opposite part is set to zero. */ -template -template -void TriangularBase::evalTo(MatrixBase &other) const -{ - if(internal::traits::Flags & EvalBeforeAssigningBit) - { - typename internal::plain_matrix_type::type other_evaluated(rows(), cols()); - evalToLazy(other_evaluated); - other.derived().swap(other_evaluated); - } - else - evalToLazy(other.derived()); -} - -/** Assigns a triangular or selfadjoint matrix to a dense matrix. - * If the matrix is triangular, the opposite part is set to zero. */ -template -template -void TriangularBase::evalToLazy(MatrixBase &other) const -{ - enum { - unroll = DenseDerived::SizeAtCompileTime != Dynamic - && internal::traits::CoeffReadCost != Dynamic - && DenseDerived::SizeAtCompileTime * internal::traits::CoeffReadCost / 2 - <= EIGEN_UNROLLING_LIMIT - }; - other.derived().resize(this->rows(), this->cols()); - - internal::triangular_assignment_selector - ::MatrixTypeNestedCleaned, Derived::Mode, - unroll ? int(DenseDerived::SizeAtCompileTime) : Dynamic, - true // clear the opposite triangular part - >::run(other.derived(), derived().nestedExpression()); -} - -/*************************************************************************** -* Implementation of TriangularView methods -***************************************************************************/ - -/*************************************************************************** -* Implementation of MatrixBase methods -***************************************************************************/ - -#ifdef EIGEN2_SUPPORT - -// implementation of part<>(), including the SelfAdjoint case. - -namespace internal { -template -struct eigen2_part_return_type -{ - typedef TriangularView type; -}; - -template -struct eigen2_part_return_type -{ - typedef SelfAdjointView type; -}; -} - -/** \deprecated use MatrixBase::triangularView() */ -template -template -const typename internal::eigen2_part_return_type::type MatrixBase::part() const -{ - return derived(); -} - -/** \deprecated use MatrixBase::triangularView() */ -template -template -typename internal::eigen2_part_return_type::type MatrixBase::part() -{ - return derived(); -} -#endif - -/** - * \returns an expression of a triangular view extracted from the current matrix - * - * The parameter \a Mode can have the following values: \c #Upper, \c #StrictlyUpper, \c #UnitUpper, - * \c #Lower, \c #StrictlyLower, \c #UnitLower. - * - * Example: \include MatrixBase_extract.cpp - * Output: \verbinclude MatrixBase_extract.out - * - * \sa class TriangularView - */ -template -template -typename MatrixBase::template TriangularViewReturnType::Type -MatrixBase::triangularView() -{ - return derived(); -} - -/** This is the const version of MatrixBase::triangularView() */ -template -template -typename MatrixBase::template ConstTriangularViewReturnType::Type -MatrixBase::triangularView() const -{ - return derived(); -} - -/** \returns true if *this is approximately equal to an upper triangular matrix, - * within the precision given by \a prec. - * - * \sa isLowerTriangular() - */ -template -bool MatrixBase::isUpperTriangular(const RealScalar& prec) const -{ - using std::abs; - RealScalar maxAbsOnUpperPart = static_cast(-1); - for(Index j = 0; j < cols(); ++j) - { - Index maxi = (std::min)(j, rows()-1); - for(Index i = 0; i <= maxi; ++i) - { - RealScalar absValue = abs(coeff(i,j)); - if(absValue > maxAbsOnUpperPart) maxAbsOnUpperPart = absValue; - } - } - RealScalar threshold = maxAbsOnUpperPart * prec; - for(Index j = 0; j < cols(); ++j) - for(Index i = j+1; i < rows(); ++i) - if(abs(coeff(i, j)) > threshold) return false; - return true; -} - -/** \returns true if *this is approximately equal to a lower triangular matrix, - * within the precision given by \a prec. - * - * \sa isUpperTriangular() - */ -template -bool MatrixBase::isLowerTriangular(const RealScalar& prec) const -{ - using std::abs; - RealScalar maxAbsOnLowerPart = static_cast(-1); - for(Index j = 0; j < cols(); ++j) - for(Index i = j; i < rows(); ++i) - { - RealScalar absValue = abs(coeff(i,j)); - if(absValue > maxAbsOnLowerPart) maxAbsOnLowerPart = absValue; - } - RealScalar threshold = maxAbsOnLowerPart * prec; - for(Index j = 1; j < cols(); ++j) - { - Index maxi = (std::min)(j, rows()-1); - for(Index i = 0; i < maxi; ++i) - if(abs(coeff(i, j)) > threshold) return false; - } - return true; -} - -} // end namespace Eigen - -#endif // EIGEN_TRIANGULARMATRIX_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/VectorBlock.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/VectorBlock.h deleted file mode 100644 index 1a7330f3..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Core/VectorBlock.h +++ /dev/null @@ -1,95 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2010 Gael Guennebaud -// Copyright (C) 2006-2008 Benoit Jacob -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_VECTORBLOCK_H -#define EIGEN_VECTORBLOCK_H - -namespace Eigen { - -/** \class VectorBlock - * \ingroup Core_Module - * - * \brief Expression of a fixed-size or dynamic-size sub-vector - * - * \param VectorType the type of the object in which we are taking a sub-vector - * \param Size size of the sub-vector we are taking at compile time (optional) - * - * This class represents an expression of either a fixed-size or dynamic-size sub-vector. - * It is the return type of DenseBase::segment(Index,Index) and DenseBase::segment(Index) and - * most of the time this is the only way it is used. - * - * However, if you want to directly maniputate sub-vector expressions, - * for instance if you want to write a function returning such an expression, you - * will need to use this class. - * - * Here is an example illustrating the dynamic case: - * \include class_VectorBlock.cpp - * Output: \verbinclude class_VectorBlock.out - * - * \note Even though this expression has dynamic size, in the case where \a VectorType - * has fixed size, this expression inherits a fixed maximal size which means that evaluating - * it does not cause a dynamic memory allocation. - * - * Here is an example illustrating the fixed-size case: - * \include class_FixedVectorBlock.cpp - * Output: \verbinclude class_FixedVectorBlock.out - * - * \sa class Block, DenseBase::segment(Index,Index,Index,Index), DenseBase::segment(Index,Index) - */ - -namespace internal { -template -struct traits > - : public traits::Flags & RowMajorBit ? 1 : Size, - traits::Flags & RowMajorBit ? Size : 1> > -{ -}; -} - -template class VectorBlock - : public Block::Flags & RowMajorBit ? 1 : Size, - internal::traits::Flags & RowMajorBit ? Size : 1> -{ - typedef Block::Flags & RowMajorBit ? 1 : Size, - internal::traits::Flags & RowMajorBit ? Size : 1> Base; - enum { - IsColVector = !(internal::traits::Flags & RowMajorBit) - }; - public: - EIGEN_DENSE_PUBLIC_INTERFACE(VectorBlock) - - using Base::operator=; - - /** Dynamic-size constructor - */ - inline VectorBlock(VectorType& vector, Index start, Index size) - : Base(vector, - IsColVector ? start : 0, IsColVector ? 0 : start, - IsColVector ? size : 1, IsColVector ? 1 : size) - { - EIGEN_STATIC_ASSERT_VECTOR_ONLY(VectorBlock); - } - - /** Fixed-size constructor - */ - inline VectorBlock(VectorType& vector, Index start) - : Base(vector, IsColVector ? start : 0, IsColVector ? 0 : start) - { - EIGEN_STATIC_ASSERT_VECTOR_ONLY(VectorBlock); - } -}; - - -} // end namespace Eigen - -#endif // EIGEN_VECTORBLOCK_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/VectorwiseOp.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/VectorwiseOp.h deleted file mode 100644 index d5ab0366..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Core/VectorwiseOp.h +++ /dev/null @@ -1,642 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2010 Gael Guennebaud -// Copyright (C) 2006-2008 Benoit Jacob -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_PARTIAL_REDUX_H -#define EIGEN_PARTIAL_REDUX_H - -namespace Eigen { - -/** \class PartialReduxExpr - * \ingroup Core_Module - * - * \brief Generic expression of a partially reduxed matrix - * - * \tparam MatrixType the type of the matrix we are applying the redux operation - * \tparam MemberOp type of the member functor - * \tparam Direction indicates the direction of the redux (#Vertical or #Horizontal) - * - * This class represents an expression of a partial redux operator of a matrix. - * It is the return type of some VectorwiseOp functions, - * and most of the time this is the only way it is used. - * - * \sa class VectorwiseOp - */ - -template< typename MatrixType, typename MemberOp, int Direction> -class PartialReduxExpr; - -namespace internal { -template -struct traits > - : traits -{ - typedef typename MemberOp::result_type Scalar; - typedef typename traits::StorageKind StorageKind; - typedef typename traits::XprKind XprKind; - typedef typename MatrixType::Scalar InputScalar; - typedef typename nested::type MatrixTypeNested; - typedef typename remove_all::type _MatrixTypeNested; - enum { - RowsAtCompileTime = Direction==Vertical ? 1 : MatrixType::RowsAtCompileTime, - ColsAtCompileTime = Direction==Horizontal ? 1 : MatrixType::ColsAtCompileTime, - MaxRowsAtCompileTime = Direction==Vertical ? 1 : MatrixType::MaxRowsAtCompileTime, - MaxColsAtCompileTime = Direction==Horizontal ? 1 : MatrixType::MaxColsAtCompileTime, - Flags0 = (unsigned int)_MatrixTypeNested::Flags & HereditaryBits, - Flags = (Flags0 & ~RowMajorBit) | (RowsAtCompileTime == 1 ? RowMajorBit : 0), - TraversalSize = Direction==Vertical ? MatrixType::RowsAtCompileTime : MatrixType::ColsAtCompileTime - }; - #if EIGEN_GNUC_AT_LEAST(3,4) - typedef typename MemberOp::template Cost CostOpType; - #else - typedef typename MemberOp::template Cost CostOpType; - #endif - enum { - CoeffReadCost = TraversalSize==Dynamic ? Dynamic - : TraversalSize * traits<_MatrixTypeNested>::CoeffReadCost + int(CostOpType::value) - }; -}; -} - -template< typename MatrixType, typename MemberOp, int Direction> -class PartialReduxExpr : internal::no_assignment_operator, - public internal::dense_xpr_base< PartialReduxExpr >::type -{ - public: - - typedef typename internal::dense_xpr_base::type Base; - EIGEN_DENSE_PUBLIC_INTERFACE(PartialReduxExpr) - typedef typename internal::traits::MatrixTypeNested MatrixTypeNested; - typedef typename internal::traits::_MatrixTypeNested _MatrixTypeNested; - - PartialReduxExpr(const MatrixType& mat, const MemberOp& func = MemberOp()) - : m_matrix(mat), m_functor(func) {} - - Index rows() const { return (Direction==Vertical ? 1 : m_matrix.rows()); } - Index cols() const { return (Direction==Horizontal ? 1 : m_matrix.cols()); } - - EIGEN_STRONG_INLINE const Scalar coeff(Index i, Index j) const - { - if (Direction==Vertical) - return m_functor(m_matrix.col(j)); - else - return m_functor(m_matrix.row(i)); - } - - const Scalar coeff(Index index) const - { - if (Direction==Vertical) - return m_functor(m_matrix.col(index)); - else - return m_functor(m_matrix.row(index)); - } - - protected: - MatrixTypeNested m_matrix; - const MemberOp m_functor; -}; - -#define EIGEN_MEMBER_FUNCTOR(MEMBER,COST) \ - template \ - struct member_##MEMBER { \ - EIGEN_EMPTY_STRUCT_CTOR(member_##MEMBER) \ - typedef ResultType result_type; \ - template struct Cost \ - { enum { value = COST }; }; \ - template \ - EIGEN_STRONG_INLINE ResultType operator()(const XprType& mat) const \ - { return mat.MEMBER(); } \ - } - -namespace internal { - -EIGEN_MEMBER_FUNCTOR(squaredNorm, Size * NumTraits::MulCost + (Size-1)*NumTraits::AddCost); -EIGEN_MEMBER_FUNCTOR(norm, (Size+5) * NumTraits::MulCost + (Size-1)*NumTraits::AddCost); -EIGEN_MEMBER_FUNCTOR(stableNorm, (Size+5) * NumTraits::MulCost + (Size-1)*NumTraits::AddCost); -EIGEN_MEMBER_FUNCTOR(blueNorm, (Size+5) * NumTraits::MulCost + (Size-1)*NumTraits::AddCost); -EIGEN_MEMBER_FUNCTOR(hypotNorm, (Size-1) * functor_traits >::Cost ); -EIGEN_MEMBER_FUNCTOR(sum, (Size-1)*NumTraits::AddCost); -EIGEN_MEMBER_FUNCTOR(mean, (Size-1)*NumTraits::AddCost + NumTraits::MulCost); -EIGEN_MEMBER_FUNCTOR(minCoeff, (Size-1)*NumTraits::AddCost); -EIGEN_MEMBER_FUNCTOR(maxCoeff, (Size-1)*NumTraits::AddCost); -EIGEN_MEMBER_FUNCTOR(all, (Size-1)*NumTraits::AddCost); -EIGEN_MEMBER_FUNCTOR(any, (Size-1)*NumTraits::AddCost); -EIGEN_MEMBER_FUNCTOR(count, (Size-1)*NumTraits::AddCost); -EIGEN_MEMBER_FUNCTOR(prod, (Size-1)*NumTraits::MulCost); - - -template -struct member_redux { - typedef typename result_of< - BinaryOp(Scalar) - >::type result_type; - template struct Cost - { enum { value = (Size-1) * functor_traits::Cost }; }; - member_redux(const BinaryOp func) : m_functor(func) {} - template - inline result_type operator()(const DenseBase& mat) const - { return mat.redux(m_functor); } - const BinaryOp m_functor; -}; -} - -/** \class VectorwiseOp - * \ingroup Core_Module - * - * \brief Pseudo expression providing partial reduction operations - * - * \param ExpressionType the type of the object on which to do partial reductions - * \param Direction indicates the direction of the redux (#Vertical or #Horizontal) - * - * This class represents a pseudo expression with partial reduction features. - * It is the return type of DenseBase::colwise() and DenseBase::rowwise() - * and most of the time this is the only way it is used. - * - * Example: \include MatrixBase_colwise.cpp - * Output: \verbinclude MatrixBase_colwise.out - * - * \sa DenseBase::colwise(), DenseBase::rowwise(), class PartialReduxExpr - */ -template class VectorwiseOp -{ - public: - - typedef typename ExpressionType::Scalar Scalar; - typedef typename ExpressionType::RealScalar RealScalar; - typedef typename ExpressionType::Index Index; - typedef typename internal::conditional::ret, - ExpressionType, ExpressionType&>::type ExpressionTypeNested; - typedef typename internal::remove_all::type ExpressionTypeNestedCleaned; - - template class Functor, - typename Scalar=typename internal::traits::Scalar> struct ReturnType - { - typedef PartialReduxExpr, - Direction - > Type; - }; - - template struct ReduxReturnType - { - typedef PartialReduxExpr::Scalar>, - Direction - > Type; - }; - - enum { - IsVertical = (Direction==Vertical) ? 1 : 0, - IsHorizontal = (Direction==Horizontal) ? 1 : 0 - }; - - protected: - - /** \internal - * \returns the i-th subvector according to the \c Direction */ - typedef typename internal::conditional::type SubVector; - SubVector subVector(Index i) - { - return SubVector(m_matrix.derived(),i); - } - - /** \internal - * \returns the number of subvectors in the direction \c Direction */ - Index subVectors() const - { return Direction==Vertical?m_matrix.cols():m_matrix.rows(); } - - template struct ExtendedType { - typedef Replicate Type; - }; - - /** \internal - * Replicates a vector to match the size of \c *this */ - template - typename ExtendedType::Type - extendedTo(const DenseBase& other) const - { - EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(Direction==Vertical, OtherDerived::MaxColsAtCompileTime==1), - YOU_PASSED_A_ROW_VECTOR_BUT_A_COLUMN_VECTOR_WAS_EXPECTED) - EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(Direction==Horizontal, OtherDerived::MaxRowsAtCompileTime==1), - YOU_PASSED_A_COLUMN_VECTOR_BUT_A_ROW_VECTOR_WAS_EXPECTED) - return typename ExtendedType::Type - (other.derived(), - Direction==Vertical ? 1 : m_matrix.rows(), - Direction==Horizontal ? 1 : m_matrix.cols()); - } - - template struct OppositeExtendedType { - typedef Replicate Type; - }; - - /** \internal - * Replicates a vector in the opposite direction to match the size of \c *this */ - template - typename OppositeExtendedType::Type - extendedToOpposite(const DenseBase& other) const - { - EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(Direction==Horizontal, OtherDerived::MaxColsAtCompileTime==1), - YOU_PASSED_A_ROW_VECTOR_BUT_A_COLUMN_VECTOR_WAS_EXPECTED) - EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(Direction==Vertical, OtherDerived::MaxRowsAtCompileTime==1), - YOU_PASSED_A_COLUMN_VECTOR_BUT_A_ROW_VECTOR_WAS_EXPECTED) - return typename OppositeExtendedType::Type - (other.derived(), - Direction==Horizontal ? 1 : m_matrix.rows(), - Direction==Vertical ? 1 : m_matrix.cols()); - } - - public: - - inline VectorwiseOp(ExpressionType& matrix) : m_matrix(matrix) {} - - /** \internal */ - inline const ExpressionType& _expression() const { return m_matrix; } - - /** \returns a row or column vector expression of \c *this reduxed by \a func - * - * The template parameter \a BinaryOp is the type of the functor - * of the custom redux operator. Note that func must be an associative operator. - * - * \sa class VectorwiseOp, DenseBase::colwise(), DenseBase::rowwise() - */ - template - const typename ReduxReturnType::Type - redux(const BinaryOp& func = BinaryOp()) const - { return typename ReduxReturnType::Type(_expression(), func); } - - /** \returns a row (or column) vector expression of the smallest coefficient - * of each column (or row) of the referenced expression. - * - * \warning the result is undefined if \c *this contains NaN. - * - * Example: \include PartialRedux_minCoeff.cpp - * Output: \verbinclude PartialRedux_minCoeff.out - * - * \sa DenseBase::minCoeff() */ - const typename ReturnType::Type minCoeff() const - { return _expression(); } - - /** \returns a row (or column) vector expression of the largest coefficient - * of each column (or row) of the referenced expression. - * - * \warning the result is undefined if \c *this contains NaN. - * - * Example: \include PartialRedux_maxCoeff.cpp - * Output: \verbinclude PartialRedux_maxCoeff.out - * - * \sa DenseBase::maxCoeff() */ - const typename ReturnType::Type maxCoeff() const - { return _expression(); } - - /** \returns a row (or column) vector expression of the squared norm - * of each column (or row) of the referenced expression. - * - * Example: \include PartialRedux_squaredNorm.cpp - * Output: \verbinclude PartialRedux_squaredNorm.out - * - * \sa DenseBase::squaredNorm() */ - const typename ReturnType::Type squaredNorm() const - { return _expression(); } - - /** \returns a row (or column) vector expression of the norm - * of each column (or row) of the referenced expression. - * - * Example: \include PartialRedux_norm.cpp - * Output: \verbinclude PartialRedux_norm.out - * - * \sa DenseBase::norm() */ - const typename ReturnType::Type norm() const - { return _expression(); } - - - /** \returns a row (or column) vector expression of the norm - * of each column (or row) of the referenced expression, using - * blue's algorithm. - * - * \sa DenseBase::blueNorm() */ - const typename ReturnType::Type blueNorm() const - { return _expression(); } - - - /** \returns a row (or column) vector expression of the norm - * of each column (or row) of the referenced expression, avoiding - * underflow and overflow. - * - * \sa DenseBase::stableNorm() */ - const typename ReturnType::Type stableNorm() const - { return _expression(); } - - - /** \returns a row (or column) vector expression of the norm - * of each column (or row) of the referenced expression, avoiding - * underflow and overflow using a concatenation of hypot() calls. - * - * \sa DenseBase::hypotNorm() */ - const typename ReturnType::Type hypotNorm() const - { return _expression(); } - - /** \returns a row (or column) vector expression of the sum - * of each column (or row) of the referenced expression. - * - * Example: \include PartialRedux_sum.cpp - * Output: \verbinclude PartialRedux_sum.out - * - * \sa DenseBase::sum() */ - const typename ReturnType::Type sum() const - { return _expression(); } - - /** \returns a row (or column) vector expression of the mean - * of each column (or row) of the referenced expression. - * - * \sa DenseBase::mean() */ - const typename ReturnType::Type mean() const - { return _expression(); } - - /** \returns a row (or column) vector expression representing - * whether \b all coefficients of each respective column (or row) are \c true. - * - * \sa DenseBase::all() */ - const typename ReturnType::Type all() const - { return _expression(); } - - /** \returns a row (or column) vector expression representing - * whether \b at \b least one coefficient of each respective column (or row) is \c true. - * - * \sa DenseBase::any() */ - const typename ReturnType::Type any() const - { return _expression(); } - - /** \returns a row (or column) vector expression representing - * the number of \c true coefficients of each respective column (or row). - * - * Example: \include PartialRedux_count.cpp - * Output: \verbinclude PartialRedux_count.out - * - * \sa DenseBase::count() */ - const PartialReduxExpr, Direction> count() const - { return _expression(); } - - /** \returns a row (or column) vector expression of the product - * of each column (or row) of the referenced expression. - * - * Example: \include PartialRedux_prod.cpp - * Output: \verbinclude PartialRedux_prod.out - * - * \sa DenseBase::prod() */ - const typename ReturnType::Type prod() const - { return _expression(); } - - - /** \returns a matrix expression - * where each column (or row) are reversed. - * - * Example: \include Vectorwise_reverse.cpp - * Output: \verbinclude Vectorwise_reverse.out - * - * \sa DenseBase::reverse() */ - const Reverse reverse() const - { return Reverse( _expression() ); } - - typedef Replicate ReplicateReturnType; - const ReplicateReturnType replicate(Index factor) const; - - /** - * \return an expression of the replication of each column (or row) of \c *this - * - * Example: \include DirectionWise_replicate.cpp - * Output: \verbinclude DirectionWise_replicate.out - * - * \sa VectorwiseOp::replicate(Index), DenseBase::replicate(), class Replicate - */ - // NOTE implemented here because of sunstudio's compilation errors - template const Replicate - replicate(Index factor = Factor) const - { - return Replicate - (_expression(),Direction==Vertical?factor:1,Direction==Horizontal?factor:1); - } - -/////////// Artithmetic operators /////////// - - /** Copies the vector \a other to each subvector of \c *this */ - template - ExpressionType& operator=(const DenseBase& other) - { - EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived) - EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived) - //eigen_assert((m_matrix.isNull()) == (other.isNull())); FIXME - return const_cast(m_matrix = extendedTo(other.derived())); - } - - /** Adds the vector \a other to each subvector of \c *this */ - template - ExpressionType& operator+=(const DenseBase& other) - { - EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived) - EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived) - return const_cast(m_matrix += extendedTo(other.derived())); - } - - /** Substracts the vector \a other to each subvector of \c *this */ - template - ExpressionType& operator-=(const DenseBase& other) - { - EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived) - EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived) - return const_cast(m_matrix -= extendedTo(other.derived())); - } - - /** Multiples each subvector of \c *this by the vector \a other */ - template - ExpressionType& operator*=(const DenseBase& other) - { - EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived) - EIGEN_STATIC_ASSERT_ARRAYXPR(ExpressionType) - EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived) - m_matrix *= extendedTo(other.derived()); - return const_cast(m_matrix); - } - - /** Divides each subvector of \c *this by the vector \a other */ - template - ExpressionType& operator/=(const DenseBase& other) - { - EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived) - EIGEN_STATIC_ASSERT_ARRAYXPR(ExpressionType) - EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived) - m_matrix /= extendedTo(other.derived()); - return const_cast(m_matrix); - } - - /** Returns the expression of the sum of the vector \a other to each subvector of \c *this */ - template EIGEN_STRONG_INLINE - CwiseBinaryOp, - const ExpressionTypeNestedCleaned, - const typename ExtendedType::Type> - operator+(const DenseBase& other) const - { - EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived) - EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived) - return m_matrix + extendedTo(other.derived()); - } - - /** Returns the expression of the difference between each subvector of \c *this and the vector \a other */ - template - CwiseBinaryOp, - const ExpressionTypeNestedCleaned, - const typename ExtendedType::Type> - operator-(const DenseBase& other) const - { - EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived) - EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived) - return m_matrix - extendedTo(other.derived()); - } - - /** Returns the expression where each subvector is the product of the vector \a other - * by the corresponding subvector of \c *this */ - template EIGEN_STRONG_INLINE - CwiseBinaryOp, - const ExpressionTypeNestedCleaned, - const typename ExtendedType::Type> - operator*(const DenseBase& other) const - { - EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived) - EIGEN_STATIC_ASSERT_ARRAYXPR(ExpressionType) - EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived) - return m_matrix * extendedTo(other.derived()); - } - - /** Returns the expression where each subvector is the quotient of the corresponding - * subvector of \c *this by the vector \a other */ - template - CwiseBinaryOp, - const ExpressionTypeNestedCleaned, - const typename ExtendedType::Type> - operator/(const DenseBase& other) const - { - EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived) - EIGEN_STATIC_ASSERT_ARRAYXPR(ExpressionType) - EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived) - return m_matrix / extendedTo(other.derived()); - } - - /** \returns an expression where each column of row of the referenced matrix are normalized. - * The referenced matrix is \b not modified. - * \sa MatrixBase::normalized(), normalize() - */ - CwiseBinaryOp, - const ExpressionTypeNestedCleaned, - const typename OppositeExtendedType::Type>::Type> - normalized() const { return m_matrix.cwiseQuotient(extendedToOpposite(this->norm())); } - - - /** Normalize in-place each row or columns of the referenced matrix. - * \sa MatrixBase::normalize(), normalized() - */ - void normalize() { - m_matrix = this->normalized(); - } - -/////////// Geometry module /////////// - - #if EIGEN2_SUPPORT_STAGE > STAGE20_RESOLVE_API_CONFLICTS - Homogeneous homogeneous() const; - #endif - - typedef typename ExpressionType::PlainObject CrossReturnType; - template - const CrossReturnType cross(const MatrixBase& other) const; - - enum { - HNormalized_Size = Direction==Vertical ? internal::traits::RowsAtCompileTime - : internal::traits::ColsAtCompileTime, - HNormalized_SizeMinusOne = HNormalized_Size==Dynamic ? Dynamic : HNormalized_Size-1 - }; - typedef Block::RowsAtCompileTime), - Direction==Horizontal ? int(HNormalized_SizeMinusOne) - : int(internal::traits::ColsAtCompileTime)> - HNormalized_Block; - typedef Block::RowsAtCompileTime), - Direction==Horizontal ? 1 : int(internal::traits::ColsAtCompileTime)> - HNormalized_Factors; - typedef CwiseBinaryOp::Scalar>, - const HNormalized_Block, - const Replicate > - HNormalizedReturnType; - - const HNormalizedReturnType hnormalized() const; - - protected: - ExpressionTypeNested m_matrix; -}; - -/** \returns a VectorwiseOp wrapper of *this providing additional partial reduction operations - * - * Example: \include MatrixBase_colwise.cpp - * Output: \verbinclude MatrixBase_colwise.out - * - * \sa rowwise(), class VectorwiseOp, \ref TutorialReductionsVisitorsBroadcasting - */ -template -inline const typename DenseBase::ConstColwiseReturnType -DenseBase::colwise() const -{ - return derived(); -} - -/** \returns a writable VectorwiseOp wrapper of *this providing additional partial reduction operations - * - * \sa rowwise(), class VectorwiseOp, \ref TutorialReductionsVisitorsBroadcasting - */ -template -inline typename DenseBase::ColwiseReturnType -DenseBase::colwise() -{ - return derived(); -} - -/** \returns a VectorwiseOp wrapper of *this providing additional partial reduction operations - * - * Example: \include MatrixBase_rowwise.cpp - * Output: \verbinclude MatrixBase_rowwise.out - * - * \sa colwise(), class VectorwiseOp, \ref TutorialReductionsVisitorsBroadcasting - */ -template -inline const typename DenseBase::ConstRowwiseReturnType -DenseBase::rowwise() const -{ - return derived(); -} - -/** \returns a writable VectorwiseOp wrapper of *this providing additional partial reduction operations - * - * \sa colwise(), class VectorwiseOp, \ref TutorialReductionsVisitorsBroadcasting - */ -template -inline typename DenseBase::RowwiseReturnType -DenseBase::rowwise() -{ - return derived(); -} - -} // end namespace Eigen - -#endif // EIGEN_PARTIAL_REDUX_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/Visitor.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/Visitor.h deleted file mode 100644 index 64867b7a..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Core/Visitor.h +++ /dev/null @@ -1,237 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_VISITOR_H -#define EIGEN_VISITOR_H - -namespace Eigen { - -namespace internal { - -template -struct visitor_impl -{ - enum { - col = (UnrollCount-1) / Derived::RowsAtCompileTime, - row = (UnrollCount-1) % Derived::RowsAtCompileTime - }; - - static inline void run(const Derived &mat, Visitor& visitor) - { - visitor_impl::run(mat, visitor); - visitor(mat.coeff(row, col), row, col); - } -}; - -template -struct visitor_impl -{ - static inline void run(const Derived &mat, Visitor& visitor) - { - return visitor.init(mat.coeff(0, 0), 0, 0); - } -}; - -template -struct visitor_impl -{ - typedef typename Derived::Index Index; - static inline void run(const Derived& mat, Visitor& visitor) - { - visitor.init(mat.coeff(0,0), 0, 0); - for(Index i = 1; i < mat.rows(); ++i) - visitor(mat.coeff(i, 0), i, 0); - for(Index j = 1; j < mat.cols(); ++j) - for(Index i = 0; i < mat.rows(); ++i) - visitor(mat.coeff(i, j), i, j); - } -}; - -} // end namespace internal - -/** Applies the visitor \a visitor to the whole coefficients of the matrix or vector. - * - * The template parameter \a Visitor is the type of the visitor and provides the following interface: - * \code - * struct MyVisitor { - * // called for the first coefficient - * void init(const Scalar& value, Index i, Index j); - * // called for all other coefficients - * void operator() (const Scalar& value, Index i, Index j); - * }; - * \endcode - * - * \note compared to one or two \em for \em loops, visitors offer automatic - * unrolling for small fixed size matrix. - * - * \sa minCoeff(Index*,Index*), maxCoeff(Index*,Index*), DenseBase::redux() - */ -template -template -void DenseBase::visit(Visitor& visitor) const -{ - enum { unroll = SizeAtCompileTime != Dynamic - && CoeffReadCost != Dynamic - && (SizeAtCompileTime == 1 || internal::functor_traits::Cost != Dynamic) - && SizeAtCompileTime * CoeffReadCost + (SizeAtCompileTime-1) * internal::functor_traits::Cost - <= EIGEN_UNROLLING_LIMIT }; - return internal::visitor_impl::run(derived(), visitor); -} - -namespace internal { - -/** \internal - * \brief Base class to implement min and max visitors - */ -template -struct coeff_visitor -{ - typedef typename Derived::Index Index; - typedef typename Derived::Scalar Scalar; - Index row, col; - Scalar res; - inline void init(const Scalar& value, Index i, Index j) - { - res = value; - row = i; - col = j; - } -}; - -/** \internal - * \brief Visitor computing the min coefficient with its value and coordinates - * - * \sa DenseBase::minCoeff(Index*, Index*) - */ -template -struct min_coeff_visitor : coeff_visitor -{ - typedef typename Derived::Index Index; - typedef typename Derived::Scalar Scalar; - void operator() (const Scalar& value, Index i, Index j) - { - if(value < this->res) - { - this->res = value; - this->row = i; - this->col = j; - } - } -}; - -template -struct functor_traits > { - enum { - Cost = NumTraits::AddCost - }; -}; - -/** \internal - * \brief Visitor computing the max coefficient with its value and coordinates - * - * \sa DenseBase::maxCoeff(Index*, Index*) - */ -template -struct max_coeff_visitor : coeff_visitor -{ - typedef typename Derived::Index Index; - typedef typename Derived::Scalar Scalar; - void operator() (const Scalar& value, Index i, Index j) - { - if(value > this->res) - { - this->res = value; - this->row = i; - this->col = j; - } - } -}; - -template -struct functor_traits > { - enum { - Cost = NumTraits::AddCost - }; -}; - -} // end namespace internal - -/** \returns the minimum of all coefficients of *this and puts in *row and *col its location. - * \warning the result is undefined if \c *this contains NaN. - * - * \sa DenseBase::minCoeff(Index*), DenseBase::maxCoeff(Index*,Index*), DenseBase::visitor(), DenseBase::minCoeff() - */ -template -template -typename internal::traits::Scalar -DenseBase::minCoeff(IndexType* rowId, IndexType* colId) const -{ - internal::min_coeff_visitor minVisitor; - this->visit(minVisitor); - *rowId = minVisitor.row; - if (colId) *colId = minVisitor.col; - return minVisitor.res; -} - -/** \returns the minimum of all coefficients of *this and puts in *index its location. - * \warning the result is undefined if \c *this contains NaN. - * - * \sa DenseBase::minCoeff(IndexType*,IndexType*), DenseBase::maxCoeff(IndexType*,IndexType*), DenseBase::visitor(), DenseBase::minCoeff() - */ -template -template -typename internal::traits::Scalar -DenseBase::minCoeff(IndexType* index) const -{ - EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) - internal::min_coeff_visitor minVisitor; - this->visit(minVisitor); - *index = (RowsAtCompileTime==1) ? minVisitor.col : minVisitor.row; - return minVisitor.res; -} - -/** \returns the maximum of all coefficients of *this and puts in *row and *col its location. - * \warning the result is undefined if \c *this contains NaN. - * - * \sa DenseBase::minCoeff(IndexType*,IndexType*), DenseBase::visitor(), DenseBase::maxCoeff() - */ -template -template -typename internal::traits::Scalar -DenseBase::maxCoeff(IndexType* rowPtr, IndexType* colPtr) const -{ - internal::max_coeff_visitor maxVisitor; - this->visit(maxVisitor); - *rowPtr = maxVisitor.row; - if (colPtr) *colPtr = maxVisitor.col; - return maxVisitor.res; -} - -/** \returns the maximum of all coefficients of *this and puts in *index its location. - * \warning the result is undefined if \c *this contains NaN. - * - * \sa DenseBase::maxCoeff(IndexType*,IndexType*), DenseBase::minCoeff(IndexType*,IndexType*), DenseBase::visitor(), DenseBase::maxCoeff() - */ -template -template -typename internal::traits::Scalar -DenseBase::maxCoeff(IndexType* index) const -{ - EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) - internal::max_coeff_visitor maxVisitor; - this->visit(maxVisitor); - *index = (RowsAtCompileTime==1) ? maxVisitor.col : maxVisitor.row; - return maxVisitor.res; -} - -} // end namespace Eigen - -#endif // EIGEN_VISITOR_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/arch/AltiVec/Complex.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/arch/AltiVec/Complex.h deleted file mode 100644 index 68d9a2bf..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Core/arch/AltiVec/Complex.h +++ /dev/null @@ -1,217 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2010 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_COMPLEX_ALTIVEC_H -#define EIGEN_COMPLEX_ALTIVEC_H - -namespace Eigen { - -namespace internal { - -static Packet4ui p4ui_CONJ_XOR = vec_mergeh((Packet4ui)p4i_ZERO, (Packet4ui)p4f_ZERO_);//{ 0x00000000, 0x80000000, 0x00000000, 0x80000000 }; -static Packet16uc p16uc_COMPLEX_RE = vec_sld((Packet16uc) vec_splat((Packet4ui)p16uc_FORWARD, 0), (Packet16uc) vec_splat((Packet4ui)p16uc_FORWARD, 2), 8);//{ 0,1,2,3, 0,1,2,3, 8,9,10,11, 8,9,10,11 }; -static Packet16uc p16uc_COMPLEX_IM = vec_sld((Packet16uc) vec_splat((Packet4ui)p16uc_FORWARD, 1), (Packet16uc) vec_splat((Packet4ui)p16uc_FORWARD, 3), 8);//{ 4,5,6,7, 4,5,6,7, 12,13,14,15, 12,13,14,15 }; -static Packet16uc p16uc_COMPLEX_REV = vec_sld(p16uc_REVERSE, p16uc_REVERSE, 8);//{ 4,5,6,7, 0,1,2,3, 12,13,14,15, 8,9,10,11 }; -static Packet16uc p16uc_COMPLEX_REV2 = vec_sld(p16uc_FORWARD, p16uc_FORWARD, 8);//{ 8,9,10,11, 12,13,14,15, 0,1,2,3, 4,5,6,7 }; -static Packet16uc p16uc_PSET_HI = (Packet16uc) vec_mergeh((Packet4ui) vec_splat((Packet4ui)p16uc_FORWARD, 0), (Packet4ui) vec_splat((Packet4ui)p16uc_FORWARD, 1));//{ 0,1,2,3, 4,5,6,7, 0,1,2,3, 4,5,6,7 }; -static Packet16uc p16uc_PSET_LO = (Packet16uc) vec_mergeh((Packet4ui) vec_splat((Packet4ui)p16uc_FORWARD, 2), (Packet4ui) vec_splat((Packet4ui)p16uc_FORWARD, 3));//{ 8,9,10,11, 12,13,14,15, 8,9,10,11, 12,13,14,15 }; - -//---------- float ---------- -struct Packet2cf -{ - EIGEN_STRONG_INLINE Packet2cf() {} - EIGEN_STRONG_INLINE explicit Packet2cf(const Packet4f& a) : v(a) {} - Packet4f v; -}; - -template<> struct packet_traits > : default_packet_traits -{ - typedef Packet2cf type; - enum { - Vectorizable = 1, - AlignedOnScalar = 1, - size = 2, - - HasAdd = 1, - HasSub = 1, - HasMul = 1, - HasDiv = 1, - HasNegate = 1, - HasAbs = 0, - HasAbs2 = 0, - HasMin = 0, - HasMax = 0, - HasSetLinear = 0 - }; -}; - -template<> struct unpacket_traits { typedef std::complex type; enum {size=2}; }; - -template<> EIGEN_STRONG_INLINE Packet2cf pset1(const std::complex& from) -{ - Packet2cf res; - /* On AltiVec we cannot load 64-bit registers, so wa have to take care of alignment */ - if((ptrdiff_t(&from) % 16) == 0) - res.v = pload((const float *)&from); - else - res.v = ploadu((const float *)&from); - res.v = vec_perm(res.v, res.v, p16uc_PSET_HI); - return res; -} - -template<> EIGEN_STRONG_INLINE Packet2cf padd(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(vec_add(a.v,b.v)); } -template<> EIGEN_STRONG_INLINE Packet2cf psub(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(vec_sub(a.v,b.v)); } -template<> EIGEN_STRONG_INLINE Packet2cf pnegate(const Packet2cf& a) { return Packet2cf(pnegate(a.v)); } -template<> EIGEN_STRONG_INLINE Packet2cf pconj(const Packet2cf& a) { return Packet2cf((Packet4f)vec_xor((Packet4ui)a.v, p4ui_CONJ_XOR)); } - -template<> EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& a, const Packet2cf& b) -{ - Packet4f v1, v2; - - // Permute and multiply the real parts of a and b - v1 = vec_perm(a.v, a.v, p16uc_COMPLEX_RE); - // Get the imaginary parts of a - v2 = vec_perm(a.v, a.v, p16uc_COMPLEX_IM); - // multiply a_re * b - v1 = vec_madd(v1, b.v, p4f_ZERO); - // multiply a_im * b and get the conjugate result - v2 = vec_madd(v2, b.v, p4f_ZERO); - v2 = (Packet4f) vec_xor((Packet4ui)v2, p4ui_CONJ_XOR); - // permute back to a proper order - v2 = vec_perm(v2, v2, p16uc_COMPLEX_REV); - - return Packet2cf(vec_add(v1, v2)); -} - -template<> EIGEN_STRONG_INLINE Packet2cf pand (const Packet2cf& a, const Packet2cf& b) { return Packet2cf(vec_and(a.v,b.v)); } -template<> EIGEN_STRONG_INLINE Packet2cf por (const Packet2cf& a, const Packet2cf& b) { return Packet2cf(vec_or(a.v,b.v)); } -template<> EIGEN_STRONG_INLINE Packet2cf pxor (const Packet2cf& a, const Packet2cf& b) { return Packet2cf(vec_xor(a.v,b.v)); } -template<> EIGEN_STRONG_INLINE Packet2cf pandnot(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(vec_and(a.v, vec_nor(b.v,b.v))); } - -template<> EIGEN_STRONG_INLINE Packet2cf pload (const std::complex* from) { EIGEN_DEBUG_ALIGNED_LOAD return Packet2cf(pload((const float*)from)); } -template<> EIGEN_STRONG_INLINE Packet2cf ploadu(const std::complex* from) { EIGEN_DEBUG_UNALIGNED_LOAD return Packet2cf(ploadu((const float*)from)); } - -template<> EIGEN_STRONG_INLINE Packet2cf ploaddup(const std::complex* from) -{ - return pset1(*from); -} - -template<> EIGEN_STRONG_INLINE void pstore >(std::complex * to, const Packet2cf& from) { EIGEN_DEBUG_ALIGNED_STORE pstore((float*)to, from.v); } -template<> EIGEN_STRONG_INLINE void pstoreu >(std::complex * to, const Packet2cf& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu((float*)to, from.v); } - -template<> EIGEN_STRONG_INLINE void prefetch >(const std::complex * addr) { vec_dstt((float *)addr, DST_CTRL(2,2,32), DST_CHAN); } - -template<> EIGEN_STRONG_INLINE std::complex pfirst(const Packet2cf& a) -{ - std::complex EIGEN_ALIGN16 res[2]; - pstore((float *)&res, a.v); - - return res[0]; -} - -template<> EIGEN_STRONG_INLINE Packet2cf preverse(const Packet2cf& a) -{ - Packet4f rev_a; - rev_a = vec_perm(a.v, a.v, p16uc_COMPLEX_REV2); - return Packet2cf(rev_a); -} - -template<> EIGEN_STRONG_INLINE std::complex predux(const Packet2cf& a) -{ - Packet4f b; - b = (Packet4f) vec_sld(a.v, a.v, 8); - b = padd(a.v, b); - return pfirst(Packet2cf(b)); -} - -template<> EIGEN_STRONG_INLINE Packet2cf preduxp(const Packet2cf* vecs) -{ - Packet4f b1, b2; - - b1 = (Packet4f) vec_sld(vecs[0].v, vecs[1].v, 8); - b2 = (Packet4f) vec_sld(vecs[1].v, vecs[0].v, 8); - b2 = (Packet4f) vec_sld(b2, b2, 8); - b2 = padd(b1, b2); - - return Packet2cf(b2); -} - -template<> EIGEN_STRONG_INLINE std::complex predux_mul(const Packet2cf& a) -{ - Packet4f b; - Packet2cf prod; - b = (Packet4f) vec_sld(a.v, a.v, 8); - prod = pmul(a, Packet2cf(b)); - - return pfirst(prod); -} - -template -struct palign_impl -{ - static EIGEN_STRONG_INLINE void run(Packet2cf& first, const Packet2cf& second) - { - if (Offset==1) - { - first.v = vec_sld(first.v, second.v, 8); - } - } -}; - -template<> struct conj_helper -{ - EIGEN_STRONG_INLINE Packet2cf pmadd(const Packet2cf& x, const Packet2cf& y, const Packet2cf& c) const - { return padd(pmul(x,y),c); } - - EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& a, const Packet2cf& b) const - { - return internal::pmul(a, pconj(b)); - } -}; - -template<> struct conj_helper -{ - EIGEN_STRONG_INLINE Packet2cf pmadd(const Packet2cf& x, const Packet2cf& y, const Packet2cf& c) const - { return padd(pmul(x,y),c); } - - EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& a, const Packet2cf& b) const - { - return internal::pmul(pconj(a), b); - } -}; - -template<> struct conj_helper -{ - EIGEN_STRONG_INLINE Packet2cf pmadd(const Packet2cf& x, const Packet2cf& y, const Packet2cf& c) const - { return padd(pmul(x,y),c); } - - EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& a, const Packet2cf& b) const - { - return pconj(internal::pmul(a, b)); - } -}; - -template<> EIGEN_STRONG_INLINE Packet2cf pdiv(const Packet2cf& a, const Packet2cf& b) -{ - // TODO optimize it for AltiVec - Packet2cf res = conj_helper().pmul(a,b); - Packet4f s = vec_madd(b.v, b.v, p4f_ZERO); - return Packet2cf(pdiv(res.v, vec_add(s,vec_perm(s, s, p16uc_COMPLEX_REV)))); -} - -template<> EIGEN_STRONG_INLINE Packet2cf pcplxflip(const Packet2cf& x) -{ - return Packet2cf(vec_perm(x.v, x.v, p16uc_COMPLEX_REV)); -} - -} // end namespace internal - -} // end namespace Eigen - -#endif // EIGEN_COMPLEX_ALTIVEC_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/arch/AltiVec/PacketMath.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/arch/AltiVec/PacketMath.h deleted file mode 100644 index e4089962..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Core/arch/AltiVec/PacketMath.h +++ /dev/null @@ -1,501 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Konstantinos Margaritis -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_PACKET_MATH_ALTIVEC_H -#define EIGEN_PACKET_MATH_ALTIVEC_H - -namespace Eigen { - -namespace internal { - -#ifndef EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD -#define EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD 4 -#endif - -#ifndef EIGEN_HAS_FUSE_CJMADD -#define EIGEN_HAS_FUSE_CJMADD 1 -#endif - -// NOTE Altivec has 32 registers, but Eigen only accepts a value of 8 or 16 -#ifndef EIGEN_ARCH_DEFAULT_NUMBER_OF_REGISTERS -#define EIGEN_ARCH_DEFAULT_NUMBER_OF_REGISTERS 16 -#endif - -typedef __vector float Packet4f; -typedef __vector int Packet4i; -typedef __vector unsigned int Packet4ui; -typedef __vector __bool int Packet4bi; -typedef __vector short int Packet8i; -typedef __vector unsigned char Packet16uc; - -// We don't want to write the same code all the time, but we need to reuse the constants -// and it doesn't really work to declare them global, so we define macros instead - -#define _EIGEN_DECLARE_CONST_FAST_Packet4f(NAME,X) \ - Packet4f p4f_##NAME = (Packet4f) vec_splat_s32(X) - -#define _EIGEN_DECLARE_CONST_FAST_Packet4i(NAME,X) \ - Packet4i p4i_##NAME = vec_splat_s32(X) - -#define _EIGEN_DECLARE_CONST_Packet4f(NAME,X) \ - Packet4f p4f_##NAME = pset1(X) - -#define _EIGEN_DECLARE_CONST_Packet4f_FROM_INT(NAME,X) \ - Packet4f p4f_##NAME = vreinterpretq_f32_u32(pset1(X)) - -#define _EIGEN_DECLARE_CONST_Packet4i(NAME,X) \ - Packet4i p4i_##NAME = pset1(X) - -#define DST_CHAN 1 -#define DST_CTRL(size, count, stride) (((size) << 24) | ((count) << 16) | (stride)) - -// Define global static constants: -static Packet4f p4f_COUNTDOWN = { 3.0, 2.0, 1.0, 0.0 }; -static Packet4i p4i_COUNTDOWN = { 3, 2, 1, 0 }; -static Packet16uc p16uc_REVERSE = {12,13,14,15, 8,9,10,11, 4,5,6,7, 0,1,2,3}; -static Packet16uc p16uc_FORWARD = vec_lvsl(0, (float*)0); -static Packet16uc p16uc_DUPLICATE = {0,1,2,3, 0,1,2,3, 4,5,6,7, 4,5,6,7}; - -static _EIGEN_DECLARE_CONST_FAST_Packet4f(ZERO, 0); -static _EIGEN_DECLARE_CONST_FAST_Packet4i(ZERO, 0); -static _EIGEN_DECLARE_CONST_FAST_Packet4i(ONE,1); -static _EIGEN_DECLARE_CONST_FAST_Packet4i(MINUS16,-16); -static _EIGEN_DECLARE_CONST_FAST_Packet4i(MINUS1,-1); -static Packet4f p4f_ONE = vec_ctf(p4i_ONE, 0); -static Packet4f p4f_ZERO_ = (Packet4f) vec_sl((Packet4ui)p4i_MINUS1, (Packet4ui)p4i_MINUS1); - -template<> struct packet_traits : default_packet_traits -{ - typedef Packet4f type; - enum { - Vectorizable = 1, - AlignedOnScalar = 1, - size=4, - - // FIXME check the Has* - HasSin = 0, - HasCos = 0, - HasLog = 0, - HasExp = 0, - HasSqrt = 0 - }; -}; -template<> struct packet_traits : default_packet_traits -{ - typedef Packet4i type; - enum { - // FIXME check the Has* - Vectorizable = 1, - AlignedOnScalar = 1, - size=4 - }; -}; - -template<> struct unpacket_traits { typedef float type; enum {size=4}; }; -template<> struct unpacket_traits { typedef int type; enum {size=4}; }; -/* -inline std::ostream & operator <<(std::ostream & s, const Packet4f & v) -{ - union { - Packet4f v; - float n[4]; - } vt; - vt.v = v; - s << vt.n[0] << ", " << vt.n[1] << ", " << vt.n[2] << ", " << vt.n[3]; - return s; -} - -inline std::ostream & operator <<(std::ostream & s, const Packet4i & v) -{ - union { - Packet4i v; - int n[4]; - } vt; - vt.v = v; - s << vt.n[0] << ", " << vt.n[1] << ", " << vt.n[2] << ", " << vt.n[3]; - return s; -} - -inline std::ostream & operator <<(std::ostream & s, const Packet4ui & v) -{ - union { - Packet4ui v; - unsigned int n[4]; - } vt; - vt.v = v; - s << vt.n[0] << ", " << vt.n[1] << ", " << vt.n[2] << ", " << vt.n[3]; - return s; -} - -inline std::ostream & operator <<(std::ostream & s, const Packetbi & v) -{ - union { - Packet4bi v; - unsigned int n[4]; - } vt; - vt.v = v; - s << vt.n[0] << ", " << vt.n[1] << ", " << vt.n[2] << ", " << vt.n[3]; - return s; -} -*/ -template<> EIGEN_STRONG_INLINE Packet4f pset1(const float& from) { - // Taken from http://developer.apple.com/hardwaredrivers/ve/alignment.html - float EIGEN_ALIGN16 af[4]; - af[0] = from; - Packet4f vc = vec_ld(0, af); - vc = vec_splat(vc, 0); - return vc; -} - -template<> EIGEN_STRONG_INLINE Packet4i pset1(const int& from) { - int EIGEN_ALIGN16 ai[4]; - ai[0] = from; - Packet4i vc = vec_ld(0, ai); - vc = vec_splat(vc, 0); - return vc; -} - -template<> EIGEN_STRONG_INLINE Packet4f plset(const float& a) { return vec_add(pset1(a), p4f_COUNTDOWN); } -template<> EIGEN_STRONG_INLINE Packet4i plset(const int& a) { return vec_add(pset1(a), p4i_COUNTDOWN); } - -template<> EIGEN_STRONG_INLINE Packet4f padd(const Packet4f& a, const Packet4f& b) { return vec_add(a,b); } -template<> EIGEN_STRONG_INLINE Packet4i padd(const Packet4i& a, const Packet4i& b) { return vec_add(a,b); } - -template<> EIGEN_STRONG_INLINE Packet4f psub(const Packet4f& a, const Packet4f& b) { return vec_sub(a,b); } -template<> EIGEN_STRONG_INLINE Packet4i psub(const Packet4i& a, const Packet4i& b) { return vec_sub(a,b); } - -template<> EIGEN_STRONG_INLINE Packet4f pnegate(const Packet4f& a) { return psub(p4f_ZERO, a); } -template<> EIGEN_STRONG_INLINE Packet4i pnegate(const Packet4i& a) { return psub(p4i_ZERO, a); } - -template<> EIGEN_STRONG_INLINE Packet4f pconj(const Packet4f& a) { return a; } -template<> EIGEN_STRONG_INLINE Packet4i pconj(const Packet4i& a) { return a; } - -template<> EIGEN_STRONG_INLINE Packet4f pmul(const Packet4f& a, const Packet4f& b) { return vec_madd(a,b,p4f_ZERO); } -/* Commented out: it's actually slower than processing it scalar - * -template<> EIGEN_STRONG_INLINE Packet4i pmul(const Packet4i& a, const Packet4i& b) -{ - // Detailed in: http://freevec.org/content/32bit_signed_integer_multiplication_altivec - //Set up constants, variables - Packet4i a1, b1, bswap, low_prod, high_prod, prod, prod_, v1sel; - - // Get the absolute values - a1 = vec_abs(a); - b1 = vec_abs(b); - - // Get the signs using xor - Packet4bi sgn = (Packet4bi) vec_cmplt(vec_xor(a, b), p4i_ZERO); - - // Do the multiplication for the asbolute values. - bswap = (Packet4i) vec_rl((Packet4ui) b1, (Packet4ui) p4i_MINUS16 ); - low_prod = vec_mulo((Packet8i) a1, (Packet8i)b1); - high_prod = vec_msum((Packet8i) a1, (Packet8i) bswap, p4i_ZERO); - high_prod = (Packet4i) vec_sl((Packet4ui) high_prod, (Packet4ui) p4i_MINUS16); - prod = vec_add( low_prod, high_prod ); - - // NOR the product and select only the negative elements according to the sign mask - prod_ = vec_nor(prod, prod); - prod_ = vec_sel(p4i_ZERO, prod_, sgn); - - // Add 1 to the result to get the negative numbers - v1sel = vec_sel(p4i_ZERO, p4i_ONE, sgn); - prod_ = vec_add(prod_, v1sel); - - // Merge the results back to the final vector. - prod = vec_sel(prod, prod_, sgn); - - return prod; -} -*/ -template<> EIGEN_STRONG_INLINE Packet4f pdiv(const Packet4f& a, const Packet4f& b) -{ - Packet4f t, y_0, y_1, res; - - // Altivec does not offer a divide instruction, we have to do a reciprocal approximation - y_0 = vec_re(b); - - // Do one Newton-Raphson iteration to get the needed accuracy - t = vec_nmsub(y_0, b, p4f_ONE); - y_1 = vec_madd(y_0, t, y_0); - - res = vec_madd(a, y_1, p4f_ZERO); - return res; -} - -template<> EIGEN_STRONG_INLINE Packet4i pdiv(const Packet4i& /*a*/, const Packet4i& /*b*/) -{ eigen_assert(false && "packet integer division are not supported by AltiVec"); - return pset1(0); -} - -// for some weird raisons, it has to be overloaded for packet of integers -template<> EIGEN_STRONG_INLINE Packet4f pmadd(const Packet4f& a, const Packet4f& b, const Packet4f& c) { return vec_madd(a, b, c); } -template<> EIGEN_STRONG_INLINE Packet4i pmadd(const Packet4i& a, const Packet4i& b, const Packet4i& c) { return padd(pmul(a,b), c); } - -template<> EIGEN_STRONG_INLINE Packet4f pmin(const Packet4f& a, const Packet4f& b) { return vec_min(a, b); } -template<> EIGEN_STRONG_INLINE Packet4i pmin(const Packet4i& a, const Packet4i& b) { return vec_min(a, b); } - -template<> EIGEN_STRONG_INLINE Packet4f pmax(const Packet4f& a, const Packet4f& b) { return vec_max(a, b); } -template<> EIGEN_STRONG_INLINE Packet4i pmax(const Packet4i& a, const Packet4i& b) { return vec_max(a, b); } - -// Logical Operations are not supported for float, so we have to reinterpret casts using NEON intrinsics -template<> EIGEN_STRONG_INLINE Packet4f pand(const Packet4f& a, const Packet4f& b) { return vec_and(a, b); } -template<> EIGEN_STRONG_INLINE Packet4i pand(const Packet4i& a, const Packet4i& b) { return vec_and(a, b); } - -template<> EIGEN_STRONG_INLINE Packet4f por(const Packet4f& a, const Packet4f& b) { return vec_or(a, b); } -template<> EIGEN_STRONG_INLINE Packet4i por(const Packet4i& a, const Packet4i& b) { return vec_or(a, b); } - -template<> EIGEN_STRONG_INLINE Packet4f pxor(const Packet4f& a, const Packet4f& b) { return vec_xor(a, b); } -template<> EIGEN_STRONG_INLINE Packet4i pxor(const Packet4i& a, const Packet4i& b) { return vec_xor(a, b); } - -template<> EIGEN_STRONG_INLINE Packet4f pandnot(const Packet4f& a, const Packet4f& b) { return vec_and(a, vec_nor(b, b)); } -template<> EIGEN_STRONG_INLINE Packet4i pandnot(const Packet4i& a, const Packet4i& b) { return vec_and(a, vec_nor(b, b)); } - -template<> EIGEN_STRONG_INLINE Packet4f pload(const float* from) { EIGEN_DEBUG_ALIGNED_LOAD return vec_ld(0, from); } -template<> EIGEN_STRONG_INLINE Packet4i pload(const int* from) { EIGEN_DEBUG_ALIGNED_LOAD return vec_ld(0, from); } - -template<> EIGEN_STRONG_INLINE Packet4f ploadu(const float* from) -{ - EIGEN_DEBUG_ALIGNED_LOAD - // Taken from http://developer.apple.com/hardwaredrivers/ve/alignment.html - Packet16uc MSQ, LSQ; - Packet16uc mask; - MSQ = vec_ld(0, (unsigned char *)from); // most significant quadword - LSQ = vec_ld(15, (unsigned char *)from); // least significant quadword - mask = vec_lvsl(0, from); // create the permute mask - return (Packet4f) vec_perm(MSQ, LSQ, mask); // align the data - -} -template<> EIGEN_STRONG_INLINE Packet4i ploadu(const int* from) -{ - EIGEN_DEBUG_ALIGNED_LOAD - // Taken from http://developer.apple.com/hardwaredrivers/ve/alignment.html - Packet16uc MSQ, LSQ; - Packet16uc mask; - MSQ = vec_ld(0, (unsigned char *)from); // most significant quadword - LSQ = vec_ld(15, (unsigned char *)from); // least significant quadword - mask = vec_lvsl(0, from); // create the permute mask - return (Packet4i) vec_perm(MSQ, LSQ, mask); // align the data -} - -template<> EIGEN_STRONG_INLINE Packet4f ploaddup(const float* from) -{ - Packet4f p; - if((ptrdiff_t(&from) % 16) == 0) p = pload(from); - else p = ploadu(from); - return vec_perm(p, p, p16uc_DUPLICATE); -} -template<> EIGEN_STRONG_INLINE Packet4i ploaddup(const int* from) -{ - Packet4i p; - if((ptrdiff_t(&from) % 16) == 0) p = pload(from); - else p = ploadu(from); - return vec_perm(p, p, p16uc_DUPLICATE); -} - -template<> EIGEN_STRONG_INLINE void pstore(float* to, const Packet4f& from) { EIGEN_DEBUG_ALIGNED_STORE vec_st(from, 0, to); } -template<> EIGEN_STRONG_INLINE void pstore(int* to, const Packet4i& from) { EIGEN_DEBUG_ALIGNED_STORE vec_st(from, 0, to); } - -template<> EIGEN_STRONG_INLINE void pstoreu(float* to, const Packet4f& from) -{ - EIGEN_DEBUG_UNALIGNED_STORE - // Taken from http://developer.apple.com/hardwaredrivers/ve/alignment.html - // Warning: not thread safe! - Packet16uc MSQ, LSQ, edges; - Packet16uc edgeAlign, align; - - MSQ = vec_ld(0, (unsigned char *)to); // most significant quadword - LSQ = vec_ld(15, (unsigned char *)to); // least significant quadword - edgeAlign = vec_lvsl(0, to); // permute map to extract edges - edges=vec_perm(LSQ,MSQ,edgeAlign); // extract the edges - align = vec_lvsr( 0, to ); // permute map to misalign data - MSQ = vec_perm(edges,(Packet16uc)from,align); // misalign the data (MSQ) - LSQ = vec_perm((Packet16uc)from,edges,align); // misalign the data (LSQ) - vec_st( LSQ, 15, (unsigned char *)to ); // Store the LSQ part first - vec_st( MSQ, 0, (unsigned char *)to ); // Store the MSQ part -} -template<> EIGEN_STRONG_INLINE void pstoreu(int* to, const Packet4i& from) -{ - EIGEN_DEBUG_UNALIGNED_STORE - // Taken from http://developer.apple.com/hardwaredrivers/ve/alignment.html - // Warning: not thread safe! - Packet16uc MSQ, LSQ, edges; - Packet16uc edgeAlign, align; - - MSQ = vec_ld(0, (unsigned char *)to); // most significant quadword - LSQ = vec_ld(15, (unsigned char *)to); // least significant quadword - edgeAlign = vec_lvsl(0, to); // permute map to extract edges - edges=vec_perm(LSQ, MSQ, edgeAlign); // extract the edges - align = vec_lvsr( 0, to ); // permute map to misalign data - MSQ = vec_perm(edges, (Packet16uc) from, align); // misalign the data (MSQ) - LSQ = vec_perm((Packet16uc) from, edges, align); // misalign the data (LSQ) - vec_st( LSQ, 15, (unsigned char *)to ); // Store the LSQ part first - vec_st( MSQ, 0, (unsigned char *)to ); // Store the MSQ part -} - -template<> EIGEN_STRONG_INLINE void prefetch(const float* addr) { vec_dstt(addr, DST_CTRL(2,2,32), DST_CHAN); } -template<> EIGEN_STRONG_INLINE void prefetch(const int* addr) { vec_dstt(addr, DST_CTRL(2,2,32), DST_CHAN); } - -template<> EIGEN_STRONG_INLINE float pfirst(const Packet4f& a) { float EIGEN_ALIGN16 x[4]; vec_st(a, 0, x); return x[0]; } -template<> EIGEN_STRONG_INLINE int pfirst(const Packet4i& a) { int EIGEN_ALIGN16 x[4]; vec_st(a, 0, x); return x[0]; } - -template<> EIGEN_STRONG_INLINE Packet4f preverse(const Packet4f& a) { return (Packet4f)vec_perm((Packet16uc)a,(Packet16uc)a, p16uc_REVERSE); } -template<> EIGEN_STRONG_INLINE Packet4i preverse(const Packet4i& a) { return (Packet4i)vec_perm((Packet16uc)a,(Packet16uc)a, p16uc_REVERSE); } - -template<> EIGEN_STRONG_INLINE Packet4f pabs(const Packet4f& a) { return vec_abs(a); } -template<> EIGEN_STRONG_INLINE Packet4i pabs(const Packet4i& a) { return vec_abs(a); } - -template<> EIGEN_STRONG_INLINE float predux(const Packet4f& a) -{ - Packet4f b, sum; - b = (Packet4f) vec_sld(a, a, 8); - sum = vec_add(a, b); - b = (Packet4f) vec_sld(sum, sum, 4); - sum = vec_add(sum, b); - return pfirst(sum); -} - -template<> EIGEN_STRONG_INLINE Packet4f preduxp(const Packet4f* vecs) -{ - Packet4f v[4], sum[4]; - - // It's easier and faster to transpose then add as columns - // Check: http://www.freevec.org/function/matrix_4x4_transpose_floats for explanation - // Do the transpose, first set of moves - v[0] = vec_mergeh(vecs[0], vecs[2]); - v[1] = vec_mergel(vecs[0], vecs[2]); - v[2] = vec_mergeh(vecs[1], vecs[3]); - v[3] = vec_mergel(vecs[1], vecs[3]); - // Get the resulting vectors - sum[0] = vec_mergeh(v[0], v[2]); - sum[1] = vec_mergel(v[0], v[2]); - sum[2] = vec_mergeh(v[1], v[3]); - sum[3] = vec_mergel(v[1], v[3]); - - // Now do the summation: - // Lines 0+1 - sum[0] = vec_add(sum[0], sum[1]); - // Lines 2+3 - sum[1] = vec_add(sum[2], sum[3]); - // Add the results - sum[0] = vec_add(sum[0], sum[1]); - - return sum[0]; -} - -template<> EIGEN_STRONG_INLINE int predux(const Packet4i& a) -{ - Packet4i sum; - sum = vec_sums(a, p4i_ZERO); - sum = vec_sld(sum, p4i_ZERO, 12); - return pfirst(sum); -} - -template<> EIGEN_STRONG_INLINE Packet4i preduxp(const Packet4i* vecs) -{ - Packet4i v[4], sum[4]; - - // It's easier and faster to transpose then add as columns - // Check: http://www.freevec.org/function/matrix_4x4_transpose_floats for explanation - // Do the transpose, first set of moves - v[0] = vec_mergeh(vecs[0], vecs[2]); - v[1] = vec_mergel(vecs[0], vecs[2]); - v[2] = vec_mergeh(vecs[1], vecs[3]); - v[3] = vec_mergel(vecs[1], vecs[3]); - // Get the resulting vectors - sum[0] = vec_mergeh(v[0], v[2]); - sum[1] = vec_mergel(v[0], v[2]); - sum[2] = vec_mergeh(v[1], v[3]); - sum[3] = vec_mergel(v[1], v[3]); - - // Now do the summation: - // Lines 0+1 - sum[0] = vec_add(sum[0], sum[1]); - // Lines 2+3 - sum[1] = vec_add(sum[2], sum[3]); - // Add the results - sum[0] = vec_add(sum[0], sum[1]); - - return sum[0]; -} - -// Other reduction functions: -// mul -template<> EIGEN_STRONG_INLINE float predux_mul(const Packet4f& a) -{ - Packet4f prod; - prod = pmul(a, (Packet4f)vec_sld(a, a, 8)); - return pfirst(pmul(prod, (Packet4f)vec_sld(prod, prod, 4))); -} - -template<> EIGEN_STRONG_INLINE int predux_mul(const Packet4i& a) -{ - EIGEN_ALIGN16 int aux[4]; - pstore(aux, a); - return aux[0] * aux[1] * aux[2] * aux[3]; -} - -// min -template<> EIGEN_STRONG_INLINE float predux_min(const Packet4f& a) -{ - Packet4f b, res; - b = vec_min(a, vec_sld(a, a, 8)); - res = vec_min(b, vec_sld(b, b, 4)); - return pfirst(res); -} - -template<> EIGEN_STRONG_INLINE int predux_min(const Packet4i& a) -{ - Packet4i b, res; - b = vec_min(a, vec_sld(a, a, 8)); - res = vec_min(b, vec_sld(b, b, 4)); - return pfirst(res); -} - -// max -template<> EIGEN_STRONG_INLINE float predux_max(const Packet4f& a) -{ - Packet4f b, res; - b = vec_max(a, vec_sld(a, a, 8)); - res = vec_max(b, vec_sld(b, b, 4)); - return pfirst(res); -} - -template<> EIGEN_STRONG_INLINE int predux_max(const Packet4i& a) -{ - Packet4i b, res; - b = vec_max(a, vec_sld(a, a, 8)); - res = vec_max(b, vec_sld(b, b, 4)); - return pfirst(res); -} - -template -struct palign_impl -{ - static EIGEN_STRONG_INLINE void run(Packet4f& first, const Packet4f& second) - { - if (Offset!=0) - first = vec_sld(first, second, Offset*4); - } -}; - -template -struct palign_impl -{ - static EIGEN_STRONG_INLINE void run(Packet4i& first, const Packet4i& second) - { - if (Offset!=0) - first = vec_sld(first, second, Offset*4); - } -}; - -} // end namespace internal - -} // end namespace Eigen - -#endif // EIGEN_PACKET_MATH_ALTIVEC_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/arch/Default/Settings.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/arch/Default/Settings.h deleted file mode 100644 index 097373c8..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Core/arch/Default/Settings.h +++ /dev/null @@ -1,49 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2010 Gael Guennebaud -// Copyright (C) 2006-2008 Benoit Jacob -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - - -/* All the parameters defined in this file can be specialized in the - * architecture specific files, and/or by the user. - * More to come... */ - -#ifndef EIGEN_DEFAULT_SETTINGS_H -#define EIGEN_DEFAULT_SETTINGS_H - -/** Defines the maximal loop size to enable meta unrolling of loops. - * Note that the value here is expressed in Eigen's own notion of "number of FLOPS", - * it does not correspond to the number of iterations or the number of instructions - */ -#ifndef EIGEN_UNROLLING_LIMIT -#define EIGEN_UNROLLING_LIMIT 100 -#endif - -/** Defines the threshold between a "small" and a "large" matrix. - * This threshold is mainly used to select the proper product implementation. - */ -#ifndef EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD -#define EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD 8 -#endif - -/** Defines the maximal width of the blocks used in the triangular product and solver - * for vectors (level 2 blas xTRMV and xTRSV). The default is 8. - */ -#ifndef EIGEN_TUNE_TRIANGULAR_PANEL_WIDTH -#define EIGEN_TUNE_TRIANGULAR_PANEL_WIDTH 8 -#endif - - -/** Defines the default number of registers available for that architecture. - * Currently it must be 8 or 16. Other values will fail. - */ -#ifndef EIGEN_ARCH_DEFAULT_NUMBER_OF_REGISTERS -#define EIGEN_ARCH_DEFAULT_NUMBER_OF_REGISTERS 8 -#endif - -#endif // EIGEN_DEFAULT_SETTINGS_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/arch/NEON/Complex.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/arch/NEON/Complex.h deleted file mode 100644 index 8d9255ee..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Core/arch/NEON/Complex.h +++ /dev/null @@ -1,253 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2010 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_COMPLEX_NEON_H -#define EIGEN_COMPLEX_NEON_H - -namespace Eigen { - -namespace internal { - -static uint32x4_t p4ui_CONJ_XOR = EIGEN_INIT_NEON_PACKET4(0x00000000, 0x80000000, 0x00000000, 0x80000000); -static uint32x2_t p2ui_CONJ_XOR = EIGEN_INIT_NEON_PACKET2(0x00000000, 0x80000000); - -//---------- float ---------- -struct Packet2cf -{ - EIGEN_STRONG_INLINE Packet2cf() {} - EIGEN_STRONG_INLINE explicit Packet2cf(const Packet4f& a) : v(a) {} - Packet4f v; -}; - -template<> struct packet_traits > : default_packet_traits -{ - typedef Packet2cf type; - enum { - Vectorizable = 1, - AlignedOnScalar = 1, - size = 2, - - HasAdd = 1, - HasSub = 1, - HasMul = 1, - HasDiv = 1, - HasNegate = 1, - HasAbs = 0, - HasAbs2 = 0, - HasMin = 0, - HasMax = 0, - HasSetLinear = 0 - }; -}; - -template<> struct unpacket_traits { typedef std::complex type; enum {size=2}; }; - -template<> EIGEN_STRONG_INLINE Packet2cf pset1(const std::complex& from) -{ - float32x2_t r64; - r64 = vld1_f32((float *)&from); - - return Packet2cf(vcombine_f32(r64, r64)); -} - -template<> EIGEN_STRONG_INLINE Packet2cf padd(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(padd(a.v,b.v)); } -template<> EIGEN_STRONG_INLINE Packet2cf psub(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(psub(a.v,b.v)); } -template<> EIGEN_STRONG_INLINE Packet2cf pnegate(const Packet2cf& a) { return Packet2cf(pnegate(a.v)); } -template<> EIGEN_STRONG_INLINE Packet2cf pconj(const Packet2cf& a) -{ - Packet4ui b = vreinterpretq_u32_f32(a.v); - return Packet2cf(vreinterpretq_f32_u32(veorq_u32(b, p4ui_CONJ_XOR))); -} - -template<> EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& a, const Packet2cf& b) -{ - Packet4f v1, v2; - - // Get the real values of a | a1_re | a1_re | a2_re | a2_re | - v1 = vcombine_f32(vdup_lane_f32(vget_low_f32(a.v), 0), vdup_lane_f32(vget_high_f32(a.v), 0)); - // Get the real values of a | a1_im | a1_im | a2_im | a2_im | - v2 = vcombine_f32(vdup_lane_f32(vget_low_f32(a.v), 1), vdup_lane_f32(vget_high_f32(a.v), 1)); - // Multiply the real a with b - v1 = vmulq_f32(v1, b.v); - // Multiply the imag a with b - v2 = vmulq_f32(v2, b.v); - // Conjugate v2 - v2 = vreinterpretq_f32_u32(veorq_u32(vreinterpretq_u32_f32(v2), p4ui_CONJ_XOR)); - // Swap real/imag elements in v2. - v2 = vrev64q_f32(v2); - // Add and return the result - return Packet2cf(vaddq_f32(v1, v2)); -} - -template<> EIGEN_STRONG_INLINE Packet2cf pand (const Packet2cf& a, const Packet2cf& b) -{ - return Packet2cf(vreinterpretq_f32_u32(vorrq_u32(vreinterpretq_u32_f32(a.v),vreinterpretq_u32_f32(b.v)))); -} -template<> EIGEN_STRONG_INLINE Packet2cf por (const Packet2cf& a, const Packet2cf& b) -{ - return Packet2cf(vreinterpretq_f32_u32(vorrq_u32(vreinterpretq_u32_f32(a.v),vreinterpretq_u32_f32(b.v)))); -} -template<> EIGEN_STRONG_INLINE Packet2cf pxor (const Packet2cf& a, const Packet2cf& b) -{ - return Packet2cf(vreinterpretq_f32_u32(veorq_u32(vreinterpretq_u32_f32(a.v),vreinterpretq_u32_f32(b.v)))); -} -template<> EIGEN_STRONG_INLINE Packet2cf pandnot(const Packet2cf& a, const Packet2cf& b) -{ - return Packet2cf(vreinterpretq_f32_u32(vbicq_u32(vreinterpretq_u32_f32(a.v),vreinterpretq_u32_f32(b.v)))); -} - -template<> EIGEN_STRONG_INLINE Packet2cf pload(const std::complex* from) { EIGEN_DEBUG_ALIGNED_LOAD return Packet2cf(pload((const float*)from)); } -template<> EIGEN_STRONG_INLINE Packet2cf ploadu(const std::complex* from) { EIGEN_DEBUG_UNALIGNED_LOAD return Packet2cf(ploadu((const float*)from)); } - -template<> EIGEN_STRONG_INLINE Packet2cf ploaddup(const std::complex* from) { return pset1(*from); } - -template<> EIGEN_STRONG_INLINE void pstore >(std::complex * to, const Packet2cf& from) { EIGEN_DEBUG_ALIGNED_STORE pstore((float*)to, from.v); } -template<> EIGEN_STRONG_INLINE void pstoreu >(std::complex * to, const Packet2cf& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu((float*)to, from.v); } - -template<> EIGEN_STRONG_INLINE void prefetch >(const std::complex * addr) { EIGEN_ARM_PREFETCH((float *)addr); } - -template<> EIGEN_STRONG_INLINE std::complex pfirst(const Packet2cf& a) -{ - std::complex EIGEN_ALIGN16 x[2]; - vst1q_f32((float *)x, a.v); - return x[0]; -} - -template<> EIGEN_STRONG_INLINE Packet2cf preverse(const Packet2cf& a) -{ - float32x2_t a_lo, a_hi; - Packet4f a_r128; - - a_lo = vget_low_f32(a.v); - a_hi = vget_high_f32(a.v); - a_r128 = vcombine_f32(a_hi, a_lo); - - return Packet2cf(a_r128); -} - -template<> EIGEN_STRONG_INLINE Packet2cf pcplxflip(const Packet2cf& a) -{ - return Packet2cf(vrev64q_f32(a.v)); -} - -template<> EIGEN_STRONG_INLINE std::complex predux(const Packet2cf& a) -{ - float32x2_t a1, a2; - std::complex s; - - a1 = vget_low_f32(a.v); - a2 = vget_high_f32(a.v); - a2 = vadd_f32(a1, a2); - vst1_f32((float *)&s, a2); - - return s; -} - -template<> EIGEN_STRONG_INLINE Packet2cf preduxp(const Packet2cf* vecs) -{ - Packet4f sum1, sum2, sum; - - // Add the first two 64-bit float32x2_t of vecs[0] - sum1 = vcombine_f32(vget_low_f32(vecs[0].v), vget_low_f32(vecs[1].v)); - sum2 = vcombine_f32(vget_high_f32(vecs[0].v), vget_high_f32(vecs[1].v)); - sum = vaddq_f32(sum1, sum2); - - return Packet2cf(sum); -} - -template<> EIGEN_STRONG_INLINE std::complex predux_mul(const Packet2cf& a) -{ - float32x2_t a1, a2, v1, v2, prod; - std::complex s; - - a1 = vget_low_f32(a.v); - a2 = vget_high_f32(a.v); - // Get the real values of a | a1_re | a1_re | a2_re | a2_re | - v1 = vdup_lane_f32(a1, 0); - // Get the real values of a | a1_im | a1_im | a2_im | a2_im | - v2 = vdup_lane_f32(a1, 1); - // Multiply the real a with b - v1 = vmul_f32(v1, a2); - // Multiply the imag a with b - v2 = vmul_f32(v2, a2); - // Conjugate v2 - v2 = vreinterpret_f32_u32(veor_u32(vreinterpret_u32_f32(v2), p2ui_CONJ_XOR)); - // Swap real/imag elements in v2. - v2 = vrev64_f32(v2); - // Add v1, v2 - prod = vadd_f32(v1, v2); - - vst1_f32((float *)&s, prod); - - return s; -} - -template -struct palign_impl -{ - EIGEN_STRONG_INLINE static void run(Packet2cf& first, const Packet2cf& second) - { - if (Offset==1) - { - first.v = vextq_f32(first.v, second.v, 2); - } - } -}; - -template<> struct conj_helper -{ - EIGEN_STRONG_INLINE Packet2cf pmadd(const Packet2cf& x, const Packet2cf& y, const Packet2cf& c) const - { return padd(pmul(x,y),c); } - - EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& a, const Packet2cf& b) const - { - return internal::pmul(a, pconj(b)); - } -}; - -template<> struct conj_helper -{ - EIGEN_STRONG_INLINE Packet2cf pmadd(const Packet2cf& x, const Packet2cf& y, const Packet2cf& c) const - { return padd(pmul(x,y),c); } - - EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& a, const Packet2cf& b) const - { - return internal::pmul(pconj(a), b); - } -}; - -template<> struct conj_helper -{ - EIGEN_STRONG_INLINE Packet2cf pmadd(const Packet2cf& x, const Packet2cf& y, const Packet2cf& c) const - { return padd(pmul(x,y),c); } - - EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& a, const Packet2cf& b) const - { - return pconj(internal::pmul(a, b)); - } -}; - -template<> EIGEN_STRONG_INLINE Packet2cf pdiv(const Packet2cf& a, const Packet2cf& b) -{ - // TODO optimize it for AltiVec - Packet2cf res = conj_helper().pmul(a,b); - Packet4f s, rev_s; - - // this computes the norm - s = vmulq_f32(b.v, b.v); - rev_s = vrev64q_f32(s); - - return Packet2cf(pdiv(res.v, vaddq_f32(s,rev_s))); -} - -} // end namespace internal - -} // end namespace Eigen - -#endif // EIGEN_COMPLEX_NEON_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/arch/NEON/PacketMath.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/arch/NEON/PacketMath.h deleted file mode 100644 index d49670e0..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Core/arch/NEON/PacketMath.h +++ /dev/null @@ -1,420 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2009 Gael Guennebaud -// Copyright (C) 2010 Konstantinos Margaritis -// Heavily based on Gael's SSE version. -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_PACKET_MATH_NEON_H -#define EIGEN_PACKET_MATH_NEON_H - -namespace Eigen { - -namespace internal { - -#ifndef EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD -#define EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD 8 -#endif - -// FIXME NEON has 16 quad registers, but since the current register allocator -// is so bad, it is much better to reduce it to 8 -#ifndef EIGEN_ARCH_DEFAULT_NUMBER_OF_REGISTERS -#define EIGEN_ARCH_DEFAULT_NUMBER_OF_REGISTERS 8 -#endif - -typedef float32x4_t Packet4f; -typedef int32x4_t Packet4i; -typedef uint32x4_t Packet4ui; - -#define _EIGEN_DECLARE_CONST_Packet4f(NAME,X) \ - const Packet4f p4f_##NAME = pset1(X) - -#define _EIGEN_DECLARE_CONST_Packet4f_FROM_INT(NAME,X) \ - const Packet4f p4f_##NAME = vreinterpretq_f32_u32(pset1(X)) - -#define _EIGEN_DECLARE_CONST_Packet4i(NAME,X) \ - const Packet4i p4i_##NAME = pset1(X) - -#if defined(__llvm__) && !defined(__clang__) - //Special treatment for Apple's llvm-gcc, its NEON packet types are unions - #define EIGEN_INIT_NEON_PACKET2(X, Y) {{X, Y}} - #define EIGEN_INIT_NEON_PACKET4(X, Y, Z, W) {{X, Y, Z, W}} -#else - //Default initializer for packets - #define EIGEN_INIT_NEON_PACKET2(X, Y) {X, Y} - #define EIGEN_INIT_NEON_PACKET4(X, Y, Z, W) {X, Y, Z, W} -#endif - -// arm64 does have the pld instruction. If available, let's trust the __builtin_prefetch built-in function -// which available on LLVM and GCC (at least) -#if EIGEN_HAS_BUILTIN(__builtin_prefetch) || defined(__GNUC__) - #define EIGEN_ARM_PREFETCH(ADDR) __builtin_prefetch(ADDR); -#elif defined __pld - #define EIGEN_ARM_PREFETCH(ADDR) __pld(ADDR) -#elif !defined(__aarch64__) - #define EIGEN_ARM_PREFETCH(ADDR) __asm__ __volatile__ ( " pld [%[addr]]\n" :: [addr] "r" (ADDR) : "cc" ); -#else - // by default no explicit prefetching - #define EIGEN_ARM_PREFETCH(ADDR) -#endif - -template<> struct packet_traits : default_packet_traits -{ - typedef Packet4f type; - enum { - Vectorizable = 1, - AlignedOnScalar = 1, - size = 4, - - HasDiv = 1, - // FIXME check the Has* - HasSin = 0, - HasCos = 0, - HasLog = 0, - HasExp = 0, - HasSqrt = 0 - }; -}; -template<> struct packet_traits : default_packet_traits -{ - typedef Packet4i type; - enum { - Vectorizable = 1, - AlignedOnScalar = 1, - size=4 - // FIXME check the Has* - }; -}; - -#if EIGEN_GNUC_AT_MOST(4,4) && !defined(__llvm__) -// workaround gcc 4.2, 4.3 and 4.4 compilatin issue -EIGEN_STRONG_INLINE float32x4_t vld1q_f32(const float* x) { return ::vld1q_f32((const float32_t*)x); } -EIGEN_STRONG_INLINE float32x2_t vld1_f32 (const float* x) { return ::vld1_f32 ((const float32_t*)x); } -EIGEN_STRONG_INLINE void vst1q_f32(float* to, float32x4_t from) { ::vst1q_f32((float32_t*)to,from); } -EIGEN_STRONG_INLINE void vst1_f32 (float* to, float32x2_t from) { ::vst1_f32 ((float32_t*)to,from); } -#endif - -template<> struct unpacket_traits { typedef float type; enum {size=4}; }; -template<> struct unpacket_traits { typedef int type; enum {size=4}; }; - -template<> EIGEN_STRONG_INLINE Packet4f pset1(const float& from) { return vdupq_n_f32(from); } -template<> EIGEN_STRONG_INLINE Packet4i pset1(const int& from) { return vdupq_n_s32(from); } - -template<> EIGEN_STRONG_INLINE Packet4f plset(const float& a) -{ - Packet4f countdown = EIGEN_INIT_NEON_PACKET4(0, 1, 2, 3); - return vaddq_f32(pset1(a), countdown); -} -template<> EIGEN_STRONG_INLINE Packet4i plset(const int& a) -{ - Packet4i countdown = EIGEN_INIT_NEON_PACKET4(0, 1, 2, 3); - return vaddq_s32(pset1(a), countdown); -} - -template<> EIGEN_STRONG_INLINE Packet4f padd(const Packet4f& a, const Packet4f& b) { return vaddq_f32(a,b); } -template<> EIGEN_STRONG_INLINE Packet4i padd(const Packet4i& a, const Packet4i& b) { return vaddq_s32(a,b); } - -template<> EIGEN_STRONG_INLINE Packet4f psub(const Packet4f& a, const Packet4f& b) { return vsubq_f32(a,b); } -template<> EIGEN_STRONG_INLINE Packet4i psub(const Packet4i& a, const Packet4i& b) { return vsubq_s32(a,b); } - -template<> EIGEN_STRONG_INLINE Packet4f pnegate(const Packet4f& a) { return vnegq_f32(a); } -template<> EIGEN_STRONG_INLINE Packet4i pnegate(const Packet4i& a) { return vnegq_s32(a); } - -template<> EIGEN_STRONG_INLINE Packet4f pconj(const Packet4f& a) { return a; } -template<> EIGEN_STRONG_INLINE Packet4i pconj(const Packet4i& a) { return a; } - -template<> EIGEN_STRONG_INLINE Packet4f pmul(const Packet4f& a, const Packet4f& b) { return vmulq_f32(a,b); } -template<> EIGEN_STRONG_INLINE Packet4i pmul(const Packet4i& a, const Packet4i& b) { return vmulq_s32(a,b); } - -template<> EIGEN_STRONG_INLINE Packet4f pdiv(const Packet4f& a, const Packet4f& b) -{ - Packet4f inv, restep, div; - - // NEON does not offer a divide instruction, we have to do a reciprocal approximation - // However NEON in contrast to other SIMD engines (AltiVec/SSE), offers - // a reciprocal estimate AND a reciprocal step -which saves a few instructions - // vrecpeq_f32() returns an estimate to 1/b, which we will finetune with - // Newton-Raphson and vrecpsq_f32() - inv = vrecpeq_f32(b); - - // This returns a differential, by which we will have to multiply inv to get a better - // approximation of 1/b. - restep = vrecpsq_f32(b, inv); - inv = vmulq_f32(restep, inv); - - // Finally, multiply a by 1/b and get the wanted result of the division. - div = vmulq_f32(a, inv); - - return div; -} -template<> EIGEN_STRONG_INLINE Packet4i pdiv(const Packet4i& /*a*/, const Packet4i& /*b*/) -{ eigen_assert(false && "packet integer division are not supported by NEON"); - return pset1(0); -} - -// for some weird raisons, it has to be overloaded for packet of integers -template<> EIGEN_STRONG_INLINE Packet4f pmadd(const Packet4f& a, const Packet4f& b, const Packet4f& c) { return vmlaq_f32(c,a,b); } -template<> EIGEN_STRONG_INLINE Packet4i pmadd(const Packet4i& a, const Packet4i& b, const Packet4i& c) { return vmlaq_s32(c,a,b); } - -template<> EIGEN_STRONG_INLINE Packet4f pmin(const Packet4f& a, const Packet4f& b) { return vminq_f32(a,b); } -template<> EIGEN_STRONG_INLINE Packet4i pmin(const Packet4i& a, const Packet4i& b) { return vminq_s32(a,b); } - -template<> EIGEN_STRONG_INLINE Packet4f pmax(const Packet4f& a, const Packet4f& b) { return vmaxq_f32(a,b); } -template<> EIGEN_STRONG_INLINE Packet4i pmax(const Packet4i& a, const Packet4i& b) { return vmaxq_s32(a,b); } - -// Logical Operations are not supported for float, so we have to reinterpret casts using NEON intrinsics -template<> EIGEN_STRONG_INLINE Packet4f pand(const Packet4f& a, const Packet4f& b) -{ - return vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(a),vreinterpretq_u32_f32(b))); -} -template<> EIGEN_STRONG_INLINE Packet4i pand(const Packet4i& a, const Packet4i& b) { return vandq_s32(a,b); } - -template<> EIGEN_STRONG_INLINE Packet4f por(const Packet4f& a, const Packet4f& b) -{ - return vreinterpretq_f32_u32(vorrq_u32(vreinterpretq_u32_f32(a),vreinterpretq_u32_f32(b))); -} -template<> EIGEN_STRONG_INLINE Packet4i por(const Packet4i& a, const Packet4i& b) { return vorrq_s32(a,b); } - -template<> EIGEN_STRONG_INLINE Packet4f pxor(const Packet4f& a, const Packet4f& b) -{ - return vreinterpretq_f32_u32(veorq_u32(vreinterpretq_u32_f32(a),vreinterpretq_u32_f32(b))); -} -template<> EIGEN_STRONG_INLINE Packet4i pxor(const Packet4i& a, const Packet4i& b) { return veorq_s32(a,b); } - -template<> EIGEN_STRONG_INLINE Packet4f pandnot(const Packet4f& a, const Packet4f& b) -{ - return vreinterpretq_f32_u32(vbicq_u32(vreinterpretq_u32_f32(a),vreinterpretq_u32_f32(b))); -} -template<> EIGEN_STRONG_INLINE Packet4i pandnot(const Packet4i& a, const Packet4i& b) { return vbicq_s32(a,b); } - -template<> EIGEN_STRONG_INLINE Packet4f pload(const float* from) { EIGEN_DEBUG_ALIGNED_LOAD return vld1q_f32(from); } -template<> EIGEN_STRONG_INLINE Packet4i pload(const int* from) { EIGEN_DEBUG_ALIGNED_LOAD return vld1q_s32(from); } - -template<> EIGEN_STRONG_INLINE Packet4f ploadu(const float* from) { EIGEN_DEBUG_UNALIGNED_LOAD return vld1q_f32(from); } -template<> EIGEN_STRONG_INLINE Packet4i ploadu(const int* from) { EIGEN_DEBUG_UNALIGNED_LOAD return vld1q_s32(from); } - -template<> EIGEN_STRONG_INLINE Packet4f ploaddup(const float* from) -{ - float32x2_t lo, hi; - lo = vld1_dup_f32(from); - hi = vld1_dup_f32(from+1); - return vcombine_f32(lo, hi); -} -template<> EIGEN_STRONG_INLINE Packet4i ploaddup(const int* from) -{ - int32x2_t lo, hi; - lo = vld1_dup_s32(from); - hi = vld1_dup_s32(from+1); - return vcombine_s32(lo, hi); -} - -template<> EIGEN_STRONG_INLINE void pstore(float* to, const Packet4f& from) { EIGEN_DEBUG_ALIGNED_STORE vst1q_f32(to, from); } -template<> EIGEN_STRONG_INLINE void pstore(int* to, const Packet4i& from) { EIGEN_DEBUG_ALIGNED_STORE vst1q_s32(to, from); } - -template<> EIGEN_STRONG_INLINE void pstoreu(float* to, const Packet4f& from) { EIGEN_DEBUG_UNALIGNED_STORE vst1q_f32(to, from); } -template<> EIGEN_STRONG_INLINE void pstoreu(int* to, const Packet4i& from) { EIGEN_DEBUG_UNALIGNED_STORE vst1q_s32(to, from); } - -template<> EIGEN_STRONG_INLINE void prefetch(const float* addr) { EIGEN_ARM_PREFETCH(addr); } -template<> EIGEN_STRONG_INLINE void prefetch(const int* addr) { EIGEN_ARM_PREFETCH(addr); } - -// FIXME only store the 2 first elements ? -template<> EIGEN_STRONG_INLINE float pfirst(const Packet4f& a) { float EIGEN_ALIGN16 x[4]; vst1q_f32(x, a); return x[0]; } -template<> EIGEN_STRONG_INLINE int pfirst(const Packet4i& a) { int EIGEN_ALIGN16 x[4]; vst1q_s32(x, a); return x[0]; } - -template<> EIGEN_STRONG_INLINE Packet4f preverse(const Packet4f& a) { - float32x2_t a_lo, a_hi; - Packet4f a_r64; - - a_r64 = vrev64q_f32(a); - a_lo = vget_low_f32(a_r64); - a_hi = vget_high_f32(a_r64); - return vcombine_f32(a_hi, a_lo); -} -template<> EIGEN_STRONG_INLINE Packet4i preverse(const Packet4i& a) { - int32x2_t a_lo, a_hi; - Packet4i a_r64; - - a_r64 = vrev64q_s32(a); - a_lo = vget_low_s32(a_r64); - a_hi = vget_high_s32(a_r64); - return vcombine_s32(a_hi, a_lo); -} -template<> EIGEN_STRONG_INLINE Packet4f pabs(const Packet4f& a) { return vabsq_f32(a); } -template<> EIGEN_STRONG_INLINE Packet4i pabs(const Packet4i& a) { return vabsq_s32(a); } - -template<> EIGEN_STRONG_INLINE float predux(const Packet4f& a) -{ - float32x2_t a_lo, a_hi, sum; - - a_lo = vget_low_f32(a); - a_hi = vget_high_f32(a); - sum = vpadd_f32(a_lo, a_hi); - sum = vpadd_f32(sum, sum); - return vget_lane_f32(sum, 0); -} - -template<> EIGEN_STRONG_INLINE Packet4f preduxp(const Packet4f* vecs) -{ - float32x4x2_t vtrn1, vtrn2, res1, res2; - Packet4f sum1, sum2, sum; - - // NEON zip performs interleaving of the supplied vectors. - // We perform two interleaves in a row to acquire the transposed vector - vtrn1 = vzipq_f32(vecs[0], vecs[2]); - vtrn2 = vzipq_f32(vecs[1], vecs[3]); - res1 = vzipq_f32(vtrn1.val[0], vtrn2.val[0]); - res2 = vzipq_f32(vtrn1.val[1], vtrn2.val[1]); - - // Do the addition of the resulting vectors - sum1 = vaddq_f32(res1.val[0], res1.val[1]); - sum2 = vaddq_f32(res2.val[0], res2.val[1]); - sum = vaddq_f32(sum1, sum2); - - return sum; -} - -template<> EIGEN_STRONG_INLINE int predux(const Packet4i& a) -{ - int32x2_t a_lo, a_hi, sum; - - a_lo = vget_low_s32(a); - a_hi = vget_high_s32(a); - sum = vpadd_s32(a_lo, a_hi); - sum = vpadd_s32(sum, sum); - return vget_lane_s32(sum, 0); -} - -template<> EIGEN_STRONG_INLINE Packet4i preduxp(const Packet4i* vecs) -{ - int32x4x2_t vtrn1, vtrn2, res1, res2; - Packet4i sum1, sum2, sum; - - // NEON zip performs interleaving of the supplied vectors. - // We perform two interleaves in a row to acquire the transposed vector - vtrn1 = vzipq_s32(vecs[0], vecs[2]); - vtrn2 = vzipq_s32(vecs[1], vecs[3]); - res1 = vzipq_s32(vtrn1.val[0], vtrn2.val[0]); - res2 = vzipq_s32(vtrn1.val[1], vtrn2.val[1]); - - // Do the addition of the resulting vectors - sum1 = vaddq_s32(res1.val[0], res1.val[1]); - sum2 = vaddq_s32(res2.val[0], res2.val[1]); - sum = vaddq_s32(sum1, sum2); - - return sum; -} - -// Other reduction functions: -// mul -template<> EIGEN_STRONG_INLINE float predux_mul(const Packet4f& a) -{ - float32x2_t a_lo, a_hi, prod; - - // Get a_lo = |a1|a2| and a_hi = |a3|a4| - a_lo = vget_low_f32(a); - a_hi = vget_high_f32(a); - // Get the product of a_lo * a_hi -> |a1*a3|a2*a4| - prod = vmul_f32(a_lo, a_hi); - // Multiply prod with its swapped value |a2*a4|a1*a3| - prod = vmul_f32(prod, vrev64_f32(prod)); - - return vget_lane_f32(prod, 0); -} -template<> EIGEN_STRONG_INLINE int predux_mul(const Packet4i& a) -{ - int32x2_t a_lo, a_hi, prod; - - // Get a_lo = |a1|a2| and a_hi = |a3|a4| - a_lo = vget_low_s32(a); - a_hi = vget_high_s32(a); - // Get the product of a_lo * a_hi -> |a1*a3|a2*a4| - prod = vmul_s32(a_lo, a_hi); - // Multiply prod with its swapped value |a2*a4|a1*a3| - prod = vmul_s32(prod, vrev64_s32(prod)); - - return vget_lane_s32(prod, 0); -} - -// min -template<> EIGEN_STRONG_INLINE float predux_min(const Packet4f& a) -{ - float32x2_t a_lo, a_hi, min; - - a_lo = vget_low_f32(a); - a_hi = vget_high_f32(a); - min = vpmin_f32(a_lo, a_hi); - min = vpmin_f32(min, min); - - return vget_lane_f32(min, 0); -} - -template<> EIGEN_STRONG_INLINE int predux_min(const Packet4i& a) -{ - int32x2_t a_lo, a_hi, min; - - a_lo = vget_low_s32(a); - a_hi = vget_high_s32(a); - min = vpmin_s32(a_lo, a_hi); - min = vpmin_s32(min, min); - - return vget_lane_s32(min, 0); -} - -// max -template<> EIGEN_STRONG_INLINE float predux_max(const Packet4f& a) -{ - float32x2_t a_lo, a_hi, max; - - a_lo = vget_low_f32(a); - a_hi = vget_high_f32(a); - max = vpmax_f32(a_lo, a_hi); - max = vpmax_f32(max, max); - - return vget_lane_f32(max, 0); -} - -template<> EIGEN_STRONG_INLINE int predux_max(const Packet4i& a) -{ - int32x2_t a_lo, a_hi, max; - - a_lo = vget_low_s32(a); - a_hi = vget_high_s32(a); - max = vpmax_s32(a_lo, a_hi); - max = vpmax_s32(max, max); - - return vget_lane_s32(max, 0); -} - -// this PALIGN_NEON business is to work around a bug in LLVM Clang 3.0 causing incorrect compilation errors, -// see bug 347 and this LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=11074 -#define PALIGN_NEON(Offset,Type,Command) \ -template<>\ -struct palign_impl\ -{\ - EIGEN_STRONG_INLINE static void run(Type& first, const Type& second)\ - {\ - if (Offset!=0)\ - first = Command(first, second, Offset);\ - }\ -};\ - -PALIGN_NEON(0,Packet4f,vextq_f32) -PALIGN_NEON(1,Packet4f,vextq_f32) -PALIGN_NEON(2,Packet4f,vextq_f32) -PALIGN_NEON(3,Packet4f,vextq_f32) -PALIGN_NEON(0,Packet4i,vextq_s32) -PALIGN_NEON(1,Packet4i,vextq_s32) -PALIGN_NEON(2,Packet4i,vextq_s32) -PALIGN_NEON(3,Packet4i,vextq_s32) - -#undef PALIGN_NEON - -} // end namespace internal - -} // end namespace Eigen - -#endif // EIGEN_PACKET_MATH_NEON_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/arch/SSE/Complex.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/arch/SSE/Complex.h deleted file mode 100644 index 91bba5e3..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Core/arch/SSE/Complex.h +++ /dev/null @@ -1,442 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2010 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_COMPLEX_SSE_H -#define EIGEN_COMPLEX_SSE_H - -namespace Eigen { - -namespace internal { - -//---------- float ---------- -struct Packet2cf -{ - EIGEN_STRONG_INLINE Packet2cf() {} - EIGEN_STRONG_INLINE explicit Packet2cf(const __m128& a) : v(a) {} - __m128 v; -}; - -template<> struct packet_traits > : default_packet_traits -{ - typedef Packet2cf type; - enum { - Vectorizable = 1, - AlignedOnScalar = 1, - size = 2, - - HasAdd = 1, - HasSub = 1, - HasMul = 1, - HasDiv = 1, - HasNegate = 1, - HasAbs = 0, - HasAbs2 = 0, - HasMin = 0, - HasMax = 0, - HasSetLinear = 0 - }; -}; - -template<> struct unpacket_traits { typedef std::complex type; enum {size=2}; }; - -template<> EIGEN_STRONG_INLINE Packet2cf padd(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(_mm_add_ps(a.v,b.v)); } -template<> EIGEN_STRONG_INLINE Packet2cf psub(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(_mm_sub_ps(a.v,b.v)); } -template<> EIGEN_STRONG_INLINE Packet2cf pnegate(const Packet2cf& a) -{ - const __m128 mask = _mm_castsi128_ps(_mm_setr_epi32(0x80000000,0x80000000,0x80000000,0x80000000)); - return Packet2cf(_mm_xor_ps(a.v,mask)); -} -template<> EIGEN_STRONG_INLINE Packet2cf pconj(const Packet2cf& a) -{ - const __m128 mask = _mm_castsi128_ps(_mm_setr_epi32(0x00000000,0x80000000,0x00000000,0x80000000)); - return Packet2cf(_mm_xor_ps(a.v,mask)); -} - -template<> EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& a, const Packet2cf& b) -{ - // TODO optimize it for SSE3 and 4 - #ifdef EIGEN_VECTORIZE_SSE3 - return Packet2cf(_mm_addsub_ps(_mm_mul_ps(_mm_moveldup_ps(a.v), b.v), - _mm_mul_ps(_mm_movehdup_ps(a.v), - vec4f_swizzle1(b.v, 1, 0, 3, 2)))); -// return Packet2cf(_mm_addsub_ps(_mm_mul_ps(vec4f_swizzle1(a.v, 0, 0, 2, 2), b.v), -// _mm_mul_ps(vec4f_swizzle1(a.v, 1, 1, 3, 3), -// vec4f_swizzle1(b.v, 1, 0, 3, 2)))); - #else - const __m128 mask = _mm_castsi128_ps(_mm_setr_epi32(0x80000000,0x00000000,0x80000000,0x00000000)); - return Packet2cf(_mm_add_ps(_mm_mul_ps(vec4f_swizzle1(a.v, 0, 0, 2, 2), b.v), - _mm_xor_ps(_mm_mul_ps(vec4f_swizzle1(a.v, 1, 1, 3, 3), - vec4f_swizzle1(b.v, 1, 0, 3, 2)), mask))); - #endif -} - -template<> EIGEN_STRONG_INLINE Packet2cf pand (const Packet2cf& a, const Packet2cf& b) { return Packet2cf(_mm_and_ps(a.v,b.v)); } -template<> EIGEN_STRONG_INLINE Packet2cf por (const Packet2cf& a, const Packet2cf& b) { return Packet2cf(_mm_or_ps(a.v,b.v)); } -template<> EIGEN_STRONG_INLINE Packet2cf pxor (const Packet2cf& a, const Packet2cf& b) { return Packet2cf(_mm_xor_ps(a.v,b.v)); } -template<> EIGEN_STRONG_INLINE Packet2cf pandnot(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(_mm_andnot_ps(a.v,b.v)); } - -template<> EIGEN_STRONG_INLINE Packet2cf pload (const std::complex* from) { EIGEN_DEBUG_ALIGNED_LOAD return Packet2cf(pload(&numext::real_ref(*from))); } -template<> EIGEN_STRONG_INLINE Packet2cf ploadu(const std::complex* from) { EIGEN_DEBUG_UNALIGNED_LOAD return Packet2cf(ploadu(&numext::real_ref(*from))); } - -template<> EIGEN_STRONG_INLINE Packet2cf pset1(const std::complex& from) -{ - Packet2cf res; -#if EIGEN_GNUC_AT_MOST(4,2) - // Workaround annoying "may be used uninitialized in this function" warning with gcc 4.2 - res.v = _mm_loadl_pi(_mm_set1_ps(0.0f), reinterpret_cast(&from)); -#elif EIGEN_GNUC_AT_LEAST(4,6) - // Suppress annoying "may be used uninitialized in this function" warning with gcc >= 4.6 - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wuninitialized" - res.v = _mm_loadl_pi(res.v, (const __m64*)&from); - #pragma GCC diagnostic pop -#else - res.v = _mm_loadl_pi(res.v, (const __m64*)&from); -#endif - return Packet2cf(_mm_movelh_ps(res.v,res.v)); -} - -template<> EIGEN_STRONG_INLINE Packet2cf ploaddup(const std::complex* from) { return pset1(*from); } - -template<> EIGEN_STRONG_INLINE void pstore >(std::complex * to, const Packet2cf& from) { EIGEN_DEBUG_ALIGNED_STORE pstore(&numext::real_ref(*to), from.v); } -template<> EIGEN_STRONG_INLINE void pstoreu >(std::complex * to, const Packet2cf& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu(&numext::real_ref(*to), from.v); } - -template<> EIGEN_STRONG_INLINE void prefetch >(const std::complex * addr) { _mm_prefetch((const char*)(addr), _MM_HINT_T0); } - -template<> EIGEN_STRONG_INLINE std::complex pfirst(const Packet2cf& a) -{ - #if EIGEN_GNUC_AT_MOST(4,3) - // Workaround gcc 4.2 ICE - this is not performance wise ideal, but who cares... - // This workaround also fix invalid code generation with gcc 4.3 - EIGEN_ALIGN16 std::complex res[2]; - _mm_store_ps((float*)res, a.v); - return res[0]; - #else - std::complex res; - _mm_storel_pi((__m64*)&res, a.v); - return res; - #endif -} - -template<> EIGEN_STRONG_INLINE Packet2cf preverse(const Packet2cf& a) { return Packet2cf(_mm_castpd_ps(preverse(_mm_castps_pd(a.v)))); } - -template<> EIGEN_STRONG_INLINE std::complex predux(const Packet2cf& a) -{ - return pfirst(Packet2cf(_mm_add_ps(a.v, _mm_movehl_ps(a.v,a.v)))); -} - -template<> EIGEN_STRONG_INLINE Packet2cf preduxp(const Packet2cf* vecs) -{ - return Packet2cf(_mm_add_ps(_mm_movelh_ps(vecs[0].v,vecs[1].v), _mm_movehl_ps(vecs[1].v,vecs[0].v))); -} - -template<> EIGEN_STRONG_INLINE std::complex predux_mul(const Packet2cf& a) -{ - return pfirst(pmul(a, Packet2cf(_mm_movehl_ps(a.v,a.v)))); -} - -template -struct palign_impl -{ - static EIGEN_STRONG_INLINE void run(Packet2cf& first, const Packet2cf& second) - { - if (Offset==1) - { - first.v = _mm_movehl_ps(first.v, first.v); - first.v = _mm_movelh_ps(first.v, second.v); - } - } -}; - -template<> struct conj_helper -{ - EIGEN_STRONG_INLINE Packet2cf pmadd(const Packet2cf& x, const Packet2cf& y, const Packet2cf& c) const - { return padd(pmul(x,y),c); } - - EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& a, const Packet2cf& b) const - { - #ifdef EIGEN_VECTORIZE_SSE3 - return internal::pmul(a, pconj(b)); - #else - const __m128 mask = _mm_castsi128_ps(_mm_setr_epi32(0x00000000,0x80000000,0x00000000,0x80000000)); - return Packet2cf(_mm_add_ps(_mm_xor_ps(_mm_mul_ps(vec4f_swizzle1(a.v, 0, 0, 2, 2), b.v), mask), - _mm_mul_ps(vec4f_swizzle1(a.v, 1, 1, 3, 3), - vec4f_swizzle1(b.v, 1, 0, 3, 2)))); - #endif - } -}; - -template<> struct conj_helper -{ - EIGEN_STRONG_INLINE Packet2cf pmadd(const Packet2cf& x, const Packet2cf& y, const Packet2cf& c) const - { return padd(pmul(x,y),c); } - - EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& a, const Packet2cf& b) const - { - #ifdef EIGEN_VECTORIZE_SSE3 - return internal::pmul(pconj(a), b); - #else - const __m128 mask = _mm_castsi128_ps(_mm_setr_epi32(0x00000000,0x80000000,0x00000000,0x80000000)); - return Packet2cf(_mm_add_ps(_mm_mul_ps(vec4f_swizzle1(a.v, 0, 0, 2, 2), b.v), - _mm_xor_ps(_mm_mul_ps(vec4f_swizzle1(a.v, 1, 1, 3, 3), - vec4f_swizzle1(b.v, 1, 0, 3, 2)), mask))); - #endif - } -}; - -template<> struct conj_helper -{ - EIGEN_STRONG_INLINE Packet2cf pmadd(const Packet2cf& x, const Packet2cf& y, const Packet2cf& c) const - { return padd(pmul(x,y),c); } - - EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& a, const Packet2cf& b) const - { - #ifdef EIGEN_VECTORIZE_SSE3 - return pconj(internal::pmul(a, b)); - #else - const __m128 mask = _mm_castsi128_ps(_mm_setr_epi32(0x00000000,0x80000000,0x00000000,0x80000000)); - return Packet2cf(_mm_sub_ps(_mm_xor_ps(_mm_mul_ps(vec4f_swizzle1(a.v, 0, 0, 2, 2), b.v), mask), - _mm_mul_ps(vec4f_swizzle1(a.v, 1, 1, 3, 3), - vec4f_swizzle1(b.v, 1, 0, 3, 2)))); - #endif - } -}; - -template<> struct conj_helper -{ - EIGEN_STRONG_INLINE Packet2cf pmadd(const Packet4f& x, const Packet2cf& y, const Packet2cf& c) const - { return padd(c, pmul(x,y)); } - - EIGEN_STRONG_INLINE Packet2cf pmul(const Packet4f& x, const Packet2cf& y) const - { return Packet2cf(Eigen::internal::pmul(x, y.v)); } -}; - -template<> struct conj_helper -{ - EIGEN_STRONG_INLINE Packet2cf pmadd(const Packet2cf& x, const Packet4f& y, const Packet2cf& c) const - { return padd(c, pmul(x,y)); } - - EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& x, const Packet4f& y) const - { return Packet2cf(Eigen::internal::pmul(x.v, y)); } -}; - -template<> EIGEN_STRONG_INLINE Packet2cf pdiv(const Packet2cf& a, const Packet2cf& b) -{ - // TODO optimize it for SSE3 and 4 - Packet2cf res = conj_helper().pmul(a,b); - __m128 s = _mm_mul_ps(b.v,b.v); - return Packet2cf(_mm_div_ps(res.v,_mm_add_ps(s,_mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(s), 0xb1))))); -} - -EIGEN_STRONG_INLINE Packet2cf pcplxflip/**/(const Packet2cf& x) -{ - return Packet2cf(vec4f_swizzle1(x.v, 1, 0, 3, 2)); -} - - -//---------- double ---------- -struct Packet1cd -{ - EIGEN_STRONG_INLINE Packet1cd() {} - EIGEN_STRONG_INLINE explicit Packet1cd(const __m128d& a) : v(a) {} - __m128d v; -}; - -template<> struct packet_traits > : default_packet_traits -{ - typedef Packet1cd type; - enum { - Vectorizable = 1, - AlignedOnScalar = 0, - size = 1, - - HasAdd = 1, - HasSub = 1, - HasMul = 1, - HasDiv = 1, - HasNegate = 1, - HasAbs = 0, - HasAbs2 = 0, - HasMin = 0, - HasMax = 0, - HasSetLinear = 0 - }; -}; - -template<> struct unpacket_traits { typedef std::complex type; enum {size=1}; }; - -template<> EIGEN_STRONG_INLINE Packet1cd padd(const Packet1cd& a, const Packet1cd& b) { return Packet1cd(_mm_add_pd(a.v,b.v)); } -template<> EIGEN_STRONG_INLINE Packet1cd psub(const Packet1cd& a, const Packet1cd& b) { return Packet1cd(_mm_sub_pd(a.v,b.v)); } -template<> EIGEN_STRONG_INLINE Packet1cd pnegate(const Packet1cd& a) { return Packet1cd(pnegate(a.v)); } -template<> EIGEN_STRONG_INLINE Packet1cd pconj(const Packet1cd& a) -{ - const __m128d mask = _mm_castsi128_pd(_mm_set_epi32(0x80000000,0x0,0x0,0x0)); - return Packet1cd(_mm_xor_pd(a.v,mask)); -} - -template<> EIGEN_STRONG_INLINE Packet1cd pmul(const Packet1cd& a, const Packet1cd& b) -{ - // TODO optimize it for SSE3 and 4 - #ifdef EIGEN_VECTORIZE_SSE3 - return Packet1cd(_mm_addsub_pd(_mm_mul_pd(vec2d_swizzle1(a.v, 0, 0), b.v), - _mm_mul_pd(vec2d_swizzle1(a.v, 1, 1), - vec2d_swizzle1(b.v, 1, 0)))); - #else - const __m128d mask = _mm_castsi128_pd(_mm_set_epi32(0x0,0x0,0x80000000,0x0)); - return Packet1cd(_mm_add_pd(_mm_mul_pd(vec2d_swizzle1(a.v, 0, 0), b.v), - _mm_xor_pd(_mm_mul_pd(vec2d_swizzle1(a.v, 1, 1), - vec2d_swizzle1(b.v, 1, 0)), mask))); - #endif -} - -template<> EIGEN_STRONG_INLINE Packet1cd pand (const Packet1cd& a, const Packet1cd& b) { return Packet1cd(_mm_and_pd(a.v,b.v)); } -template<> EIGEN_STRONG_INLINE Packet1cd por (const Packet1cd& a, const Packet1cd& b) { return Packet1cd(_mm_or_pd(a.v,b.v)); } -template<> EIGEN_STRONG_INLINE Packet1cd pxor (const Packet1cd& a, const Packet1cd& b) { return Packet1cd(_mm_xor_pd(a.v,b.v)); } -template<> EIGEN_STRONG_INLINE Packet1cd pandnot(const Packet1cd& a, const Packet1cd& b) { return Packet1cd(_mm_andnot_pd(a.v,b.v)); } - -// FIXME force unaligned load, this is a temporary fix -template<> EIGEN_STRONG_INLINE Packet1cd pload (const std::complex* from) -{ EIGEN_DEBUG_ALIGNED_LOAD return Packet1cd(pload((const double*)from)); } -template<> EIGEN_STRONG_INLINE Packet1cd ploadu(const std::complex* from) -{ EIGEN_DEBUG_UNALIGNED_LOAD return Packet1cd(ploadu((const double*)from)); } -template<> EIGEN_STRONG_INLINE Packet1cd pset1(const std::complex& from) -{ /* here we really have to use unaligned loads :( */ return ploadu(&from); } - -template<> EIGEN_STRONG_INLINE Packet1cd ploaddup(const std::complex* from) { return pset1(*from); } - -// FIXME force unaligned store, this is a temporary fix -template<> EIGEN_STRONG_INLINE void pstore >(std::complex * to, const Packet1cd& from) { EIGEN_DEBUG_ALIGNED_STORE pstore((double*)to, from.v); } -template<> EIGEN_STRONG_INLINE void pstoreu >(std::complex * to, const Packet1cd& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu((double*)to, from.v); } - -template<> EIGEN_STRONG_INLINE void prefetch >(const std::complex * addr) { _mm_prefetch((const char*)(addr), _MM_HINT_T0); } - -template<> EIGEN_STRONG_INLINE std::complex pfirst(const Packet1cd& a) -{ - EIGEN_ALIGN16 double res[2]; - _mm_store_pd(res, a.v); - return std::complex(res[0],res[1]); -} - -template<> EIGEN_STRONG_INLINE Packet1cd preverse(const Packet1cd& a) { return a; } - -template<> EIGEN_STRONG_INLINE std::complex predux(const Packet1cd& a) -{ - return pfirst(a); -} - -template<> EIGEN_STRONG_INLINE Packet1cd preduxp(const Packet1cd* vecs) -{ - return vecs[0]; -} - -template<> EIGEN_STRONG_INLINE std::complex predux_mul(const Packet1cd& a) -{ - return pfirst(a); -} - -template -struct palign_impl -{ - static EIGEN_STRONG_INLINE void run(Packet1cd& /*first*/, const Packet1cd& /*second*/) - { - // FIXME is it sure we never have to align a Packet1cd? - // Even though a std::complex has 16 bytes, it is not necessarily aligned on a 16 bytes boundary... - } -}; - -template<> struct conj_helper -{ - EIGEN_STRONG_INLINE Packet1cd pmadd(const Packet1cd& x, const Packet1cd& y, const Packet1cd& c) const - { return padd(pmul(x,y),c); } - - EIGEN_STRONG_INLINE Packet1cd pmul(const Packet1cd& a, const Packet1cd& b) const - { - #ifdef EIGEN_VECTORIZE_SSE3 - return internal::pmul(a, pconj(b)); - #else - const __m128d mask = _mm_castsi128_pd(_mm_set_epi32(0x80000000,0x0,0x0,0x0)); - return Packet1cd(_mm_add_pd(_mm_xor_pd(_mm_mul_pd(vec2d_swizzle1(a.v, 0, 0), b.v), mask), - _mm_mul_pd(vec2d_swizzle1(a.v, 1, 1), - vec2d_swizzle1(b.v, 1, 0)))); - #endif - } -}; - -template<> struct conj_helper -{ - EIGEN_STRONG_INLINE Packet1cd pmadd(const Packet1cd& x, const Packet1cd& y, const Packet1cd& c) const - { return padd(pmul(x,y),c); } - - EIGEN_STRONG_INLINE Packet1cd pmul(const Packet1cd& a, const Packet1cd& b) const - { - #ifdef EIGEN_VECTORIZE_SSE3 - return internal::pmul(pconj(a), b); - #else - const __m128d mask = _mm_castsi128_pd(_mm_set_epi32(0x80000000,0x0,0x0,0x0)); - return Packet1cd(_mm_add_pd(_mm_mul_pd(vec2d_swizzle1(a.v, 0, 0), b.v), - _mm_xor_pd(_mm_mul_pd(vec2d_swizzle1(a.v, 1, 1), - vec2d_swizzle1(b.v, 1, 0)), mask))); - #endif - } -}; - -template<> struct conj_helper -{ - EIGEN_STRONG_INLINE Packet1cd pmadd(const Packet1cd& x, const Packet1cd& y, const Packet1cd& c) const - { return padd(pmul(x,y),c); } - - EIGEN_STRONG_INLINE Packet1cd pmul(const Packet1cd& a, const Packet1cd& b) const - { - #ifdef EIGEN_VECTORIZE_SSE3 - return pconj(internal::pmul(a, b)); - #else - const __m128d mask = _mm_castsi128_pd(_mm_set_epi32(0x80000000,0x0,0x0,0x0)); - return Packet1cd(_mm_sub_pd(_mm_xor_pd(_mm_mul_pd(vec2d_swizzle1(a.v, 0, 0), b.v), mask), - _mm_mul_pd(vec2d_swizzle1(a.v, 1, 1), - vec2d_swizzle1(b.v, 1, 0)))); - #endif - } -}; - -template<> struct conj_helper -{ - EIGEN_STRONG_INLINE Packet1cd pmadd(const Packet2d& x, const Packet1cd& y, const Packet1cd& c) const - { return padd(c, pmul(x,y)); } - - EIGEN_STRONG_INLINE Packet1cd pmul(const Packet2d& x, const Packet1cd& y) const - { return Packet1cd(Eigen::internal::pmul(x, y.v)); } -}; - -template<> struct conj_helper -{ - EIGEN_STRONG_INLINE Packet1cd pmadd(const Packet1cd& x, const Packet2d& y, const Packet1cd& c) const - { return padd(c, pmul(x,y)); } - - EIGEN_STRONG_INLINE Packet1cd pmul(const Packet1cd& x, const Packet2d& y) const - { return Packet1cd(Eigen::internal::pmul(x.v, y)); } -}; - -template<> EIGEN_STRONG_INLINE Packet1cd pdiv(const Packet1cd& a, const Packet1cd& b) -{ - // TODO optimize it for SSE3 and 4 - Packet1cd res = conj_helper().pmul(a,b); - __m128d s = _mm_mul_pd(b.v,b.v); - return Packet1cd(_mm_div_pd(res.v, _mm_add_pd(s,_mm_shuffle_pd(s, s, 0x1)))); -} - -EIGEN_STRONG_INLINE Packet1cd pcplxflip/**/(const Packet1cd& x) -{ - return Packet1cd(preverse(x.v)); -} - -} // end namespace internal - -} // end namespace Eigen - -#endif // EIGEN_COMPLEX_SSE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/arch/SSE/MathFunctions.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/arch/SSE/MathFunctions.h deleted file mode 100644 index 2b07168a..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Core/arch/SSE/MathFunctions.h +++ /dev/null @@ -1,475 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2007 Julien Pommier -// Copyright (C) 2009 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -/* The sin, cos, exp, and log functions of this file come from - * Julien Pommier's sse math library: http://gruntthepeon.free.fr/ssemath/ - */ - -#ifndef EIGEN_MATH_FUNCTIONS_SSE_H -#define EIGEN_MATH_FUNCTIONS_SSE_H - -namespace Eigen { - -namespace internal { - -template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED -Packet4f plog(const Packet4f& _x) -{ - Packet4f x = _x; - _EIGEN_DECLARE_CONST_Packet4f(1 , 1.0f); - _EIGEN_DECLARE_CONST_Packet4f(half, 0.5f); - _EIGEN_DECLARE_CONST_Packet4i(0x7f, 0x7f); - - _EIGEN_DECLARE_CONST_Packet4f_FROM_INT(inv_mant_mask, ~0x7f800000); - - /* the smallest non denormalized float number */ - _EIGEN_DECLARE_CONST_Packet4f_FROM_INT(min_norm_pos, 0x00800000); - _EIGEN_DECLARE_CONST_Packet4f_FROM_INT(minus_inf, 0xff800000);//-1.f/0.f); - - /* natural logarithm computed for 4 simultaneous float - return NaN for x <= 0 - */ - _EIGEN_DECLARE_CONST_Packet4f(cephes_SQRTHF, 0.707106781186547524f); - _EIGEN_DECLARE_CONST_Packet4f(cephes_log_p0, 7.0376836292E-2f); - _EIGEN_DECLARE_CONST_Packet4f(cephes_log_p1, - 1.1514610310E-1f); - _EIGEN_DECLARE_CONST_Packet4f(cephes_log_p2, 1.1676998740E-1f); - _EIGEN_DECLARE_CONST_Packet4f(cephes_log_p3, - 1.2420140846E-1f); - _EIGEN_DECLARE_CONST_Packet4f(cephes_log_p4, + 1.4249322787E-1f); - _EIGEN_DECLARE_CONST_Packet4f(cephes_log_p5, - 1.6668057665E-1f); - _EIGEN_DECLARE_CONST_Packet4f(cephes_log_p6, + 2.0000714765E-1f); - _EIGEN_DECLARE_CONST_Packet4f(cephes_log_p7, - 2.4999993993E-1f); - _EIGEN_DECLARE_CONST_Packet4f(cephes_log_p8, + 3.3333331174E-1f); - _EIGEN_DECLARE_CONST_Packet4f(cephes_log_q1, -2.12194440e-4f); - _EIGEN_DECLARE_CONST_Packet4f(cephes_log_q2, 0.693359375f); - - - Packet4i emm0; - - Packet4f invalid_mask = _mm_cmpnge_ps(x, _mm_setzero_ps()); // not greater equal is true if x is NaN - Packet4f iszero_mask = _mm_cmpeq_ps(x, _mm_setzero_ps()); - - x = pmax(x, p4f_min_norm_pos); /* cut off denormalized stuff */ - emm0 = _mm_srli_epi32(_mm_castps_si128(x), 23); - - /* keep only the fractional part */ - x = _mm_and_ps(x, p4f_inv_mant_mask); - x = _mm_or_ps(x, p4f_half); - - emm0 = _mm_sub_epi32(emm0, p4i_0x7f); - Packet4f e = padd(_mm_cvtepi32_ps(emm0), p4f_1); - - /* part2: - if( x < SQRTHF ) { - e -= 1; - x = x + x - 1.0; - } else { x = x - 1.0; } - */ - Packet4f mask = _mm_cmplt_ps(x, p4f_cephes_SQRTHF); - Packet4f tmp = _mm_and_ps(x, mask); - x = psub(x, p4f_1); - e = psub(e, _mm_and_ps(p4f_1, mask)); - x = padd(x, tmp); - - Packet4f x2 = pmul(x,x); - Packet4f x3 = pmul(x2,x); - - Packet4f y, y1, y2; - y = pmadd(p4f_cephes_log_p0, x, p4f_cephes_log_p1); - y1 = pmadd(p4f_cephes_log_p3, x, p4f_cephes_log_p4); - y2 = pmadd(p4f_cephes_log_p6, x, p4f_cephes_log_p7); - y = pmadd(y , x, p4f_cephes_log_p2); - y1 = pmadd(y1, x, p4f_cephes_log_p5); - y2 = pmadd(y2, x, p4f_cephes_log_p8); - y = pmadd(y, x3, y1); - y = pmadd(y, x3, y2); - y = pmul(y, x3); - - y1 = pmul(e, p4f_cephes_log_q1); - tmp = pmul(x2, p4f_half); - y = padd(y, y1); - x = psub(x, tmp); - y2 = pmul(e, p4f_cephes_log_q2); - x = padd(x, y); - x = padd(x, y2); - // negative arg will be NAN, 0 will be -INF - return _mm_or_ps(_mm_andnot_ps(iszero_mask, _mm_or_ps(x, invalid_mask)), - _mm_and_ps(iszero_mask, p4f_minus_inf)); -} - -template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED -Packet4f pexp(const Packet4f& _x) -{ - Packet4f x = _x; - _EIGEN_DECLARE_CONST_Packet4f(1 , 1.0f); - _EIGEN_DECLARE_CONST_Packet4f(half, 0.5f); - _EIGEN_DECLARE_CONST_Packet4i(0x7f, 0x7f); - - - _EIGEN_DECLARE_CONST_Packet4f(exp_hi, 88.3762626647950f); - _EIGEN_DECLARE_CONST_Packet4f(exp_lo, -88.3762626647949f); - - _EIGEN_DECLARE_CONST_Packet4f(cephes_LOG2EF, 1.44269504088896341f); - _EIGEN_DECLARE_CONST_Packet4f(cephes_exp_C1, 0.693359375f); - _EIGEN_DECLARE_CONST_Packet4f(cephes_exp_C2, -2.12194440e-4f); - - _EIGEN_DECLARE_CONST_Packet4f(cephes_exp_p0, 1.9875691500E-4f); - _EIGEN_DECLARE_CONST_Packet4f(cephes_exp_p1, 1.3981999507E-3f); - _EIGEN_DECLARE_CONST_Packet4f(cephes_exp_p2, 8.3334519073E-3f); - _EIGEN_DECLARE_CONST_Packet4f(cephes_exp_p3, 4.1665795894E-2f); - _EIGEN_DECLARE_CONST_Packet4f(cephes_exp_p4, 1.6666665459E-1f); - _EIGEN_DECLARE_CONST_Packet4f(cephes_exp_p5, 5.0000001201E-1f); - - Packet4f tmp, fx; - Packet4i emm0; - - // clamp x - x = pmax(pmin(x, p4f_exp_hi), p4f_exp_lo); - - /* express exp(x) as exp(g + n*log(2)) */ - fx = pmadd(x, p4f_cephes_LOG2EF, p4f_half); - -#ifdef EIGEN_VECTORIZE_SSE4_1 - fx = _mm_floor_ps(fx); -#else - emm0 = _mm_cvttps_epi32(fx); - tmp = _mm_cvtepi32_ps(emm0); - /* if greater, substract 1 */ - Packet4f mask = _mm_cmpgt_ps(tmp, fx); - mask = _mm_and_ps(mask, p4f_1); - fx = psub(tmp, mask); -#endif - - tmp = pmul(fx, p4f_cephes_exp_C1); - Packet4f z = pmul(fx, p4f_cephes_exp_C2); - x = psub(x, tmp); - x = psub(x, z); - - z = pmul(x,x); - - Packet4f y = p4f_cephes_exp_p0; - y = pmadd(y, x, p4f_cephes_exp_p1); - y = pmadd(y, x, p4f_cephes_exp_p2); - y = pmadd(y, x, p4f_cephes_exp_p3); - y = pmadd(y, x, p4f_cephes_exp_p4); - y = pmadd(y, x, p4f_cephes_exp_p5); - y = pmadd(y, z, x); - y = padd(y, p4f_1); - - // build 2^n - emm0 = _mm_cvttps_epi32(fx); - emm0 = _mm_add_epi32(emm0, p4i_0x7f); - emm0 = _mm_slli_epi32(emm0, 23); - return pmax(pmul(y, Packet4f(_mm_castsi128_ps(emm0))), _x); -} -template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED -Packet2d pexp(const Packet2d& _x) -{ - Packet2d x = _x; - - _EIGEN_DECLARE_CONST_Packet2d(1 , 1.0); - _EIGEN_DECLARE_CONST_Packet2d(2 , 2.0); - _EIGEN_DECLARE_CONST_Packet2d(half, 0.5); - - _EIGEN_DECLARE_CONST_Packet2d(exp_hi, 709.437); - _EIGEN_DECLARE_CONST_Packet2d(exp_lo, -709.436139303); - - _EIGEN_DECLARE_CONST_Packet2d(cephes_LOG2EF, 1.4426950408889634073599); - - _EIGEN_DECLARE_CONST_Packet2d(cephes_exp_p0, 1.26177193074810590878e-4); - _EIGEN_DECLARE_CONST_Packet2d(cephes_exp_p1, 3.02994407707441961300e-2); - _EIGEN_DECLARE_CONST_Packet2d(cephes_exp_p2, 9.99999999999999999910e-1); - - _EIGEN_DECLARE_CONST_Packet2d(cephes_exp_q0, 3.00198505138664455042e-6); - _EIGEN_DECLARE_CONST_Packet2d(cephes_exp_q1, 2.52448340349684104192e-3); - _EIGEN_DECLARE_CONST_Packet2d(cephes_exp_q2, 2.27265548208155028766e-1); - _EIGEN_DECLARE_CONST_Packet2d(cephes_exp_q3, 2.00000000000000000009e0); - - _EIGEN_DECLARE_CONST_Packet2d(cephes_exp_C1, 0.693145751953125); - _EIGEN_DECLARE_CONST_Packet2d(cephes_exp_C2, 1.42860682030941723212e-6); - static const __m128i p4i_1023_0 = _mm_setr_epi32(1023, 1023, 0, 0); - - Packet2d tmp, fx; - Packet4i emm0; - - // clamp x - x = pmax(pmin(x, p2d_exp_hi), p2d_exp_lo); - /* express exp(x) as exp(g + n*log(2)) */ - fx = pmadd(p2d_cephes_LOG2EF, x, p2d_half); - -#ifdef EIGEN_VECTORIZE_SSE4_1 - fx = _mm_floor_pd(fx); -#else - emm0 = _mm_cvttpd_epi32(fx); - tmp = _mm_cvtepi32_pd(emm0); - /* if greater, substract 1 */ - Packet2d mask = _mm_cmpgt_pd(tmp, fx); - mask = _mm_and_pd(mask, p2d_1); - fx = psub(tmp, mask); -#endif - - tmp = pmul(fx, p2d_cephes_exp_C1); - Packet2d z = pmul(fx, p2d_cephes_exp_C2); - x = psub(x, tmp); - x = psub(x, z); - - Packet2d x2 = pmul(x,x); - - Packet2d px = p2d_cephes_exp_p0; - px = pmadd(px, x2, p2d_cephes_exp_p1); - px = pmadd(px, x2, p2d_cephes_exp_p2); - px = pmul (px, x); - - Packet2d qx = p2d_cephes_exp_q0; - qx = pmadd(qx, x2, p2d_cephes_exp_q1); - qx = pmadd(qx, x2, p2d_cephes_exp_q2); - qx = pmadd(qx, x2, p2d_cephes_exp_q3); - - x = pdiv(px,psub(qx,px)); - x = pmadd(p2d_2,x,p2d_1); - - // build 2^n - emm0 = _mm_cvttpd_epi32(fx); - emm0 = _mm_add_epi32(emm0, p4i_1023_0); - emm0 = _mm_slli_epi32(emm0, 20); - emm0 = _mm_shuffle_epi32(emm0, _MM_SHUFFLE(1,2,0,3)); - return pmax(pmul(x, Packet2d(_mm_castsi128_pd(emm0))), _x); -} - -/* evaluation of 4 sines at onces, using SSE2 intrinsics. - - The code is the exact rewriting of the cephes sinf function. - Precision is excellent as long as x < 8192 (I did not bother to - take into account the special handling they have for greater values - -- it does not return garbage for arguments over 8192, though, but - the extra precision is missing). - - Note that it is such that sinf((float)M_PI) = 8.74e-8, which is the - surprising but correct result. -*/ - -template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED -Packet4f psin(const Packet4f& _x) -{ - Packet4f x = _x; - _EIGEN_DECLARE_CONST_Packet4f(1 , 1.0f); - _EIGEN_DECLARE_CONST_Packet4f(half, 0.5f); - - _EIGEN_DECLARE_CONST_Packet4i(1, 1); - _EIGEN_DECLARE_CONST_Packet4i(not1, ~1); - _EIGEN_DECLARE_CONST_Packet4i(2, 2); - _EIGEN_DECLARE_CONST_Packet4i(4, 4); - - _EIGEN_DECLARE_CONST_Packet4f_FROM_INT(sign_mask, 0x80000000); - - _EIGEN_DECLARE_CONST_Packet4f(minus_cephes_DP1,-0.78515625f); - _EIGEN_DECLARE_CONST_Packet4f(minus_cephes_DP2, -2.4187564849853515625e-4f); - _EIGEN_DECLARE_CONST_Packet4f(minus_cephes_DP3, -3.77489497744594108e-8f); - _EIGEN_DECLARE_CONST_Packet4f(sincof_p0, -1.9515295891E-4f); - _EIGEN_DECLARE_CONST_Packet4f(sincof_p1, 8.3321608736E-3f); - _EIGEN_DECLARE_CONST_Packet4f(sincof_p2, -1.6666654611E-1f); - _EIGEN_DECLARE_CONST_Packet4f(coscof_p0, 2.443315711809948E-005f); - _EIGEN_DECLARE_CONST_Packet4f(coscof_p1, -1.388731625493765E-003f); - _EIGEN_DECLARE_CONST_Packet4f(coscof_p2, 4.166664568298827E-002f); - _EIGEN_DECLARE_CONST_Packet4f(cephes_FOPI, 1.27323954473516f); // 4 / M_PI - - Packet4f xmm1, xmm2, xmm3, sign_bit, y; - - Packet4i emm0, emm2; - sign_bit = x; - /* take the absolute value */ - x = pabs(x); - - /* take the modulo */ - - /* extract the sign bit (upper one) */ - sign_bit = _mm_and_ps(sign_bit, p4f_sign_mask); - - /* scale by 4/Pi */ - y = pmul(x, p4f_cephes_FOPI); - - /* store the integer part of y in mm0 */ - emm2 = _mm_cvttps_epi32(y); - /* j=(j+1) & (~1) (see the cephes sources) */ - emm2 = _mm_add_epi32(emm2, p4i_1); - emm2 = _mm_and_si128(emm2, p4i_not1); - y = _mm_cvtepi32_ps(emm2); - /* get the swap sign flag */ - emm0 = _mm_and_si128(emm2, p4i_4); - emm0 = _mm_slli_epi32(emm0, 29); - /* get the polynom selection mask - there is one polynom for 0 <= x <= Pi/4 - and another one for Pi/4 EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED -Packet4f pcos(const Packet4f& _x) -{ - Packet4f x = _x; - _EIGEN_DECLARE_CONST_Packet4f(1 , 1.0f); - _EIGEN_DECLARE_CONST_Packet4f(half, 0.5f); - - _EIGEN_DECLARE_CONST_Packet4i(1, 1); - _EIGEN_DECLARE_CONST_Packet4i(not1, ~1); - _EIGEN_DECLARE_CONST_Packet4i(2, 2); - _EIGEN_DECLARE_CONST_Packet4i(4, 4); - - _EIGEN_DECLARE_CONST_Packet4f(minus_cephes_DP1,-0.78515625f); - _EIGEN_DECLARE_CONST_Packet4f(minus_cephes_DP2, -2.4187564849853515625e-4f); - _EIGEN_DECLARE_CONST_Packet4f(minus_cephes_DP3, -3.77489497744594108e-8f); - _EIGEN_DECLARE_CONST_Packet4f(sincof_p0, -1.9515295891E-4f); - _EIGEN_DECLARE_CONST_Packet4f(sincof_p1, 8.3321608736E-3f); - _EIGEN_DECLARE_CONST_Packet4f(sincof_p2, -1.6666654611E-1f); - _EIGEN_DECLARE_CONST_Packet4f(coscof_p0, 2.443315711809948E-005f); - _EIGEN_DECLARE_CONST_Packet4f(coscof_p1, -1.388731625493765E-003f); - _EIGEN_DECLARE_CONST_Packet4f(coscof_p2, 4.166664568298827E-002f); - _EIGEN_DECLARE_CONST_Packet4f(cephes_FOPI, 1.27323954473516f); // 4 / M_PI - - Packet4f xmm1, xmm2, xmm3, y; - Packet4i emm0, emm2; - - x = pabs(x); - - /* scale by 4/Pi */ - y = pmul(x, p4f_cephes_FOPI); - - /* get the integer part of y */ - emm2 = _mm_cvttps_epi32(y); - /* j=(j+1) & (~1) (see the cephes sources) */ - emm2 = _mm_add_epi32(emm2, p4i_1); - emm2 = _mm_and_si128(emm2, p4i_not1); - y = _mm_cvtepi32_ps(emm2); - - emm2 = _mm_sub_epi32(emm2, p4i_2); - - /* get the swap sign flag */ - emm0 = _mm_andnot_si128(emm2, p4i_4); - emm0 = _mm_slli_epi32(emm0, 29); - /* get the polynom selection mask */ - emm2 = _mm_and_si128(emm2, p4i_2); - emm2 = _mm_cmpeq_epi32(emm2, _mm_setzero_si128()); - - Packet4f sign_bit = _mm_castsi128_ps(emm0); - Packet4f poly_mask = _mm_castsi128_ps(emm2); - - /* The magic pass: "Extended precision modular arithmetic" - x = ((x - y * DP1) - y * DP2) - y * DP3; */ - xmm1 = pmul(y, p4f_minus_cephes_DP1); - xmm2 = pmul(y, p4f_minus_cephes_DP2); - xmm3 = pmul(y, p4f_minus_cephes_DP3); - x = padd(x, xmm1); - x = padd(x, xmm2); - x = padd(x, xmm3); - - /* Evaluate the first polynom (0 <= x <= Pi/4) */ - y = p4f_coscof_p0; - Packet4f z = pmul(x,x); - - y = pmadd(y,z,p4f_coscof_p1); - y = pmadd(y,z,p4f_coscof_p2); - y = pmul(y, z); - y = pmul(y, z); - Packet4f tmp = _mm_mul_ps(z, p4f_half); - y = psub(y, tmp); - y = padd(y, p4f_1); - - /* Evaluate the second polynom (Pi/4 <= x <= 0) */ - Packet4f y2 = p4f_sincof_p0; - y2 = pmadd(y2, z, p4f_sincof_p1); - y2 = pmadd(y2, z, p4f_sincof_p2); - y2 = pmul(y2, z); - y2 = pmadd(y2, x, x); - - /* select the correct result from the two polynoms */ - y2 = _mm_and_ps(poly_mask, y2); - y = _mm_andnot_ps(poly_mask, y); - y = _mm_or_ps(y,y2); - - /* update the sign */ - return _mm_xor_ps(y, sign_bit); -} - -#if EIGEN_FAST_MATH - -// This is based on Quake3's fast inverse square root. -// For detail see here: http://www.beyond3d.com/content/articles/8/ -// It lacks 1 (or 2 bits in some rare cases) of precision, and does not handle negative, +inf, or denormalized numbers correctly. -template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED -Packet4f psqrt(const Packet4f& _x) -{ - Packet4f half = pmul(_x, pset1(.5f)); - - /* select only the inverse sqrt of non-zero inputs */ - Packet4f non_zero_mask = _mm_cmpge_ps(_x, pset1((std::numeric_limits::min)())); - Packet4f x = _mm_and_ps(non_zero_mask, _mm_rsqrt_ps(_x)); - - x = pmul(x, psub(pset1(1.5f), pmul(half, pmul(x,x)))); - return pmul(_x,x); -} - -#else - -template<> EIGEN_STRONG_INLINE Packet4f psqrt(const Packet4f& x) { return _mm_sqrt_ps(x); } - -#endif - -template<> EIGEN_STRONG_INLINE Packet2d psqrt(const Packet2d& x) { return _mm_sqrt_pd(x); } - -} // end namespace internal - -} // end namespace Eigen - -#endif // EIGEN_MATH_FUNCTIONS_SSE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/arch/SSE/PacketMath.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/arch/SSE/PacketMath.h deleted file mode 100644 index fc8ae50f..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Core/arch/SSE/PacketMath.h +++ /dev/null @@ -1,649 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2009 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_PACKET_MATH_SSE_H -#define EIGEN_PACKET_MATH_SSE_H - -namespace Eigen { - -namespace internal { - -#ifndef EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD -#define EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD 8 -#endif - -#ifndef EIGEN_ARCH_DEFAULT_NUMBER_OF_REGISTERS -#define EIGEN_ARCH_DEFAULT_NUMBER_OF_REGISTERS (2*sizeof(void*)) -#endif - -typedef __m128 Packet4f; -typedef __m128i Packet4i; -typedef __m128d Packet2d; - -template<> struct is_arithmetic<__m128> { enum { value = true }; }; -template<> struct is_arithmetic<__m128i> { enum { value = true }; }; -template<> struct is_arithmetic<__m128d> { enum { value = true }; }; - -#define vec4f_swizzle1(v,p,q,r,s) \ - (_mm_castsi128_ps(_mm_shuffle_epi32( _mm_castps_si128(v), ((s)<<6|(r)<<4|(q)<<2|(p))))) - -#define vec4i_swizzle1(v,p,q,r,s) \ - (_mm_shuffle_epi32( v, ((s)<<6|(r)<<4|(q)<<2|(p)))) - -#define vec2d_swizzle1(v,p,q) \ - (_mm_castsi128_pd(_mm_shuffle_epi32( _mm_castpd_si128(v), ((q*2+1)<<6|(q*2)<<4|(p*2+1)<<2|(p*2))))) - -#define vec4f_swizzle2(a,b,p,q,r,s) \ - (_mm_shuffle_ps( (a), (b), ((s)<<6|(r)<<4|(q)<<2|(p)))) - -#define vec4i_swizzle2(a,b,p,q,r,s) \ - (_mm_castps_si128( (_mm_shuffle_ps( _mm_castsi128_ps(a), _mm_castsi128_ps(b), ((s)<<6|(r)<<4|(q)<<2|(p)))))) - -#define _EIGEN_DECLARE_CONST_Packet4f(NAME,X) \ - const Packet4f p4f_##NAME = pset1(X) - -#define _EIGEN_DECLARE_CONST_Packet2d(NAME,X) \ - const Packet2d p2d_##NAME = pset1(X) - -#define _EIGEN_DECLARE_CONST_Packet4f_FROM_INT(NAME,X) \ - const Packet4f p4f_##NAME = _mm_castsi128_ps(pset1(X)) - -#define _EIGEN_DECLARE_CONST_Packet4i(NAME,X) \ - const Packet4i p4i_##NAME = pset1(X) - - -template<> struct packet_traits : default_packet_traits -{ - typedef Packet4f type; - enum { - Vectorizable = 1, - AlignedOnScalar = 1, - size=4, - - HasDiv = 1, - HasSin = EIGEN_FAST_MATH, - HasCos = EIGEN_FAST_MATH, - HasLog = 1, - HasExp = 1, - HasSqrt = 1 - }; -}; -template<> struct packet_traits : default_packet_traits -{ - typedef Packet2d type; - enum { - Vectorizable = 1, - AlignedOnScalar = 1, - size=2, - - HasDiv = 1, - HasExp = 1, - HasSqrt = 1 - }; -}; -template<> struct packet_traits : default_packet_traits -{ - typedef Packet4i type; - enum { - // FIXME check the Has* - Vectorizable = 1, - AlignedOnScalar = 1, - size=4 - }; -}; - -template<> struct unpacket_traits { typedef float type; enum {size=4}; }; -template<> struct unpacket_traits { typedef double type; enum {size=2}; }; -template<> struct unpacket_traits { typedef int type; enum {size=4}; }; - -#if defined(_MSC_VER) && (_MSC_VER==1500) -// Workaround MSVC 9 internal compiler error. -// TODO: It has been detected with win64 builds (amd64), so let's check whether it also happens in 32bits+SSE mode -// TODO: let's check whether there does not exist a better fix, like adding a pset0() function. (it crashed on pset1(0)). -template<> EIGEN_STRONG_INLINE Packet4f pset1(const float& from) { return _mm_set_ps(from,from,from,from); } -template<> EIGEN_STRONG_INLINE Packet2d pset1(const double& from) { return _mm_set_pd(from,from); } -template<> EIGEN_STRONG_INLINE Packet4i pset1(const int& from) { return _mm_set_epi32(from,from,from,from); } -#else -template<> EIGEN_STRONG_INLINE Packet4f pset1(const float& from) { return _mm_set1_ps(from); } -template<> EIGEN_STRONG_INLINE Packet2d pset1(const double& from) { return _mm_set1_pd(from); } -template<> EIGEN_STRONG_INLINE Packet4i pset1(const int& from) { return _mm_set1_epi32(from); } -#endif - -template<> EIGEN_STRONG_INLINE Packet4f plset(const float& a) { return _mm_add_ps(pset1(a), _mm_set_ps(3,2,1,0)); } -template<> EIGEN_STRONG_INLINE Packet2d plset(const double& a) { return _mm_add_pd(pset1(a),_mm_set_pd(1,0)); } -template<> EIGEN_STRONG_INLINE Packet4i plset(const int& a) { return _mm_add_epi32(pset1(a),_mm_set_epi32(3,2,1,0)); } - -template<> EIGEN_STRONG_INLINE Packet4f padd(const Packet4f& a, const Packet4f& b) { return _mm_add_ps(a,b); } -template<> EIGEN_STRONG_INLINE Packet2d padd(const Packet2d& a, const Packet2d& b) { return _mm_add_pd(a,b); } -template<> EIGEN_STRONG_INLINE Packet4i padd(const Packet4i& a, const Packet4i& b) { return _mm_add_epi32(a,b); } - -template<> EIGEN_STRONG_INLINE Packet4f psub(const Packet4f& a, const Packet4f& b) { return _mm_sub_ps(a,b); } -template<> EIGEN_STRONG_INLINE Packet2d psub(const Packet2d& a, const Packet2d& b) { return _mm_sub_pd(a,b); } -template<> EIGEN_STRONG_INLINE Packet4i psub(const Packet4i& a, const Packet4i& b) { return _mm_sub_epi32(a,b); } - -template<> EIGEN_STRONG_INLINE Packet4f pnegate(const Packet4f& a) -{ - const Packet4f mask = _mm_castsi128_ps(_mm_setr_epi32(0x80000000,0x80000000,0x80000000,0x80000000)); - return _mm_xor_ps(a,mask); -} -template<> EIGEN_STRONG_INLINE Packet2d pnegate(const Packet2d& a) -{ - const Packet2d mask = _mm_castsi128_pd(_mm_setr_epi32(0x0,0x80000000,0x0,0x80000000)); - return _mm_xor_pd(a,mask); -} -template<> EIGEN_STRONG_INLINE Packet4i pnegate(const Packet4i& a) -{ - return psub(_mm_setr_epi32(0,0,0,0), a); -} - -template<> EIGEN_STRONG_INLINE Packet4f pconj(const Packet4f& a) { return a; } -template<> EIGEN_STRONG_INLINE Packet2d pconj(const Packet2d& a) { return a; } -template<> EIGEN_STRONG_INLINE Packet4i pconj(const Packet4i& a) { return a; } - -template<> EIGEN_STRONG_INLINE Packet4f pmul(const Packet4f& a, const Packet4f& b) { return _mm_mul_ps(a,b); } -template<> EIGEN_STRONG_INLINE Packet2d pmul(const Packet2d& a, const Packet2d& b) { return _mm_mul_pd(a,b); } -template<> EIGEN_STRONG_INLINE Packet4i pmul(const Packet4i& a, const Packet4i& b) -{ -#ifdef EIGEN_VECTORIZE_SSE4_1 - return _mm_mullo_epi32(a,b); -#else - // this version is slightly faster than 4 scalar products - return vec4i_swizzle1( - vec4i_swizzle2( - _mm_mul_epu32(a,b), - _mm_mul_epu32(vec4i_swizzle1(a,1,0,3,2), - vec4i_swizzle1(b,1,0,3,2)), - 0,2,0,2), - 0,2,1,3); -#endif -} - -template<> EIGEN_STRONG_INLINE Packet4f pdiv(const Packet4f& a, const Packet4f& b) { return _mm_div_ps(a,b); } -template<> EIGEN_STRONG_INLINE Packet2d pdiv(const Packet2d& a, const Packet2d& b) { return _mm_div_pd(a,b); } -template<> EIGEN_STRONG_INLINE Packet4i pdiv(const Packet4i& /*a*/, const Packet4i& /*b*/) -{ eigen_assert(false && "packet integer division are not supported by SSE"); - return pset1(0); -} - -// for some weird raisons, it has to be overloaded for packet of integers -template<> EIGEN_STRONG_INLINE Packet4i pmadd(const Packet4i& a, const Packet4i& b, const Packet4i& c) { return padd(pmul(a,b), c); } - -template<> EIGEN_STRONG_INLINE Packet4f pmin(const Packet4f& a, const Packet4f& b) { return _mm_min_ps(a,b); } -template<> EIGEN_STRONG_INLINE Packet2d pmin(const Packet2d& a, const Packet2d& b) { return _mm_min_pd(a,b); } -template<> EIGEN_STRONG_INLINE Packet4i pmin(const Packet4i& a, const Packet4i& b) -{ -#ifdef EIGEN_VECTORIZE_SSE4_1 - return _mm_min_epi32(a,b); -#else - // after some bench, this version *is* faster than a scalar implementation - Packet4i mask = _mm_cmplt_epi32(a,b); - return _mm_or_si128(_mm_and_si128(mask,a),_mm_andnot_si128(mask,b)); -#endif -} - -template<> EIGEN_STRONG_INLINE Packet4f pmax(const Packet4f& a, const Packet4f& b) { return _mm_max_ps(a,b); } -template<> EIGEN_STRONG_INLINE Packet2d pmax(const Packet2d& a, const Packet2d& b) { return _mm_max_pd(a,b); } -template<> EIGEN_STRONG_INLINE Packet4i pmax(const Packet4i& a, const Packet4i& b) -{ -#ifdef EIGEN_VECTORIZE_SSE4_1 - return _mm_max_epi32(a,b); -#else - // after some bench, this version *is* faster than a scalar implementation - Packet4i mask = _mm_cmpgt_epi32(a,b); - return _mm_or_si128(_mm_and_si128(mask,a),_mm_andnot_si128(mask,b)); -#endif -} - -template<> EIGEN_STRONG_INLINE Packet4f pand(const Packet4f& a, const Packet4f& b) { return _mm_and_ps(a,b); } -template<> EIGEN_STRONG_INLINE Packet2d pand(const Packet2d& a, const Packet2d& b) { return _mm_and_pd(a,b); } -template<> EIGEN_STRONG_INLINE Packet4i pand(const Packet4i& a, const Packet4i& b) { return _mm_and_si128(a,b); } - -template<> EIGEN_STRONG_INLINE Packet4f por(const Packet4f& a, const Packet4f& b) { return _mm_or_ps(a,b); } -template<> EIGEN_STRONG_INLINE Packet2d por(const Packet2d& a, const Packet2d& b) { return _mm_or_pd(a,b); } -template<> EIGEN_STRONG_INLINE Packet4i por(const Packet4i& a, const Packet4i& b) { return _mm_or_si128(a,b); } - -template<> EIGEN_STRONG_INLINE Packet4f pxor(const Packet4f& a, const Packet4f& b) { return _mm_xor_ps(a,b); } -template<> EIGEN_STRONG_INLINE Packet2d pxor(const Packet2d& a, const Packet2d& b) { return _mm_xor_pd(a,b); } -template<> EIGEN_STRONG_INLINE Packet4i pxor(const Packet4i& a, const Packet4i& b) { return _mm_xor_si128(a,b); } - -template<> EIGEN_STRONG_INLINE Packet4f pandnot(const Packet4f& a, const Packet4f& b) { return _mm_andnot_ps(a,b); } -template<> EIGEN_STRONG_INLINE Packet2d pandnot(const Packet2d& a, const Packet2d& b) { return _mm_andnot_pd(a,b); } -template<> EIGEN_STRONG_INLINE Packet4i pandnot(const Packet4i& a, const Packet4i& b) { return _mm_andnot_si128(a,b); } - -template<> EIGEN_STRONG_INLINE Packet4f pload(const float* from) { EIGEN_DEBUG_ALIGNED_LOAD return _mm_load_ps(from); } -template<> EIGEN_STRONG_INLINE Packet2d pload(const double* from) { EIGEN_DEBUG_ALIGNED_LOAD return _mm_load_pd(from); } -template<> EIGEN_STRONG_INLINE Packet4i pload(const int* from) { EIGEN_DEBUG_ALIGNED_LOAD return _mm_load_si128(reinterpret_cast(from)); } - -#if defined(_MSC_VER) - template<> EIGEN_STRONG_INLINE Packet4f ploadu(const float* from) { - EIGEN_DEBUG_UNALIGNED_LOAD - #if (_MSC_VER==1600) - // NOTE Some version of MSVC10 generates bad code when using _mm_loadu_ps - // (i.e., it does not generate an unaligned load!! - // TODO On most architectures this version should also be faster than a single _mm_loadu_ps - // so we could also enable it for MSVC08 but first we have to make this later does not generate crap when doing so... - __m128 res = _mm_loadl_pi(_mm_set1_ps(0.0f), (const __m64*)(from)); - res = _mm_loadh_pi(res, (const __m64*)(from+2)); - return res; - #else - return _mm_loadu_ps(from); - #endif - } - template<> EIGEN_STRONG_INLINE Packet2d ploadu(const double* from) { EIGEN_DEBUG_UNALIGNED_LOAD return _mm_loadu_pd(from); } - template<> EIGEN_STRONG_INLINE Packet4i ploadu(const int* from) { EIGEN_DEBUG_UNALIGNED_LOAD return _mm_loadu_si128(reinterpret_cast(from)); } -#else -// Fast unaligned loads. Note that here we cannot directly use intrinsics: this would -// require pointer casting to incompatible pointer types and leads to invalid code -// because of the strict aliasing rule. The "dummy" stuff are required to enforce -// a correct instruction dependency. -// TODO: do the same for MSVC (ICC is compatible) -// NOTE: with the code below, MSVC's compiler crashes! - -#if defined(__GNUC__) && defined(__i386__) - // bug 195: gcc/i386 emits weird x87 fldl/fstpl instructions for _mm_load_sd - #define EIGEN_AVOID_CUSTOM_UNALIGNED_LOADS 1 -#elif defined(__clang__) - // bug 201: Segfaults in __mm_loadh_pd with clang 2.8 - #define EIGEN_AVOID_CUSTOM_UNALIGNED_LOADS 1 -#else - #define EIGEN_AVOID_CUSTOM_UNALIGNED_LOADS 0 -#endif - -template<> EIGEN_STRONG_INLINE Packet4f ploadu(const float* from) -{ - EIGEN_DEBUG_UNALIGNED_LOAD -#if EIGEN_AVOID_CUSTOM_UNALIGNED_LOADS - return _mm_loadu_ps(from); -#else - __m128d res; - res = _mm_load_sd((const double*)(from)) ; - res = _mm_loadh_pd(res, (const double*)(from+2)) ; - return _mm_castpd_ps(res); -#endif -} -template<> EIGEN_STRONG_INLINE Packet2d ploadu(const double* from) -{ - EIGEN_DEBUG_UNALIGNED_LOAD -#if EIGEN_AVOID_CUSTOM_UNALIGNED_LOADS - return _mm_loadu_pd(from); -#else - __m128d res; - res = _mm_load_sd(from) ; - res = _mm_loadh_pd(res,from+1); - return res; -#endif -} -template<> EIGEN_STRONG_INLINE Packet4i ploadu(const int* from) -{ - EIGEN_DEBUG_UNALIGNED_LOAD -#if EIGEN_AVOID_CUSTOM_UNALIGNED_LOADS - return _mm_loadu_si128(reinterpret_cast(from)); -#else - __m128d res; - res = _mm_load_sd((const double*)(from)) ; - res = _mm_loadh_pd(res, (const double*)(from+2)) ; - return _mm_castpd_si128(res); -#endif -} -#endif - -template<> EIGEN_STRONG_INLINE Packet4f ploaddup(const float* from) -{ - return vec4f_swizzle1(_mm_castpd_ps(_mm_load_sd(reinterpret_cast(from))), 0, 0, 1, 1); -} -template<> EIGEN_STRONG_INLINE Packet2d ploaddup(const double* from) -{ return pset1(from[0]); } -template<> EIGEN_STRONG_INLINE Packet4i ploaddup(const int* from) -{ - Packet4i tmp; - tmp = _mm_loadl_epi64(reinterpret_cast(from)); - return vec4i_swizzle1(tmp, 0, 0, 1, 1); -} - -template<> EIGEN_STRONG_INLINE void pstore(float* to, const Packet4f& from) { EIGEN_DEBUG_ALIGNED_STORE _mm_store_ps(to, from); } -template<> EIGEN_STRONG_INLINE void pstore(double* to, const Packet2d& from) { EIGEN_DEBUG_ALIGNED_STORE _mm_store_pd(to, from); } -template<> EIGEN_STRONG_INLINE void pstore(int* to, const Packet4i& from) { EIGEN_DEBUG_ALIGNED_STORE _mm_store_si128(reinterpret_cast(to), from); } - -template<> EIGEN_STRONG_INLINE void pstoreu(double* to, const Packet2d& from) { - EIGEN_DEBUG_UNALIGNED_STORE - _mm_storel_pd((to), from); - _mm_storeh_pd((to+1), from); -} -template<> EIGEN_STRONG_INLINE void pstoreu(float* to, const Packet4f& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu(reinterpret_cast(to), _mm_castps_pd(from)); } -template<> EIGEN_STRONG_INLINE void pstoreu(int* to, const Packet4i& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu(reinterpret_cast(to), _mm_castsi128_pd(from)); } - -// some compilers might be tempted to perform multiple moves instead of using a vector path. -template<> EIGEN_STRONG_INLINE void pstore1(float* to, const float& a) -{ - Packet4f pa = _mm_set_ss(a); - pstore(to, vec4f_swizzle1(pa,0,0,0,0)); -} -// some compilers might be tempted to perform multiple moves instead of using a vector path. -template<> EIGEN_STRONG_INLINE void pstore1(double* to, const double& a) -{ - Packet2d pa = _mm_set_sd(a); - pstore(to, vec2d_swizzle1(pa,0,0)); -} - -template<> EIGEN_STRONG_INLINE void prefetch(const float* addr) { _mm_prefetch((const char*)(addr), _MM_HINT_T0); } -template<> EIGEN_STRONG_INLINE void prefetch(const double* addr) { _mm_prefetch((const char*)(addr), _MM_HINT_T0); } -template<> EIGEN_STRONG_INLINE void prefetch(const int* addr) { _mm_prefetch((const char*)(addr), _MM_HINT_T0); } - -#if defined(_MSC_VER) && defined(_WIN64) && !defined(__INTEL_COMPILER) -// The temporary variable fixes an internal compilation error in vs <= 2008 and a wrong-result bug in vs 2010 -// Direct of the struct members fixed bug #62. -template<> EIGEN_STRONG_INLINE float pfirst(const Packet4f& a) { return a.m128_f32[0]; } -template<> EIGEN_STRONG_INLINE double pfirst(const Packet2d& a) { return a.m128d_f64[0]; } -template<> EIGEN_STRONG_INLINE int pfirst(const Packet4i& a) { int x = _mm_cvtsi128_si32(a); return x; } -#elif defined(_MSC_VER) && !defined(__INTEL_COMPILER) -// The temporary variable fixes an internal compilation error in vs <= 2008 and a wrong-result bug in vs 2010 -template<> EIGEN_STRONG_INLINE float pfirst(const Packet4f& a) { float x = _mm_cvtss_f32(a); return x; } -template<> EIGEN_STRONG_INLINE double pfirst(const Packet2d& a) { double x = _mm_cvtsd_f64(a); return x; } -template<> EIGEN_STRONG_INLINE int pfirst(const Packet4i& a) { int x = _mm_cvtsi128_si32(a); return x; } -#else -template<> EIGEN_STRONG_INLINE float pfirst(const Packet4f& a) { return _mm_cvtss_f32(a); } -template<> EIGEN_STRONG_INLINE double pfirst(const Packet2d& a) { return _mm_cvtsd_f64(a); } -template<> EIGEN_STRONG_INLINE int pfirst(const Packet4i& a) { return _mm_cvtsi128_si32(a); } -#endif - -template<> EIGEN_STRONG_INLINE Packet4f preverse(const Packet4f& a) -{ return _mm_shuffle_ps(a,a,0x1B); } -template<> EIGEN_STRONG_INLINE Packet2d preverse(const Packet2d& a) -{ return _mm_shuffle_pd(a,a,0x1); } -template<> EIGEN_STRONG_INLINE Packet4i preverse(const Packet4i& a) -{ return _mm_shuffle_epi32(a,0x1B); } - - -template<> EIGEN_STRONG_INLINE Packet4f pabs(const Packet4f& a) -{ - const Packet4f mask = _mm_castsi128_ps(_mm_setr_epi32(0x7FFFFFFF,0x7FFFFFFF,0x7FFFFFFF,0x7FFFFFFF)); - return _mm_and_ps(a,mask); -} -template<> EIGEN_STRONG_INLINE Packet2d pabs(const Packet2d& a) -{ - const Packet2d mask = _mm_castsi128_pd(_mm_setr_epi32(0xFFFFFFFF,0x7FFFFFFF,0xFFFFFFFF,0x7FFFFFFF)); - return _mm_and_pd(a,mask); -} -template<> EIGEN_STRONG_INLINE Packet4i pabs(const Packet4i& a) -{ - #ifdef EIGEN_VECTORIZE_SSSE3 - return _mm_abs_epi32(a); - #else - Packet4i aux = _mm_srai_epi32(a,31); - return _mm_sub_epi32(_mm_xor_si128(a,aux),aux); - #endif -} - -EIGEN_STRONG_INLINE void punpackp(Packet4f* vecs) -{ - vecs[1] = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(vecs[0]), 0x55)); - vecs[2] = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(vecs[0]), 0xAA)); - vecs[3] = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(vecs[0]), 0xFF)); - vecs[0] = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(vecs[0]), 0x00)); -} - -#ifdef EIGEN_VECTORIZE_SSE3 -// TODO implement SSE2 versions as well as integer versions -template<> EIGEN_STRONG_INLINE Packet4f preduxp(const Packet4f* vecs) -{ - return _mm_hadd_ps(_mm_hadd_ps(vecs[0], vecs[1]),_mm_hadd_ps(vecs[2], vecs[3])); -} -template<> EIGEN_STRONG_INLINE Packet2d preduxp(const Packet2d* vecs) -{ - return _mm_hadd_pd(vecs[0], vecs[1]); -} -// SSSE3 version: -// EIGEN_STRONG_INLINE Packet4i preduxp(const Packet4i* vecs) -// { -// return _mm_hadd_epi32(_mm_hadd_epi32(vecs[0], vecs[1]),_mm_hadd_epi32(vecs[2], vecs[3])); -// } - -template<> EIGEN_STRONG_INLINE float predux(const Packet4f& a) -{ - Packet4f tmp0 = _mm_hadd_ps(a,a); - return pfirst(_mm_hadd_ps(tmp0, tmp0)); -} - -template<> EIGEN_STRONG_INLINE double predux(const Packet2d& a) { return pfirst(_mm_hadd_pd(a, a)); } - -// SSSE3 version: -// EIGEN_STRONG_INLINE float predux(const Packet4i& a) -// { -// Packet4i tmp0 = _mm_hadd_epi32(a,a); -// return pfirst(_mm_hadd_epi32(tmp0, tmp0)); -// } -#else -// SSE2 versions -template<> EIGEN_STRONG_INLINE float predux(const Packet4f& a) -{ - Packet4f tmp = _mm_add_ps(a, _mm_movehl_ps(a,a)); - return pfirst(_mm_add_ss(tmp, _mm_shuffle_ps(tmp,tmp, 1))); -} -template<> EIGEN_STRONG_INLINE double predux(const Packet2d& a) -{ - return pfirst(_mm_add_sd(a, _mm_unpackhi_pd(a,a))); -} - -template<> EIGEN_STRONG_INLINE Packet4f preduxp(const Packet4f* vecs) -{ - Packet4f tmp0, tmp1, tmp2; - tmp0 = _mm_unpacklo_ps(vecs[0], vecs[1]); - tmp1 = _mm_unpackhi_ps(vecs[0], vecs[1]); - tmp2 = _mm_unpackhi_ps(vecs[2], vecs[3]); - tmp0 = _mm_add_ps(tmp0, tmp1); - tmp1 = _mm_unpacklo_ps(vecs[2], vecs[3]); - tmp1 = _mm_add_ps(tmp1, tmp2); - tmp2 = _mm_movehl_ps(tmp1, tmp0); - tmp0 = _mm_movelh_ps(tmp0, tmp1); - return _mm_add_ps(tmp0, tmp2); -} - -template<> EIGEN_STRONG_INLINE Packet2d preduxp(const Packet2d* vecs) -{ - return _mm_add_pd(_mm_unpacklo_pd(vecs[0], vecs[1]), _mm_unpackhi_pd(vecs[0], vecs[1])); -} -#endif // SSE3 - -template<> EIGEN_STRONG_INLINE int predux(const Packet4i& a) -{ - Packet4i tmp = _mm_add_epi32(a, _mm_unpackhi_epi64(a,a)); - return pfirst(tmp) + pfirst(_mm_shuffle_epi32(tmp, 1)); -} - -template<> EIGEN_STRONG_INLINE Packet4i preduxp(const Packet4i* vecs) -{ - Packet4i tmp0, tmp1, tmp2; - tmp0 = _mm_unpacklo_epi32(vecs[0], vecs[1]); - tmp1 = _mm_unpackhi_epi32(vecs[0], vecs[1]); - tmp2 = _mm_unpackhi_epi32(vecs[2], vecs[3]); - tmp0 = _mm_add_epi32(tmp0, tmp1); - tmp1 = _mm_unpacklo_epi32(vecs[2], vecs[3]); - tmp1 = _mm_add_epi32(tmp1, tmp2); - tmp2 = _mm_unpacklo_epi64(tmp0, tmp1); - tmp0 = _mm_unpackhi_epi64(tmp0, tmp1); - return _mm_add_epi32(tmp0, tmp2); -} - -// Other reduction functions: - -// mul -template<> EIGEN_STRONG_INLINE float predux_mul(const Packet4f& a) -{ - Packet4f tmp = _mm_mul_ps(a, _mm_movehl_ps(a,a)); - return pfirst(_mm_mul_ss(tmp, _mm_shuffle_ps(tmp,tmp, 1))); -} -template<> EIGEN_STRONG_INLINE double predux_mul(const Packet2d& a) -{ - return pfirst(_mm_mul_sd(a, _mm_unpackhi_pd(a,a))); -} -template<> EIGEN_STRONG_INLINE int predux_mul(const Packet4i& a) -{ - // after some experiments, it is seems this is the fastest way to implement it - // for GCC (eg., reusing pmul is very slow !) - // TODO try to call _mm_mul_epu32 directly - EIGEN_ALIGN16 int aux[4]; - pstore(aux, a); - return (aux[0] * aux[1]) * (aux[2] * aux[3]);; -} - -// min -template<> EIGEN_STRONG_INLINE float predux_min(const Packet4f& a) -{ - Packet4f tmp = _mm_min_ps(a, _mm_movehl_ps(a,a)); - return pfirst(_mm_min_ss(tmp, _mm_shuffle_ps(tmp,tmp, 1))); -} -template<> EIGEN_STRONG_INLINE double predux_min(const Packet2d& a) -{ - return pfirst(_mm_min_sd(a, _mm_unpackhi_pd(a,a))); -} -template<> EIGEN_STRONG_INLINE int predux_min(const Packet4i& a) -{ - // after some experiments, it is seems this is the fastest way to implement it - // for GCC (eg., it does not like using std::min after the pstore !!) - EIGEN_ALIGN16 int aux[4]; - pstore(aux, a); - int aux0 = aux[0] EIGEN_STRONG_INLINE float predux_max(const Packet4f& a) -{ - Packet4f tmp = _mm_max_ps(a, _mm_movehl_ps(a,a)); - return pfirst(_mm_max_ss(tmp, _mm_shuffle_ps(tmp,tmp, 1))); -} -template<> EIGEN_STRONG_INLINE double predux_max(const Packet2d& a) -{ - return pfirst(_mm_max_sd(a, _mm_unpackhi_pd(a,a))); -} -template<> EIGEN_STRONG_INLINE int predux_max(const Packet4i& a) -{ - // after some experiments, it is seems this is the fastest way to implement it - // for GCC (eg., it does not like using std::min after the pstore !!) - EIGEN_ALIGN16 int aux[4]; - pstore(aux, a); - int aux0 = aux[0]>aux[1] ? aux[0] : aux[1]; - int aux2 = aux[2]>aux[3] ? aux[2] : aux[3]; - return aux0>aux2 ? aux0 : aux2; -} - -#if (defined __GNUC__) -// template <> EIGEN_STRONG_INLINE Packet4f pmadd(const Packet4f& a, const Packet4f& b, const Packet4f& c) -// { -// Packet4f res = b; -// asm("mulps %[a], %[b] \n\taddps %[c], %[b]" : [b] "+x" (res) : [a] "x" (a), [c] "x" (c)); -// return res; -// } -// EIGEN_STRONG_INLINE Packet4i _mm_alignr_epi8(const Packet4i& a, const Packet4i& b, const int i) -// { -// Packet4i res = a; -// asm("palignr %[i], %[a], %[b] " : [b] "+x" (res) : [a] "x" (a), [i] "i" (i)); -// return res; -// } -#endif - -#ifdef EIGEN_VECTORIZE_SSSE3 -// SSSE3 versions -template -struct palign_impl -{ - static EIGEN_STRONG_INLINE void run(Packet4f& first, const Packet4f& second) - { - if (Offset!=0) - first = _mm_castsi128_ps(_mm_alignr_epi8(_mm_castps_si128(second), _mm_castps_si128(first), Offset*4)); - } -}; - -template -struct palign_impl -{ - static EIGEN_STRONG_INLINE void run(Packet4i& first, const Packet4i& second) - { - if (Offset!=0) - first = _mm_alignr_epi8(second,first, Offset*4); - } -}; - -template -struct palign_impl -{ - static EIGEN_STRONG_INLINE void run(Packet2d& first, const Packet2d& second) - { - if (Offset==1) - first = _mm_castsi128_pd(_mm_alignr_epi8(_mm_castpd_si128(second), _mm_castpd_si128(first), 8)); - } -}; -#else -// SSE2 versions -template -struct palign_impl -{ - static EIGEN_STRONG_INLINE void run(Packet4f& first, const Packet4f& second) - { - if (Offset==1) - { - first = _mm_move_ss(first,second); - first = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(first),0x39)); - } - else if (Offset==2) - { - first = _mm_movehl_ps(first,first); - first = _mm_movelh_ps(first,second); - } - else if (Offset==3) - { - first = _mm_move_ss(first,second); - first = _mm_shuffle_ps(first,second,0x93); - } - } -}; - -template -struct palign_impl -{ - static EIGEN_STRONG_INLINE void run(Packet4i& first, const Packet4i& second) - { - if (Offset==1) - { - first = _mm_castps_si128(_mm_move_ss(_mm_castsi128_ps(first),_mm_castsi128_ps(second))); - first = _mm_shuffle_epi32(first,0x39); - } - else if (Offset==2) - { - first = _mm_castps_si128(_mm_movehl_ps(_mm_castsi128_ps(first),_mm_castsi128_ps(first))); - first = _mm_castps_si128(_mm_movelh_ps(_mm_castsi128_ps(first),_mm_castsi128_ps(second))); - } - else if (Offset==3) - { - first = _mm_castps_si128(_mm_move_ss(_mm_castsi128_ps(first),_mm_castsi128_ps(second))); - first = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(first),_mm_castsi128_ps(second),0x93)); - } - } -}; - -template -struct palign_impl -{ - static EIGEN_STRONG_INLINE void run(Packet2d& first, const Packet2d& second) - { - if (Offset==1) - { - first = _mm_castps_pd(_mm_movehl_ps(_mm_castpd_ps(first),_mm_castpd_ps(first))); - first = _mm_castps_pd(_mm_movelh_ps(_mm_castpd_ps(first),_mm_castpd_ps(second))); - } - } -}; -#endif - -} // end namespace internal - -} // end namespace Eigen - -#endif // EIGEN_PACKET_MATH_SSE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/products/CoeffBasedProduct.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/products/CoeffBasedProduct.h deleted file mode 100644 index 2a9d65b9..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Core/products/CoeffBasedProduct.h +++ /dev/null @@ -1,476 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2006-2008 Benoit Jacob -// Copyright (C) 2008-2010 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_COEFFBASED_PRODUCT_H -#define EIGEN_COEFFBASED_PRODUCT_H - -namespace Eigen { - -namespace internal { - -/********************************************************************************* -* Coefficient based product implementation. -* It is designed for the following use cases: -* - small fixed sizes -* - lazy products -*********************************************************************************/ - -/* Since the all the dimensions of the product are small, here we can rely - * on the generic Assign mechanism to evaluate the product per coeff (or packet). - * - * Note that here the inner-loops should always be unrolled. - */ - -template -struct product_coeff_impl; - -template -struct product_packet_impl; - -template -struct traits > -{ - typedef MatrixXpr XprKind; - typedef typename remove_all::type _LhsNested; - typedef typename remove_all::type _RhsNested; - typedef typename scalar_product_traits::ReturnType Scalar; - typedef typename promote_storage_type::StorageKind, - typename traits<_RhsNested>::StorageKind>::ret StorageKind; - typedef typename promote_index_type::Index, - typename traits<_RhsNested>::Index>::type Index; - - enum { - LhsCoeffReadCost = _LhsNested::CoeffReadCost, - RhsCoeffReadCost = _RhsNested::CoeffReadCost, - LhsFlags = _LhsNested::Flags, - RhsFlags = _RhsNested::Flags, - - RowsAtCompileTime = _LhsNested::RowsAtCompileTime, - ColsAtCompileTime = _RhsNested::ColsAtCompileTime, - InnerSize = EIGEN_SIZE_MIN_PREFER_FIXED(_LhsNested::ColsAtCompileTime, _RhsNested::RowsAtCompileTime), - - MaxRowsAtCompileTime = _LhsNested::MaxRowsAtCompileTime, - MaxColsAtCompileTime = _RhsNested::MaxColsAtCompileTime, - - LhsRowMajor = LhsFlags & RowMajorBit, - RhsRowMajor = RhsFlags & RowMajorBit, - - SameType = is_same::value, - - CanVectorizeRhs = RhsRowMajor && (RhsFlags & PacketAccessBit) - && (ColsAtCompileTime == Dynamic - || ( (ColsAtCompileTime % packet_traits::size) == 0 - && (RhsFlags&AlignedBit) - ) - ), - - CanVectorizeLhs = (!LhsRowMajor) && (LhsFlags & PacketAccessBit) - && (RowsAtCompileTime == Dynamic - || ( (RowsAtCompileTime % packet_traits::size) == 0 - && (LhsFlags&AlignedBit) - ) - ), - - EvalToRowMajor = (MaxRowsAtCompileTime==1&&MaxColsAtCompileTime!=1) ? 1 - : (MaxColsAtCompileTime==1&&MaxRowsAtCompileTime!=1) ? 0 - : (RhsRowMajor && !CanVectorizeLhs), - - Flags = ((unsigned int)(LhsFlags | RhsFlags) & HereditaryBits & ~RowMajorBit) - | (EvalToRowMajor ? RowMajorBit : 0) - | NestingFlags - | (LhsFlags & RhsFlags & AlignedBit) - // TODO enable vectorization for mixed types - | (SameType && (CanVectorizeLhs || CanVectorizeRhs) ? PacketAccessBit : 0), - - CoeffReadCost = InnerSize == Dynamic ? Dynamic - : InnerSize == 0 ? 0 - : InnerSize * (NumTraits::MulCost + LhsCoeffReadCost + RhsCoeffReadCost) - + (InnerSize - 1) * NumTraits::AddCost, - - /* CanVectorizeInner deserves special explanation. It does not affect the product flags. It is not used outside - * of Product. If the Product itself is not a packet-access expression, there is still a chance that the inner - * loop of the product might be vectorized. This is the meaning of CanVectorizeInner. Since it doesn't affect - * the Flags, it is safe to make this value depend on ActualPacketAccessBit, that doesn't affect the ABI. - */ - CanVectorizeInner = SameType - && LhsRowMajor - && (!RhsRowMajor) - && (LhsFlags & RhsFlags & ActualPacketAccessBit) - && (LhsFlags & RhsFlags & AlignedBit) - && (InnerSize % packet_traits::size == 0) - }; -}; - -} // end namespace internal - -template -class CoeffBasedProduct - : internal::no_assignment_operator, - public MatrixBase > -{ - public: - - typedef MatrixBase Base; - EIGEN_DENSE_PUBLIC_INTERFACE(CoeffBasedProduct) - typedef typename Base::PlainObject PlainObject; - - private: - - typedef typename internal::traits::_LhsNested _LhsNested; - typedef typename internal::traits::_RhsNested _RhsNested; - - enum { - PacketSize = internal::packet_traits::size, - InnerSize = internal::traits::InnerSize, - Unroll = CoeffReadCost != Dynamic && CoeffReadCost <= EIGEN_UNROLLING_LIMIT, - CanVectorizeInner = internal::traits::CanVectorizeInner - }; - - typedef internal::product_coeff_impl ScalarCoeffImpl; - - typedef CoeffBasedProduct LazyCoeffBasedProductType; - - public: - - inline CoeffBasedProduct(const CoeffBasedProduct& other) - : Base(), m_lhs(other.m_lhs), m_rhs(other.m_rhs) - {} - - template - inline CoeffBasedProduct(const Lhs& lhs, const Rhs& rhs) - : m_lhs(lhs), m_rhs(rhs) - { - // we don't allow taking products of matrices of different real types, as that wouldn't be vectorizable. - // We still allow to mix T and complex. - EIGEN_STATIC_ASSERT((internal::scalar_product_traits::Defined), - YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) - eigen_assert(lhs.cols() == rhs.rows() - && "invalid matrix product" - && "if you wanted a coeff-wise or a dot product use the respective explicit functions"); - } - - EIGEN_STRONG_INLINE Index rows() const { return m_lhs.rows(); } - EIGEN_STRONG_INLINE Index cols() const { return m_rhs.cols(); } - - EIGEN_STRONG_INLINE const Scalar coeff(Index row, Index col) const - { - Scalar res; - ScalarCoeffImpl::run(row, col, m_lhs, m_rhs, res); - return res; - } - - /* Allow index-based non-packet access. It is impossible though to allow index-based packed access, - * which is why we don't set the LinearAccessBit. - */ - EIGEN_STRONG_INLINE const Scalar coeff(Index index) const - { - Scalar res; - const Index row = RowsAtCompileTime == 1 ? 0 : index; - const Index col = RowsAtCompileTime == 1 ? index : 0; - ScalarCoeffImpl::run(row, col, m_lhs, m_rhs, res); - return res; - } - - template - EIGEN_STRONG_INLINE const PacketScalar packet(Index row, Index col) const - { - PacketScalar res; - internal::product_packet_impl - ::run(row, col, m_lhs, m_rhs, res); - return res; - } - - // Implicit conversion to the nested type (trigger the evaluation of the product) - EIGEN_STRONG_INLINE operator const PlainObject& () const - { - m_result.lazyAssign(*this); - return m_result; - } - - const _LhsNested& lhs() const { return m_lhs; } - const _RhsNested& rhs() const { return m_rhs; } - - const Diagonal diagonal() const - { return reinterpret_cast(*this); } - - template - const Diagonal diagonal() const - { return reinterpret_cast(*this); } - - const Diagonal diagonal(Index index) const - { return reinterpret_cast(*this).diagonal(index); } - - protected: - typename internal::add_const_on_value_type::type m_lhs; - typename internal::add_const_on_value_type::type m_rhs; - - mutable PlainObject m_result; -}; - -namespace internal { - -// here we need to overload the nested rule for products -// such that the nested type is a const reference to a plain matrix -template -struct nested, N, PlainObject> -{ - typedef PlainObject const& type; -}; - -/*************************************************************************** -* Normal product .coeff() implementation (with meta-unrolling) -***************************************************************************/ - -/************************************** -*** Scalar path - no vectorization *** -**************************************/ - -template -struct product_coeff_impl -{ - typedef typename Lhs::Index Index; - static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, RetScalar &res) - { - product_coeff_impl::run(row, col, lhs, rhs, res); - res += lhs.coeff(row, UnrollingIndex-1) * rhs.coeff(UnrollingIndex-1, col); - } -}; - -template -struct product_coeff_impl -{ - typedef typename Lhs::Index Index; - static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, RetScalar &res) - { - res = lhs.coeff(row, 0) * rhs.coeff(0, col); - } -}; - -template -struct product_coeff_impl -{ - typedef typename Lhs::Index Index; - static EIGEN_STRONG_INLINE void run(Index /*row*/, Index /*col*/, const Lhs& /*lhs*/, const Rhs& /*rhs*/, RetScalar &res) - { - res = RetScalar(0); - } -}; - -template -struct product_coeff_impl -{ - typedef typename Lhs::Index Index; - static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, RetScalar& res) - { - res = (lhs.row(row).transpose().cwiseProduct( rhs.col(col) )).sum(); - } -}; - -/******************************************* -*** Scalar path with inner vectorization *** -*******************************************/ - -template -struct product_coeff_vectorized_unroller -{ - typedef typename Lhs::Index Index; - enum { PacketSize = packet_traits::size }; - static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, typename Lhs::PacketScalar &pres) - { - product_coeff_vectorized_unroller::run(row, col, lhs, rhs, pres); - pres = padd(pres, pmul( lhs.template packet(row, UnrollingIndex) , rhs.template packet(UnrollingIndex, col) )); - } -}; - -template -struct product_coeff_vectorized_unroller<0, Lhs, Rhs, Packet> -{ - typedef typename Lhs::Index Index; - static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, typename Lhs::PacketScalar &pres) - { - pres = pmul(lhs.template packet(row, 0) , rhs.template packet(0, col)); - } -}; - -template -struct product_coeff_impl -{ - typedef typename Lhs::Index Index; - static EIGEN_STRONG_INLINE void run(Index /*row*/, Index /*col*/, const Lhs& /*lhs*/, const Rhs& /*rhs*/, RetScalar &res) - { - res = 0; - } -}; - -template -struct product_coeff_impl -{ - typedef typename Lhs::PacketScalar Packet; - typedef typename Lhs::Index Index; - enum { PacketSize = packet_traits::size }; - static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, RetScalar &res) - { - Packet pres; - product_coeff_vectorized_unroller::run(row, col, lhs, rhs, pres); - res = predux(pres); - } -}; - -template -struct product_coeff_vectorized_dyn_selector -{ - typedef typename Lhs::Index Index; - static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res) - { - res = lhs.row(row).transpose().cwiseProduct(rhs.col(col)).sum(); - } -}; - -// NOTE the 3 following specializations are because taking .col(0) on a vector is a bit slower -// NOTE maybe they are now useless since we have a specialization for Block -template -struct product_coeff_vectorized_dyn_selector -{ - typedef typename Lhs::Index Index; - static EIGEN_STRONG_INLINE void run(Index /*row*/, Index col, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res) - { - res = lhs.transpose().cwiseProduct(rhs.col(col)).sum(); - } -}; - -template -struct product_coeff_vectorized_dyn_selector -{ - typedef typename Lhs::Index Index; - static EIGEN_STRONG_INLINE void run(Index row, Index /*col*/, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res) - { - res = lhs.row(row).transpose().cwiseProduct(rhs).sum(); - } -}; - -template -struct product_coeff_vectorized_dyn_selector -{ - typedef typename Lhs::Index Index; - static EIGEN_STRONG_INLINE void run(Index /*row*/, Index /*col*/, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res) - { - res = lhs.transpose().cwiseProduct(rhs).sum(); - } -}; - -template -struct product_coeff_impl -{ - typedef typename Lhs::Index Index; - static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res) - { - product_coeff_vectorized_dyn_selector::run(row, col, lhs, rhs, res); - } -}; - -/******************* -*** Packet path *** -*******************/ - -template -struct product_packet_impl -{ - typedef typename Lhs::Index Index; - static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet &res) - { - product_packet_impl::run(row, col, lhs, rhs, res); - res = pmadd(pset1(lhs.coeff(row, UnrollingIndex-1)), rhs.template packet(UnrollingIndex-1, col), res); - } -}; - -template -struct product_packet_impl -{ - typedef typename Lhs::Index Index; - static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet &res) - { - product_packet_impl::run(row, col, lhs, rhs, res); - res = pmadd(lhs.template packet(row, UnrollingIndex-1), pset1(rhs.coeff(UnrollingIndex-1, col)), res); - } -}; - -template -struct product_packet_impl -{ - typedef typename Lhs::Index Index; - static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet &res) - { - res = pmul(pset1(lhs.coeff(row, 0)),rhs.template packet(0, col)); - } -}; - -template -struct product_packet_impl -{ - typedef typename Lhs::Index Index; - static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet &res) - { - res = pmul(lhs.template packet(row, 0), pset1(rhs.coeff(0, col))); - } -}; - -template -struct product_packet_impl -{ - typedef typename Lhs::Index Index; - static EIGEN_STRONG_INLINE void run(Index /*row*/, Index /*col*/, const Lhs& /*lhs*/, const Rhs& /*rhs*/, Packet &res) - { - res = pset1(0); - } -}; - -template -struct product_packet_impl -{ - typedef typename Lhs::Index Index; - static EIGEN_STRONG_INLINE void run(Index /*row*/, Index /*col*/, const Lhs& /*lhs*/, const Rhs& /*rhs*/, Packet &res) - { - res = pset1(0); - } -}; - -template -struct product_packet_impl -{ - typedef typename Lhs::Index Index; - static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet& res) - { - res = pset1(0); - for(Index i = 0; i < lhs.cols(); ++i) - res = pmadd(pset1(lhs.coeff(row, i)), rhs.template packet(i, col), res); - } -}; - -template -struct product_packet_impl -{ - typedef typename Lhs::Index Index; - static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet& res) - { - res = pset1(0); - for(Index i = 0; i < lhs.cols(); ++i) - res = pmadd(lhs.template packet(row, i), pset1(rhs.coeff(i, col)), res); - } -}; - -} // end namespace internal - -} // end namespace Eigen - -#endif // EIGEN_COEFFBASED_PRODUCT_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/products/GeneralBlockPanelKernel.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/products/GeneralBlockPanelKernel.h deleted file mode 100644 index bcdca5b0..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Core/products/GeneralBlockPanelKernel.h +++ /dev/null @@ -1,1341 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2009 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_GENERAL_BLOCK_PANEL_H -#define EIGEN_GENERAL_BLOCK_PANEL_H - -namespace Eigen { - -namespace internal { - -template -class gebp_traits; - - -/** \internal \returns b if a<=0, and returns a otherwise. */ -inline std::ptrdiff_t manage_caching_sizes_helper(std::ptrdiff_t a, std::ptrdiff_t b) -{ - return a<=0 ? b : a; -} - -/** \internal */ -inline void manage_caching_sizes(Action action, std::ptrdiff_t* l1=0, std::ptrdiff_t* l2=0) -{ - static std::ptrdiff_t m_l1CacheSize = 0; - static std::ptrdiff_t m_l2CacheSize = 0; - if(m_l2CacheSize==0) - { - m_l1CacheSize = manage_caching_sizes_helper(queryL1CacheSize(),8 * 1024); - m_l2CacheSize = manage_caching_sizes_helper(queryTopLevelCacheSize(),1*1024*1024); - } - - if(action==SetAction) - { - // set the cpu cache size and cache all block sizes from a global cache size in byte - eigen_internal_assert(l1!=0 && l2!=0); - m_l1CacheSize = *l1; - m_l2CacheSize = *l2; - } - else if(action==GetAction) - { - eigen_internal_assert(l1!=0 && l2!=0); - *l1 = m_l1CacheSize; - *l2 = m_l2CacheSize; - } - else - { - eigen_internal_assert(false); - } -} - -/** \brief Computes the blocking parameters for a m x k times k x n matrix product - * - * \param[in,out] k Input: the third dimension of the product. Output: the blocking size along the same dimension. - * \param[in,out] m Input: the number of rows of the left hand side. Output: the blocking size along the same dimension. - * \param[in,out] n Input: the number of columns of the right hand side. Output: the blocking size along the same dimension. - * - * Given a m x k times k x n matrix product of scalar types \c LhsScalar and \c RhsScalar, - * this function computes the blocking size parameters along the respective dimensions - * for matrix products and related algorithms. The blocking sizes depends on various - * parameters: - * - the L1 and L2 cache sizes, - * - the register level blocking sizes defined by gebp_traits, - * - the number of scalars that fit into a packet (when vectorization is enabled). - * - * \sa setCpuCacheSizes */ -template -void computeProductBlockingSizes(SizeType& k, SizeType& m, SizeType& n) -{ - EIGEN_UNUSED_VARIABLE(n); - // Explanations: - // Let's recall the product algorithms form kc x nc horizontal panels B' on the rhs and - // mc x kc blocks A' on the lhs. A' has to fit into L2 cache. Moreover, B' is processed - // per kc x nr vertical small panels where nr is the blocking size along the n dimension - // at the register level. For vectorization purpose, these small vertical panels are unpacked, - // e.g., each coefficient is replicated to fit a packet. This small vertical panel has to - // stay in L1 cache. - std::ptrdiff_t l1, l2; - - typedef gebp_traits Traits; - enum { - kdiv = KcFactor * 2 * Traits::nr - * Traits::RhsProgress * sizeof(RhsScalar), - mr = gebp_traits::mr, - mr_mask = (0xffffffff/mr)*mr - }; - - manage_caching_sizes(GetAction, &l1, &l2); - k = std::min(k, l1/kdiv); - SizeType _m = k>0 ? l2/(4 * sizeof(LhsScalar) * k) : 0; - if(_m -inline void computeProductBlockingSizes(SizeType& k, SizeType& m, SizeType& n) -{ - computeProductBlockingSizes(k, m, n); -} - -#ifdef EIGEN_HAS_FUSE_CJMADD - #define MADD(CJ,A,B,C,T) C = CJ.pmadd(A,B,C); -#else - - // FIXME (a bit overkill maybe ?) - - template struct gebp_madd_selector { - EIGEN_ALWAYS_INLINE static void run(const CJ& cj, A& a, B& b, C& c, T& /*t*/) - { - c = cj.pmadd(a,b,c); - } - }; - - template struct gebp_madd_selector { - EIGEN_ALWAYS_INLINE static void run(const CJ& cj, T& a, T& b, T& c, T& t) - { - t = b; t = cj.pmul(a,t); c = padd(c,t); - } - }; - - template - EIGEN_STRONG_INLINE void gebp_madd(const CJ& cj, A& a, B& b, C& c, T& t) - { - gebp_madd_selector::run(cj,a,b,c,t); - } - - #define MADD(CJ,A,B,C,T) gebp_madd(CJ,A,B,C,T); -// #define MADD(CJ,A,B,C,T) T = B; T = CJ.pmul(A,T); C = padd(C,T); -#endif - -/* Vectorization logic - * real*real: unpack rhs to constant packets, ... - * - * cd*cd : unpack rhs to (b_r,b_r), (b_i,b_i), mul to get (a_r b_r,a_i b_r) (a_r b_i,a_i b_i), - * storing each res packet into two packets (2x2), - * at the end combine them: swap the second and addsub them - * cf*cf : same but with 2x4 blocks - * cplx*real : unpack rhs to constant packets, ... - * real*cplx : load lhs as (a0,a0,a1,a1), and mul as usual - */ -template -class gebp_traits -{ -public: - typedef _LhsScalar LhsScalar; - typedef _RhsScalar RhsScalar; - typedef typename scalar_product_traits::ReturnType ResScalar; - - enum { - ConjLhs = _ConjLhs, - ConjRhs = _ConjRhs, - Vectorizable = packet_traits::Vectorizable && packet_traits::Vectorizable, - LhsPacketSize = Vectorizable ? packet_traits::size : 1, - RhsPacketSize = Vectorizable ? packet_traits::size : 1, - ResPacketSize = Vectorizable ? packet_traits::size : 1, - - NumberOfRegisters = EIGEN_ARCH_DEFAULT_NUMBER_OF_REGISTERS, - - // register block size along the N direction (must be either 2 or 4) - nr = NumberOfRegisters/4, - - // register block size along the M direction (currently, this one cannot be modified) - mr = 2 * LhsPacketSize, - - WorkSpaceFactor = nr * RhsPacketSize, - - LhsProgress = LhsPacketSize, - RhsProgress = RhsPacketSize - }; - - typedef typename packet_traits::type _LhsPacket; - typedef typename packet_traits::type _RhsPacket; - typedef typename packet_traits::type _ResPacket; - - typedef typename conditional::type LhsPacket; - typedef typename conditional::type RhsPacket; - typedef typename conditional::type ResPacket; - - typedef ResPacket AccPacket; - - EIGEN_STRONG_INLINE void initAcc(AccPacket& p) - { - p = pset1(ResScalar(0)); - } - - EIGEN_STRONG_INLINE void unpackRhs(DenseIndex n, const RhsScalar* rhs, RhsScalar* b) - { - for(DenseIndex k=0; k(&b[k*RhsPacketSize], rhs[k]); - } - - EIGEN_STRONG_INLINE void loadRhs(const RhsScalar* b, RhsPacket& dest) const - { - dest = pload(b); - } - - EIGEN_STRONG_INLINE void loadLhs(const LhsScalar* a, LhsPacket& dest) const - { - dest = pload(a); - } - - EIGEN_STRONG_INLINE void madd(const LhsPacket& a, const RhsPacket& b, AccPacket& c, AccPacket& tmp) const - { - tmp = b; tmp = pmul(a,tmp); c = padd(c,tmp); - } - - EIGEN_STRONG_INLINE void acc(const AccPacket& c, const ResPacket& alpha, ResPacket& r) const - { - r = pmadd(c,alpha,r); - } - -protected: -// conj_helper cj; -// conj_helper pcj; -}; - -template -class gebp_traits, RealScalar, _ConjLhs, false> -{ -public: - typedef std::complex LhsScalar; - typedef RealScalar RhsScalar; - typedef typename scalar_product_traits::ReturnType ResScalar; - - enum { - ConjLhs = _ConjLhs, - ConjRhs = false, - Vectorizable = packet_traits::Vectorizable && packet_traits::Vectorizable, - LhsPacketSize = Vectorizable ? packet_traits::size : 1, - RhsPacketSize = Vectorizable ? packet_traits::size : 1, - ResPacketSize = Vectorizable ? packet_traits::size : 1, - - NumberOfRegisters = EIGEN_ARCH_DEFAULT_NUMBER_OF_REGISTERS, - nr = NumberOfRegisters/4, - mr = 2 * LhsPacketSize, - WorkSpaceFactor = nr*RhsPacketSize, - - LhsProgress = LhsPacketSize, - RhsProgress = RhsPacketSize - }; - - typedef typename packet_traits::type _LhsPacket; - typedef typename packet_traits::type _RhsPacket; - typedef typename packet_traits::type _ResPacket; - - typedef typename conditional::type LhsPacket; - typedef typename conditional::type RhsPacket; - typedef typename conditional::type ResPacket; - - typedef ResPacket AccPacket; - - EIGEN_STRONG_INLINE void initAcc(AccPacket& p) - { - p = pset1(ResScalar(0)); - } - - EIGEN_STRONG_INLINE void unpackRhs(DenseIndex n, const RhsScalar* rhs, RhsScalar* b) - { - for(DenseIndex k=0; k(&b[k*RhsPacketSize], rhs[k]); - } - - EIGEN_STRONG_INLINE void loadRhs(const RhsScalar* b, RhsPacket& dest) const - { - dest = pload(b); - } - - EIGEN_STRONG_INLINE void loadLhs(const LhsScalar* a, LhsPacket& dest) const - { - dest = pload(a); - } - - EIGEN_STRONG_INLINE void madd(const LhsPacket& a, const RhsPacket& b, AccPacket& c, RhsPacket& tmp) const - { - madd_impl(a, b, c, tmp, typename conditional::type()); - } - - EIGEN_STRONG_INLINE void madd_impl(const LhsPacket& a, const RhsPacket& b, AccPacket& c, RhsPacket& tmp, const true_type&) const - { - tmp = b; tmp = pmul(a.v,tmp); c.v = padd(c.v,tmp); - } - - EIGEN_STRONG_INLINE void madd_impl(const LhsScalar& a, const RhsScalar& b, ResScalar& c, RhsScalar& /*tmp*/, const false_type&) const - { - c += a * b; - } - - EIGEN_STRONG_INLINE void acc(const AccPacket& c, const ResPacket& alpha, ResPacket& r) const - { - r = cj.pmadd(c,alpha,r); - } - -protected: - conj_helper cj; -}; - -template -class gebp_traits, std::complex, _ConjLhs, _ConjRhs > -{ -public: - typedef std::complex Scalar; - typedef std::complex LhsScalar; - typedef std::complex RhsScalar; - typedef std::complex ResScalar; - - enum { - ConjLhs = _ConjLhs, - ConjRhs = _ConjRhs, - Vectorizable = packet_traits::Vectorizable - && packet_traits::Vectorizable, - RealPacketSize = Vectorizable ? packet_traits::size : 1, - ResPacketSize = Vectorizable ? packet_traits::size : 1, - - nr = 2, - mr = 2 * ResPacketSize, - WorkSpaceFactor = Vectorizable ? 2*nr*RealPacketSize : nr, - - LhsProgress = ResPacketSize, - RhsProgress = Vectorizable ? 2*ResPacketSize : 1 - }; - - typedef typename packet_traits::type RealPacket; - typedef typename packet_traits::type ScalarPacket; - struct DoublePacket - { - RealPacket first; - RealPacket second; - }; - - typedef typename conditional::type LhsPacket; - typedef typename conditional::type RhsPacket; - typedef typename conditional::type ResPacket; - typedef typename conditional::type AccPacket; - - EIGEN_STRONG_INLINE void initAcc(Scalar& p) { p = Scalar(0); } - - EIGEN_STRONG_INLINE void initAcc(DoublePacket& p) - { - p.first = pset1(RealScalar(0)); - p.second = pset1(RealScalar(0)); - } - - /* Unpack the rhs coeff such that each complex coefficient is spread into - * two packects containing respectively the real and imaginary coefficient - * duplicated as many time as needed: (x+iy) => [x, ..., x] [y, ..., y] - */ - EIGEN_STRONG_INLINE void unpackRhs(DenseIndex n, const Scalar* rhs, Scalar* b) - { - for(DenseIndex k=0; k((RealScalar*)&b[k*ResPacketSize*2+0], real(rhs[k])); - pstore1((RealScalar*)&b[k*ResPacketSize*2+ResPacketSize], imag(rhs[k])); - } - else - b[k] = rhs[k]; - } - } - - EIGEN_STRONG_INLINE void loadRhs(const RhsScalar* b, ResPacket& dest) const { dest = *b; } - - EIGEN_STRONG_INLINE void loadRhs(const RhsScalar* b, DoublePacket& dest) const - { - dest.first = pload((const RealScalar*)b); - dest.second = pload((const RealScalar*)(b+ResPacketSize)); - } - - // nothing special here - EIGEN_STRONG_INLINE void loadLhs(const LhsScalar* a, LhsPacket& dest) const - { - dest = pload((const typename unpacket_traits::type*)(a)); - } - - EIGEN_STRONG_INLINE void madd(const LhsPacket& a, const RhsPacket& b, DoublePacket& c, RhsPacket& /*tmp*/) const - { - c.first = padd(pmul(a,b.first), c.first); - c.second = padd(pmul(a,b.second),c.second); - } - - EIGEN_STRONG_INLINE void madd(const LhsPacket& a, const RhsPacket& b, ResPacket& c, RhsPacket& /*tmp*/) const - { - c = cj.pmadd(a,b,c); - } - - EIGEN_STRONG_INLINE void acc(const Scalar& c, const Scalar& alpha, Scalar& r) const { r += alpha * c; } - - EIGEN_STRONG_INLINE void acc(const DoublePacket& c, const ResPacket& alpha, ResPacket& r) const - { - // assemble c - ResPacket tmp; - if((!ConjLhs)&&(!ConjRhs)) - { - tmp = pcplxflip(pconj(ResPacket(c.second))); - tmp = padd(ResPacket(c.first),tmp); - } - else if((!ConjLhs)&&(ConjRhs)) - { - tmp = pconj(pcplxflip(ResPacket(c.second))); - tmp = padd(ResPacket(c.first),tmp); - } - else if((ConjLhs)&&(!ConjRhs)) - { - tmp = pcplxflip(ResPacket(c.second)); - tmp = padd(pconj(ResPacket(c.first)),tmp); - } - else if((ConjLhs)&&(ConjRhs)) - { - tmp = pcplxflip(ResPacket(c.second)); - tmp = psub(pconj(ResPacket(c.first)),tmp); - } - - r = pmadd(tmp,alpha,r); - } - -protected: - conj_helper cj; -}; - -template -class gebp_traits, false, _ConjRhs > -{ -public: - typedef std::complex Scalar; - typedef RealScalar LhsScalar; - typedef Scalar RhsScalar; - typedef Scalar ResScalar; - - enum { - ConjLhs = false, - ConjRhs = _ConjRhs, - Vectorizable = packet_traits::Vectorizable - && packet_traits::Vectorizable, - LhsPacketSize = Vectorizable ? packet_traits::size : 1, - RhsPacketSize = Vectorizable ? packet_traits::size : 1, - ResPacketSize = Vectorizable ? packet_traits::size : 1, - - NumberOfRegisters = EIGEN_ARCH_DEFAULT_NUMBER_OF_REGISTERS, - nr = 4, - mr = 2*ResPacketSize, - WorkSpaceFactor = nr*RhsPacketSize, - - LhsProgress = ResPacketSize, - RhsProgress = ResPacketSize - }; - - typedef typename packet_traits::type _LhsPacket; - typedef typename packet_traits::type _RhsPacket; - typedef typename packet_traits::type _ResPacket; - - typedef typename conditional::type LhsPacket; - typedef typename conditional::type RhsPacket; - typedef typename conditional::type ResPacket; - - typedef ResPacket AccPacket; - - EIGEN_STRONG_INLINE void initAcc(AccPacket& p) - { - p = pset1(ResScalar(0)); - } - - EIGEN_STRONG_INLINE void unpackRhs(DenseIndex n, const RhsScalar* rhs, RhsScalar* b) - { - for(DenseIndex k=0; k(&b[k*RhsPacketSize], rhs[k]); - } - - EIGEN_STRONG_INLINE void loadRhs(const RhsScalar* b, RhsPacket& dest) const - { - dest = pload(b); - } - - EIGEN_STRONG_INLINE void loadLhs(const LhsScalar* a, LhsPacket& dest) const - { - dest = ploaddup(a); - } - - EIGEN_STRONG_INLINE void madd(const LhsPacket& a, const RhsPacket& b, AccPacket& c, RhsPacket& tmp) const - { - madd_impl(a, b, c, tmp, typename conditional::type()); - } - - EIGEN_STRONG_INLINE void madd_impl(const LhsPacket& a, const RhsPacket& b, AccPacket& c, RhsPacket& tmp, const true_type&) const - { - tmp = b; tmp.v = pmul(a,tmp.v); c = padd(c,tmp); - } - - EIGEN_STRONG_INLINE void madd_impl(const LhsScalar& a, const RhsScalar& b, ResScalar& c, RhsScalar& /*tmp*/, const false_type&) const - { - c += a * b; - } - - EIGEN_STRONG_INLINE void acc(const AccPacket& c, const ResPacket& alpha, ResPacket& r) const - { - r = cj.pmadd(alpha,c,r); - } - -protected: - conj_helper cj; -}; - -/* optimized GEneral packed Block * packed Panel product kernel - * - * Mixing type logic: C += A * B - * | A | B | comments - * |real |cplx | no vectorization yet, would require to pack A with duplication - * |cplx |real | easy vectorization - */ -template -struct gebp_kernel -{ - typedef gebp_traits Traits; - typedef typename Traits::ResScalar ResScalar; - typedef typename Traits::LhsPacket LhsPacket; - typedef typename Traits::RhsPacket RhsPacket; - typedef typename Traits::ResPacket ResPacket; - typedef typename Traits::AccPacket AccPacket; - - enum { - Vectorizable = Traits::Vectorizable, - LhsProgress = Traits::LhsProgress, - RhsProgress = Traits::RhsProgress, - ResPacketSize = Traits::ResPacketSize - }; - - EIGEN_DONT_INLINE - void operator()(ResScalar* res, Index resStride, const LhsScalar* blockA, const RhsScalar* blockB, Index rows, Index depth, Index cols, ResScalar alpha, - Index strideA=-1, Index strideB=-1, Index offsetA=0, Index offsetB=0, RhsScalar* unpackedB=0); -}; - -template -EIGEN_DONT_INLINE -void gebp_kernel - ::operator()(ResScalar* res, Index resStride, const LhsScalar* blockA, const RhsScalar* blockB, Index rows, Index depth, Index cols, ResScalar alpha, - Index strideA, Index strideB, Index offsetA, Index offsetB, RhsScalar* unpackedB) - { - Traits traits; - - if(strideA==-1) strideA = depth; - if(strideB==-1) strideB = depth; - conj_helper cj; -// conj_helper pcj; - Index packet_cols = (cols/nr) * nr; - const Index peeled_mc = (rows/mr)*mr; - // FIXME: - const Index peeled_mc2 = peeled_mc + (rows-peeled_mc >= LhsProgress ? LhsProgress : 0); - const Index peeled_kc = (depth/4)*4; - - if(unpackedB==0) - unpackedB = const_cast(blockB - strideB * nr * RhsProgress); - - // loops on each micro vertical panel of rhs (depth x nr) - for(Index j2=0; j2 we select a mr x nr micro block of res which is entirely - // stored into mr/packet_size x nr registers. - for(Index i=0; i(alpha); - - R0 = ploadu(r0); - R1 = ploadu(r1); - R2 = ploadu(r2); - R3 = ploadu(r3); - R4 = ploadu(r0 + ResPacketSize); - R5 = ploadu(r1 + ResPacketSize); - R6 = ploadu(r2 + ResPacketSize); - traits.acc(C0, alphav, R0); - pstoreu(r0, R0); - R0 = ploadu(r3 + ResPacketSize); - - traits.acc(C1, alphav, R1); - traits.acc(C2, alphav, R2); - traits.acc(C3, alphav, R3); - traits.acc(C4, alphav, R4); - traits.acc(C5, alphav, R5); - traits.acc(C6, alphav, R6); - traits.acc(C7, alphav, R0); - - pstoreu(r1, R1); - pstoreu(r2, R2); - pstoreu(r3, R3); - pstoreu(r0 + ResPacketSize, R4); - pstoreu(r1 + ResPacketSize, R5); - pstoreu(r2 + ResPacketSize, R6); - pstoreu(r3 + ResPacketSize, R0); - } - else - { - ResPacket R0, R1, R4; - ResPacket alphav = pset1(alpha); - - R0 = ploadu(r0); - R1 = ploadu(r1); - R4 = ploadu(r0 + ResPacketSize); - traits.acc(C0, alphav, R0); - pstoreu(r0, R0); - R0 = ploadu(r1 + ResPacketSize); - traits.acc(C1, alphav, R1); - traits.acc(C4, alphav, R4); - traits.acc(C5, alphav, R0); - pstoreu(r1, R1); - pstoreu(r0 + ResPacketSize, R4); - pstoreu(r1 + ResPacketSize, R0); - } - - } - - if(rows-peeled_mc>=LhsProgress) - { - Index i = peeled_mc; - const LhsScalar* blA = &blockA[i*strideA+offsetA*LhsProgress]; - prefetch(&blA[0]); - - // gets res block as register - AccPacket C0, C1, C2, C3; - traits.initAcc(C0); - traits.initAcc(C1); - if(nr==4) traits.initAcc(C2); - if(nr==4) traits.initAcc(C3); - - // performs "inner" product - const RhsScalar* blB = unpackedB; - for(Index k=0; k(alpha); - - ResScalar* r0 = &res[(j2+0)*resStride + i]; - ResScalar* r1 = r0 + resStride; - ResScalar* r2 = r1 + resStride; - ResScalar* r3 = r2 + resStride; - - R0 = ploadu(r0); - R1 = ploadu(r1); - if(nr==4) R2 = ploadu(r2); - if(nr==4) R3 = ploadu(r3); - - traits.acc(C0, alphav, R0); - traits.acc(C1, alphav, R1); - if(nr==4) traits.acc(C2, alphav, R2); - if(nr==4) traits.acc(C3, alphav, R3); - - pstoreu(r0, R0); - pstoreu(r1, R1); - if(nr==4) pstoreu(r2, R2); - if(nr==4) pstoreu(r3, R3); - } - for(Index i=peeled_mc2; i do the same but with nr==1 - for(Index j2=packet_cols; j2(alpha); - - ResScalar* r0 = &res[(j2+0)*resStride + i]; - - R0 = ploadu(r0); - R4 = ploadu(r0+ResPacketSize); - - traits.acc(C0, alphav, R0); - traits.acc(C4, alphav, R4); - - pstoreu(r0, R0); - pstoreu(r0+ResPacketSize, R4); - } - if(rows-peeled_mc>=LhsProgress) - { - Index i = peeled_mc; - const LhsScalar* blA = &blockA[i*strideA+offsetA*LhsProgress]; - prefetch(&blA[0]); - - AccPacket C0; - traits.initAcc(C0); - - const RhsScalar* blB = unpackedB; - for(Index k=0; k(alpha); - ResPacket R0 = ploadu(&res[(j2+0)*resStride + i]); - traits.acc(C0, alphav, R0); - pstoreu(&res[(j2+0)*resStride + i], R0); - } - for(Index i=peeled_mc2; i -struct gemm_pack_lhs -{ - EIGEN_DONT_INLINE void operator()(Scalar* blockA, const Scalar* EIGEN_RESTRICT _lhs, Index lhsStride, Index depth, Index rows, Index stride=0, Index offset=0); -}; - -template -EIGEN_DONT_INLINE void gemm_pack_lhs - ::operator()(Scalar* blockA, const Scalar* EIGEN_RESTRICT _lhs, Index lhsStride, Index depth, Index rows, Index stride, Index offset) -{ - typedef typename packet_traits::type Packet; - enum { PacketSize = packet_traits::size }; - - EIGEN_ASM_COMMENT("EIGEN PRODUCT PACK LHS"); - EIGEN_UNUSED_VARIABLE(stride) - EIGEN_UNUSED_VARIABLE(offset) - eigen_assert(((!PanelMode) && stride==0 && offset==0) || (PanelMode && stride>=depth && offset<=stride)); - eigen_assert( (StorageOrder==RowMajor) || ((Pack1%PacketSize)==0 && Pack1<=4*PacketSize) ); - conj_if::IsComplex && Conjugate> cj; - const_blas_data_mapper lhs(_lhs,lhsStride); - Index count = 0; - Index peeled_mc = (rows/Pack1)*Pack1; - for(Index i=0; i=1*PacketSize) A = ploadu(&lhs(i+0*PacketSize, k)); - if(Pack1>=2*PacketSize) B = ploadu(&lhs(i+1*PacketSize, k)); - if(Pack1>=3*PacketSize) C = ploadu(&lhs(i+2*PacketSize, k)); - if(Pack1>=4*PacketSize) D = ploadu(&lhs(i+3*PacketSize, k)); - if(Pack1>=1*PacketSize) { pstore(blockA+count, cj.pconj(A)); count+=PacketSize; } - if(Pack1>=2*PacketSize) { pstore(blockA+count, cj.pconj(B)); count+=PacketSize; } - if(Pack1>=3*PacketSize) { pstore(blockA+count, cj.pconj(C)); count+=PacketSize; } - if(Pack1>=4*PacketSize) { pstore(blockA+count, cj.pconj(D)); count+=PacketSize; } - } - } - else - { - for(Index k=0; k=Pack2) - { - if(PanelMode) count += Pack2*offset; - for(Index k=0; k -struct gemm_pack_rhs -{ - typedef typename packet_traits::type Packet; - enum { PacketSize = packet_traits::size }; - EIGEN_DONT_INLINE void operator()(Scalar* blockB, const Scalar* rhs, Index rhsStride, Index depth, Index cols, Index stride=0, Index offset=0); -}; - -template -EIGEN_DONT_INLINE void gemm_pack_rhs - ::operator()(Scalar* blockB, const Scalar* rhs, Index rhsStride, Index depth, Index cols, Index stride, Index offset) -{ - EIGEN_ASM_COMMENT("EIGEN PRODUCT PACK RHS COLMAJOR"); - EIGEN_UNUSED_VARIABLE(stride) - EIGEN_UNUSED_VARIABLE(offset) - eigen_assert(((!PanelMode) && stride==0 && offset==0) || (PanelMode && stride>=depth && offset<=stride)); - conj_if::IsComplex && Conjugate> cj; - Index packet_cols = (cols/nr) * nr; - Index count = 0; - for(Index j2=0; j2 -struct gemm_pack_rhs -{ - enum { PacketSize = packet_traits::size }; - EIGEN_DONT_INLINE void operator()(Scalar* blockB, const Scalar* rhs, Index rhsStride, Index depth, Index cols, Index stride=0, Index offset=0); -}; - -template -EIGEN_DONT_INLINE void gemm_pack_rhs - ::operator()(Scalar* blockB, const Scalar* rhs, Index rhsStride, Index depth, Index cols, Index stride, Index offset) -{ - EIGEN_ASM_COMMENT("EIGEN PRODUCT PACK RHS ROWMAJOR"); - EIGEN_UNUSED_VARIABLE(stride) - EIGEN_UNUSED_VARIABLE(offset) - eigen_assert(((!PanelMode) && stride==0 && offset==0) || (PanelMode && stride>=depth && offset<=stride)); - conj_if::IsComplex && Conjugate> cj; - Index packet_cols = (cols/nr) * nr; - Index count = 0; - for(Index j2=0; j2 -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_GENERAL_MATRIX_MATRIX_H -#define EIGEN_GENERAL_MATRIX_MATRIX_H - -namespace Eigen { - -namespace internal { - -template class level3_blocking; - -/* Specialization for a row-major destination matrix => simple transposition of the product */ -template< - typename Index, - typename LhsScalar, int LhsStorageOrder, bool ConjugateLhs, - typename RhsScalar, int RhsStorageOrder, bool ConjugateRhs> -struct general_matrix_matrix_product -{ - typedef typename scalar_product_traits::ReturnType ResScalar; - static EIGEN_STRONG_INLINE void run( - Index rows, Index cols, Index depth, - const LhsScalar* lhs, Index lhsStride, - const RhsScalar* rhs, Index rhsStride, - ResScalar* res, Index resStride, - ResScalar alpha, - level3_blocking& blocking, - GemmParallelInfo* info = 0) - { - // transpose the product such that the result is column major - general_matrix_matrix_product - ::run(cols,rows,depth,rhs,rhsStride,lhs,lhsStride,res,resStride,alpha,blocking,info); - } -}; - -/* Specialization for a col-major destination matrix - * => Blocking algorithm following Goto's paper */ -template< - typename Index, - typename LhsScalar, int LhsStorageOrder, bool ConjugateLhs, - typename RhsScalar, int RhsStorageOrder, bool ConjugateRhs> -struct general_matrix_matrix_product -{ - -typedef typename scalar_product_traits::ReturnType ResScalar; -static void run(Index rows, Index cols, Index depth, - const LhsScalar* _lhs, Index lhsStride, - const RhsScalar* _rhs, Index rhsStride, - ResScalar* res, Index resStride, - ResScalar alpha, - level3_blocking& blocking, - GemmParallelInfo* info = 0) -{ - const_blas_data_mapper lhs(_lhs,lhsStride); - const_blas_data_mapper rhs(_rhs,rhsStride); - - typedef gebp_traits Traits; - - Index kc = blocking.kc(); // cache block size along the K direction - Index mc = (std::min)(rows,blocking.mc()); // cache block size along the M direction - //Index nc = blocking.nc(); // cache block size along the N direction - - gemm_pack_lhs pack_lhs; - gemm_pack_rhs pack_rhs; - gebp_kernel gebp; - -#ifdef EIGEN_HAS_OPENMP - if(info) - { - // this is the parallel version! - Index tid = omp_get_thread_num(); - Index threads = omp_get_num_threads(); - - std::size_t sizeA = kc*mc; - std::size_t sizeW = kc*Traits::WorkSpaceFactor; - ei_declare_aligned_stack_constructed_variable(LhsScalar, blockA, sizeA, 0); - ei_declare_aligned_stack_constructed_variable(RhsScalar, w, sizeW, 0); - - RhsScalar* blockB = blocking.blockB(); - eigen_internal_assert(blockB!=0); - - // For each horizontal panel of the rhs, and corresponding vertical panel of the lhs... - for(Index k=0; k rows of B', and cols of the A' - - // In order to reduce the chance that a thread has to wait for the other, - // let's start by packing A'. - pack_lhs(blockA, &lhs(0,k), lhsStride, actual_kc, mc); - - // Pack B_k to B' in a parallel fashion: - // each thread packs the sub block B_k,j to B'_j where j is the thread id. - - // However, before copying to B'_j, we have to make sure that no other thread is still using it, - // i.e., we test that info[tid].users equals 0. - // Then, we set info[tid].users to the number of threads to mark that all other threads are going to use it. - while(info[tid].users!=0) {} - info[tid].users += threads; - - pack_rhs(blockB+info[tid].rhs_start*actual_kc, &rhs(k,info[tid].rhs_start), rhsStride, actual_kc, info[tid].rhs_length); - - // Notify the other threads that the part B'_j is ready to go. - info[tid].sync = k; - - // Computes C_i += A' * B' per B'_j - for(Index shift=0; shift0) - while(info[j].sync!=k) {} - - gebp(res+info[j].rhs_start*resStride, resStride, blockA, blockB+info[j].rhs_start*actual_kc, mc, actual_kc, info[j].rhs_length, alpha, -1,-1,0,0, w); - } - - // Then keep going as usual with the remaining A' - for(Index i=mc; i Pack rhs's panel into a sequential chunk of memory (L2 caching) - // Note that this panel will be read as many times as the number of blocks in the lhs's - // vertical panel which is, in practice, a very low number. - pack_rhs(blockB, &rhs(k2,0), rhsStride, actual_kc, cols); - - // For each mc x kc block of the lhs's vertical panel... - // (==GEPP_VAR1) - for(Index i2=0; i2 for "large" GEMM, i.e., -* implementation of the high level wrapper to general_matrix_matrix_product -**********************************************************************************/ - -template -struct traits > - : traits, Lhs, Rhs> > -{}; - -template -struct gemm_functor -{ - gemm_functor(const Lhs& lhs, const Rhs& rhs, Dest& dest, const Scalar& actualAlpha, - BlockingType& blocking) - : m_lhs(lhs), m_rhs(rhs), m_dest(dest), m_actualAlpha(actualAlpha), m_blocking(blocking) - {} - - void initParallelSession() const - { - m_blocking.allocateB(); - } - - void operator() (Index row, Index rows, Index col=0, Index cols=-1, GemmParallelInfo* info=0) const - { - if(cols==-1) - cols = m_rhs.cols(); - - Gemm::run(rows, cols, m_lhs.cols(), - /*(const Scalar*)*/&m_lhs.coeffRef(row,0), m_lhs.outerStride(), - /*(const Scalar*)*/&m_rhs.coeffRef(0,col), m_rhs.outerStride(), - (Scalar*)&(m_dest.coeffRef(row,col)), m_dest.outerStride(), - m_actualAlpha, m_blocking, info); - } - - protected: - const Lhs& m_lhs; - const Rhs& m_rhs; - Dest& m_dest; - Scalar m_actualAlpha; - BlockingType& m_blocking; -}; - -template class gemm_blocking_space; - -template -class level3_blocking -{ - typedef _LhsScalar LhsScalar; - typedef _RhsScalar RhsScalar; - - protected: - LhsScalar* m_blockA; - RhsScalar* m_blockB; - RhsScalar* m_blockW; - - DenseIndex m_mc; - DenseIndex m_nc; - DenseIndex m_kc; - - public: - - level3_blocking() - : m_blockA(0), m_blockB(0), m_blockW(0), m_mc(0), m_nc(0), m_kc(0) - {} - - inline DenseIndex mc() const { return m_mc; } - inline DenseIndex nc() const { return m_nc; } - inline DenseIndex kc() const { return m_kc; } - - inline LhsScalar* blockA() { return m_blockA; } - inline RhsScalar* blockB() { return m_blockB; } - inline RhsScalar* blockW() { return m_blockW; } -}; - -template -class gemm_blocking_space - : public level3_blocking< - typename conditional::type, - typename conditional::type> -{ - enum { - Transpose = StorageOrder==RowMajor, - ActualRows = Transpose ? MaxCols : MaxRows, - ActualCols = Transpose ? MaxRows : MaxCols - }; - typedef typename conditional::type LhsScalar; - typedef typename conditional::type RhsScalar; - typedef gebp_traits Traits; - enum { - SizeA = ActualRows * MaxDepth, - SizeB = ActualCols * MaxDepth, - SizeW = MaxDepth * Traits::WorkSpaceFactor - }; - - EIGEN_ALIGN16 LhsScalar m_staticA[SizeA]; - EIGEN_ALIGN16 RhsScalar m_staticB[SizeB]; - EIGEN_ALIGN16 RhsScalar m_staticW[SizeW]; - - public: - - gemm_blocking_space(DenseIndex /*rows*/, DenseIndex /*cols*/, DenseIndex /*depth*/) - { - this->m_mc = ActualRows; - this->m_nc = ActualCols; - this->m_kc = MaxDepth; - this->m_blockA = m_staticA; - this->m_blockB = m_staticB; - this->m_blockW = m_staticW; - } - - inline void allocateA() {} - inline void allocateB() {} - inline void allocateW() {} - inline void allocateAll() {} -}; - -template -class gemm_blocking_space - : public level3_blocking< - typename conditional::type, - typename conditional::type> -{ - enum { - Transpose = StorageOrder==RowMajor - }; - typedef typename conditional::type LhsScalar; - typedef typename conditional::type RhsScalar; - typedef gebp_traits Traits; - - DenseIndex m_sizeA; - DenseIndex m_sizeB; - DenseIndex m_sizeW; - - public: - - gemm_blocking_space(DenseIndex rows, DenseIndex cols, DenseIndex depth) - { - this->m_mc = Transpose ? cols : rows; - this->m_nc = Transpose ? rows : cols; - this->m_kc = depth; - - computeProductBlockingSizes(this->m_kc, this->m_mc, this->m_nc); - m_sizeA = this->m_mc * this->m_kc; - m_sizeB = this->m_kc * this->m_nc; - m_sizeW = this->m_kc*Traits::WorkSpaceFactor; - } - - void allocateA() - { - if(this->m_blockA==0) - this->m_blockA = aligned_new(m_sizeA); - } - - void allocateB() - { - if(this->m_blockB==0) - this->m_blockB = aligned_new(m_sizeB); - } - - void allocateW() - { - if(this->m_blockW==0) - this->m_blockW = aligned_new(m_sizeW); - } - - void allocateAll() - { - allocateA(); - allocateB(); - allocateW(); - } - - ~gemm_blocking_space() - { - aligned_delete(this->m_blockA, m_sizeA); - aligned_delete(this->m_blockB, m_sizeB); - aligned_delete(this->m_blockW, m_sizeW); - } -}; - -} // end namespace internal - -template -class GeneralProduct - : public ProductBase, Lhs, Rhs> -{ - enum { - MaxDepthAtCompileTime = EIGEN_SIZE_MIN_PREFER_FIXED(Lhs::MaxColsAtCompileTime,Rhs::MaxRowsAtCompileTime) - }; - public: - EIGEN_PRODUCT_PUBLIC_INTERFACE(GeneralProduct) - - typedef typename Lhs::Scalar LhsScalar; - typedef typename Rhs::Scalar RhsScalar; - typedef Scalar ResScalar; - - GeneralProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs) - { - typedef internal::scalar_product_op BinOp; - EIGEN_CHECK_BINARY_COMPATIBILIY(BinOp,LhsScalar,RhsScalar); - } - - template void scaleAndAddTo(Dest& dst, const Scalar& alpha) const - { - eigen_assert(dst.rows()==m_lhs.rows() && dst.cols()==m_rhs.cols()); - - typename internal::add_const_on_value_type::type lhs = LhsBlasTraits::extract(m_lhs); - typename internal::add_const_on_value_type::type rhs = RhsBlasTraits::extract(m_rhs); - - Scalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(m_lhs) - * RhsBlasTraits::extractScalarFactor(m_rhs); - - typedef internal::gemm_blocking_space<(Dest::Flags&RowMajorBit) ? RowMajor : ColMajor,LhsScalar,RhsScalar, - Dest::MaxRowsAtCompileTime,Dest::MaxColsAtCompileTime,MaxDepthAtCompileTime> BlockingType; - - typedef internal::gemm_functor< - Scalar, Index, - internal::general_matrix_matrix_product< - Index, - LhsScalar, (_ActualLhsType::Flags&RowMajorBit) ? RowMajor : ColMajor, bool(LhsBlasTraits::NeedToConjugate), - RhsScalar, (_ActualRhsType::Flags&RowMajorBit) ? RowMajor : ColMajor, bool(RhsBlasTraits::NeedToConjugate), - (Dest::Flags&RowMajorBit) ? RowMajor : ColMajor>, - _ActualLhsType, _ActualRhsType, Dest, BlockingType> GemmFunctor; - - BlockingType blocking(dst.rows(), dst.cols(), lhs.cols()); - - internal::parallelize_gemm<(Dest::MaxRowsAtCompileTime>32 || Dest::MaxRowsAtCompileTime==Dynamic)>(GemmFunctor(lhs, rhs, dst, actualAlpha, blocking), this->rows(), this->cols(), Dest::Flags&RowMajorBit); - } -}; - -} // end namespace Eigen - -#endif // EIGEN_GENERAL_MATRIX_MATRIX_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h deleted file mode 100644 index 5c376390..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h +++ /dev/null @@ -1,278 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2009-2010 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_GENERAL_MATRIX_MATRIX_TRIANGULAR_H -#define EIGEN_GENERAL_MATRIX_MATRIX_TRIANGULAR_H - -namespace Eigen { - -template -struct selfadjoint_rank1_update; - -namespace internal { - -/********************************************************************** -* This file implements a general A * B product while -* evaluating only one triangular part of the product. -* This is more general version of self adjoint product (C += A A^T) -* as the level 3 SYRK Blas routine. -**********************************************************************/ - -// forward declarations (defined at the end of this file) -template -struct tribb_kernel; - -/* Optimized matrix-matrix product evaluating only one triangular half */ -template -struct general_matrix_matrix_triangular_product; - -// as usual if the result is row major => we transpose the product -template -struct general_matrix_matrix_triangular_product -{ - typedef typename scalar_product_traits::ReturnType ResScalar; - static EIGEN_STRONG_INLINE void run(Index size, Index depth,const LhsScalar* lhs, Index lhsStride, - const RhsScalar* rhs, Index rhsStride, ResScalar* res, Index resStride, const ResScalar& alpha) - { - general_matrix_matrix_triangular_product - ::run(size,depth,rhs,rhsStride,lhs,lhsStride,res,resStride,alpha); - } -}; - -template -struct general_matrix_matrix_triangular_product -{ - typedef typename scalar_product_traits::ReturnType ResScalar; - static EIGEN_STRONG_INLINE void run(Index size, Index depth,const LhsScalar* _lhs, Index lhsStride, - const RhsScalar* _rhs, Index rhsStride, ResScalar* res, Index resStride, const ResScalar& alpha) - { - const_blas_data_mapper lhs(_lhs,lhsStride); - const_blas_data_mapper rhs(_rhs,rhsStride); - - typedef gebp_traits Traits; - - Index kc = depth; // cache block size along the K direction - Index mc = size; // cache block size along the M direction - Index nc = size; // cache block size along the N direction - computeProductBlockingSizes(kc, mc, nc); - // !!! mc must be a multiple of nr: - if(mc > Traits::nr) - mc = (mc/Traits::nr)*Traits::nr; - - std::size_t sizeW = kc*Traits::WorkSpaceFactor; - std::size_t sizeB = sizeW + kc*size; - ei_declare_aligned_stack_constructed_variable(LhsScalar, blockA, kc*mc, 0); - ei_declare_aligned_stack_constructed_variable(RhsScalar, allocatedBlockB, sizeB, 0); - RhsScalar* blockB = allocatedBlockB + sizeW; - - gemm_pack_lhs pack_lhs; - gemm_pack_rhs pack_rhs; - gebp_kernel gebp; - tribb_kernel sybb; - - for(Index k2=0; k2 processed with gebp or skipped - // 2 - the actual_mc x actual_mc symmetric block => processed with a special kernel - // 3 - after the diagonal => processed with gebp or skipped - if (UpLo==Lower) - gebp(res+i2, resStride, blockA, blockB, actual_mc, actual_kc, (std::min)(size,i2), alpha, - -1, -1, 0, 0, allocatedBlockB); - - sybb(res+resStride*i2 + i2, resStride, blockA, blockB + actual_kc*i2, actual_mc, actual_kc, alpha, allocatedBlockB); - - if (UpLo==Upper) - { - Index j2 = i2+actual_mc; - gebp(res+resStride*j2+i2, resStride, blockA, blockB+actual_kc*j2, actual_mc, actual_kc, (std::max)(Index(0), size-j2), alpha, - -1, -1, 0, 0, allocatedBlockB); - } - } - } - } -}; - -// Optimized packed Block * packed Block product kernel evaluating only one given triangular part -// This kernel is built on top of the gebp kernel: -// - the current destination block is processed per panel of actual_mc x BlockSize -// where BlockSize is set to the minimal value allowing gebp to be as fast as possible -// - then, as usual, each panel is split into three parts along the diagonal, -// the sub blocks above and below the diagonal are processed as usual, -// while the triangular block overlapping the diagonal is evaluated into a -// small temporary buffer which is then accumulated into the result using a -// triangular traversal. -template -struct tribb_kernel -{ - typedef gebp_traits Traits; - typedef typename Traits::ResScalar ResScalar; - - enum { - BlockSize = EIGEN_PLAIN_ENUM_MAX(mr,nr) - }; - void operator()(ResScalar* res, Index resStride, const LhsScalar* blockA, const RhsScalar* blockB, Index size, Index depth, const ResScalar& alpha, RhsScalar* workspace) - { - gebp_kernel gebp_kernel; - Matrix buffer; - - // let's process the block per panel of actual_mc x BlockSize, - // again, each is split into three parts, etc. - for (Index j=0; j(BlockSize,size - j); - const RhsScalar* actual_b = blockB+j*depth; - - if(UpLo==Upper) - gebp_kernel(res+j*resStride, resStride, blockA, actual_b, j, depth, actualBlockSize, alpha, - -1, -1, 0, 0, workspace); - - // selfadjoint micro block - { - Index i = j; - buffer.setZero(); - // 1 - apply the kernel on the temporary buffer - gebp_kernel(buffer.data(), BlockSize, blockA+depth*i, actual_b, actualBlockSize, depth, actualBlockSize, alpha, - -1, -1, 0, 0, workspace); - // 2 - triangular accumulation - for(Index j1=0; j1 -struct general_product_to_triangular_selector; - - -template -struct general_product_to_triangular_selector -{ - static void run(MatrixType& mat, const ProductType& prod, const typename MatrixType::Scalar& alpha) - { - typedef typename MatrixType::Scalar Scalar; - typedef typename MatrixType::Index Index; - - typedef typename internal::remove_all::type Lhs; - typedef internal::blas_traits LhsBlasTraits; - typedef typename LhsBlasTraits::DirectLinearAccessType ActualLhs; - typedef typename internal::remove_all::type _ActualLhs; - typename internal::add_const_on_value_type::type actualLhs = LhsBlasTraits::extract(prod.lhs()); - - typedef typename internal::remove_all::type Rhs; - typedef internal::blas_traits RhsBlasTraits; - typedef typename RhsBlasTraits::DirectLinearAccessType ActualRhs; - typedef typename internal::remove_all::type _ActualRhs; - typename internal::add_const_on_value_type::type actualRhs = RhsBlasTraits::extract(prod.rhs()); - - Scalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(prod.lhs().derived()) * RhsBlasTraits::extractScalarFactor(prod.rhs().derived()); - - enum { - StorageOrder = (internal::traits::Flags&RowMajorBit) ? RowMajor : ColMajor, - UseLhsDirectly = _ActualLhs::InnerStrideAtCompileTime==1, - UseRhsDirectly = _ActualRhs::InnerStrideAtCompileTime==1 - }; - - internal::gemv_static_vector_if static_lhs; - ei_declare_aligned_stack_constructed_variable(Scalar, actualLhsPtr, actualLhs.size(), - (UseLhsDirectly ? const_cast(actualLhs.data()) : static_lhs.data())); - if(!UseLhsDirectly) Map(actualLhsPtr, actualLhs.size()) = actualLhs; - - internal::gemv_static_vector_if static_rhs; - ei_declare_aligned_stack_constructed_variable(Scalar, actualRhsPtr, actualRhs.size(), - (UseRhsDirectly ? const_cast(actualRhs.data()) : static_rhs.data())); - if(!UseRhsDirectly) Map(actualRhsPtr, actualRhs.size()) = actualRhs; - - - selfadjoint_rank1_update::IsComplex, - RhsBlasTraits::NeedToConjugate && NumTraits::IsComplex> - ::run(actualLhs.size(), mat.data(), mat.outerStride(), actualLhsPtr, actualRhsPtr, actualAlpha); - } -}; - -template -struct general_product_to_triangular_selector -{ - static void run(MatrixType& mat, const ProductType& prod, const typename MatrixType::Scalar& alpha) - { - typedef typename MatrixType::Index Index; - - typedef typename internal::remove_all::type Lhs; - typedef internal::blas_traits LhsBlasTraits; - typedef typename LhsBlasTraits::DirectLinearAccessType ActualLhs; - typedef typename internal::remove_all::type _ActualLhs; - typename internal::add_const_on_value_type::type actualLhs = LhsBlasTraits::extract(prod.lhs()); - - typedef typename internal::remove_all::type Rhs; - typedef internal::blas_traits RhsBlasTraits; - typedef typename RhsBlasTraits::DirectLinearAccessType ActualRhs; - typedef typename internal::remove_all::type _ActualRhs; - typename internal::add_const_on_value_type::type actualRhs = RhsBlasTraits::extract(prod.rhs()); - - typename ProductType::Scalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(prod.lhs().derived()) * RhsBlasTraits::extractScalarFactor(prod.rhs().derived()); - - internal::general_matrix_matrix_triangular_product - ::run(mat.cols(), actualLhs.cols(), - &actualLhs.coeffRef(0,0), actualLhs.outerStride(), &actualRhs.coeffRef(0,0), actualRhs.outerStride(), - mat.data(), mat.outerStride(), actualAlpha); - } -}; - -template -template -TriangularView& TriangularView::assignProduct(const ProductBase& prod, const Scalar& alpha) -{ - general_product_to_triangular_selector::run(m_matrix.const_cast_derived(), prod.derived(), alpha); - - return *this; -} - -} // end namespace Eigen - -#endif // EIGEN_GENERAL_MATRIX_MATRIX_TRIANGULAR_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_MKL.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_MKL.h deleted file mode 100644 index 3deed068..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_MKL.h +++ /dev/null @@ -1,146 +0,0 @@ -/* - Copyright (c) 2011, Intel Corporation. All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of Intel Corporation nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - ******************************************************************************** - * Content : Eigen bindings to Intel(R) MKL - * Level 3 BLAS SYRK/HERK implementation. - ******************************************************************************** -*/ - -#ifndef EIGEN_GENERAL_MATRIX_MATRIX_TRIANGULAR_MKL_H -#define EIGEN_GENERAL_MATRIX_MATRIX_TRIANGULAR_MKL_H - -namespace Eigen { - -namespace internal { - -template -struct general_matrix_matrix_rankupdate : - general_matrix_matrix_triangular_product< - Index,Scalar,AStorageOrder,ConjugateA,Scalar,AStorageOrder,ConjugateA,ResStorageOrder,UpLo,BuiltIn> {}; - - -// try to go to BLAS specialization -#define EIGEN_MKL_RANKUPDATE_SPECIALIZE(Scalar) \ -template \ -struct general_matrix_matrix_triangular_product { \ - static EIGEN_STRONG_INLINE void run(Index size, Index depth,const Scalar* lhs, Index lhsStride, \ - const Scalar* rhs, Index rhsStride, Scalar* res, Index resStride, Scalar alpha) \ - { \ - if (lhs==rhs) { \ - general_matrix_matrix_rankupdate \ - ::run(size,depth,lhs,lhsStride,rhs,rhsStride,res,resStride,alpha); \ - } else { \ - general_matrix_matrix_triangular_product \ - ::run(size,depth,lhs,lhsStride,rhs,rhsStride,res,resStride,alpha); \ - } \ - } \ -}; - -EIGEN_MKL_RANKUPDATE_SPECIALIZE(double) -//EIGEN_MKL_RANKUPDATE_SPECIALIZE(dcomplex) -EIGEN_MKL_RANKUPDATE_SPECIALIZE(float) -//EIGEN_MKL_RANKUPDATE_SPECIALIZE(scomplex) - -// SYRK for float/double -#define EIGEN_MKL_RANKUPDATE_R(EIGTYPE, MKLTYPE, MKLFUNC) \ -template \ -struct general_matrix_matrix_rankupdate { \ - enum { \ - IsLower = (UpLo&Lower) == Lower, \ - LowUp = IsLower ? Lower : Upper, \ - conjA = ((AStorageOrder==ColMajor) && ConjugateA) ? 1 : 0 \ - }; \ - static EIGEN_STRONG_INLINE void run(Index size, Index depth,const EIGTYPE* lhs, Index lhsStride, \ - const EIGTYPE* rhs, Index rhsStride, EIGTYPE* res, Index resStride, EIGTYPE alpha) \ - { \ - /* typedef Matrix MatrixRhs;*/ \ -\ - MKL_INT lda=lhsStride, ldc=resStride, n=size, k=depth; \ - char uplo=(IsLower) ? 'L' : 'U', trans=(AStorageOrder==RowMajor) ? 'T':'N'; \ - MKLTYPE alpha_, beta_; \ -\ -/* Set alpha_ & beta_ */ \ - assign_scalar_eig2mkl(alpha_, alpha); \ - assign_scalar_eig2mkl(beta_, EIGTYPE(1)); \ - MKLFUNC(&uplo, &trans, &n, &k, &alpha_, lhs, &lda, &beta_, res, &ldc); \ - } \ -}; - -// HERK for complex data -#define EIGEN_MKL_RANKUPDATE_C(EIGTYPE, MKLTYPE, RTYPE, MKLFUNC) \ -template \ -struct general_matrix_matrix_rankupdate { \ - enum { \ - IsLower = (UpLo&Lower) == Lower, \ - LowUp = IsLower ? Lower : Upper, \ - conjA = (((AStorageOrder==ColMajor) && ConjugateA) || ((AStorageOrder==RowMajor) && !ConjugateA)) ? 1 : 0 \ - }; \ - static EIGEN_STRONG_INLINE void run(Index size, Index depth,const EIGTYPE* lhs, Index lhsStride, \ - const EIGTYPE* rhs, Index rhsStride, EIGTYPE* res, Index resStride, EIGTYPE alpha) \ - { \ - typedef Matrix MatrixType; \ -\ - MKL_INT lda=lhsStride, ldc=resStride, n=size, k=depth; \ - char uplo=(IsLower) ? 'L' : 'U', trans=(AStorageOrder==RowMajor) ? 'C':'N'; \ - RTYPE alpha_, beta_; \ - const EIGTYPE* a_ptr; \ -\ -/* Set alpha_ & beta_ */ \ -/* assign_scalar_eig2mkl(alpha_, alpha); */\ -/* assign_scalar_eig2mkl(beta_, EIGTYPE(1));*/ \ - alpha_ = alpha.real(); \ - beta_ = 1.0; \ -/* Copy with conjugation in some cases*/ \ - MatrixType a; \ - if (conjA) { \ - Map > mapA(lhs,n,k,OuterStride<>(lhsStride)); \ - a = mapA.conjugate(); \ - lda = a.outerStride(); \ - a_ptr = a.data(); \ - } else a_ptr=lhs; \ - MKLFUNC(&uplo, &trans, &n, &k, &alpha_, (MKLTYPE*)a_ptr, &lda, &beta_, (MKLTYPE*)res, &ldc); \ - } \ -}; - - -EIGEN_MKL_RANKUPDATE_R(double, double, dsyrk) -EIGEN_MKL_RANKUPDATE_R(float, float, ssyrk) - -//EIGEN_MKL_RANKUPDATE_C(dcomplex, MKL_Complex16, double, zherk) -//EIGEN_MKL_RANKUPDATE_C(scomplex, MKL_Complex8, double, cherk) - - -} // end namespace internal - -} // end namespace Eigen - -#endif // EIGEN_GENERAL_MATRIX_MATRIX_TRIANGULAR_MKL_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/products/GeneralMatrixMatrix_MKL.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/products/GeneralMatrixMatrix_MKL.h deleted file mode 100644 index 060af328..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Core/products/GeneralMatrixMatrix_MKL.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - Copyright (c) 2011, Intel Corporation. All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of Intel Corporation nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - ******************************************************************************** - * Content : Eigen bindings to Intel(R) MKL - * General matrix-matrix product functionality based on ?GEMM. - ******************************************************************************** -*/ - -#ifndef EIGEN_GENERAL_MATRIX_MATRIX_MKL_H -#define EIGEN_GENERAL_MATRIX_MATRIX_MKL_H - -namespace Eigen { - -namespace internal { - -/********************************************************************** -* This file implements general matrix-matrix multiplication using BLAS -* gemm function via partial specialization of -* general_matrix_matrix_product::run(..) method for float, double, -* std::complex and std::complex types -**********************************************************************/ - -// gemm specialization - -#define GEMM_SPECIALIZATION(EIGTYPE, EIGPREFIX, MKLTYPE, MKLPREFIX) \ -template< \ - typename Index, \ - int LhsStorageOrder, bool ConjugateLhs, \ - int RhsStorageOrder, bool ConjugateRhs> \ -struct general_matrix_matrix_product \ -{ \ -static void run(Index rows, Index cols, Index depth, \ - const EIGTYPE* _lhs, Index lhsStride, \ - const EIGTYPE* _rhs, Index rhsStride, \ - EIGTYPE* res, Index resStride, \ - EIGTYPE alpha, \ - level3_blocking& /*blocking*/, \ - GemmParallelInfo* /*info = 0*/) \ -{ \ - using std::conj; \ -\ - char transa, transb; \ - MKL_INT m, n, k, lda, ldb, ldc; \ - const EIGTYPE *a, *b; \ - MKLTYPE alpha_, beta_; \ - MatrixX##EIGPREFIX a_tmp, b_tmp; \ - EIGTYPE myone(1);\ -\ -/* Set transpose options */ \ - transa = (LhsStorageOrder==RowMajor) ? ((ConjugateLhs) ? 'C' : 'T') : 'N'; \ - transb = (RhsStorageOrder==RowMajor) ? ((ConjugateRhs) ? 'C' : 'T') : 'N'; \ -\ -/* Set m, n, k */ \ - m = (MKL_INT)rows; \ - n = (MKL_INT)cols; \ - k = (MKL_INT)depth; \ -\ -/* Set alpha_ & beta_ */ \ - assign_scalar_eig2mkl(alpha_, alpha); \ - assign_scalar_eig2mkl(beta_, myone); \ -\ -/* Set lda, ldb, ldc */ \ - lda = (MKL_INT)lhsStride; \ - ldb = (MKL_INT)rhsStride; \ - ldc = (MKL_INT)resStride; \ -\ -/* Set a, b, c */ \ - if ((LhsStorageOrder==ColMajor) && (ConjugateLhs)) { \ - Map > lhs(_lhs,m,k,OuterStride<>(lhsStride)); \ - a_tmp = lhs.conjugate(); \ - a = a_tmp.data(); \ - lda = a_tmp.outerStride(); \ - } else a = _lhs; \ -\ - if ((RhsStorageOrder==ColMajor) && (ConjugateRhs)) { \ - Map > rhs(_rhs,k,n,OuterStride<>(rhsStride)); \ - b_tmp = rhs.conjugate(); \ - b = b_tmp.data(); \ - ldb = b_tmp.outerStride(); \ - } else b = _rhs; \ -\ - MKLPREFIX##gemm(&transa, &transb, &m, &n, &k, &alpha_, (const MKLTYPE*)a, &lda, (const MKLTYPE*)b, &ldb, &beta_, (MKLTYPE*)res, &ldc); \ -}}; - -GEMM_SPECIALIZATION(double, d, double, d) -GEMM_SPECIALIZATION(float, f, float, s) -GEMM_SPECIALIZATION(dcomplex, cd, MKL_Complex16, z) -GEMM_SPECIALIZATION(scomplex, cf, MKL_Complex8, c) - -} // end namespase internal - -} // end namespace Eigen - -#endif // EIGEN_GENERAL_MATRIX_MATRIX_MKL_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/products/GeneralMatrixVector.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/products/GeneralMatrixVector.h deleted file mode 100644 index 09387703..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Core/products/GeneralMatrixVector.h +++ /dev/null @@ -1,566 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2009 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_GENERAL_MATRIX_VECTOR_H -#define EIGEN_GENERAL_MATRIX_VECTOR_H - -namespace Eigen { - -namespace internal { - -/* Optimized col-major matrix * vector product: - * This algorithm processes 4 columns at onces that allows to both reduce - * the number of load/stores of the result by a factor 4 and to reduce - * the instruction dependency. Moreover, we know that all bands have the - * same alignment pattern. - * - * Mixing type logic: C += alpha * A * B - * | A | B |alpha| comments - * |real |cplx |cplx | no vectorization - * |real |cplx |real | alpha is converted to a cplx when calling the run function, no vectorization - * |cplx |real |cplx | invalid, the caller has to do tmp: = A * B; C += alpha*tmp - * |cplx |real |real | optimal case, vectorization possible via real-cplx mul - */ -template -struct general_matrix_vector_product -{ -typedef typename scalar_product_traits::ReturnType ResScalar; - -enum { - Vectorizable = packet_traits::Vectorizable && packet_traits::Vectorizable - && int(packet_traits::size)==int(packet_traits::size), - LhsPacketSize = Vectorizable ? packet_traits::size : 1, - RhsPacketSize = Vectorizable ? packet_traits::size : 1, - ResPacketSize = Vectorizable ? packet_traits::size : 1 -}; - -typedef typename packet_traits::type _LhsPacket; -typedef typename packet_traits::type _RhsPacket; -typedef typename packet_traits::type _ResPacket; - -typedef typename conditional::type LhsPacket; -typedef typename conditional::type RhsPacket; -typedef typename conditional::type ResPacket; - -EIGEN_DONT_INLINE static void run( - Index rows, Index cols, - const LhsScalar* lhs, Index lhsStride, - const RhsScalar* rhs, Index rhsIncr, - ResScalar* res, Index resIncr, RhsScalar alpha); -}; - -template -EIGEN_DONT_INLINE void general_matrix_vector_product::run( - Index rows, Index cols, - const LhsScalar* lhs, Index lhsStride, - const RhsScalar* rhs, Index rhsIncr, - ResScalar* res, Index resIncr, RhsScalar alpha) -{ - EIGEN_UNUSED_VARIABLE(resIncr) - eigen_internal_assert(resIncr==1); - #ifdef _EIGEN_ACCUMULATE_PACKETS - #error _EIGEN_ACCUMULATE_PACKETS has already been defined - #endif - #define _EIGEN_ACCUMULATE_PACKETS(A0,A13,A2) \ - pstore(&res[j], \ - padd(pload(&res[j]), \ - padd( \ - padd(pcj.pmul(EIGEN_CAT(ploa , A0)(&lhs0[j]), ptmp0), \ - pcj.pmul(EIGEN_CAT(ploa , A13)(&lhs1[j]), ptmp1)), \ - padd(pcj.pmul(EIGEN_CAT(ploa , A2)(&lhs2[j]), ptmp2), \ - pcj.pmul(EIGEN_CAT(ploa , A13)(&lhs3[j]), ptmp3)) ))) - - conj_helper cj; - conj_helper pcj; - if(ConjugateRhs) - alpha = numext::conj(alpha); - - enum { AllAligned = 0, EvenAligned, FirstAligned, NoneAligned }; - const Index columnsAtOnce = 4; - const Index peels = 2; - const Index LhsPacketAlignedMask = LhsPacketSize-1; - const Index ResPacketAlignedMask = ResPacketSize-1; -// const Index PeelAlignedMask = ResPacketSize*peels-1; - const Index size = rows; - - // How many coeffs of the result do we have to skip to be aligned. - // Here we assume data are at least aligned on the base scalar type. - Index alignedStart = internal::first_aligned(res,size); - Index alignedSize = ResPacketSize>1 ? alignedStart + ((size-alignedStart) & ~ResPacketAlignedMask) : 0; - const Index peeledSize = alignedSize - RhsPacketSize*peels - RhsPacketSize + 1; - - const Index alignmentStep = LhsPacketSize>1 ? (LhsPacketSize - lhsStride % LhsPacketSize) & LhsPacketAlignedMask : 0; - Index alignmentPattern = alignmentStep==0 ? AllAligned - : alignmentStep==(LhsPacketSize/2) ? EvenAligned - : FirstAligned; - - // we cannot assume the first element is aligned because of sub-matrices - const Index lhsAlignmentOffset = internal::first_aligned(lhs,size); - - // find how many columns do we have to skip to be aligned with the result (if possible) - Index skipColumns = 0; - // if the data cannot be aligned (TODO add some compile time tests when possible, e.g. for floats) - if( (size_t(lhs)%sizeof(LhsScalar)) || (size_t(res)%sizeof(ResScalar)) ) - { - alignedSize = 0; - alignedStart = 0; - } - else if (LhsPacketSize>1) - { - eigen_internal_assert(size_t(lhs+lhsAlignmentOffset)%sizeof(LhsPacket)==0 || size= cols) - || LhsPacketSize > size - || (size_t(lhs+alignedStart+lhsStride*skipColumns)%sizeof(LhsPacket))==0); - } - else if(Vectorizable) - { - alignedStart = 0; - alignedSize = size; - alignmentPattern = AllAligned; - } - - Index offset1 = (FirstAligned && alignmentStep==1?3:1); - Index offset3 = (FirstAligned && alignmentStep==1?1:3); - - Index columnBound = ((cols-skipColumns)/columnsAtOnce)*columnsAtOnce + skipColumns; - for (Index i=skipColumns; i(alpha*rhs[i*rhsIncr]), - ptmp1 = pset1(alpha*rhs[(i+offset1)*rhsIncr]), - ptmp2 = pset1(alpha*rhs[(i+2)*rhsIncr]), - ptmp3 = pset1(alpha*rhs[(i+offset3)*rhsIncr]); - - // this helps a lot generating better binary code - const LhsScalar *lhs0 = lhs + i*lhsStride, *lhs1 = lhs + (i+offset1)*lhsStride, - *lhs2 = lhs + (i+2)*lhsStride, *lhs3 = lhs + (i+offset3)*lhsStride; - - if (Vectorizable) - { - /* explicit vectorization */ - // process initial unaligned coeffs - for (Index j=0; jalignedStart) - { - switch(alignmentPattern) - { - case AllAligned: - for (Index j = alignedStart; j1) - { - LhsPacket A00, A01, A02, A03, A10, A11, A12, A13; - ResPacket T0, T1; - - A01 = pload(&lhs1[alignedStart-1]); - A02 = pload(&lhs2[alignedStart-2]); - A03 = pload(&lhs3[alignedStart-3]); - - for (; j(&lhs1[j-1+LhsPacketSize]); palign<1>(A01,A11); - A12 = pload(&lhs2[j-2+LhsPacketSize]); palign<2>(A02,A12); - A13 = pload(&lhs3[j-3+LhsPacketSize]); palign<3>(A03,A13); - - A00 = pload(&lhs0[j]); - A10 = pload(&lhs0[j+LhsPacketSize]); - T0 = pcj.pmadd(A00, ptmp0, pload(&res[j])); - T1 = pcj.pmadd(A10, ptmp0, pload(&res[j+ResPacketSize])); - - T0 = pcj.pmadd(A01, ptmp1, T0); - A01 = pload(&lhs1[j-1+2*LhsPacketSize]); palign<1>(A11,A01); - T0 = pcj.pmadd(A02, ptmp2, T0); - A02 = pload(&lhs2[j-2+2*LhsPacketSize]); palign<2>(A12,A02); - T0 = pcj.pmadd(A03, ptmp3, T0); - pstore(&res[j],T0); - A03 = pload(&lhs3[j-3+2*LhsPacketSize]); palign<3>(A13,A03); - T1 = pcj.pmadd(A11, ptmp1, T1); - T1 = pcj.pmadd(A12, ptmp2, T1); - T1 = pcj.pmadd(A13, ptmp3, T1); - pstore(&res[j+ResPacketSize],T1); - } - } - for (; j(alpha*rhs[k*rhsIncr]); - const LhsScalar* lhs0 = lhs + k*lhsStride; - - if (Vectorizable) - { - /* explicit vectorization */ - // process first unaligned result's coeffs - for (Index j=0; j(&lhs0[i]), ptmp0, pload(&res[i]))); - else - for (Index i = alignedStart;i(&lhs0[i]), ptmp0, pload(&res[i]))); - } - - // process remaining scalars (or all if no explicit vectorization) - for (Index i=alignedSize; i -struct general_matrix_vector_product -{ -typedef typename scalar_product_traits::ReturnType ResScalar; - -enum { - Vectorizable = packet_traits::Vectorizable && packet_traits::Vectorizable - && int(packet_traits::size)==int(packet_traits::size), - LhsPacketSize = Vectorizable ? packet_traits::size : 1, - RhsPacketSize = Vectorizable ? packet_traits::size : 1, - ResPacketSize = Vectorizable ? packet_traits::size : 1 -}; - -typedef typename packet_traits::type _LhsPacket; -typedef typename packet_traits::type _RhsPacket; -typedef typename packet_traits::type _ResPacket; - -typedef typename conditional::type LhsPacket; -typedef typename conditional::type RhsPacket; -typedef typename conditional::type ResPacket; - -EIGEN_DONT_INLINE static void run( - Index rows, Index cols, - const LhsScalar* lhs, Index lhsStride, - const RhsScalar* rhs, Index rhsIncr, - ResScalar* res, Index resIncr, - ResScalar alpha); -}; - -template -EIGEN_DONT_INLINE void general_matrix_vector_product::run( - Index rows, Index cols, - const LhsScalar* lhs, Index lhsStride, - const RhsScalar* rhs, Index rhsIncr, - ResScalar* res, Index resIncr, - ResScalar alpha) -{ - EIGEN_UNUSED_VARIABLE(rhsIncr); - eigen_internal_assert(rhsIncr==1); - #ifdef _EIGEN_ACCUMULATE_PACKETS - #error _EIGEN_ACCUMULATE_PACKETS has already been defined - #endif - - #define _EIGEN_ACCUMULATE_PACKETS(A0,A13,A2) {\ - RhsPacket b = pload(&rhs[j]); \ - ptmp0 = pcj.pmadd(EIGEN_CAT(ploa,A0) (&lhs0[j]), b, ptmp0); \ - ptmp1 = pcj.pmadd(EIGEN_CAT(ploa,A13)(&lhs1[j]), b, ptmp1); \ - ptmp2 = pcj.pmadd(EIGEN_CAT(ploa,A2) (&lhs2[j]), b, ptmp2); \ - ptmp3 = pcj.pmadd(EIGEN_CAT(ploa,A13)(&lhs3[j]), b, ptmp3); } - - conj_helper cj; - conj_helper pcj; - - enum { AllAligned=0, EvenAligned=1, FirstAligned=2, NoneAligned=3 }; - const Index rowsAtOnce = 4; - const Index peels = 2; - const Index RhsPacketAlignedMask = RhsPacketSize-1; - const Index LhsPacketAlignedMask = LhsPacketSize-1; -// const Index PeelAlignedMask = RhsPacketSize*peels-1; - const Index depth = cols; - - // How many coeffs of the result do we have to skip to be aligned. - // Here we assume data are at least aligned on the base scalar type - // if that's not the case then vectorization is discarded, see below. - Index alignedStart = internal::first_aligned(rhs, depth); - Index alignedSize = RhsPacketSize>1 ? alignedStart + ((depth-alignedStart) & ~RhsPacketAlignedMask) : 0; - const Index peeledSize = alignedSize - RhsPacketSize*peels - RhsPacketSize + 1; - - const Index alignmentStep = LhsPacketSize>1 ? (LhsPacketSize - lhsStride % LhsPacketSize) & LhsPacketAlignedMask : 0; - Index alignmentPattern = alignmentStep==0 ? AllAligned - : alignmentStep==(LhsPacketSize/2) ? EvenAligned - : FirstAligned; - - // we cannot assume the first element is aligned because of sub-matrices - const Index lhsAlignmentOffset = internal::first_aligned(lhs,depth); - - // find how many rows do we have to skip to be aligned with rhs (if possible) - Index skipRows = 0; - // if the data cannot be aligned (TODO add some compile time tests when possible, e.g. for floats) - if( (sizeof(LhsScalar)!=sizeof(RhsScalar)) || (size_t(lhs)%sizeof(LhsScalar)) || (size_t(rhs)%sizeof(RhsScalar)) ) - { - alignedSize = 0; - alignedStart = 0; - } - else if (LhsPacketSize>1) - { - eigen_internal_assert(size_t(lhs+lhsAlignmentOffset)%sizeof(LhsPacket)==0 || depth= rows) - || LhsPacketSize > depth - || (size_t(lhs+alignedStart+lhsStride*skipRows)%sizeof(LhsPacket))==0); - } - else if(Vectorizable) - { - alignedStart = 0; - alignedSize = depth; - alignmentPattern = AllAligned; - } - - Index offset1 = (FirstAligned && alignmentStep==1?3:1); - Index offset3 = (FirstAligned && alignmentStep==1?1:3); - - Index rowBound = ((rows-skipRows)/rowsAtOnce)*rowsAtOnce + skipRows; - for (Index i=skipRows; i(ResScalar(0)), ptmp1 = pset1(ResScalar(0)), - ptmp2 = pset1(ResScalar(0)), ptmp3 = pset1(ResScalar(0)); - - // process initial unaligned coeffs - // FIXME this loop get vectorized by the compiler ! - for (Index j=0; jalignedStart) - { - switch(alignmentPattern) - { - case AllAligned: - for (Index j = alignedStart; j1) - { - /* Here we proccess 4 rows with with two peeled iterations to hide - * the overhead of unaligned loads. Moreover unaligned loads are handled - * using special shift/move operations between the two aligned packets - * overlaping the desired unaligned packet. This is *much* more efficient - * than basic unaligned loads. - */ - LhsPacket A01, A02, A03, A11, A12, A13; - A01 = pload(&lhs1[alignedStart-1]); - A02 = pload(&lhs2[alignedStart-2]); - A03 = pload(&lhs3[alignedStart-3]); - - for (; j(&rhs[j]); - A11 = pload(&lhs1[j-1+LhsPacketSize]); palign<1>(A01,A11); - A12 = pload(&lhs2[j-2+LhsPacketSize]); palign<2>(A02,A12); - A13 = pload(&lhs3[j-3+LhsPacketSize]); palign<3>(A03,A13); - - ptmp0 = pcj.pmadd(pload(&lhs0[j]), b, ptmp0); - ptmp1 = pcj.pmadd(A01, b, ptmp1); - A01 = pload(&lhs1[j-1+2*LhsPacketSize]); palign<1>(A11,A01); - ptmp2 = pcj.pmadd(A02, b, ptmp2); - A02 = pload(&lhs2[j-2+2*LhsPacketSize]); palign<2>(A12,A02); - ptmp3 = pcj.pmadd(A03, b, ptmp3); - A03 = pload(&lhs3[j-3+2*LhsPacketSize]); palign<3>(A13,A03); - - b = pload(&rhs[j+RhsPacketSize]); - ptmp0 = pcj.pmadd(pload(&lhs0[j+LhsPacketSize]), b, ptmp0); - ptmp1 = pcj.pmadd(A11, b, ptmp1); - ptmp2 = pcj.pmadd(A12, b, ptmp2); - ptmp3 = pcj.pmadd(A13, b, ptmp3); - } - } - for (; j(tmp0); - const LhsScalar* lhs0 = lhs + i*lhsStride; - // process first unaligned result's coeffs - // FIXME this loop get vectorized by the compiler ! - for (Index j=0; jalignedStart) - { - // process aligned rhs coeffs - if ((size_t(lhs0+alignedStart)%sizeof(LhsPacket))==0) - for (Index j = alignedStart;j(&lhs0[j]), pload(&rhs[j]), ptmp0); - else - for (Index j = alignedStart;j(&lhs0[j]), pload(&rhs[j]), ptmp0); - tmp0 += predux(ptmp0); - } - - // process remaining scalars - // FIXME this loop get vectorized by the compiler ! - for (Index j=alignedSize; j and std::complex types -**********************************************************************/ - -// gemv specialization - -template -struct general_matrix_vector_product_gemv : - general_matrix_vector_product {}; - -#define EIGEN_MKL_GEMV_SPECIALIZE(Scalar) \ -template \ -struct general_matrix_vector_product { \ -static void run( \ - Index rows, Index cols, \ - const Scalar* lhs, Index lhsStride, \ - const Scalar* rhs, Index rhsIncr, \ - Scalar* res, Index resIncr, Scalar alpha) \ -{ \ - if (ConjugateLhs) { \ - general_matrix_vector_product::run( \ - rows, cols, lhs, lhsStride, rhs, rhsIncr, res, resIncr, alpha); \ - } else { \ - general_matrix_vector_product_gemv::run( \ - rows, cols, lhs, lhsStride, rhs, rhsIncr, res, resIncr, alpha); \ - } \ -} \ -}; \ -template \ -struct general_matrix_vector_product { \ -static void run( \ - Index rows, Index cols, \ - const Scalar* lhs, Index lhsStride, \ - const Scalar* rhs, Index rhsIncr, \ - Scalar* res, Index resIncr, Scalar alpha) \ -{ \ - general_matrix_vector_product_gemv::run( \ - rows, cols, lhs, lhsStride, rhs, rhsIncr, res, resIncr, alpha); \ -} \ -}; \ - -EIGEN_MKL_GEMV_SPECIALIZE(double) -EIGEN_MKL_GEMV_SPECIALIZE(float) -EIGEN_MKL_GEMV_SPECIALIZE(dcomplex) -EIGEN_MKL_GEMV_SPECIALIZE(scomplex) - -#define EIGEN_MKL_GEMV_SPECIALIZATION(EIGTYPE,MKLTYPE,MKLPREFIX) \ -template \ -struct general_matrix_vector_product_gemv \ -{ \ -typedef Matrix GEMVVector;\ -\ -static void run( \ - Index rows, Index cols, \ - const EIGTYPE* lhs, Index lhsStride, \ - const EIGTYPE* rhs, Index rhsIncr, \ - EIGTYPE* res, Index resIncr, EIGTYPE alpha) \ -{ \ - MKL_INT m=rows, n=cols, lda=lhsStride, incx=rhsIncr, incy=resIncr; \ - MKLTYPE alpha_, beta_; \ - const EIGTYPE *x_ptr, myone(1); \ - char trans=(LhsStorageOrder==ColMajor) ? 'N' : (ConjugateLhs) ? 'C' : 'T'; \ - if (LhsStorageOrder==RowMajor) { \ - m=cols; \ - n=rows; \ - }\ - assign_scalar_eig2mkl(alpha_, alpha); \ - assign_scalar_eig2mkl(beta_, myone); \ - GEMVVector x_tmp; \ - if (ConjugateRhs) { \ - Map > map_x(rhs,cols,1,InnerStride<>(incx)); \ - x_tmp=map_x.conjugate(); \ - x_ptr=x_tmp.data(); \ - incx=1; \ - } else x_ptr=rhs; \ - MKLPREFIX##gemv(&trans, &m, &n, &alpha_, (const MKLTYPE*)lhs, &lda, (const MKLTYPE*)x_ptr, &incx, &beta_, (MKLTYPE*)res, &incy); \ -}\ -}; - -EIGEN_MKL_GEMV_SPECIALIZATION(double, double, d) -EIGEN_MKL_GEMV_SPECIALIZATION(float, float, s) -EIGEN_MKL_GEMV_SPECIALIZATION(dcomplex, MKL_Complex16, z) -EIGEN_MKL_GEMV_SPECIALIZATION(scomplex, MKL_Complex8, c) - -} // end namespase internal - -} // end namespace Eigen - -#endif // EIGEN_GENERAL_MATRIX_VECTOR_MKL_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/products/Parallelizer.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/products/Parallelizer.h deleted file mode 100644 index 6937ee33..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Core/products/Parallelizer.h +++ /dev/null @@ -1,162 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2010 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_PARALLELIZER_H -#define EIGEN_PARALLELIZER_H - -namespace Eigen { - -namespace internal { - -/** \internal */ -inline void manage_multi_threading(Action action, int* v) -{ - static EIGEN_UNUSED int m_maxThreads = -1; - - if(action==SetAction) - { - eigen_internal_assert(v!=0); - m_maxThreads = *v; - } - else if(action==GetAction) - { - eigen_internal_assert(v!=0); - #ifdef EIGEN_HAS_OPENMP - if(m_maxThreads>0) - *v = m_maxThreads; - else - *v = omp_get_max_threads(); - #else - *v = 1; - #endif - } - else - { - eigen_internal_assert(false); - } -} - -} - -/** Must be call first when calling Eigen from multiple threads */ -inline void initParallel() -{ - int nbt; - internal::manage_multi_threading(GetAction, &nbt); - std::ptrdiff_t l1, l2; - internal::manage_caching_sizes(GetAction, &l1, &l2); -} - -/** \returns the max number of threads reserved for Eigen - * \sa setNbThreads */ -inline int nbThreads() -{ - int ret; - internal::manage_multi_threading(GetAction, &ret); - return ret; -} - -/** Sets the max number of threads reserved for Eigen - * \sa nbThreads */ -inline void setNbThreads(int v) -{ - internal::manage_multi_threading(SetAction, &v); -} - -namespace internal { - -template struct GemmParallelInfo -{ - GemmParallelInfo() : sync(-1), users(0), rhs_start(0), rhs_length(0) {} - - int volatile sync; - int volatile users; - - Index rhs_start; - Index rhs_length; -}; - -template -void parallelize_gemm(const Functor& func, Index rows, Index cols, bool transpose) -{ - // TODO when EIGEN_USE_BLAS is defined, - // we should still enable OMP for other scalar types -#if !(defined (EIGEN_HAS_OPENMP)) || defined (EIGEN_USE_BLAS) - // FIXME the transpose variable is only needed to properly split - // the matrix product when multithreading is enabled. This is a temporary - // fix to support row-major destination matrices. This whole - // parallelizer mechanism has to be redisigned anyway. - EIGEN_UNUSED_VARIABLE(transpose); - func(0,rows, 0,cols); -#else - - // Dynamically check whether we should enable or disable OpenMP. - // The conditions are: - // - the max number of threads we can create is greater than 1 - // - we are not already in a parallel code - // - the sizes are large enough - - // 1- are we already in a parallel session? - // FIXME omp_get_num_threads()>1 only works for openmp, what if the user does not use openmp? - if((!Condition) || (omp_get_num_threads()>1)) - return func(0,rows, 0,cols); - - Index size = transpose ? cols : rows; - - // 2- compute the maximal number of threads from the size of the product: - // FIXME this has to be fine tuned - Index max_threads = std::max(1,size / 32); - - // 3 - compute the number of threads we are going to use - Index threads = std::min(nbThreads(), max_threads); - - if(threads==1) - return func(0,rows, 0,cols); - - Eigen::initParallel(); - func.initParallelSession(); - - if(transpose) - std::swap(rows,cols); - - GemmParallelInfo* info = new GemmParallelInfo[threads]; - - #pragma omp parallel num_threads(threads) - { - Index i = omp_get_thread_num(); - // Note that the actual number of threads might be lower than the number of request ones. - Index actual_threads = omp_get_num_threads(); - - Index blockCols = (cols / actual_threads) & ~Index(0x3); - Index blockRows = (rows / actual_threads) & ~Index(0x7); - - Index r0 = i*blockRows; - Index actualBlockRows = (i+1==actual_threads) ? rows-r0 : blockRows; - - Index c0 = i*blockCols; - Index actualBlockCols = (i+1==actual_threads) ? cols-c0 : blockCols; - - info[i].rhs_start = c0; - info[i].rhs_length = actualBlockCols; - - if(transpose) - func(0, cols, r0, actualBlockRows, info); - else - func(r0, actualBlockRows, 0,cols, info); - } - - delete[] info; -#endif -} - -} // end namespace internal - -} // end namespace Eigen - -#endif // EIGEN_PARALLELIZER_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/products/SelfadjointMatrixMatrix.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/products/SelfadjointMatrixMatrix.h deleted file mode 100644 index 99cf9e0a..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Core/products/SelfadjointMatrixMatrix.h +++ /dev/null @@ -1,436 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2009 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_SELFADJOINT_MATRIX_MATRIX_H -#define EIGEN_SELFADJOINT_MATRIX_MATRIX_H - -namespace Eigen { - -namespace internal { - -// pack a selfadjoint block diagonal for use with the gebp_kernel -template -struct symm_pack_lhs -{ - template inline - void pack(Scalar* blockA, const const_blas_data_mapper& lhs, Index cols, Index i, Index& count) - { - // normal copy - for(Index k=0; k lhs(_lhs,lhsStride); - Index count = 0; - Index peeled_mc = (rows/Pack1)*Pack1; - for(Index i=0; i(blockA, lhs, cols, i, count); - } - - if(rows-peeled_mc>=Pack2) - { - pack(blockA, lhs, cols, peeled_mc, count); - peeled_mc += Pack2; - } - - // do the same with mr==1 - for(Index i=peeled_mc; i -struct symm_pack_rhs -{ - enum { PacketSize = packet_traits::size }; - void operator()(Scalar* blockB, const Scalar* _rhs, Index rhsStride, Index rows, Index cols, Index k2) - { - Index end_k = k2 + rows; - Index count = 0; - const_blas_data_mapper rhs(_rhs,rhsStride); - Index packet_cols = (cols/nr)*nr; - - // first part: normal case - for(Index j2=0; j2 the same with nr==1) - for(Index j2=packet_cols; j2 -struct product_selfadjoint_matrix; - -template -struct product_selfadjoint_matrix -{ - - static EIGEN_STRONG_INLINE void run( - Index rows, Index cols, - const Scalar* lhs, Index lhsStride, - const Scalar* rhs, Index rhsStride, - Scalar* res, Index resStride, - const Scalar& alpha) - { - product_selfadjoint_matrix::IsComplex && EIGEN_LOGICAL_XOR(RhsSelfAdjoint,ConjugateRhs), - EIGEN_LOGICAL_XOR(LhsSelfAdjoint,LhsStorageOrder==RowMajor) ? ColMajor : RowMajor, - LhsSelfAdjoint, NumTraits::IsComplex && EIGEN_LOGICAL_XOR(LhsSelfAdjoint,ConjugateLhs), - ColMajor> - ::run(cols, rows, rhs, rhsStride, lhs, lhsStride, res, resStride, alpha); - } -}; - -template -struct product_selfadjoint_matrix -{ - - static EIGEN_DONT_INLINE void run( - Index rows, Index cols, - const Scalar* _lhs, Index lhsStride, - const Scalar* _rhs, Index rhsStride, - Scalar* res, Index resStride, - const Scalar& alpha); -}; - -template -EIGEN_DONT_INLINE void product_selfadjoint_matrix::run( - Index rows, Index cols, - const Scalar* _lhs, Index lhsStride, - const Scalar* _rhs, Index rhsStride, - Scalar* res, Index resStride, - const Scalar& alpha) - { - Index size = rows; - - const_blas_data_mapper lhs(_lhs,lhsStride); - const_blas_data_mapper rhs(_rhs,rhsStride); - - typedef gebp_traits Traits; - - Index kc = size; // cache block size along the K direction - Index mc = rows; // cache block size along the M direction - Index nc = cols; // cache block size along the N direction - computeProductBlockingSizes(kc, mc, nc); - // kc must smaller than mc - kc = (std::min)(kc,mc); - - std::size_t sizeW = kc*Traits::WorkSpaceFactor; - std::size_t sizeB = sizeW + kc*cols; - ei_declare_aligned_stack_constructed_variable(Scalar, blockA, kc*mc, 0); - ei_declare_aligned_stack_constructed_variable(Scalar, allocatedBlockB, sizeB, 0); - Scalar* blockB = allocatedBlockB + sizeW; - - gebp_kernel gebp_kernel; - symm_pack_lhs pack_lhs; - gemm_pack_rhs pack_rhs; - gemm_pack_lhs pack_lhs_transposed; - - for(Index k2=0; k2 transposed packed copy - // 2 - the diagonal block => special packed copy - // 3 - the panel below the diagonal block => generic packed copy - for(Index i2=0; i2() - (blockA, &lhs(i2, k2), lhsStride, actual_kc, actual_mc); - - gebp_kernel(res+i2, resStride, blockA, blockB, actual_mc, actual_kc, cols, alpha); - } - } - } - -// matrix * selfadjoint product -template -struct product_selfadjoint_matrix -{ - - static EIGEN_DONT_INLINE void run( - Index rows, Index cols, - const Scalar* _lhs, Index lhsStride, - const Scalar* _rhs, Index rhsStride, - Scalar* res, Index resStride, - const Scalar& alpha); -}; - -template -EIGEN_DONT_INLINE void product_selfadjoint_matrix::run( - Index rows, Index cols, - const Scalar* _lhs, Index lhsStride, - const Scalar* _rhs, Index rhsStride, - Scalar* res, Index resStride, - const Scalar& alpha) - { - Index size = cols; - - const_blas_data_mapper lhs(_lhs,lhsStride); - - typedef gebp_traits Traits; - - Index kc = size; // cache block size along the K direction - Index mc = rows; // cache block size along the M direction - Index nc = cols; // cache block size along the N direction - computeProductBlockingSizes(kc, mc, nc); - std::size_t sizeW = kc*Traits::WorkSpaceFactor; - std::size_t sizeB = sizeW + kc*cols; - ei_declare_aligned_stack_constructed_variable(Scalar, blockA, kc*mc, 0); - ei_declare_aligned_stack_constructed_variable(Scalar, allocatedBlockB, sizeB, 0); - Scalar* blockB = allocatedBlockB + sizeW; - - gebp_kernel gebp_kernel; - gemm_pack_lhs pack_lhs; - symm_pack_rhs pack_rhs; - - for(Index k2=0; k2 GEPP - for(Index i2=0; i2 -struct traits > - : traits, Lhs, Rhs> > -{}; -} - -template -struct SelfadjointProductMatrix - : public ProductBase, Lhs, Rhs > -{ - EIGEN_PRODUCT_PUBLIC_INTERFACE(SelfadjointProductMatrix) - - SelfadjointProductMatrix(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs) {} - - enum { - LhsIsUpper = (LhsMode&(Upper|Lower))==Upper, - LhsIsSelfAdjoint = (LhsMode&SelfAdjoint)==SelfAdjoint, - RhsIsUpper = (RhsMode&(Upper|Lower))==Upper, - RhsIsSelfAdjoint = (RhsMode&SelfAdjoint)==SelfAdjoint - }; - - template void scaleAndAddTo(Dest& dst, const Scalar& alpha) const - { - eigen_assert(dst.rows()==m_lhs.rows() && dst.cols()==m_rhs.cols()); - - typename internal::add_const_on_value_type::type lhs = LhsBlasTraits::extract(m_lhs); - typename internal::add_const_on_value_type::type rhs = RhsBlasTraits::extract(m_rhs); - - Scalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(m_lhs) - * RhsBlasTraits::extractScalarFactor(m_rhs); - - internal::product_selfadjoint_matrix::Flags &RowMajorBit) ? RowMajor : ColMajor, LhsIsSelfAdjoint, - NumTraits::IsComplex && EIGEN_LOGICAL_XOR(LhsIsUpper,bool(LhsBlasTraits::NeedToConjugate)), - EIGEN_LOGICAL_XOR(RhsIsUpper, - internal::traits::Flags &RowMajorBit) ? RowMajor : ColMajor, RhsIsSelfAdjoint, - NumTraits::IsComplex && EIGEN_LOGICAL_XOR(RhsIsUpper,bool(RhsBlasTraits::NeedToConjugate)), - internal::traits::Flags&RowMajorBit ? RowMajor : ColMajor> - ::run( - lhs.rows(), rhs.cols(), // sizes - &lhs.coeffRef(0,0), lhs.outerStride(), // lhs info - &rhs.coeffRef(0,0), rhs.outerStride(), // rhs info - &dst.coeffRef(0,0), dst.outerStride(), // result info - actualAlpha // alpha - ); - } -}; - -} // end namespace Eigen - -#endif // EIGEN_SELFADJOINT_MATRIX_MATRIX_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/products/SelfadjointMatrixMatrix_MKL.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/products/SelfadjointMatrixMatrix_MKL.h deleted file mode 100644 index dfa687fe..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Core/products/SelfadjointMatrixMatrix_MKL.h +++ /dev/null @@ -1,295 +0,0 @@ -/* - Copyright (c) 2011, Intel Corporation. All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of Intel Corporation nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// - ******************************************************************************** - * Content : Eigen bindings to Intel(R) MKL - * Self adjoint matrix * matrix product functionality based on ?SYMM/?HEMM. - ******************************************************************************** -*/ - -#ifndef EIGEN_SELFADJOINT_MATRIX_MATRIX_MKL_H -#define EIGEN_SELFADJOINT_MATRIX_MATRIX_MKL_H - -namespace Eigen { - -namespace internal { - - -/* Optimized selfadjoint matrix * matrix (?SYMM/?HEMM) product */ - -#define EIGEN_MKL_SYMM_L(EIGTYPE, MKLTYPE, EIGPREFIX, MKLPREFIX) \ -template \ -struct product_selfadjoint_matrix \ -{\ -\ - static void run( \ - Index rows, Index cols, \ - const EIGTYPE* _lhs, Index lhsStride, \ - const EIGTYPE* _rhs, Index rhsStride, \ - EIGTYPE* res, Index resStride, \ - EIGTYPE alpha) \ - { \ - char side='L', uplo='L'; \ - MKL_INT m, n, lda, ldb, ldc; \ - const EIGTYPE *a, *b; \ - MKLTYPE alpha_, beta_; \ - MatrixX##EIGPREFIX b_tmp; \ - EIGTYPE myone(1);\ -\ -/* Set transpose options */ \ -/* Set m, n, k */ \ - m = (MKL_INT)rows; \ - n = (MKL_INT)cols; \ -\ -/* Set alpha_ & beta_ */ \ - assign_scalar_eig2mkl(alpha_, alpha); \ - assign_scalar_eig2mkl(beta_, myone); \ -\ -/* Set lda, ldb, ldc */ \ - lda = (MKL_INT)lhsStride; \ - ldb = (MKL_INT)rhsStride; \ - ldc = (MKL_INT)resStride; \ -\ -/* Set a, b, c */ \ - if (LhsStorageOrder==RowMajor) uplo='U'; \ - a = _lhs; \ -\ - if (RhsStorageOrder==RowMajor) { \ - Map > rhs(_rhs,n,m,OuterStride<>(rhsStride)); \ - b_tmp = rhs.adjoint(); \ - b = b_tmp.data(); \ - ldb = b_tmp.outerStride(); \ - } else b = _rhs; \ -\ - MKLPREFIX##symm(&side, &uplo, &m, &n, &alpha_, (const MKLTYPE*)a, &lda, (const MKLTYPE*)b, &ldb, &beta_, (MKLTYPE*)res, &ldc); \ -\ - } \ -}; - - -#define EIGEN_MKL_HEMM_L(EIGTYPE, MKLTYPE, EIGPREFIX, MKLPREFIX) \ -template \ -struct product_selfadjoint_matrix \ -{\ - static void run( \ - Index rows, Index cols, \ - const EIGTYPE* _lhs, Index lhsStride, \ - const EIGTYPE* _rhs, Index rhsStride, \ - EIGTYPE* res, Index resStride, \ - EIGTYPE alpha) \ - { \ - char side='L', uplo='L'; \ - MKL_INT m, n, lda, ldb, ldc; \ - const EIGTYPE *a, *b; \ - MKLTYPE alpha_, beta_; \ - MatrixX##EIGPREFIX b_tmp; \ - Matrix a_tmp; \ - EIGTYPE myone(1); \ -\ -/* Set transpose options */ \ -/* Set m, n, k */ \ - m = (MKL_INT)rows; \ - n = (MKL_INT)cols; \ -\ -/* Set alpha_ & beta_ */ \ - assign_scalar_eig2mkl(alpha_, alpha); \ - assign_scalar_eig2mkl(beta_, myone); \ -\ -/* Set lda, ldb, ldc */ \ - lda = (MKL_INT)lhsStride; \ - ldb = (MKL_INT)rhsStride; \ - ldc = (MKL_INT)resStride; \ -\ -/* Set a, b, c */ \ - if (((LhsStorageOrder==ColMajor) && ConjugateLhs) || ((LhsStorageOrder==RowMajor) && (!ConjugateLhs))) { \ - Map, 0, OuterStride<> > lhs(_lhs,m,m,OuterStride<>(lhsStride)); \ - a_tmp = lhs.conjugate(); \ - a = a_tmp.data(); \ - lda = a_tmp.outerStride(); \ - } else a = _lhs; \ - if (LhsStorageOrder==RowMajor) uplo='U'; \ -\ - if (RhsStorageOrder==ColMajor && (!ConjugateRhs)) { \ - b = _rhs; } \ - else { \ - if (RhsStorageOrder==ColMajor && ConjugateRhs) { \ - Map > rhs(_rhs,m,n,OuterStride<>(rhsStride)); \ - b_tmp = rhs.conjugate(); \ - } else \ - if (ConjugateRhs) { \ - Map > rhs(_rhs,n,m,OuterStride<>(rhsStride)); \ - b_tmp = rhs.adjoint(); \ - } else { \ - Map > rhs(_rhs,n,m,OuterStride<>(rhsStride)); \ - b_tmp = rhs.transpose(); \ - } \ - b = b_tmp.data(); \ - ldb = b_tmp.outerStride(); \ - } \ -\ - MKLPREFIX##hemm(&side, &uplo, &m, &n, &alpha_, (const MKLTYPE*)a, &lda, (const MKLTYPE*)b, &ldb, &beta_, (MKLTYPE*)res, &ldc); \ -\ - } \ -}; - -EIGEN_MKL_SYMM_L(double, double, d, d) -EIGEN_MKL_SYMM_L(float, float, f, s) -EIGEN_MKL_HEMM_L(dcomplex, MKL_Complex16, cd, z) -EIGEN_MKL_HEMM_L(scomplex, MKL_Complex8, cf, c) - - -/* Optimized matrix * selfadjoint matrix (?SYMM/?HEMM) product */ - -#define EIGEN_MKL_SYMM_R(EIGTYPE, MKLTYPE, EIGPREFIX, MKLPREFIX) \ -template \ -struct product_selfadjoint_matrix \ -{\ -\ - static void run( \ - Index rows, Index cols, \ - const EIGTYPE* _lhs, Index lhsStride, \ - const EIGTYPE* _rhs, Index rhsStride, \ - EIGTYPE* res, Index resStride, \ - EIGTYPE alpha) \ - { \ - char side='R', uplo='L'; \ - MKL_INT m, n, lda, ldb, ldc; \ - const EIGTYPE *a, *b; \ - MKLTYPE alpha_, beta_; \ - MatrixX##EIGPREFIX b_tmp; \ - EIGTYPE myone(1);\ -\ -/* Set m, n, k */ \ - m = (MKL_INT)rows; \ - n = (MKL_INT)cols; \ -\ -/* Set alpha_ & beta_ */ \ - assign_scalar_eig2mkl(alpha_, alpha); \ - assign_scalar_eig2mkl(beta_, myone); \ -\ -/* Set lda, ldb, ldc */ \ - lda = (MKL_INT)rhsStride; \ - ldb = (MKL_INT)lhsStride; \ - ldc = (MKL_INT)resStride; \ -\ -/* Set a, b, c */ \ - if (RhsStorageOrder==RowMajor) uplo='U'; \ - a = _rhs; \ -\ - if (LhsStorageOrder==RowMajor) { \ - Map > lhs(_lhs,n,m,OuterStride<>(rhsStride)); \ - b_tmp = lhs.adjoint(); \ - b = b_tmp.data(); \ - ldb = b_tmp.outerStride(); \ - } else b = _lhs; \ -\ - MKLPREFIX##symm(&side, &uplo, &m, &n, &alpha_, (const MKLTYPE*)a, &lda, (const MKLTYPE*)b, &ldb, &beta_, (MKLTYPE*)res, &ldc); \ -\ - } \ -}; - - -#define EIGEN_MKL_HEMM_R(EIGTYPE, MKLTYPE, EIGPREFIX, MKLPREFIX) \ -template \ -struct product_selfadjoint_matrix \ -{\ - static void run( \ - Index rows, Index cols, \ - const EIGTYPE* _lhs, Index lhsStride, \ - const EIGTYPE* _rhs, Index rhsStride, \ - EIGTYPE* res, Index resStride, \ - EIGTYPE alpha) \ - { \ - char side='R', uplo='L'; \ - MKL_INT m, n, lda, ldb, ldc; \ - const EIGTYPE *a, *b; \ - MKLTYPE alpha_, beta_; \ - MatrixX##EIGPREFIX b_tmp; \ - Matrix a_tmp; \ - EIGTYPE myone(1); \ -\ -/* Set m, n, k */ \ - m = (MKL_INT)rows; \ - n = (MKL_INT)cols; \ -\ -/* Set alpha_ & beta_ */ \ - assign_scalar_eig2mkl(alpha_, alpha); \ - assign_scalar_eig2mkl(beta_, myone); \ -\ -/* Set lda, ldb, ldc */ \ - lda = (MKL_INT)rhsStride; \ - ldb = (MKL_INT)lhsStride; \ - ldc = (MKL_INT)resStride; \ -\ -/* Set a, b, c */ \ - if (((RhsStorageOrder==ColMajor) && ConjugateRhs) || ((RhsStorageOrder==RowMajor) && (!ConjugateRhs))) { \ - Map, 0, OuterStride<> > rhs(_rhs,n,n,OuterStride<>(rhsStride)); \ - a_tmp = rhs.conjugate(); \ - a = a_tmp.data(); \ - lda = a_tmp.outerStride(); \ - } else a = _rhs; \ - if (RhsStorageOrder==RowMajor) uplo='U'; \ -\ - if (LhsStorageOrder==ColMajor && (!ConjugateLhs)) { \ - b = _lhs; } \ - else { \ - if (LhsStorageOrder==ColMajor && ConjugateLhs) { \ - Map > lhs(_lhs,m,n,OuterStride<>(lhsStride)); \ - b_tmp = lhs.conjugate(); \ - } else \ - if (ConjugateLhs) { \ - Map > lhs(_lhs,n,m,OuterStride<>(lhsStride)); \ - b_tmp = lhs.adjoint(); \ - } else { \ - Map > lhs(_lhs,n,m,OuterStride<>(lhsStride)); \ - b_tmp = lhs.transpose(); \ - } \ - b = b_tmp.data(); \ - ldb = b_tmp.outerStride(); \ - } \ -\ - MKLPREFIX##hemm(&side, &uplo, &m, &n, &alpha_, (const MKLTYPE*)a, &lda, (const MKLTYPE*)b, &ldb, &beta_, (MKLTYPE*)res, &ldc); \ - } \ -}; - -EIGEN_MKL_SYMM_R(double, double, d, d) -EIGEN_MKL_SYMM_R(float, float, f, s) -EIGEN_MKL_HEMM_R(dcomplex, MKL_Complex16, cd, z) -EIGEN_MKL_HEMM_R(scomplex, MKL_Complex8, cf, c) - -} // end namespace internal - -} // end namespace Eigen - -#endif // EIGEN_SELFADJOINT_MATRIX_MATRIX_MKL_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/products/SelfadjointMatrixVector.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/products/SelfadjointMatrixVector.h deleted file mode 100644 index f698f67f..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Core/products/SelfadjointMatrixVector.h +++ /dev/null @@ -1,281 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2009 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_SELFADJOINT_MATRIX_VECTOR_H -#define EIGEN_SELFADJOINT_MATRIX_VECTOR_H - -namespace Eigen { - -namespace internal { - -/* Optimized selfadjoint matrix * vector product: - * This algorithm processes 2 columns at onces that allows to both reduce - * the number of load/stores of the result by a factor 2 and to reduce - * the instruction dependency. - */ - -template -struct selfadjoint_matrix_vector_product; - -template -struct selfadjoint_matrix_vector_product - -{ -static EIGEN_DONT_INLINE void run( - Index size, - const Scalar* lhs, Index lhsStride, - const Scalar* _rhs, Index rhsIncr, - Scalar* res, - Scalar alpha); -}; - -template -EIGEN_DONT_INLINE void selfadjoint_matrix_vector_product::run( - Index size, - const Scalar* lhs, Index lhsStride, - const Scalar* _rhs, Index rhsIncr, - Scalar* res, - Scalar alpha) -{ - typedef typename packet_traits::type Packet; - const Index PacketSize = sizeof(Packet)/sizeof(Scalar); - - enum { - IsRowMajor = StorageOrder==RowMajor ? 1 : 0, - IsLower = UpLo == Lower ? 1 : 0, - FirstTriangular = IsRowMajor == IsLower - }; - - conj_helper::IsComplex && EIGEN_LOGICAL_XOR(ConjugateLhs, IsRowMajor), ConjugateRhs> cj0; - conj_helper::IsComplex && EIGEN_LOGICAL_XOR(ConjugateLhs, !IsRowMajor), ConjugateRhs> cj1; - conj_helper::IsComplex, ConjugateRhs> cjd; - - conj_helper::IsComplex && EIGEN_LOGICAL_XOR(ConjugateLhs, IsRowMajor), ConjugateRhs> pcj0; - conj_helper::IsComplex && EIGEN_LOGICAL_XOR(ConjugateLhs, !IsRowMajor), ConjugateRhs> pcj1; - - Scalar cjAlpha = ConjugateRhs ? numext::conj(alpha) : alpha; - - // FIXME this copy is now handled outside product_selfadjoint_vector, so it could probably be removed. - // if the rhs is not sequentially stored in memory we copy it to a temporary buffer, - // this is because we need to extract packets - ei_declare_aligned_stack_constructed_variable(Scalar,rhs,size,rhsIncr==1 ? const_cast(_rhs) : 0); - if (rhsIncr!=1) - { - const Scalar* it = _rhs; - for (Index i=0; i(t0); - Scalar t1 = cjAlpha * rhs[j+1]; - Packet ptmp1 = pset1(t1); - - Scalar t2(0); - Packet ptmp2 = pset1(t2); - Scalar t3(0); - Packet ptmp3 = pset1(t3); - - size_t starti = FirstTriangular ? 0 : j+2; - size_t endi = FirstTriangular ? j : size; - size_t alignedStart = (starti) + internal::first_aligned(&res[starti], endi-starti); - size_t alignedEnd = alignedStart + ((endi-alignedStart)/(PacketSize))*(PacketSize); - - // TODO make sure this product is a real * complex and that the rhs is properly conjugated if needed - res[j] += cjd.pmul(numext::real(A0[j]), t0); - res[j+1] += cjd.pmul(numext::real(A1[j+1]), t1); - if(FirstTriangular) - { - res[j] += cj0.pmul(A1[j], t1); - t3 += cj1.pmul(A1[j], rhs[j]); - } - else - { - res[j+1] += cj0.pmul(A0[j+1],t0); - t2 += cj1.pmul(A0[j+1], rhs[j+1]); - } - - for (size_t i=starti; i huge speed up) - // gcc 4.2 does this optimization automatically. - const Scalar* EIGEN_RESTRICT a0It = A0 + alignedStart; - const Scalar* EIGEN_RESTRICT a1It = A1 + alignedStart; - const Scalar* EIGEN_RESTRICT rhsIt = rhs + alignedStart; - Scalar* EIGEN_RESTRICT resIt = res + alignedStart; - for (size_t i=alignedStart; i(a0It); a0It += PacketSize; - Packet A1i = ploadu(a1It); a1It += PacketSize; - Packet Bi = ploadu(rhsIt); rhsIt += PacketSize; // FIXME should be aligned in most cases - Packet Xi = pload (resIt); - - Xi = pcj0.pmadd(A0i,ptmp0, pcj0.pmadd(A1i,ptmp1,Xi)); - ptmp2 = pcj1.pmadd(A0i, Bi, ptmp2); - ptmp3 = pcj1.pmadd(A1i, Bi, ptmp3); - pstore(resIt,Xi); resIt += PacketSize; - } - for (size_t i=alignedEnd; i -struct traits > - : traits, Lhs, Rhs> > -{}; -} - -template -struct SelfadjointProductMatrix - : public ProductBase, Lhs, Rhs > -{ - EIGEN_PRODUCT_PUBLIC_INTERFACE(SelfadjointProductMatrix) - - enum { - LhsUpLo = LhsMode&(Upper|Lower) - }; - - SelfadjointProductMatrix(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs) {} - - template void scaleAndAddTo(Dest& dest, const Scalar& alpha) const - { - typedef typename Dest::Scalar ResScalar; - typedef typename Base::RhsScalar RhsScalar; - typedef Map, Aligned> MappedDest; - - eigen_assert(dest.rows()==m_lhs.rows() && dest.cols()==m_rhs.cols()); - - typename internal::add_const_on_value_type::type lhs = LhsBlasTraits::extract(m_lhs); - typename internal::add_const_on_value_type::type rhs = RhsBlasTraits::extract(m_rhs); - - Scalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(m_lhs) - * RhsBlasTraits::extractScalarFactor(m_rhs); - - enum { - EvalToDest = (Dest::InnerStrideAtCompileTime==1), - UseRhs = (_ActualRhsType::InnerStrideAtCompileTime==1) - }; - - internal::gemv_static_vector_if static_dest; - internal::gemv_static_vector_if static_rhs; - - ei_declare_aligned_stack_constructed_variable(ResScalar,actualDestPtr,dest.size(), - EvalToDest ? dest.data() : static_dest.data()); - - ei_declare_aligned_stack_constructed_variable(RhsScalar,actualRhsPtr,rhs.size(), - UseRhs ? const_cast(rhs.data()) : static_rhs.data()); - - if(!EvalToDest) - { - #ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN - int size = dest.size(); - EIGEN_DENSE_STORAGE_CTOR_PLUGIN - #endif - MappedDest(actualDestPtr, dest.size()) = dest; - } - - if(!UseRhs) - { - #ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN - int size = rhs.size(); - EIGEN_DENSE_STORAGE_CTOR_PLUGIN - #endif - Map(actualRhsPtr, rhs.size()) = rhs; - } - - - internal::selfadjoint_matrix_vector_product::Flags&RowMajorBit) ? RowMajor : ColMajor, int(LhsUpLo), bool(LhsBlasTraits::NeedToConjugate), bool(RhsBlasTraits::NeedToConjugate)>::run - ( - lhs.rows(), // size - &lhs.coeffRef(0,0), lhs.outerStride(), // lhs info - actualRhsPtr, 1, // rhs info - actualDestPtr, // result info - actualAlpha // scale factor - ); - - if(!EvalToDest) - dest = MappedDest(actualDestPtr, dest.size()); - } -}; - -namespace internal { -template -struct traits > - : traits, Lhs, Rhs> > -{}; -} - -template -struct SelfadjointProductMatrix - : public ProductBase, Lhs, Rhs > -{ - EIGEN_PRODUCT_PUBLIC_INTERFACE(SelfadjointProductMatrix) - - enum { - RhsUpLo = RhsMode&(Upper|Lower) - }; - - SelfadjointProductMatrix(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs) {} - - template void scaleAndAddTo(Dest& dest, const Scalar& alpha) const - { - // let's simply transpose the product - Transpose destT(dest); - SelfadjointProductMatrix, int(RhsUpLo)==Upper ? Lower : Upper, false, - Transpose, 0, true>(m_rhs.transpose(), m_lhs.transpose()).scaleAndAddTo(destT, alpha); - } -}; - -} // end namespace Eigen - -#endif // EIGEN_SELFADJOINT_MATRIX_VECTOR_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/products/SelfadjointMatrixVector_MKL.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/products/SelfadjointMatrixVector_MKL.h deleted file mode 100644 index 86684b66..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Core/products/SelfadjointMatrixVector_MKL.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - Copyright (c) 2011, Intel Corporation. All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of Intel Corporation nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - ******************************************************************************** - * Content : Eigen bindings to Intel(R) MKL - * Selfadjoint matrix-vector product functionality based on ?SYMV/HEMV. - ******************************************************************************** -*/ - -#ifndef EIGEN_SELFADJOINT_MATRIX_VECTOR_MKL_H -#define EIGEN_SELFADJOINT_MATRIX_VECTOR_MKL_H - -namespace Eigen { - -namespace internal { - -/********************************************************************** -* This file implements selfadjoint matrix-vector multiplication using BLAS -**********************************************************************/ - -// symv/hemv specialization - -template -struct selfadjoint_matrix_vector_product_symv : - selfadjoint_matrix_vector_product {}; - -#define EIGEN_MKL_SYMV_SPECIALIZE(Scalar) \ -template \ -struct selfadjoint_matrix_vector_product { \ -static void run( \ - Index size, const Scalar* lhs, Index lhsStride, \ - const Scalar* _rhs, Index rhsIncr, Scalar* res, Scalar alpha) { \ - enum {\ - IsColMajor = StorageOrder==ColMajor \ - }; \ - if (IsColMajor == ConjugateLhs) {\ - selfadjoint_matrix_vector_product::run( \ - size, lhs, lhsStride, _rhs, rhsIncr, res, alpha); \ - } else {\ - selfadjoint_matrix_vector_product_symv::run( \ - size, lhs, lhsStride, _rhs, rhsIncr, res, alpha); \ - }\ - } \ -}; \ - -EIGEN_MKL_SYMV_SPECIALIZE(double) -EIGEN_MKL_SYMV_SPECIALIZE(float) -EIGEN_MKL_SYMV_SPECIALIZE(dcomplex) -EIGEN_MKL_SYMV_SPECIALIZE(scomplex) - -#define EIGEN_MKL_SYMV_SPECIALIZATION(EIGTYPE,MKLTYPE,MKLFUNC) \ -template \ -struct selfadjoint_matrix_vector_product_symv \ -{ \ -typedef Matrix SYMVVector;\ -\ -static void run( \ -Index size, const EIGTYPE* lhs, Index lhsStride, \ -const EIGTYPE* _rhs, Index rhsIncr, EIGTYPE* res, EIGTYPE alpha) \ -{ \ - enum {\ - IsRowMajor = StorageOrder==RowMajor ? 1 : 0, \ - IsLower = UpLo == Lower ? 1 : 0 \ - }; \ - MKL_INT n=size, lda=lhsStride, incx=rhsIncr, incy=1; \ - MKLTYPE alpha_, beta_; \ - const EIGTYPE *x_ptr, myone(1); \ - char uplo=(IsRowMajor) ? (IsLower ? 'U' : 'L') : (IsLower ? 'L' : 'U'); \ - assign_scalar_eig2mkl(alpha_, alpha); \ - assign_scalar_eig2mkl(beta_, myone); \ - SYMVVector x_tmp; \ - if (ConjugateRhs) { \ - Map > map_x(_rhs,size,1,InnerStride<>(incx)); \ - x_tmp=map_x.conjugate(); \ - x_ptr=x_tmp.data(); \ - incx=1; \ - } else x_ptr=_rhs; \ - MKLFUNC(&uplo, &n, &alpha_, (const MKLTYPE*)lhs, &lda, (const MKLTYPE*)x_ptr, &incx, &beta_, (MKLTYPE*)res, &incy); \ -}\ -}; - -EIGEN_MKL_SYMV_SPECIALIZATION(double, double, dsymv) -EIGEN_MKL_SYMV_SPECIALIZATION(float, float, ssymv) -EIGEN_MKL_SYMV_SPECIALIZATION(dcomplex, MKL_Complex16, zhemv) -EIGEN_MKL_SYMV_SPECIALIZATION(scomplex, MKL_Complex8, chemv) - -} // end namespace internal - -} // end namespace Eigen - -#endif // EIGEN_SELFADJOINT_MATRIX_VECTOR_MKL_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/products/SelfadjointProduct.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/products/SelfadjointProduct.h deleted file mode 100644 index 6ca4ae6c..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Core/products/SelfadjointProduct.h +++ /dev/null @@ -1,123 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2009 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_SELFADJOINT_PRODUCT_H -#define EIGEN_SELFADJOINT_PRODUCT_H - -/********************************************************************** -* This file implements a self adjoint product: C += A A^T updating only -* half of the selfadjoint matrix C. -* It corresponds to the level 3 SYRK and level 2 SYR Blas routines. -**********************************************************************/ - -namespace Eigen { - - -template -struct selfadjoint_rank1_update -{ - static void run(Index size, Scalar* mat, Index stride, const Scalar* vecX, const Scalar* vecY, const Scalar& alpha) - { - internal::conj_if cj; - typedef Map > OtherMap; - typedef typename internal::conditional::type ConjLhsType; - for (Index i=0; i >(mat+stride*i+(UpLo==Lower ? i : 0), (UpLo==Lower ? size-i : (i+1))) - += (alpha * cj(vecY[i])) * ConjLhsType(OtherMap(vecX+(UpLo==Lower ? i : 0),UpLo==Lower ? size-i : (i+1))); - } - } -}; - -template -struct selfadjoint_rank1_update -{ - static void run(Index size, Scalar* mat, Index stride, const Scalar* vecX, const Scalar* vecY, const Scalar& alpha) - { - selfadjoint_rank1_update::run(size,mat,stride,vecY,vecX,alpha); - } -}; - -template -struct selfadjoint_product_selector; - -template -struct selfadjoint_product_selector -{ - static void run(MatrixType& mat, const OtherType& other, const typename MatrixType::Scalar& alpha) - { - typedef typename MatrixType::Scalar Scalar; - typedef typename MatrixType::Index Index; - typedef internal::blas_traits OtherBlasTraits; - typedef typename OtherBlasTraits::DirectLinearAccessType ActualOtherType; - typedef typename internal::remove_all::type _ActualOtherType; - typename internal::add_const_on_value_type::type actualOther = OtherBlasTraits::extract(other.derived()); - - Scalar actualAlpha = alpha * OtherBlasTraits::extractScalarFactor(other.derived()); - - enum { - StorageOrder = (internal::traits::Flags&RowMajorBit) ? RowMajor : ColMajor, - UseOtherDirectly = _ActualOtherType::InnerStrideAtCompileTime==1 - }; - internal::gemv_static_vector_if static_other; - - ei_declare_aligned_stack_constructed_variable(Scalar, actualOtherPtr, other.size(), - (UseOtherDirectly ? const_cast(actualOther.data()) : static_other.data())); - - if(!UseOtherDirectly) - Map(actualOtherPtr, actualOther.size()) = actualOther; - - selfadjoint_rank1_update::IsComplex, - (!OtherBlasTraits::NeedToConjugate) && NumTraits::IsComplex> - ::run(other.size(), mat.data(), mat.outerStride(), actualOtherPtr, actualOtherPtr, actualAlpha); - } -}; - -template -struct selfadjoint_product_selector -{ - static void run(MatrixType& mat, const OtherType& other, const typename MatrixType::Scalar& alpha) - { - typedef typename MatrixType::Scalar Scalar; - typedef typename MatrixType::Index Index; - typedef internal::blas_traits OtherBlasTraits; - typedef typename OtherBlasTraits::DirectLinearAccessType ActualOtherType; - typedef typename internal::remove_all::type _ActualOtherType; - typename internal::add_const_on_value_type::type actualOther = OtherBlasTraits::extract(other.derived()); - - Scalar actualAlpha = alpha * OtherBlasTraits::extractScalarFactor(other.derived()); - - enum { IsRowMajor = (internal::traits::Flags&RowMajorBit) ? 1 : 0 }; - - internal::general_matrix_matrix_triangular_product::IsComplex, - Scalar, _ActualOtherType::Flags&RowMajorBit ? ColMajor : RowMajor, (!OtherBlasTraits::NeedToConjugate) && NumTraits::IsComplex, - MatrixType::Flags&RowMajorBit ? RowMajor : ColMajor, UpLo> - ::run(mat.cols(), actualOther.cols(), - &actualOther.coeffRef(0,0), actualOther.outerStride(), &actualOther.coeffRef(0,0), actualOther.outerStride(), - mat.data(), mat.outerStride(), actualAlpha); - } -}; - -// high level API - -template -template -SelfAdjointView& SelfAdjointView -::rankUpdate(const MatrixBase& u, const Scalar& alpha) -{ - selfadjoint_product_selector::run(_expression().const_cast_derived(), u.derived(), alpha); - - return *this; -} - -} // end namespace Eigen - -#endif // EIGEN_SELFADJOINT_PRODUCT_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/products/SelfadjointRank2Update.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/products/SelfadjointRank2Update.h deleted file mode 100644 index 8594a97c..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Core/products/SelfadjointRank2Update.h +++ /dev/null @@ -1,93 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2009 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_SELFADJOINTRANK2UPTADE_H -#define EIGEN_SELFADJOINTRANK2UPTADE_H - -namespace Eigen { - -namespace internal { - -/* Optimized selfadjoint matrix += alpha * uv' + conj(alpha)*vu' - * It corresponds to the Level2 syr2 BLAS routine - */ - -template -struct selfadjoint_rank2_update_selector; - -template -struct selfadjoint_rank2_update_selector -{ - static void run(Scalar* mat, Index stride, const UType& u, const VType& v, const Scalar& alpha) - { - const Index size = u.size(); - for (Index i=0; i >(mat+stride*i+i, size-i) += - (numext::conj(alpha) * numext::conj(u.coeff(i))) * v.tail(size-i) - + (alpha * numext::conj(v.coeff(i))) * u.tail(size-i); - } - } -}; - -template -struct selfadjoint_rank2_update_selector -{ - static void run(Scalar* mat, Index stride, const UType& u, const VType& v, const Scalar& alpha) - { - const Index size = u.size(); - for (Index i=0; i >(mat+stride*i, i+1) += - (numext::conj(alpha) * numext::conj(u.coeff(i))) * v.head(i+1) - + (alpha * numext::conj(v.coeff(i))) * u.head(i+1); - } -}; - -template struct conj_expr_if - : conditional::Scalar>,T> > {}; - -} // end namespace internal - -template -template -SelfAdjointView& SelfAdjointView -::rankUpdate(const MatrixBase& u, const MatrixBase& v, const Scalar& alpha) -{ - typedef internal::blas_traits UBlasTraits; - typedef typename UBlasTraits::DirectLinearAccessType ActualUType; - typedef typename internal::remove_all::type _ActualUType; - typename internal::add_const_on_value_type::type actualU = UBlasTraits::extract(u.derived()); - - typedef internal::blas_traits VBlasTraits; - typedef typename VBlasTraits::DirectLinearAccessType ActualVType; - typedef typename internal::remove_all::type _ActualVType; - typename internal::add_const_on_value_type::type actualV = VBlasTraits::extract(v.derived()); - - // If MatrixType is row major, then we use the routine for lower triangular in the upper triangular case and - // vice versa, and take the complex conjugate of all coefficients and vector entries. - - enum { IsRowMajor = (internal::traits::Flags&RowMajorBit) ? 1 : 0 }; - Scalar actualAlpha = alpha * UBlasTraits::extractScalarFactor(u.derived()) - * numext::conj(VBlasTraits::extractScalarFactor(v.derived())); - if (IsRowMajor) - actualAlpha = numext::conj(actualAlpha); - - internal::selfadjoint_rank2_update_selector::type>::type, - typename internal::remove_all::type>::type, - (IsRowMajor ? int(UpLo==Upper ? Lower : Upper) : UpLo)> - ::run(_expression().const_cast_derived().data(),_expression().outerStride(),actualU,actualV,actualAlpha); - - return *this; -} - -} // end namespace Eigen - -#endif // EIGEN_SELFADJOINTRANK2UPTADE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/products/TriangularMatrixMatrix.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/products/TriangularMatrixMatrix.h deleted file mode 100644 index 8110507b..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Core/products/TriangularMatrixMatrix.h +++ /dev/null @@ -1,427 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2009 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_TRIANGULAR_MATRIX_MATRIX_H -#define EIGEN_TRIANGULAR_MATRIX_MATRIX_H - -namespace Eigen { - -namespace internal { - -// template -// struct gemm_pack_lhs_triangular -// { -// Matrix::IsComplex && Conjugate> cj; -// const_blas_data_mapper lhs(_lhs,lhsStride); -// int count = 0; -// const int peeled_mc = (rows/mr)*mr; -// for(int i=0; i -struct product_triangular_matrix_matrix; - -template -struct product_triangular_matrix_matrix -{ - static EIGEN_STRONG_INLINE void run( - Index rows, Index cols, Index depth, - const Scalar* lhs, Index lhsStride, - const Scalar* rhs, Index rhsStride, - Scalar* res, Index resStride, - const Scalar& alpha, level3_blocking& blocking) - { - product_triangular_matrix_matrix - ::run(cols, rows, depth, rhs, rhsStride, lhs, lhsStride, res, resStride, alpha, blocking); - } -}; - -// implements col-major += alpha * op(triangular) * op(general) -template -struct product_triangular_matrix_matrix -{ - - typedef gebp_traits Traits; - enum { - SmallPanelWidth = 2 * EIGEN_PLAIN_ENUM_MAX(Traits::mr,Traits::nr), - IsLower = (Mode&Lower) == Lower, - SetDiag = (Mode&(ZeroDiag|UnitDiag)) ? 0 : 1 - }; - - static EIGEN_DONT_INLINE void run( - Index _rows, Index _cols, Index _depth, - const Scalar* _lhs, Index lhsStride, - const Scalar* _rhs, Index rhsStride, - Scalar* res, Index resStride, - const Scalar& alpha, level3_blocking& blocking); -}; - -template -EIGEN_DONT_INLINE void product_triangular_matrix_matrix::run( - Index _rows, Index _cols, Index _depth, - const Scalar* _lhs, Index lhsStride, - const Scalar* _rhs, Index rhsStride, - Scalar* res, Index resStride, - const Scalar& alpha, level3_blocking& blocking) - { - // strip zeros - Index diagSize = (std::min)(_rows,_depth); - Index rows = IsLower ? _rows : diagSize; - Index depth = IsLower ? diagSize : _depth; - Index cols = _cols; - - const_blas_data_mapper lhs(_lhs,lhsStride); - const_blas_data_mapper rhs(_rhs,rhsStride); - - Index kc = blocking.kc(); // cache block size along the K direction - Index mc = (std::min)(rows,blocking.mc()); // cache block size along the M direction - - std::size_t sizeA = kc*mc; - std::size_t sizeB = kc*cols; - std::size_t sizeW = kc*Traits::WorkSpaceFactor; - - ei_declare_aligned_stack_constructed_variable(Scalar, blockA, sizeA, blocking.blockA()); - ei_declare_aligned_stack_constructed_variable(Scalar, blockB, sizeB, blocking.blockB()); - ei_declare_aligned_stack_constructed_variable(Scalar, blockW, sizeW, blocking.blockW()); - - Matrix triangularBuffer; - triangularBuffer.setZero(); - if((Mode&ZeroDiag)==ZeroDiag) - triangularBuffer.diagonal().setZero(); - else - triangularBuffer.diagonal().setOnes(); - - gebp_kernel gebp_kernel; - gemm_pack_lhs pack_lhs; - gemm_pack_rhs pack_rhs; - - for(Index k2=IsLower ? depth : 0; - IsLower ? k2>0 : k2rows)) - { - actual_kc = rows-k2; - k2 = k2+actual_kc-kc; - } - - pack_rhs(blockB, &rhs(actual_k2,0), rhsStride, actual_kc, cols); - - // the selected lhs's panel has to be split in three different parts: - // 1 - the part which is zero => skip it - // 2 - the diagonal block => special kernel - // 3 - the dense panel below (lower case) or above (upper case) the diagonal block => GEPP - - // the block diagonal, if any: - if(IsLower || actual_k2(actual_kc-k1, SmallPanelWidth); - Index lengthTarget = IsLower ? actual_kc-k1-actualPanelWidth : k1; - Index startBlock = actual_k2+k1; - Index blockBOffset = k1; - - // => GEBP with the micro triangular block - // The trick is to pack this micro block while filling the opposite triangular part with zeros. - // To this end we do an extra triangular copy to a small temporary buffer - for (Index k=0;k0) - { - Index startTarget = IsLower ? actual_k2+k1+actualPanelWidth : actual_k2; - - pack_lhs(blockA, &lhs(startTarget,startBlock), lhsStride, actualPanelWidth, lengthTarget); - - gebp_kernel(res+startTarget, resStride, blockA, blockB, lengthTarget, actualPanelWidth, cols, alpha, - actualPanelWidth, actual_kc, 0, blockBOffset, blockW); - } - } - } - // the part below (lower case) or above (upper case) the diagonal => GEPP - { - Index start = IsLower ? k2 : 0; - Index end = IsLower ? rows : (std::min)(actual_k2,rows); - for(Index i2=start; i2() - (blockA, &lhs(i2, actual_k2), lhsStride, actual_kc, actual_mc); - - gebp_kernel(res+i2, resStride, blockA, blockB, actual_mc, actual_kc, cols, alpha, -1, -1, 0, 0, blockW); - } - } - } - } - -// implements col-major += alpha * op(general) * op(triangular) -template -struct product_triangular_matrix_matrix -{ - typedef gebp_traits Traits; - enum { - SmallPanelWidth = EIGEN_PLAIN_ENUM_MAX(Traits::mr,Traits::nr), - IsLower = (Mode&Lower) == Lower, - SetDiag = (Mode&(ZeroDiag|UnitDiag)) ? 0 : 1 - }; - - static EIGEN_DONT_INLINE void run( - Index _rows, Index _cols, Index _depth, - const Scalar* _lhs, Index lhsStride, - const Scalar* _rhs, Index rhsStride, - Scalar* res, Index resStride, - const Scalar& alpha, level3_blocking& blocking); -}; - -template -EIGEN_DONT_INLINE void product_triangular_matrix_matrix::run( - Index _rows, Index _cols, Index _depth, - const Scalar* _lhs, Index lhsStride, - const Scalar* _rhs, Index rhsStride, - Scalar* res, Index resStride, - const Scalar& alpha, level3_blocking& blocking) - { - // strip zeros - Index diagSize = (std::min)(_cols,_depth); - Index rows = _rows; - Index depth = IsLower ? _depth : diagSize; - Index cols = IsLower ? diagSize : _cols; - - const_blas_data_mapper lhs(_lhs,lhsStride); - const_blas_data_mapper rhs(_rhs,rhsStride); - - Index kc = blocking.kc(); // cache block size along the K direction - Index mc = (std::min)(rows,blocking.mc()); // cache block size along the M direction - - std::size_t sizeA = kc*mc; - std::size_t sizeB = kc*cols; - std::size_t sizeW = kc*Traits::WorkSpaceFactor; - - ei_declare_aligned_stack_constructed_variable(Scalar, blockA, sizeA, blocking.blockA()); - ei_declare_aligned_stack_constructed_variable(Scalar, blockB, sizeB, blocking.blockB()); - ei_declare_aligned_stack_constructed_variable(Scalar, blockW, sizeW, blocking.blockW()); - - Matrix triangularBuffer; - triangularBuffer.setZero(); - if((Mode&ZeroDiag)==ZeroDiag) - triangularBuffer.diagonal().setZero(); - else - triangularBuffer.diagonal().setOnes(); - - gebp_kernel gebp_kernel; - gemm_pack_lhs pack_lhs; - gemm_pack_rhs pack_rhs; - gemm_pack_rhs pack_rhs_panel; - - for(Index k2=IsLower ? 0 : depth; - IsLower ? k20; - IsLower ? k2+=kc : k2-=kc) - { - Index actual_kc = (std::min)(IsLower ? depth-k2 : k2, kc); - Index actual_k2 = IsLower ? k2 : k2-actual_kc; - - // align blocks with the end of the triangular part for trapezoidal rhs - if(IsLower && (k2cols)) - { - actual_kc = cols-k2; - k2 = actual_k2 + actual_kc - kc; - } - - // remaining size - Index rs = IsLower ? (std::min)(cols,actual_k2) : cols - k2; - // size of the triangular part - Index ts = (IsLower && actual_k2>=cols) ? 0 : actual_kc; - - Scalar* geb = blockB+ts*ts; - - pack_rhs(geb, &rhs(actual_k2,IsLower ? 0 : k2), rhsStride, actual_kc, rs); - - // pack the triangular part of the rhs padding the unrolled blocks with zeros - if(ts>0) - { - for (Index j2=0; j2(actual_kc-j2, SmallPanelWidth); - Index actual_j2 = actual_k2 + j2; - Index panelOffset = IsLower ? j2+actualPanelWidth : 0; - Index panelLength = IsLower ? actual_kc-j2-actualPanelWidth : j2; - // general part - pack_rhs_panel(blockB+j2*actual_kc, - &rhs(actual_k2+panelOffset, actual_j2), rhsStride, - panelLength, actualPanelWidth, - actual_kc, panelOffset); - - // append the triangular part via a temporary buffer - for (Index j=0;j0) - { - for (Index j2=0; j2(actual_kc-j2, SmallPanelWidth); - Index panelLength = IsLower ? actual_kc-j2 : j2+actualPanelWidth; - Index blockOffset = IsLower ? j2 : 0; - - gebp_kernel(res+i2+(actual_k2+j2)*resStride, resStride, - blockA, blockB+j2*actual_kc, - actual_mc, panelLength, actualPanelWidth, - alpha, - actual_kc, actual_kc, // strides - blockOffset, blockOffset,// offsets - blockW); // workspace - } - } - gebp_kernel(res+i2+(IsLower ? 0 : k2)*resStride, resStride, - blockA, geb, actual_mc, actual_kc, rs, - alpha, - -1, -1, 0, 0, blockW); - } - } - } - -/*************************************************************************** -* Wrapper to product_triangular_matrix_matrix -***************************************************************************/ - -template -struct traits > - : traits, Lhs, Rhs> > -{}; - -} // end namespace internal - -template -struct TriangularProduct - : public ProductBase, Lhs, Rhs > -{ - EIGEN_PRODUCT_PUBLIC_INTERFACE(TriangularProduct) - - TriangularProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs) {} - - template void scaleAndAddTo(Dest& dst, const Scalar& alpha) const - { - typename internal::add_const_on_value_type::type lhs = LhsBlasTraits::extract(m_lhs); - typename internal::add_const_on_value_type::type rhs = RhsBlasTraits::extract(m_rhs); - - Scalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(m_lhs) - * RhsBlasTraits::extractScalarFactor(m_rhs); - - typedef internal::gemm_blocking_space<(Dest::Flags&RowMajorBit) ? RowMajor : ColMajor,Scalar,Scalar, - Lhs::MaxRowsAtCompileTime, Rhs::MaxColsAtCompileTime, Lhs::MaxColsAtCompileTime,4> BlockingType; - - enum { IsLower = (Mode&Lower) == Lower }; - Index stripedRows = ((!LhsIsTriangular) || (IsLower)) ? lhs.rows() : (std::min)(lhs.rows(),lhs.cols()); - Index stripedCols = ((LhsIsTriangular) || (!IsLower)) ? rhs.cols() : (std::min)(rhs.cols(),rhs.rows()); - Index stripedDepth = LhsIsTriangular ? ((!IsLower) ? lhs.cols() : (std::min)(lhs.cols(),lhs.rows())) - : ((IsLower) ? rhs.rows() : (std::min)(rhs.rows(),rhs.cols())); - - BlockingType blocking(stripedRows, stripedCols, stripedDepth); - - internal::product_triangular_matrix_matrix::Flags&RowMajorBit) ? RowMajor : ColMajor, LhsBlasTraits::NeedToConjugate, - (internal::traits<_ActualRhsType>::Flags&RowMajorBit) ? RowMajor : ColMajor, RhsBlasTraits::NeedToConjugate, - (internal::traits::Flags&RowMajorBit) ? RowMajor : ColMajor> - ::run( - stripedRows, stripedCols, stripedDepth, // sizes - &lhs.coeffRef(0,0), lhs.outerStride(), // lhs info - &rhs.coeffRef(0,0), rhs.outerStride(), // rhs info - &dst.coeffRef(0,0), dst.outerStride(), // result info - actualAlpha, blocking - ); - } -}; - -} // end namespace Eigen - -#endif // EIGEN_TRIANGULAR_MATRIX_MATRIX_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/products/TriangularMatrixMatrix_MKL.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/products/TriangularMatrixMatrix_MKL.h deleted file mode 100644 index 4cc56a42..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Core/products/TriangularMatrixMatrix_MKL.h +++ /dev/null @@ -1,309 +0,0 @@ -/* - Copyright (c) 2011, Intel Corporation. All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of Intel Corporation nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - ******************************************************************************** - * Content : Eigen bindings to Intel(R) MKL - * Triangular matrix * matrix product functionality based on ?TRMM. - ******************************************************************************** -*/ - -#ifndef EIGEN_TRIANGULAR_MATRIX_MATRIX_MKL_H -#define EIGEN_TRIANGULAR_MATRIX_MATRIX_MKL_H - -namespace Eigen { - -namespace internal { - - -template -struct product_triangular_matrix_matrix_trmm : - product_triangular_matrix_matrix {}; - - -// try to go to BLAS specialization -#define EIGEN_MKL_TRMM_SPECIALIZE(Scalar, LhsIsTriangular) \ -template \ -struct product_triangular_matrix_matrix { \ - static inline void run(Index _rows, Index _cols, Index _depth, const Scalar* _lhs, Index lhsStride,\ - const Scalar* _rhs, Index rhsStride, Scalar* res, Index resStride, Scalar alpha, level3_blocking& blocking) { \ - product_triangular_matrix_matrix_trmm::run( \ - _rows, _cols, _depth, _lhs, lhsStride, _rhs, rhsStride, res, resStride, alpha, blocking); \ - } \ -}; - -EIGEN_MKL_TRMM_SPECIALIZE(double, true) -EIGEN_MKL_TRMM_SPECIALIZE(double, false) -EIGEN_MKL_TRMM_SPECIALIZE(dcomplex, true) -EIGEN_MKL_TRMM_SPECIALIZE(dcomplex, false) -EIGEN_MKL_TRMM_SPECIALIZE(float, true) -EIGEN_MKL_TRMM_SPECIALIZE(float, false) -EIGEN_MKL_TRMM_SPECIALIZE(scomplex, true) -EIGEN_MKL_TRMM_SPECIALIZE(scomplex, false) - -// implements col-major += alpha * op(triangular) * op(general) -#define EIGEN_MKL_TRMM_L(EIGTYPE, MKLTYPE, EIGPREFIX, MKLPREFIX) \ -template \ -struct product_triangular_matrix_matrix_trmm \ -{ \ - enum { \ - IsLower = (Mode&Lower) == Lower, \ - SetDiag = (Mode&(ZeroDiag|UnitDiag)) ? 0 : 1, \ - IsUnitDiag = (Mode&UnitDiag) ? 1 : 0, \ - IsZeroDiag = (Mode&ZeroDiag) ? 1 : 0, \ - LowUp = IsLower ? Lower : Upper, \ - conjA = ((LhsStorageOrder==ColMajor) && ConjugateLhs) ? 1 : 0 \ - }; \ -\ - static void run( \ - Index _rows, Index _cols, Index _depth, \ - const EIGTYPE* _lhs, Index lhsStride, \ - const EIGTYPE* _rhs, Index rhsStride, \ - EIGTYPE* res, Index resStride, \ - EIGTYPE alpha, level3_blocking& blocking) \ - { \ - Index diagSize = (std::min)(_rows,_depth); \ - Index rows = IsLower ? _rows : diagSize; \ - Index depth = IsLower ? diagSize : _depth; \ - Index cols = _cols; \ -\ - typedef Matrix MatrixLhs; \ - typedef Matrix MatrixRhs; \ -\ -/* Non-square case - doesn't fit to MKL ?TRMM. Fall to default triangular product or call MKL ?GEMM*/ \ - if (rows != depth) { \ -\ - int nthr = mkl_domain_get_max_threads(EIGEN_MKL_DOMAIN_BLAS); \ -\ - if (((nthr==1) && (((std::max)(rows,depth)-diagSize)/(double)diagSize < 0.5))) { \ - /* Most likely no benefit to call TRMM or GEMM from MKL*/ \ - product_triangular_matrix_matrix::run( \ - _rows, _cols, _depth, _lhs, lhsStride, _rhs, rhsStride, res, resStride, alpha, blocking); \ - /*std::cout << "TRMM_L: A is not square! Go to Eigen TRMM implementation!\n";*/ \ - } else { \ - /* Make sense to call GEMM */ \ - Map > lhsMap(_lhs,rows,depth,OuterStride<>(lhsStride)); \ - MatrixLhs aa_tmp=lhsMap.template triangularView(); \ - MKL_INT aStride = aa_tmp.outerStride(); \ - gemm_blocking_space gemm_blocking(_rows,_cols,_depth); \ - general_matrix_matrix_product::run( \ - rows, cols, depth, aa_tmp.data(), aStride, _rhs, rhsStride, res, resStride, alpha, gemm_blocking, 0); \ -\ - /*std::cout << "TRMM_L: A is not square! Go to MKL GEMM implementation! " << nthr<<" \n";*/ \ - } \ - return; \ - } \ - char side = 'L', transa, uplo, diag = 'N'; \ - EIGTYPE *b; \ - const EIGTYPE *a; \ - MKL_INT m, n, lda, ldb; \ - MKLTYPE alpha_; \ -\ -/* Set alpha_*/ \ - assign_scalar_eig2mkl(alpha_, alpha); \ -\ -/* Set m, n */ \ - m = (MKL_INT)diagSize; \ - n = (MKL_INT)cols; \ -\ -/* Set trans */ \ - transa = (LhsStorageOrder==RowMajor) ? ((ConjugateLhs) ? 'C' : 'T') : 'N'; \ -\ -/* Set b, ldb */ \ - Map > rhs(_rhs,depth,cols,OuterStride<>(rhsStride)); \ - MatrixX##EIGPREFIX b_tmp; \ -\ - if (ConjugateRhs) b_tmp = rhs.conjugate(); else b_tmp = rhs; \ - b = b_tmp.data(); \ - ldb = b_tmp.outerStride(); \ -\ -/* Set uplo */ \ - uplo = IsLower ? 'L' : 'U'; \ - if (LhsStorageOrder==RowMajor) uplo = (uplo == 'L') ? 'U' : 'L'; \ -/* Set a, lda */ \ - Map > lhs(_lhs,rows,depth,OuterStride<>(lhsStride)); \ - MatrixLhs a_tmp; \ -\ - if ((conjA!=0) || (SetDiag==0)) { \ - if (conjA) a_tmp = lhs.conjugate(); else a_tmp = lhs; \ - if (IsZeroDiag) \ - a_tmp.diagonal().setZero(); \ - else if (IsUnitDiag) \ - a_tmp.diagonal().setOnes();\ - a = a_tmp.data(); \ - lda = a_tmp.outerStride(); \ - } else { \ - a = _lhs; \ - lda = lhsStride; \ - } \ - /*std::cout << "TRMM_L: A is square! Go to MKL TRMM implementation! \n";*/ \ -/* call ?trmm*/ \ - MKLPREFIX##trmm(&side, &uplo, &transa, &diag, &m, &n, &alpha_, (const MKLTYPE*)a, &lda, (MKLTYPE*)b, &ldb); \ -\ -/* Add op(a_triangular)*b into res*/ \ - Map > res_tmp(res,rows,cols,OuterStride<>(resStride)); \ - res_tmp=res_tmp+b_tmp; \ - } \ -}; - -EIGEN_MKL_TRMM_L(double, double, d, d) -EIGEN_MKL_TRMM_L(dcomplex, MKL_Complex16, cd, z) -EIGEN_MKL_TRMM_L(float, float, f, s) -EIGEN_MKL_TRMM_L(scomplex, MKL_Complex8, cf, c) - -// implements col-major += alpha * op(general) * op(triangular) -#define EIGEN_MKL_TRMM_R(EIGTYPE, MKLTYPE, EIGPREFIX, MKLPREFIX) \ -template \ -struct product_triangular_matrix_matrix_trmm \ -{ \ - enum { \ - IsLower = (Mode&Lower) == Lower, \ - SetDiag = (Mode&(ZeroDiag|UnitDiag)) ? 0 : 1, \ - IsUnitDiag = (Mode&UnitDiag) ? 1 : 0, \ - IsZeroDiag = (Mode&ZeroDiag) ? 1 : 0, \ - LowUp = IsLower ? Lower : Upper, \ - conjA = ((RhsStorageOrder==ColMajor) && ConjugateRhs) ? 1 : 0 \ - }; \ -\ - static void run( \ - Index _rows, Index _cols, Index _depth, \ - const EIGTYPE* _lhs, Index lhsStride, \ - const EIGTYPE* _rhs, Index rhsStride, \ - EIGTYPE* res, Index resStride, \ - EIGTYPE alpha, level3_blocking& blocking) \ - { \ - Index diagSize = (std::min)(_cols,_depth); \ - Index rows = _rows; \ - Index depth = IsLower ? _depth : diagSize; \ - Index cols = IsLower ? diagSize : _cols; \ -\ - typedef Matrix MatrixLhs; \ - typedef Matrix MatrixRhs; \ -\ -/* Non-square case - doesn't fit to MKL ?TRMM. Fall to default triangular product or call MKL ?GEMM*/ \ - if (cols != depth) { \ -\ - int nthr = mkl_domain_get_max_threads(EIGEN_MKL_DOMAIN_BLAS); \ -\ - if ((nthr==1) && (((std::max)(cols,depth)-diagSize)/(double)diagSize < 0.5)) { \ - /* Most likely no benefit to call TRMM or GEMM from MKL*/ \ - product_triangular_matrix_matrix::run( \ - _rows, _cols, _depth, _lhs, lhsStride, _rhs, rhsStride, res, resStride, alpha, blocking); \ - /*std::cout << "TRMM_R: A is not square! Go to Eigen TRMM implementation!\n";*/ \ - } else { \ - /* Make sense to call GEMM */ \ - Map > rhsMap(_rhs,depth,cols, OuterStride<>(rhsStride)); \ - MatrixRhs aa_tmp=rhsMap.template triangularView(); \ - MKL_INT aStride = aa_tmp.outerStride(); \ - gemm_blocking_space gemm_blocking(_rows,_cols,_depth); \ - general_matrix_matrix_product::run( \ - rows, cols, depth, _lhs, lhsStride, aa_tmp.data(), aStride, res, resStride, alpha, gemm_blocking, 0); \ -\ - /*std::cout << "TRMM_R: A is not square! Go to MKL GEMM implementation! " << nthr<<" \n";*/ \ - } \ - return; \ - } \ - char side = 'R', transa, uplo, diag = 'N'; \ - EIGTYPE *b; \ - const EIGTYPE *a; \ - MKL_INT m, n, lda, ldb; \ - MKLTYPE alpha_; \ -\ -/* Set alpha_*/ \ - assign_scalar_eig2mkl(alpha_, alpha); \ -\ -/* Set m, n */ \ - m = (MKL_INT)rows; \ - n = (MKL_INT)diagSize; \ -\ -/* Set trans */ \ - transa = (RhsStorageOrder==RowMajor) ? ((ConjugateRhs) ? 'C' : 'T') : 'N'; \ -\ -/* Set b, ldb */ \ - Map > lhs(_lhs,rows,depth,OuterStride<>(lhsStride)); \ - MatrixX##EIGPREFIX b_tmp; \ -\ - if (ConjugateLhs) b_tmp = lhs.conjugate(); else b_tmp = lhs; \ - b = b_tmp.data(); \ - ldb = b_tmp.outerStride(); \ -\ -/* Set uplo */ \ - uplo = IsLower ? 'L' : 'U'; \ - if (RhsStorageOrder==RowMajor) uplo = (uplo == 'L') ? 'U' : 'L'; \ -/* Set a, lda */ \ - Map > rhs(_rhs,depth,cols, OuterStride<>(rhsStride)); \ - MatrixRhs a_tmp; \ -\ - if ((conjA!=0) || (SetDiag==0)) { \ - if (conjA) a_tmp = rhs.conjugate(); else a_tmp = rhs; \ - if (IsZeroDiag) \ - a_tmp.diagonal().setZero(); \ - else if (IsUnitDiag) \ - a_tmp.diagonal().setOnes();\ - a = a_tmp.data(); \ - lda = a_tmp.outerStride(); \ - } else { \ - a = _rhs; \ - lda = rhsStride; \ - } \ - /*std::cout << "TRMM_R: A is square! Go to MKL TRMM implementation! \n";*/ \ -/* call ?trmm*/ \ - MKLPREFIX##trmm(&side, &uplo, &transa, &diag, &m, &n, &alpha_, (const MKLTYPE*)a, &lda, (MKLTYPE*)b, &ldb); \ -\ -/* Add op(a_triangular)*b into res*/ \ - Map > res_tmp(res,rows,cols,OuterStride<>(resStride)); \ - res_tmp=res_tmp+b_tmp; \ - } \ -}; - -EIGEN_MKL_TRMM_R(double, double, d, d) -EIGEN_MKL_TRMM_R(dcomplex, MKL_Complex16, cd, z) -EIGEN_MKL_TRMM_R(float, float, f, s) -EIGEN_MKL_TRMM_R(scomplex, MKL_Complex8, cf, c) - -} // end namespace internal - -} // end namespace Eigen - -#endif // EIGEN_TRIANGULAR_MATRIX_MATRIX_MKL_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/products/TriangularMatrixVector.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/products/TriangularMatrixVector.h deleted file mode 100644 index 6117d5a8..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Core/products/TriangularMatrixVector.h +++ /dev/null @@ -1,348 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2009 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_TRIANGULARMATRIXVECTOR_H -#define EIGEN_TRIANGULARMATRIXVECTOR_H - -namespace Eigen { - -namespace internal { - -template -struct triangular_matrix_vector_product; - -template -struct triangular_matrix_vector_product -{ - typedef typename scalar_product_traits::ReturnType ResScalar; - enum { - IsLower = ((Mode&Lower)==Lower), - HasUnitDiag = (Mode & UnitDiag)==UnitDiag, - HasZeroDiag = (Mode & ZeroDiag)==ZeroDiag - }; - static EIGEN_DONT_INLINE void run(Index _rows, Index _cols, const LhsScalar* _lhs, Index lhsStride, - const RhsScalar* _rhs, Index rhsIncr, ResScalar* _res, Index resIncr, const ResScalar& alpha); -}; - -template -EIGEN_DONT_INLINE void triangular_matrix_vector_product - ::run(Index _rows, Index _cols, const LhsScalar* _lhs, Index lhsStride, - const RhsScalar* _rhs, Index rhsIncr, ResScalar* _res, Index resIncr, const ResScalar& alpha) - { - static const Index PanelWidth = EIGEN_TUNE_TRIANGULAR_PANEL_WIDTH; - Index size = (std::min)(_rows,_cols); - Index rows = IsLower ? _rows : (std::min)(_rows,_cols); - Index cols = IsLower ? (std::min)(_rows,_cols) : _cols; - - typedef Map, 0, OuterStride<> > LhsMap; - const LhsMap lhs(_lhs,rows,cols,OuterStride<>(lhsStride)); - typename conj_expr_if::type cjLhs(lhs); - - typedef Map, 0, InnerStride<> > RhsMap; - const RhsMap rhs(_rhs,cols,InnerStride<>(rhsIncr)); - typename conj_expr_if::type cjRhs(rhs); - - typedef Map > ResMap; - ResMap res(_res,rows); - - for (Index pi=0; pi0) - res.segment(s,r) += (alpha * cjRhs.coeff(i)) * cjLhs.col(i).segment(s,r); - if (HasUnitDiag) - res.coeffRef(i) += alpha * cjRhs.coeff(i); - } - Index r = IsLower ? rows - pi - actualPanelWidth : pi; - if (r>0) - { - Index s = IsLower ? pi+actualPanelWidth : 0; - general_matrix_vector_product::run( - r, actualPanelWidth, - &lhs.coeffRef(s,pi), lhsStride, - &rhs.coeffRef(pi), rhsIncr, - &res.coeffRef(s), resIncr, alpha); - } - } - if((!IsLower) && cols>size) - { - general_matrix_vector_product::run( - rows, cols-size, - &lhs.coeffRef(0,size), lhsStride, - &rhs.coeffRef(size), rhsIncr, - _res, resIncr, alpha); - } - } - -template -struct triangular_matrix_vector_product -{ - typedef typename scalar_product_traits::ReturnType ResScalar; - enum { - IsLower = ((Mode&Lower)==Lower), - HasUnitDiag = (Mode & UnitDiag)==UnitDiag, - HasZeroDiag = (Mode & ZeroDiag)==ZeroDiag - }; - static EIGEN_DONT_INLINE void run(Index _rows, Index _cols, const LhsScalar* _lhs, Index lhsStride, - const RhsScalar* _rhs, Index rhsIncr, ResScalar* _res, Index resIncr, const ResScalar& alpha); -}; - -template -EIGEN_DONT_INLINE void triangular_matrix_vector_product - ::run(Index _rows, Index _cols, const LhsScalar* _lhs, Index lhsStride, - const RhsScalar* _rhs, Index rhsIncr, ResScalar* _res, Index resIncr, const ResScalar& alpha) - { - static const Index PanelWidth = EIGEN_TUNE_TRIANGULAR_PANEL_WIDTH; - Index diagSize = (std::min)(_rows,_cols); - Index rows = IsLower ? _rows : diagSize; - Index cols = IsLower ? diagSize : _cols; - - typedef Map, 0, OuterStride<> > LhsMap; - const LhsMap lhs(_lhs,rows,cols,OuterStride<>(lhsStride)); - typename conj_expr_if::type cjLhs(lhs); - - typedef Map > RhsMap; - const RhsMap rhs(_rhs,cols); - typename conj_expr_if::type cjRhs(rhs); - - typedef Map, 0, InnerStride<> > ResMap; - ResMap res(_res,rows,InnerStride<>(resIncr)); - - for (Index pi=0; pi0) - res.coeffRef(i) += alpha * (cjLhs.row(i).segment(s,r).cwiseProduct(cjRhs.segment(s,r).transpose())).sum(); - if (HasUnitDiag) - res.coeffRef(i) += alpha * cjRhs.coeff(i); - } - Index r = IsLower ? pi : cols - pi - actualPanelWidth; - if (r>0) - { - Index s = IsLower ? 0 : pi + actualPanelWidth; - general_matrix_vector_product::run( - actualPanelWidth, r, - &lhs.coeffRef(pi,s), lhsStride, - &rhs.coeffRef(s), rhsIncr, - &res.coeffRef(pi), resIncr, alpha); - } - } - if(IsLower && rows>diagSize) - { - general_matrix_vector_product::run( - rows-diagSize, cols, - &lhs.coeffRef(diagSize,0), lhsStride, - &rhs.coeffRef(0), rhsIncr, - &res.coeffRef(diagSize), resIncr, alpha); - } - } - -/*************************************************************************** -* Wrapper to product_triangular_vector -***************************************************************************/ - -template -struct traits > - : traits, Lhs, Rhs> > -{}; - -template -struct traits > - : traits, Lhs, Rhs> > -{}; - - -template -struct trmv_selector; - -} // end namespace internal - -template -struct TriangularProduct - : public ProductBase, Lhs, Rhs > -{ - EIGEN_PRODUCT_PUBLIC_INTERFACE(TriangularProduct) - - TriangularProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs) {} - - template void scaleAndAddTo(Dest& dst, const Scalar& alpha) const - { - eigen_assert(dst.rows()==m_lhs.rows() && dst.cols()==m_rhs.cols()); - - internal::trmv_selector<(int(internal::traits::Flags)&RowMajorBit) ? RowMajor : ColMajor>::run(*this, dst, alpha); - } -}; - -template -struct TriangularProduct - : public ProductBase, Lhs, Rhs > -{ - EIGEN_PRODUCT_PUBLIC_INTERFACE(TriangularProduct) - - TriangularProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs) {} - - template void scaleAndAddTo(Dest& dst, const Scalar& alpha) const - { - eigen_assert(dst.rows()==m_lhs.rows() && dst.cols()==m_rhs.cols()); - - typedef TriangularProduct<(Mode & (UnitDiag|ZeroDiag)) | ((Mode & Lower) ? Upper : Lower),true,Transpose,false,Transpose,true> TriangularProductTranspose; - Transpose dstT(dst); - internal::trmv_selector<(int(internal::traits::Flags)&RowMajorBit) ? ColMajor : RowMajor>::run( - TriangularProductTranspose(m_rhs.transpose(),m_lhs.transpose()), dstT, alpha); - } -}; - -namespace internal { - -// TODO: find a way to factorize this piece of code with gemv_selector since the logic is exactly the same. - -template<> struct trmv_selector -{ - template - static void run(const TriangularProduct& prod, Dest& dest, const typename TriangularProduct::Scalar& alpha) - { - typedef TriangularProduct ProductType; - typedef typename ProductType::Index Index; - typedef typename ProductType::LhsScalar LhsScalar; - typedef typename ProductType::RhsScalar RhsScalar; - typedef typename ProductType::Scalar ResScalar; - typedef typename ProductType::RealScalar RealScalar; - typedef typename ProductType::ActualLhsType ActualLhsType; - typedef typename ProductType::ActualRhsType ActualRhsType; - typedef typename ProductType::LhsBlasTraits LhsBlasTraits; - typedef typename ProductType::RhsBlasTraits RhsBlasTraits; - typedef Map, Aligned> MappedDest; - - typename internal::add_const_on_value_type::type actualLhs = LhsBlasTraits::extract(prod.lhs()); - typename internal::add_const_on_value_type::type actualRhs = RhsBlasTraits::extract(prod.rhs()); - - ResScalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(prod.lhs()) - * RhsBlasTraits::extractScalarFactor(prod.rhs()); - - enum { - // FIXME find a way to allow an inner stride on the result if packet_traits::size==1 - // on, the other hand it is good for the cache to pack the vector anyways... - EvalToDestAtCompileTime = Dest::InnerStrideAtCompileTime==1, - ComplexByReal = (NumTraits::IsComplex) && (!NumTraits::IsComplex), - MightCannotUseDest = (Dest::InnerStrideAtCompileTime!=1) || ComplexByReal - }; - - gemv_static_vector_if static_dest; - - bool alphaIsCompatible = (!ComplexByReal) || (numext::imag(actualAlpha)==RealScalar(0)); - bool evalToDest = EvalToDestAtCompileTime && alphaIsCompatible; - - RhsScalar compatibleAlpha = get_factor::run(actualAlpha); - - ei_declare_aligned_stack_constructed_variable(ResScalar,actualDestPtr,dest.size(), - evalToDest ? dest.data() : static_dest.data()); - - if(!evalToDest) - { - #ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN - Index size = dest.size(); - EIGEN_DENSE_STORAGE_CTOR_PLUGIN - #endif - if(!alphaIsCompatible) - { - MappedDest(actualDestPtr, dest.size()).setZero(); - compatibleAlpha = RhsScalar(1); - } - else - MappedDest(actualDestPtr, dest.size()) = dest; - } - - internal::triangular_matrix_vector_product - - ::run(actualLhs.rows(),actualLhs.cols(), - actualLhs.data(),actualLhs.outerStride(), - actualRhs.data(),actualRhs.innerStride(), - actualDestPtr,1,compatibleAlpha); - - if (!evalToDest) - { - if(!alphaIsCompatible) - dest += actualAlpha * MappedDest(actualDestPtr, dest.size()); - else - dest = MappedDest(actualDestPtr, dest.size()); - } - } -}; - -template<> struct trmv_selector -{ - template - static void run(const TriangularProduct& prod, Dest& dest, const typename TriangularProduct::Scalar& alpha) - { - typedef TriangularProduct ProductType; - typedef typename ProductType::LhsScalar LhsScalar; - typedef typename ProductType::RhsScalar RhsScalar; - typedef typename ProductType::Scalar ResScalar; - typedef typename ProductType::Index Index; - typedef typename ProductType::ActualLhsType ActualLhsType; - typedef typename ProductType::ActualRhsType ActualRhsType; - typedef typename ProductType::_ActualRhsType _ActualRhsType; - typedef typename ProductType::LhsBlasTraits LhsBlasTraits; - typedef typename ProductType::RhsBlasTraits RhsBlasTraits; - - typename add_const::type actualLhs = LhsBlasTraits::extract(prod.lhs()); - typename add_const::type actualRhs = RhsBlasTraits::extract(prod.rhs()); - - ResScalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(prod.lhs()) - * RhsBlasTraits::extractScalarFactor(prod.rhs()); - - enum { - DirectlyUseRhs = _ActualRhsType::InnerStrideAtCompileTime==1 - }; - - gemv_static_vector_if static_rhs; - - ei_declare_aligned_stack_constructed_variable(RhsScalar,actualRhsPtr,actualRhs.size(), - DirectlyUseRhs ? const_cast(actualRhs.data()) : static_rhs.data()); - - if(!DirectlyUseRhs) - { - #ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN - int size = actualRhs.size(); - EIGEN_DENSE_STORAGE_CTOR_PLUGIN - #endif - Map(actualRhsPtr, actualRhs.size()) = actualRhs; - } - - internal::triangular_matrix_vector_product - - ::run(actualLhs.rows(),actualLhs.cols(), - actualLhs.data(),actualLhs.outerStride(), - actualRhsPtr,1, - dest.data(),dest.innerStride(), - actualAlpha); - } -}; - -} // end namespace internal - -} // end namespace Eigen - -#endif // EIGEN_TRIANGULARMATRIXVECTOR_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/products/TriangularMatrixVector_MKL.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/products/TriangularMatrixVector_MKL.h deleted file mode 100644 index 09f110da..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Core/products/TriangularMatrixVector_MKL.h +++ /dev/null @@ -1,247 +0,0 @@ -/* - Copyright (c) 2011, Intel Corporation. All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of Intel Corporation nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - ******************************************************************************** - * Content : Eigen bindings to Intel(R) MKL - * Triangular matrix-vector product functionality based on ?TRMV. - ******************************************************************************** -*/ - -#ifndef EIGEN_TRIANGULAR_MATRIX_VECTOR_MKL_H -#define EIGEN_TRIANGULAR_MATRIX_VECTOR_MKL_H - -namespace Eigen { - -namespace internal { - -/********************************************************************** -* This file implements triangular matrix-vector multiplication using BLAS -**********************************************************************/ - -// trmv/hemv specialization - -template -struct triangular_matrix_vector_product_trmv : - triangular_matrix_vector_product {}; - -#define EIGEN_MKL_TRMV_SPECIALIZE(Scalar) \ -template \ -struct triangular_matrix_vector_product { \ - static void run(Index _rows, Index _cols, const Scalar* _lhs, Index lhsStride, \ - const Scalar* _rhs, Index rhsIncr, Scalar* _res, Index resIncr, Scalar alpha) { \ - triangular_matrix_vector_product_trmv::run( \ - _rows, _cols, _lhs, lhsStride, _rhs, rhsIncr, _res, resIncr, alpha); \ - } \ -}; \ -template \ -struct triangular_matrix_vector_product { \ - static void run(Index _rows, Index _cols, const Scalar* _lhs, Index lhsStride, \ - const Scalar* _rhs, Index rhsIncr, Scalar* _res, Index resIncr, Scalar alpha) { \ - triangular_matrix_vector_product_trmv::run( \ - _rows, _cols, _lhs, lhsStride, _rhs, rhsIncr, _res, resIncr, alpha); \ - } \ -}; - -EIGEN_MKL_TRMV_SPECIALIZE(double) -EIGEN_MKL_TRMV_SPECIALIZE(float) -EIGEN_MKL_TRMV_SPECIALIZE(dcomplex) -EIGEN_MKL_TRMV_SPECIALIZE(scomplex) - -// implements col-major: res += alpha * op(triangular) * vector -#define EIGEN_MKL_TRMV_CM(EIGTYPE, MKLTYPE, EIGPREFIX, MKLPREFIX) \ -template \ -struct triangular_matrix_vector_product_trmv { \ - enum { \ - IsLower = (Mode&Lower) == Lower, \ - SetDiag = (Mode&(ZeroDiag|UnitDiag)) ? 0 : 1, \ - IsUnitDiag = (Mode&UnitDiag) ? 1 : 0, \ - IsZeroDiag = (Mode&ZeroDiag) ? 1 : 0, \ - LowUp = IsLower ? Lower : Upper \ - }; \ - static void run(Index _rows, Index _cols, const EIGTYPE* _lhs, Index lhsStride, \ - const EIGTYPE* _rhs, Index rhsIncr, EIGTYPE* _res, Index resIncr, EIGTYPE alpha) \ - { \ - if (ConjLhs || IsZeroDiag) { \ - triangular_matrix_vector_product::run( \ - _rows, _cols, _lhs, lhsStride, _rhs, rhsIncr, _res, resIncr, alpha); \ - return; \ - }\ - Index size = (std::min)(_rows,_cols); \ - Index rows = IsLower ? _rows : size; \ - Index cols = IsLower ? size : _cols; \ -\ - typedef VectorX##EIGPREFIX VectorRhs; \ - EIGTYPE *x, *y;\ -\ -/* Set x*/ \ - Map > rhs(_rhs,cols,InnerStride<>(rhsIncr)); \ - VectorRhs x_tmp; \ - if (ConjRhs) x_tmp = rhs.conjugate(); else x_tmp = rhs; \ - x = x_tmp.data(); \ -\ -/* Square part handling */\ -\ - char trans, uplo, diag; \ - MKL_INT m, n, lda, incx, incy; \ - EIGTYPE const *a; \ - MKLTYPE alpha_, beta_; \ - assign_scalar_eig2mkl(alpha_, alpha); \ - assign_scalar_eig2mkl(beta_, EIGTYPE(1)); \ -\ -/* Set m, n */ \ - n = (MKL_INT)size; \ - lda = lhsStride; \ - incx = 1; \ - incy = resIncr; \ -\ -/* Set uplo, trans and diag*/ \ - trans = 'N'; \ - uplo = IsLower ? 'L' : 'U'; \ - diag = IsUnitDiag ? 'U' : 'N'; \ -\ -/* call ?TRMV*/ \ - MKLPREFIX##trmv(&uplo, &trans, &diag, &n, (const MKLTYPE*)_lhs, &lda, (MKLTYPE*)x, &incx); \ -\ -/* Add op(a_tr)rhs into res*/ \ - MKLPREFIX##axpy(&n, &alpha_,(const MKLTYPE*)x, &incx, (MKLTYPE*)_res, &incy); \ -/* Non-square case - doesn't fit to MKL ?TRMV. Fall to default triangular product*/ \ - if (size<(std::max)(rows,cols)) { \ - typedef Matrix MatrixLhs; \ - if (ConjRhs) x_tmp = rhs.conjugate(); else x_tmp = rhs; \ - x = x_tmp.data(); \ - if (size \ -struct triangular_matrix_vector_product_trmv { \ - enum { \ - IsLower = (Mode&Lower) == Lower, \ - SetDiag = (Mode&(ZeroDiag|UnitDiag)) ? 0 : 1, \ - IsUnitDiag = (Mode&UnitDiag) ? 1 : 0, \ - IsZeroDiag = (Mode&ZeroDiag) ? 1 : 0, \ - LowUp = IsLower ? Lower : Upper \ - }; \ - static void run(Index _rows, Index _cols, const EIGTYPE* _lhs, Index lhsStride, \ - const EIGTYPE* _rhs, Index rhsIncr, EIGTYPE* _res, Index resIncr, EIGTYPE alpha) \ - { \ - if (IsZeroDiag) { \ - triangular_matrix_vector_product::run( \ - _rows, _cols, _lhs, lhsStride, _rhs, rhsIncr, _res, resIncr, alpha); \ - return; \ - }\ - Index size = (std::min)(_rows,_cols); \ - Index rows = IsLower ? _rows : size; \ - Index cols = IsLower ? size : _cols; \ -\ - typedef VectorX##EIGPREFIX VectorRhs; \ - EIGTYPE *x, *y;\ -\ -/* Set x*/ \ - Map > rhs(_rhs,cols,InnerStride<>(rhsIncr)); \ - VectorRhs x_tmp; \ - if (ConjRhs) x_tmp = rhs.conjugate(); else x_tmp = rhs; \ - x = x_tmp.data(); \ -\ -/* Square part handling */\ -\ - char trans, uplo, diag; \ - MKL_INT m, n, lda, incx, incy; \ - EIGTYPE const *a; \ - MKLTYPE alpha_, beta_; \ - assign_scalar_eig2mkl(alpha_, alpha); \ - assign_scalar_eig2mkl(beta_, EIGTYPE(1)); \ -\ -/* Set m, n */ \ - n = (MKL_INT)size; \ - lda = lhsStride; \ - incx = 1; \ - incy = resIncr; \ -\ -/* Set uplo, trans and diag*/ \ - trans = ConjLhs ? 'C' : 'T'; \ - uplo = IsLower ? 'U' : 'L'; \ - diag = IsUnitDiag ? 'U' : 'N'; \ -\ -/* call ?TRMV*/ \ - MKLPREFIX##trmv(&uplo, &trans, &diag, &n, (const MKLTYPE*)_lhs, &lda, (MKLTYPE*)x, &incx); \ -\ -/* Add op(a_tr)rhs into res*/ \ - MKLPREFIX##axpy(&n, &alpha_,(const MKLTYPE*)x, &incx, (MKLTYPE*)_res, &incy); \ -/* Non-square case - doesn't fit to MKL ?TRMV. Fall to default triangular product*/ \ - if (size<(std::max)(rows,cols)) { \ - typedef Matrix MatrixLhs; \ - if (ConjRhs) x_tmp = rhs.conjugate(); else x_tmp = rhs; \ - x = x_tmp.data(); \ - if (size -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_TRIANGULAR_SOLVER_MATRIX_H -#define EIGEN_TRIANGULAR_SOLVER_MATRIX_H - -namespace Eigen { - -namespace internal { - -// if the rhs is row major, let's transpose the product -template -struct triangular_solve_matrix -{ - static void run( - Index size, Index cols, - const Scalar* tri, Index triStride, - Scalar* _other, Index otherStride, - level3_blocking& blocking) - { - triangular_solve_matrix< - Scalar, Index, Side==OnTheLeft?OnTheRight:OnTheLeft, - (Mode&UnitDiag) | ((Mode&Upper) ? Lower : Upper), - NumTraits::IsComplex && Conjugate, - TriStorageOrder==RowMajor ? ColMajor : RowMajor, ColMajor> - ::run(size, cols, tri, triStride, _other, otherStride, blocking); - } -}; - -/* Optimized triangular solver with multiple right hand side and the triangular matrix on the left - */ -template -struct triangular_solve_matrix -{ - static EIGEN_DONT_INLINE void run( - Index size, Index otherSize, - const Scalar* _tri, Index triStride, - Scalar* _other, Index otherStride, - level3_blocking& blocking); -}; -template -EIGEN_DONT_INLINE void triangular_solve_matrix::run( - Index size, Index otherSize, - const Scalar* _tri, Index triStride, - Scalar* _other, Index otherStride, - level3_blocking& blocking) - { - Index cols = otherSize; - const_blas_data_mapper tri(_tri,triStride); - blas_data_mapper other(_other,otherStride); - - typedef gebp_traits Traits; - enum { - SmallPanelWidth = EIGEN_PLAIN_ENUM_MAX(Traits::mr,Traits::nr), - IsLower = (Mode&Lower) == Lower - }; - - Index kc = blocking.kc(); // cache block size along the K direction - Index mc = (std::min)(size,blocking.mc()); // cache block size along the M direction - - std::size_t sizeA = kc*mc; - std::size_t sizeB = kc*cols; - std::size_t sizeW = kc*Traits::WorkSpaceFactor; - - ei_declare_aligned_stack_constructed_variable(Scalar, blockA, sizeA, blocking.blockA()); - ei_declare_aligned_stack_constructed_variable(Scalar, blockB, sizeB, blocking.blockB()); - ei_declare_aligned_stack_constructed_variable(Scalar, blockW, sizeW, blocking.blockW()); - - conj_if conj; - gebp_kernel gebp_kernel; - gemm_pack_lhs pack_lhs; - gemm_pack_rhs pack_rhs; - - // the goal here is to subdivise the Rhs panels such that we keep some cache - // coherence when accessing the rhs elements - std::ptrdiff_t l1, l2; - manage_caching_sizes(GetAction, &l1, &l2); - Index subcols = cols>0 ? l2/(4 * sizeof(Scalar) * otherStride) : 0; - subcols = std::max((subcols/Traits::nr)*Traits::nr, Traits::nr); - - for(Index k2=IsLower ? 0 : size; - IsLower ? k20; - IsLower ? k2+=kc : k2-=kc) - { - const Index actual_kc = (std::min)(IsLower ? size-k2 : k2, kc); - - // We have selected and packed a big horizontal panel R1 of rhs. Let B be the packed copy of this panel, - // and R2 the remaining part of rhs. The corresponding vertical panel of lhs is split into - // A11 (the triangular part) and A21 the remaining rectangular part. - // Then the high level algorithm is: - // - B = R1 => general block copy (done during the next step) - // - R1 = A11^-1 B => tricky part - // - update B from the new R1 => actually this has to be performed continuously during the above step - // - R2 -= A21 * B => GEPP - - // The tricky part: compute R1 = A11^-1 B while updating B from R1 - // The idea is to split A11 into multiple small vertical panels. - // Each panel can be split into a small triangular part T1k which is processed without optimization, - // and the remaining small part T2k which is processed using gebp with appropriate block strides - for(Index j2=0; j2(actual_kc-k1, SmallPanelWidth); - // tr solve - for (Index k=0; k0) - { - Index startTarget = IsLower ? k2+k1+actualPanelWidth : k2-actual_kc; - - pack_lhs(blockA, &tri(startTarget,startBlock), triStride, actualPanelWidth, lengthTarget); - - gebp_kernel(&other(startTarget,j2), otherStride, blockA, blockB+actual_kc*j2, lengthTarget, actualPanelWidth, actual_cols, Scalar(-1), - actualPanelWidth, actual_kc, 0, blockBOffset, blockW); - } - } - } - - // R2 -= A21 * B => GEPP - { - Index start = IsLower ? k2+kc : 0; - Index end = IsLower ? size : k2-kc; - for(Index i2=start; i20) - { - pack_lhs(blockA, &tri(i2, IsLower ? k2 : k2-kc), triStride, actual_kc, actual_mc); - - gebp_kernel(_other+i2, otherStride, blockA, blockB, actual_mc, actual_kc, cols, Scalar(-1), -1, -1, 0, 0, blockW); - } - } - } - } - } - -/* Optimized triangular solver with multiple left hand sides and the trinagular matrix on the right - */ -template -struct triangular_solve_matrix -{ - static EIGEN_DONT_INLINE void run( - Index size, Index otherSize, - const Scalar* _tri, Index triStride, - Scalar* _other, Index otherStride, - level3_blocking& blocking); -}; -template -EIGEN_DONT_INLINE void triangular_solve_matrix::run( - Index size, Index otherSize, - const Scalar* _tri, Index triStride, - Scalar* _other, Index otherStride, - level3_blocking& blocking) - { - Index rows = otherSize; - const_blas_data_mapper rhs(_tri,triStride); - blas_data_mapper lhs(_other,otherStride); - - typedef gebp_traits Traits; - enum { - RhsStorageOrder = TriStorageOrder, - SmallPanelWidth = EIGEN_PLAIN_ENUM_MAX(Traits::mr,Traits::nr), - IsLower = (Mode&Lower) == Lower - }; - - Index kc = blocking.kc(); // cache block size along the K direction - Index mc = (std::min)(rows,blocking.mc()); // cache block size along the M direction - - std::size_t sizeA = kc*mc; - std::size_t sizeB = kc*size; - std::size_t sizeW = kc*Traits::WorkSpaceFactor; - - ei_declare_aligned_stack_constructed_variable(Scalar, blockA, sizeA, blocking.blockA()); - ei_declare_aligned_stack_constructed_variable(Scalar, blockB, sizeB, blocking.blockB()); - ei_declare_aligned_stack_constructed_variable(Scalar, blockW, sizeW, blocking.blockW()); - - conj_if conj; - gebp_kernel gebp_kernel; - gemm_pack_rhs pack_rhs; - gemm_pack_rhs pack_rhs_panel; - gemm_pack_lhs pack_lhs_panel; - - for(Index k2=IsLower ? size : 0; - IsLower ? k2>0 : k20) pack_rhs(geb, &rhs(actual_k2,startPanel), triStride, actual_kc, rs); - - // triangular packing (we only pack the panels off the diagonal, - // neglecting the blocks overlapping the diagonal - { - for (Index j2=0; j2(actual_kc-j2, SmallPanelWidth); - Index actual_j2 = actual_k2 + j2; - Index panelOffset = IsLower ? j2+actualPanelWidth : 0; - Index panelLength = IsLower ? actual_kc-j2-actualPanelWidth : j2; - - if (panelLength>0) - pack_rhs_panel(blockB+j2*actual_kc, - &rhs(actual_k2+panelOffset, actual_j2), triStride, - panelLength, actualPanelWidth, - actual_kc, panelOffset); - } - } - - for(Index i2=0; i2 vertical panels of rhs) - for (Index j2 = IsLower - ? (actual_kc - ((actual_kc%SmallPanelWidth) ? Index(actual_kc%SmallPanelWidth) - : Index(SmallPanelWidth))) - : 0; - IsLower ? j2>=0 : j2(actual_kc-j2, SmallPanelWidth); - Index absolute_j2 = actual_k2 + j2; - Index panelOffset = IsLower ? j2+actualPanelWidth : 0; - Index panelLength = IsLower ? actual_kc - j2 - actualPanelWidth : j2; - - // GEBP - if(panelLength>0) - { - gebp_kernel(&lhs(i2,absolute_j2), otherStride, - blockA, blockB+j2*actual_kc, - actual_mc, panelLength, actualPanelWidth, - Scalar(-1), - actual_kc, actual_kc, // strides - panelOffset, panelOffset, // offsets - blockW); // workspace - } - - // unblocked triangular solve - for (Index k=0; k0) - gebp_kernel(_other+i2+startPanel*otherStride, otherStride, blockA, geb, - actual_mc, actual_kc, rs, Scalar(-1), - -1, -1, 0, 0, blockW); - } - } - } - -} // end namespace internal - -} // end namespace Eigen - -#endif // EIGEN_TRIANGULAR_SOLVER_MATRIX_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/products/TriangularSolverMatrix_MKL.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/products/TriangularSolverMatrix_MKL.h deleted file mode 100644 index 6a0bb833..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Core/products/TriangularSolverMatrix_MKL.h +++ /dev/null @@ -1,155 +0,0 @@ -/* - Copyright (c) 2011, Intel Corporation. All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of Intel Corporation nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - ******************************************************************************** - * Content : Eigen bindings to Intel(R) MKL - * Triangular matrix * matrix product functionality based on ?TRMM. - ******************************************************************************** -*/ - -#ifndef EIGEN_TRIANGULAR_SOLVER_MATRIX_MKL_H -#define EIGEN_TRIANGULAR_SOLVER_MATRIX_MKL_H - -namespace Eigen { - -namespace internal { - -// implements LeftSide op(triangular)^-1 * general -#define EIGEN_MKL_TRSM_L(EIGTYPE, MKLTYPE, MKLPREFIX) \ -template \ -struct triangular_solve_matrix \ -{ \ - enum { \ - IsLower = (Mode&Lower) == Lower, \ - IsUnitDiag = (Mode&UnitDiag) ? 1 : 0, \ - IsZeroDiag = (Mode&ZeroDiag) ? 1 : 0, \ - conjA = ((TriStorageOrder==ColMajor) && Conjugate) ? 1 : 0 \ - }; \ - static void run( \ - Index size, Index otherSize, \ - const EIGTYPE* _tri, Index triStride, \ - EIGTYPE* _other, Index otherStride, level3_blocking& /*blocking*/) \ - { \ - MKL_INT m = size, n = otherSize, lda, ldb; \ - char side = 'L', uplo, diag='N', transa; \ - /* Set alpha_ */ \ - MKLTYPE alpha; \ - EIGTYPE myone(1); \ - assign_scalar_eig2mkl(alpha, myone); \ - ldb = otherStride;\ -\ - const EIGTYPE *a; \ -/* Set trans */ \ - transa = (TriStorageOrder==RowMajor) ? ((Conjugate) ? 'C' : 'T') : 'N'; \ -/* Set uplo */ \ - uplo = IsLower ? 'L' : 'U'; \ - if (TriStorageOrder==RowMajor) uplo = (uplo == 'L') ? 'U' : 'L'; \ -/* Set a, lda */ \ - typedef Matrix MatrixTri; \ - Map > tri(_tri,size,size,OuterStride<>(triStride)); \ - MatrixTri a_tmp; \ -\ - if (conjA) { \ - a_tmp = tri.conjugate(); \ - a = a_tmp.data(); \ - lda = a_tmp.outerStride(); \ - } else { \ - a = _tri; \ - lda = triStride; \ - } \ - if (IsUnitDiag) diag='U'; \ -/* call ?trsm*/ \ - MKLPREFIX##trsm(&side, &uplo, &transa, &diag, &m, &n, &alpha, (const MKLTYPE*)a, &lda, (MKLTYPE*)_other, &ldb); \ - } \ -}; - -EIGEN_MKL_TRSM_L(double, double, d) -EIGEN_MKL_TRSM_L(dcomplex, MKL_Complex16, z) -EIGEN_MKL_TRSM_L(float, float, s) -EIGEN_MKL_TRSM_L(scomplex, MKL_Complex8, c) - - -// implements RightSide general * op(triangular)^-1 -#define EIGEN_MKL_TRSM_R(EIGTYPE, MKLTYPE, MKLPREFIX) \ -template \ -struct triangular_solve_matrix \ -{ \ - enum { \ - IsLower = (Mode&Lower) == Lower, \ - IsUnitDiag = (Mode&UnitDiag) ? 1 : 0, \ - IsZeroDiag = (Mode&ZeroDiag) ? 1 : 0, \ - conjA = ((TriStorageOrder==ColMajor) && Conjugate) ? 1 : 0 \ - }; \ - static void run( \ - Index size, Index otherSize, \ - const EIGTYPE* _tri, Index triStride, \ - EIGTYPE* _other, Index otherStride, level3_blocking& /*blocking*/) \ - { \ - MKL_INT m = otherSize, n = size, lda, ldb; \ - char side = 'R', uplo, diag='N', transa; \ - /* Set alpha_ */ \ - MKLTYPE alpha; \ - EIGTYPE myone(1); \ - assign_scalar_eig2mkl(alpha, myone); \ - ldb = otherStride;\ -\ - const EIGTYPE *a; \ -/* Set trans */ \ - transa = (TriStorageOrder==RowMajor) ? ((Conjugate) ? 'C' : 'T') : 'N'; \ -/* Set uplo */ \ - uplo = IsLower ? 'L' : 'U'; \ - if (TriStorageOrder==RowMajor) uplo = (uplo == 'L') ? 'U' : 'L'; \ -/* Set a, lda */ \ - typedef Matrix MatrixTri; \ - Map > tri(_tri,size,size,OuterStride<>(triStride)); \ - MatrixTri a_tmp; \ -\ - if (conjA) { \ - a_tmp = tri.conjugate(); \ - a = a_tmp.data(); \ - lda = a_tmp.outerStride(); \ - } else { \ - a = _tri; \ - lda = triStride; \ - } \ - if (IsUnitDiag) diag='U'; \ -/* call ?trsm*/ \ - MKLPREFIX##trsm(&side, &uplo, &transa, &diag, &m, &n, &alpha, (const MKLTYPE*)a, &lda, (MKLTYPE*)_other, &ldb); \ - /*std::cout << "TRMS_L specialization!\n";*/ \ - } \ -}; - -EIGEN_MKL_TRSM_R(double, double, d) -EIGEN_MKL_TRSM_R(dcomplex, MKL_Complex16, z) -EIGEN_MKL_TRSM_R(float, float, s) -EIGEN_MKL_TRSM_R(scomplex, MKL_Complex8, c) - - -} // end namespace internal - -} // end namespace Eigen - -#endif // EIGEN_TRIANGULAR_SOLVER_MATRIX_MKL_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/products/TriangularSolverVector.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/products/TriangularSolverVector.h deleted file mode 100644 index ce4d1008..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Core/products/TriangularSolverVector.h +++ /dev/null @@ -1,139 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2010 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_TRIANGULAR_SOLVER_VECTOR_H -#define EIGEN_TRIANGULAR_SOLVER_VECTOR_H - -namespace Eigen { - -namespace internal { - -template -struct triangular_solve_vector -{ - static void run(Index size, const LhsScalar* _lhs, Index lhsStride, RhsScalar* rhs) - { - triangular_solve_vector::run(size, _lhs, lhsStride, rhs); - } -}; - -// forward and backward substitution, row-major, rhs is a vector -template -struct triangular_solve_vector -{ - enum { - IsLower = ((Mode&Lower)==Lower) - }; - static void run(Index size, const LhsScalar* _lhs, Index lhsStride, RhsScalar* rhs) - { - typedef Map, 0, OuterStride<> > LhsMap; - const LhsMap lhs(_lhs,size,size,OuterStride<>(lhsStride)); - typename internal::conditional< - Conjugate, - const CwiseUnaryOp,LhsMap>, - const LhsMap&> - ::type cjLhs(lhs); - static const Index PanelWidth = EIGEN_TUNE_TRIANGULAR_PANEL_WIDTH; - for(Index pi=IsLower ? 0 : size; - IsLower ? pi0; - IsLower ? pi+=PanelWidth : pi-=PanelWidth) - { - Index actualPanelWidth = (std::min)(IsLower ? size - pi : pi, PanelWidth); - - Index r = IsLower ? pi : size - pi; // remaining size - if (r > 0) - { - // let's directly call the low level product function because: - // 1 - it is faster to compile - // 2 - it is slighlty faster at runtime - Index startRow = IsLower ? pi : pi-actualPanelWidth; - Index startCol = IsLower ? 0 : pi; - - general_matrix_vector_product::run( - actualPanelWidth, r, - &lhs.coeffRef(startRow,startCol), lhsStride, - rhs + startCol, 1, - rhs + startRow, 1, - RhsScalar(-1)); - } - - for(Index k=0; k0) - rhs[i] -= (cjLhs.row(i).segment(s,k).transpose().cwiseProduct(Map >(rhs+s,k))).sum(); - - if(!(Mode & UnitDiag)) - rhs[i] /= cjLhs(i,i); - } - } - } -}; - -// forward and backward substitution, column-major, rhs is a vector -template -struct triangular_solve_vector -{ - enum { - IsLower = ((Mode&Lower)==Lower) - }; - static void run(Index size, const LhsScalar* _lhs, Index lhsStride, RhsScalar* rhs) - { - typedef Map, 0, OuterStride<> > LhsMap; - const LhsMap lhs(_lhs,size,size,OuterStride<>(lhsStride)); - typename internal::conditional,LhsMap>, - const LhsMap& - >::type cjLhs(lhs); - static const Index PanelWidth = EIGEN_TUNE_TRIANGULAR_PANEL_WIDTH; - - for(Index pi=IsLower ? 0 : size; - IsLower ? pi0; - IsLower ? pi+=PanelWidth : pi-=PanelWidth) - { - Index actualPanelWidth = (std::min)(IsLower ? size - pi : pi, PanelWidth); - Index startBlock = IsLower ? pi : pi-actualPanelWidth; - Index endBlock = IsLower ? pi + actualPanelWidth : 0; - - for(Index k=0; k0) - Map >(rhs+s,r) -= rhs[i] * cjLhs.col(i).segment(s,r); - } - Index r = IsLower ? size - endBlock : startBlock; // remaining size - if (r > 0) - { - // let's directly call the low level product function because: - // 1 - it is faster to compile - // 2 - it is slighlty faster at runtime - general_matrix_vector_product::run( - r, actualPanelWidth, - &lhs.coeffRef(endBlock,startBlock), lhsStride, - rhs+startBlock, 1, - rhs+endBlock, 1, RhsScalar(-1)); - } - } - } -}; - -} // end namespace internal - -} // end namespace Eigen - -#endif // EIGEN_TRIANGULAR_SOLVER_VECTOR_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/util/BlasUtil.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/util/BlasUtil.h deleted file mode 100644 index a28f16fa..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Core/util/BlasUtil.h +++ /dev/null @@ -1,264 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2009-2010 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_BLASUTIL_H -#define EIGEN_BLASUTIL_H - -// This file contains many lightweight helper classes used to -// implement and control fast level 2 and level 3 BLAS-like routines. - -namespace Eigen { - -namespace internal { - -// forward declarations -template -struct gebp_kernel; - -template -struct gemm_pack_rhs; - -template -struct gemm_pack_lhs; - -template< - typename Index, - typename LhsScalar, int LhsStorageOrder, bool ConjugateLhs, - typename RhsScalar, int RhsStorageOrder, bool ConjugateRhs, - int ResStorageOrder> -struct general_matrix_matrix_product; - -template -struct general_matrix_vector_product; - - -template struct conj_if; - -template<> struct conj_if { - template - inline T operator()(const T& x) { return numext::conj(x); } - template - inline T pconj(const T& x) { return internal::pconj(x); } -}; - -template<> struct conj_if { - template - inline const T& operator()(const T& x) { return x; } - template - inline const T& pconj(const T& x) { return x; } -}; - -template struct conj_helper -{ - EIGEN_STRONG_INLINE Scalar pmadd(const Scalar& x, const Scalar& y, const Scalar& c) const { return internal::pmadd(x,y,c); } - EIGEN_STRONG_INLINE Scalar pmul(const Scalar& x, const Scalar& y) const { return internal::pmul(x,y); } -}; - -template struct conj_helper, std::complex, false,true> -{ - typedef std::complex Scalar; - EIGEN_STRONG_INLINE Scalar pmadd(const Scalar& x, const Scalar& y, const Scalar& c) const - { return c + pmul(x,y); } - - EIGEN_STRONG_INLINE Scalar pmul(const Scalar& x, const Scalar& y) const - { return Scalar(numext::real(x)*numext::real(y) + numext::imag(x)*numext::imag(y), numext::imag(x)*numext::real(y) - numext::real(x)*numext::imag(y)); } -}; - -template struct conj_helper, std::complex, true,false> -{ - typedef std::complex Scalar; - EIGEN_STRONG_INLINE Scalar pmadd(const Scalar& x, const Scalar& y, const Scalar& c) const - { return c + pmul(x,y); } - - EIGEN_STRONG_INLINE Scalar pmul(const Scalar& x, const Scalar& y) const - { return Scalar(numext::real(x)*numext::real(y) + numext::imag(x)*numext::imag(y), numext::real(x)*numext::imag(y) - numext::imag(x)*numext::real(y)); } -}; - -template struct conj_helper, std::complex, true,true> -{ - typedef std::complex Scalar; - EIGEN_STRONG_INLINE Scalar pmadd(const Scalar& x, const Scalar& y, const Scalar& c) const - { return c + pmul(x,y); } - - EIGEN_STRONG_INLINE Scalar pmul(const Scalar& x, const Scalar& y) const - { return Scalar(numext::real(x)*numext::real(y) - numext::imag(x)*numext::imag(y), - numext::real(x)*numext::imag(y) - numext::imag(x)*numext::real(y)); } -}; - -template struct conj_helper, RealScalar, Conj,false> -{ - typedef std::complex Scalar; - EIGEN_STRONG_INLINE Scalar pmadd(const Scalar& x, const RealScalar& y, const Scalar& c) const - { return padd(c, pmul(x,y)); } - EIGEN_STRONG_INLINE Scalar pmul(const Scalar& x, const RealScalar& y) const - { return conj_if()(x)*y; } -}; - -template struct conj_helper, false,Conj> -{ - typedef std::complex Scalar; - EIGEN_STRONG_INLINE Scalar pmadd(const RealScalar& x, const Scalar& y, const Scalar& c) const - { return padd(c, pmul(x,y)); } - EIGEN_STRONG_INLINE Scalar pmul(const RealScalar& x, const Scalar& y) const - { return x*conj_if()(y); } -}; - -template struct get_factor { - static EIGEN_STRONG_INLINE To run(const From& x) { return x; } -}; - -template struct get_factor::Real> { - static EIGEN_STRONG_INLINE typename NumTraits::Real run(const Scalar& x) { return numext::real(x); } -}; - -// Lightweight helper class to access matrix coefficients. -// Yes, this is somehow redundant with Map<>, but this version is much much lighter, -// and so I hope better compilation performance (time and code quality). -template -class blas_data_mapper -{ - public: - blas_data_mapper(Scalar* data, Index stride) : m_data(data), m_stride(stride) {} - EIGEN_STRONG_INLINE Scalar& operator()(Index i, Index j) - { return m_data[StorageOrder==RowMajor ? j + i*m_stride : i + j*m_stride]; } - protected: - Scalar* EIGEN_RESTRICT m_data; - Index m_stride; -}; - -// lightweight helper class to access matrix coefficients (const version) -template -class const_blas_data_mapper -{ - public: - const_blas_data_mapper(const Scalar* data, Index stride) : m_data(data), m_stride(stride) {} - EIGEN_STRONG_INLINE const Scalar& operator()(Index i, Index j) const - { return m_data[StorageOrder==RowMajor ? j + i*m_stride : i + j*m_stride]; } - protected: - const Scalar* EIGEN_RESTRICT m_data; - Index m_stride; -}; - - -/* Helper class to analyze the factors of a Product expression. - * In particular it allows to pop out operator-, scalar multiples, - * and conjugate */ -template struct blas_traits -{ - typedef typename traits::Scalar Scalar; - typedef const XprType& ExtractType; - typedef XprType _ExtractType; - enum { - IsComplex = NumTraits::IsComplex, - IsTransposed = false, - NeedToConjugate = false, - HasUsableDirectAccess = ( (int(XprType::Flags)&DirectAccessBit) - && ( bool(XprType::IsVectorAtCompileTime) - || int(inner_stride_at_compile_time::ret) == 1) - ) ? 1 : 0 - }; - typedef typename conditional::type DirectLinearAccessType; - static inline ExtractType extract(const XprType& x) { return x; } - static inline const Scalar extractScalarFactor(const XprType&) { return Scalar(1); } -}; - -// pop conjugate -template -struct blas_traits, NestedXpr> > - : blas_traits -{ - typedef blas_traits Base; - typedef CwiseUnaryOp, NestedXpr> XprType; - typedef typename Base::ExtractType ExtractType; - - enum { - IsComplex = NumTraits::IsComplex, - NeedToConjugate = Base::NeedToConjugate ? 0 : IsComplex - }; - static inline ExtractType extract(const XprType& x) { return Base::extract(x.nestedExpression()); } - static inline Scalar extractScalarFactor(const XprType& x) { return conj(Base::extractScalarFactor(x.nestedExpression())); } -}; - -// pop scalar multiple -template -struct blas_traits, NestedXpr> > - : blas_traits -{ - typedef blas_traits Base; - typedef CwiseUnaryOp, NestedXpr> XprType; - typedef typename Base::ExtractType ExtractType; - static inline ExtractType extract(const XprType& x) { return Base::extract(x.nestedExpression()); } - static inline Scalar extractScalarFactor(const XprType& x) - { return x.functor().m_other * Base::extractScalarFactor(x.nestedExpression()); } -}; - -// pop opposite -template -struct blas_traits, NestedXpr> > - : blas_traits -{ - typedef blas_traits Base; - typedef CwiseUnaryOp, NestedXpr> XprType; - typedef typename Base::ExtractType ExtractType; - static inline ExtractType extract(const XprType& x) { return Base::extract(x.nestedExpression()); } - static inline Scalar extractScalarFactor(const XprType& x) - { return - Base::extractScalarFactor(x.nestedExpression()); } -}; - -// pop/push transpose -template -struct blas_traits > - : blas_traits -{ - typedef typename NestedXpr::Scalar Scalar; - typedef blas_traits Base; - typedef Transpose XprType; - typedef Transpose ExtractType; // const to get rid of a compile error; anyway blas traits are only used on the RHS - typedef Transpose _ExtractType; - typedef typename conditional::type DirectLinearAccessType; - enum { - IsTransposed = Base::IsTransposed ? 0 : 1 - }; - static inline ExtractType extract(const XprType& x) { return Base::extract(x.nestedExpression()); } - static inline Scalar extractScalarFactor(const XprType& x) { return Base::extractScalarFactor(x.nestedExpression()); } -}; - -template -struct blas_traits - : blas_traits -{}; - -template::HasUsableDirectAccess> -struct extract_data_selector { - static const typename T::Scalar* run(const T& m) - { - return blas_traits::extract(m).data(); - } -}; - -template -struct extract_data_selector { - static typename T::Scalar* run(const T&) { return 0; } -}; - -template const typename T::Scalar* extract_data(const T& m) -{ - return extract_data_selector::run(m); -} - -} // end namespace internal - -} // end namespace Eigen - -#endif // EIGEN_BLASUTIL_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/util/Constants.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/util/Constants.h deleted file mode 100644 index 1e6277c4..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Core/util/Constants.h +++ /dev/null @@ -1,451 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2009 Gael Guennebaud -// Copyright (C) 2007-2009 Benoit Jacob -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_CONSTANTS_H -#define EIGEN_CONSTANTS_H - -namespace Eigen { - -/** This value means that a positive quantity (e.g., a size) is not known at compile-time, and that instead the value is - * stored in some runtime variable. - * - * Changing the value of Dynamic breaks the ABI, as Dynamic is often used as a template parameter for Matrix. - */ -const int Dynamic = -1; - -/** This value means that a signed quantity (e.g., a signed index) is not known at compile-time, and that instead its value - * has to be specified at runtime. - */ -const int DynamicIndex = 0xffffff; - -/** This value means +Infinity; it is currently used only as the p parameter to MatrixBase::lpNorm(). - * The value Infinity there means the L-infinity norm. - */ -const int Infinity = -1; - -/** \defgroup flags Flags - * \ingroup Core_Module - * - * These are the possible bits which can be OR'ed to constitute the flags of a matrix or - * expression. - * - * It is important to note that these flags are a purely compile-time notion. They are a compile-time property of - * an expression type, implemented as enum's. They are not stored in memory at runtime, and they do not incur any - * runtime overhead. - * - * \sa MatrixBase::Flags - */ - -/** \ingroup flags - * - * for a matrix, this means that the storage order is row-major. - * If this bit is not set, the storage order is column-major. - * For an expression, this determines the storage order of - * the matrix created by evaluation of that expression. - * \sa \ref TopicStorageOrders */ -const unsigned int RowMajorBit = 0x1; - -/** \ingroup flags - * - * means the expression should be evaluated by the calling expression */ -const unsigned int EvalBeforeNestingBit = 0x2; - -/** \ingroup flags - * - * means the expression should be evaluated before any assignment */ -const unsigned int EvalBeforeAssigningBit = 0x4; - -/** \ingroup flags - * - * Short version: means the expression might be vectorized - * - * Long version: means that the coefficients can be handled by packets - * and start at a memory location whose alignment meets the requirements - * of the present CPU architecture for optimized packet access. In the fixed-size - * case, there is the additional condition that it be possible to access all the - * coefficients by packets (this implies the requirement that the size be a multiple of 16 bytes, - * and that any nontrivial strides don't break the alignment). In the dynamic-size case, - * there is no such condition on the total size and strides, so it might not be possible to access - * all coeffs by packets. - * - * \note This bit can be set regardless of whether vectorization is actually enabled. - * To check for actual vectorizability, see \a ActualPacketAccessBit. - */ -const unsigned int PacketAccessBit = 0x8; - -#ifdef EIGEN_VECTORIZE -/** \ingroup flags - * - * If vectorization is enabled (EIGEN_VECTORIZE is defined) this constant - * is set to the value \a PacketAccessBit. - * - * If vectorization is not enabled (EIGEN_VECTORIZE is not defined) this constant - * is set to the value 0. - */ -const unsigned int ActualPacketAccessBit = PacketAccessBit; -#else -const unsigned int ActualPacketAccessBit = 0x0; -#endif - -/** \ingroup flags - * - * Short version: means the expression can be seen as 1D vector. - * - * Long version: means that one can access the coefficients - * of this expression by coeff(int), and coeffRef(int) in the case of a lvalue expression. These - * index-based access methods are guaranteed - * to not have to do any runtime computation of a (row, col)-pair from the index, so that it - * is guaranteed that whenever it is available, index-based access is at least as fast as - * (row,col)-based access. Expressions for which that isn't possible don't have the LinearAccessBit. - * - * If both PacketAccessBit and LinearAccessBit are set, then the - * packets of this expression can be accessed by packet(int), and writePacket(int) in the case of a - * lvalue expression. - * - * Typically, all vector expressions have the LinearAccessBit, but there is one exception: - * Product expressions don't have it, because it would be troublesome for vectorization, even when the - * Product is a vector expression. Thus, vector Product expressions allow index-based coefficient access but - * not index-based packet access, so they don't have the LinearAccessBit. - */ -const unsigned int LinearAccessBit = 0x10; - -/** \ingroup flags - * - * Means the expression has a coeffRef() method, i.e. is writable as its individual coefficients are directly addressable. - * This rules out read-only expressions. - * - * Note that DirectAccessBit and LvalueBit are mutually orthogonal, as there are examples of expression having one but note - * the other: - * \li writable expressions that don't have a very simple memory layout as a strided array, have LvalueBit but not DirectAccessBit - * \li Map-to-const expressions, for example Map, have DirectAccessBit but not LvalueBit - * - * Expressions having LvalueBit also have their coeff() method returning a const reference instead of returning a new value. - */ -const unsigned int LvalueBit = 0x20; - -/** \ingroup flags - * - * Means that the underlying array of coefficients can be directly accessed as a plain strided array. The memory layout - * of the array of coefficients must be exactly the natural one suggested by rows(), cols(), - * outerStride(), innerStride(), and the RowMajorBit. This rules out expressions such as Diagonal, whose coefficients, - * though referencable, do not have such a regular memory layout. - * - * See the comment on LvalueBit for an explanation of how LvalueBit and DirectAccessBit are mutually orthogonal. - */ -const unsigned int DirectAccessBit = 0x40; - -/** \ingroup flags - * - * means the first coefficient packet is guaranteed to be aligned */ -const unsigned int AlignedBit = 0x80; - -const unsigned int NestByRefBit = 0x100; - -// list of flags that are inherited by default -const unsigned int HereditaryBits = RowMajorBit - | EvalBeforeNestingBit - | EvalBeforeAssigningBit; - -/** \defgroup enums Enumerations - * \ingroup Core_Module - * - * Various enumerations used in %Eigen. Many of these are used as template parameters. - */ - -/** \ingroup enums - * Enum containing possible values for the \p Mode parameter of - * MatrixBase::selfadjointView() and MatrixBase::triangularView(). */ -enum { - /** View matrix as a lower triangular matrix. */ - Lower=0x1, - /** View matrix as an upper triangular matrix. */ - Upper=0x2, - /** %Matrix has ones on the diagonal; to be used in combination with #Lower or #Upper. */ - UnitDiag=0x4, - /** %Matrix has zeros on the diagonal; to be used in combination with #Lower or #Upper. */ - ZeroDiag=0x8, - /** View matrix as a lower triangular matrix with ones on the diagonal. */ - UnitLower=UnitDiag|Lower, - /** View matrix as an upper triangular matrix with ones on the diagonal. */ - UnitUpper=UnitDiag|Upper, - /** View matrix as a lower triangular matrix with zeros on the diagonal. */ - StrictlyLower=ZeroDiag|Lower, - /** View matrix as an upper triangular matrix with zeros on the diagonal. */ - StrictlyUpper=ZeroDiag|Upper, - /** Used in BandMatrix and SelfAdjointView to indicate that the matrix is self-adjoint. */ - SelfAdjoint=0x10, - /** Used to support symmetric, non-selfadjoint, complex matrices. */ - Symmetric=0x20 -}; - -/** \ingroup enums - * Enum for indicating whether an object is aligned or not. */ -enum { - /** Object is not correctly aligned for vectorization. */ - Unaligned=0, - /** Object is aligned for vectorization. */ - Aligned=1 -}; - -/** \ingroup enums - * Enum used by DenseBase::corner() in Eigen2 compatibility mode. */ -// FIXME after the corner() API change, this was not needed anymore, except by AlignedBox -// TODO: find out what to do with that. Adapt the AlignedBox API ? -enum CornerType { TopLeft, TopRight, BottomLeft, BottomRight }; - -/** \ingroup enums - * Enum containing possible values for the \p Direction parameter of - * Reverse, PartialReduxExpr and VectorwiseOp. */ -enum DirectionType { - /** For Reverse, all columns are reversed; - * for PartialReduxExpr and VectorwiseOp, act on columns. */ - Vertical, - /** For Reverse, all rows are reversed; - * for PartialReduxExpr and VectorwiseOp, act on rows. */ - Horizontal, - /** For Reverse, both rows and columns are reversed; - * not used for PartialReduxExpr and VectorwiseOp. */ - BothDirections -}; - -/** \internal \ingroup enums - * Enum to specify how to traverse the entries of a matrix. */ -enum { - /** \internal Default traversal, no vectorization, no index-based access */ - DefaultTraversal, - /** \internal No vectorization, use index-based access to have only one for loop instead of 2 nested loops */ - LinearTraversal, - /** \internal Equivalent to a slice vectorization for fixed-size matrices having good alignment - * and good size */ - InnerVectorizedTraversal, - /** \internal Vectorization path using a single loop plus scalar loops for the - * unaligned boundaries */ - LinearVectorizedTraversal, - /** \internal Generic vectorization path using one vectorized loop per row/column with some - * scalar loops to handle the unaligned boundaries */ - SliceVectorizedTraversal, - /** \internal Special case to properly handle incompatible scalar types or other defecting cases*/ - InvalidTraversal, - /** \internal Evaluate all entries at once */ - AllAtOnceTraversal -}; - -/** \internal \ingroup enums - * Enum to specify whether to unroll loops when traversing over the entries of a matrix. */ -enum { - /** \internal Do not unroll loops. */ - NoUnrolling, - /** \internal Unroll only the inner loop, but not the outer loop. */ - InnerUnrolling, - /** \internal Unroll both the inner and the outer loop. If there is only one loop, - * because linear traversal is used, then unroll that loop. */ - CompleteUnrolling -}; - -/** \internal \ingroup enums - * Enum to specify whether to use the default (built-in) implementation or the specialization. */ -enum { - Specialized, - BuiltIn -}; - -/** \ingroup enums - * Enum containing possible values for the \p _Options template parameter of - * Matrix, Array and BandMatrix. */ -enum { - /** Storage order is column major (see \ref TopicStorageOrders). */ - ColMajor = 0, - /** Storage order is row major (see \ref TopicStorageOrders). */ - RowMajor = 0x1, // it is only a coincidence that this is equal to RowMajorBit -- don't rely on that - /** Align the matrix itself if it is vectorizable fixed-size */ - AutoAlign = 0, - /** Don't require alignment for the matrix itself (the array of coefficients, if dynamically allocated, may still be requested to be aligned) */ // FIXME --- clarify the situation - DontAlign = 0x2 -}; - -/** \ingroup enums - * Enum for specifying whether to apply or solve on the left or right. */ -enum { - /** Apply transformation on the left. */ - OnTheLeft = 1, - /** Apply transformation on the right. */ - OnTheRight = 2 -}; - -/* the following used to be written as: - * - * struct NoChange_t {}; - * namespace { - * EIGEN_UNUSED NoChange_t NoChange; - * } - * - * on the ground that it feels dangerous to disambiguate overloaded functions on enum/integer types. - * However, this leads to "variable declared but never referenced" warnings on Intel Composer XE, - * and we do not know how to get rid of them (bug 450). - */ - -enum NoChange_t { NoChange }; -enum Sequential_t { Sequential }; -enum Default_t { Default }; - -/** \internal \ingroup enums - * Used in AmbiVector. */ -enum { - IsDense = 0, - IsSparse -}; - -/** \ingroup enums - * Used as template parameter in DenseCoeffBase and MapBase to indicate - * which accessors should be provided. */ -enum AccessorLevels { - /** Read-only access via a member function. */ - ReadOnlyAccessors, - /** Read/write access via member functions. */ - WriteAccessors, - /** Direct read-only access to the coefficients. */ - DirectAccessors, - /** Direct read/write access to the coefficients. */ - DirectWriteAccessors -}; - -/** \ingroup enums - * Enum with options to give to various decompositions. */ -enum DecompositionOptions { - /** \internal Not used (meant for LDLT?). */ - Pivoting = 0x01, - /** \internal Not used (meant for LDLT?). */ - NoPivoting = 0x02, - /** Used in JacobiSVD to indicate that the square matrix U is to be computed. */ - ComputeFullU = 0x04, - /** Used in JacobiSVD to indicate that the thin matrix U is to be computed. */ - ComputeThinU = 0x08, - /** Used in JacobiSVD to indicate that the square matrix V is to be computed. */ - ComputeFullV = 0x10, - /** Used in JacobiSVD to indicate that the thin matrix V is to be computed. */ - ComputeThinV = 0x20, - /** Used in SelfAdjointEigenSolver and GeneralizedSelfAdjointEigenSolver to specify - * that only the eigenvalues are to be computed and not the eigenvectors. */ - EigenvaluesOnly = 0x40, - /** Used in SelfAdjointEigenSolver and GeneralizedSelfAdjointEigenSolver to specify - * that both the eigenvalues and the eigenvectors are to be computed. */ - ComputeEigenvectors = 0x80, - /** \internal */ - EigVecMask = EigenvaluesOnly | ComputeEigenvectors, - /** Used in GeneralizedSelfAdjointEigenSolver to indicate that it should - * solve the generalized eigenproblem \f$ Ax = \lambda B x \f$. */ - Ax_lBx = 0x100, - /** Used in GeneralizedSelfAdjointEigenSolver to indicate that it should - * solve the generalized eigenproblem \f$ ABx = \lambda x \f$. */ - ABx_lx = 0x200, - /** Used in GeneralizedSelfAdjointEigenSolver to indicate that it should - * solve the generalized eigenproblem \f$ BAx = \lambda x \f$. */ - BAx_lx = 0x400, - /** \internal */ - GenEigMask = Ax_lBx | ABx_lx | BAx_lx -}; - -/** \ingroup enums - * Possible values for the \p QRPreconditioner template parameter of JacobiSVD. */ -enum QRPreconditioners { - /** Do not specify what is to be done if the SVD of a non-square matrix is asked for. */ - NoQRPreconditioner, - /** Use a QR decomposition without pivoting as the first step. */ - HouseholderQRPreconditioner, - /** Use a QR decomposition with column pivoting as the first step. */ - ColPivHouseholderQRPreconditioner, - /** Use a QR decomposition with full pivoting as the first step. */ - FullPivHouseholderQRPreconditioner -}; - -#ifdef Success -#error The preprocessor symbol 'Success' is defined, possibly by the X11 header file X.h -#endif - -/** \ingroup enums - * Enum for reporting the status of a computation. */ -enum ComputationInfo { - /** Computation was successful. */ - Success = 0, - /** The provided data did not satisfy the prerequisites. */ - NumericalIssue = 1, - /** Iterative procedure did not converge. */ - NoConvergence = 2, - /** The inputs are invalid, or the algorithm has been improperly called. - * When assertions are enabled, such errors trigger an assert. */ - InvalidInput = 3 -}; - -/** \ingroup enums - * Enum used to specify how a particular transformation is stored in a matrix. - * \sa Transform, Hyperplane::transform(). */ -enum TransformTraits { - /** Transformation is an isometry. */ - Isometry = 0x1, - /** Transformation is an affine transformation stored as a (Dim+1)^2 matrix whose last row is - * assumed to be [0 ... 0 1]. */ - Affine = 0x2, - /** Transformation is an affine transformation stored as a (Dim) x (Dim+1) matrix. */ - AffineCompact = 0x10 | Affine, - /** Transformation is a general projective transformation stored as a (Dim+1)^2 matrix. */ - Projective = 0x20 -}; - -/** \internal \ingroup enums - * Enum used to choose between implementation depending on the computer architecture. */ -namespace Architecture -{ - enum Type { - Generic = 0x0, - SSE = 0x1, - AltiVec = 0x2, -#if defined EIGEN_VECTORIZE_SSE - Target = SSE -#elif defined EIGEN_VECTORIZE_ALTIVEC - Target = AltiVec -#else - Target = Generic -#endif - }; -} - -/** \internal \ingroup enums - * Enum used as template parameter in GeneralProduct. */ -enum { CoeffBasedProductMode, LazyCoeffBasedProductMode, OuterProduct, InnerProduct, GemvProduct, GemmProduct }; - -/** \internal \ingroup enums - * Enum used in experimental parallel implementation. */ -enum Action {GetAction, SetAction}; - -/** The type used to identify a dense storage. */ -struct Dense {}; - -/** The type used to identify a matrix expression */ -struct MatrixXpr {}; - -/** The type used to identify an array expression */ -struct ArrayXpr {}; - -namespace internal { - /** \internal - * Constants for comparison functors - */ - enum ComparisonName { - cmp_EQ = 0, - cmp_LT = 1, - cmp_LE = 2, - cmp_UNORD = 3, - cmp_NEQ = 4 - }; -} - -} // end namespace Eigen - -#endif // EIGEN_CONSTANTS_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/util/DisableStupidWarnings.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/util/DisableStupidWarnings.h deleted file mode 100644 index 6a0bf062..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Core/util/DisableStupidWarnings.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef EIGEN_WARNINGS_DISABLED -#define EIGEN_WARNINGS_DISABLED - -#ifdef _MSC_VER - // 4100 - unreferenced formal parameter (occurred e.g. in aligned_allocator::destroy(pointer p)) - // 4101 - unreferenced local variable - // 4127 - conditional expression is constant - // 4181 - qualifier applied to reference type ignored - // 4211 - nonstandard extension used : redefined extern to static - // 4244 - 'argument' : conversion from 'type1' to 'type2', possible loss of data - // 4273 - QtAlignedMalloc, inconsistent DLL linkage - // 4324 - structure was padded due to declspec(align()) - // 4512 - assignment operator could not be generated - // 4522 - 'class' : multiple assignment operators specified - // 4700 - uninitialized local variable 'xyz' used - // 4717 - 'function' : recursive on all control paths, function will cause runtime stack overflow - #ifndef EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS - #pragma warning( push ) - #endif - #pragma warning( disable : 4100 4101 4127 4181 4211 4244 4273 4324 4512 4522 4700 4717 ) -#elif defined __INTEL_COMPILER - // 2196 - routine is both "inline" and "noinline" ("noinline" assumed) - // ICC 12 generates this warning even without any inline keyword, when defining class methods 'inline' i.e. inside of class body - // typedef that may be a reference type. - // 279 - controlling expression is constant - // ICC 12 generates this warning on assert(constant_expression_depending_on_template_params) and frankly this is a legitimate use case. - #ifndef EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS - #pragma warning push - #endif - #pragma warning disable 2196 279 -#elif defined __clang__ - // -Wconstant-logical-operand - warning: use of logical && with constant operand; switch to bitwise & or remove constant - // this is really a stupid warning as it warns on compile-time expressions involving enums - #ifndef EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS - #pragma clang diagnostic push - #endif - #pragma clang diagnostic ignored "-Wconstant-logical-operand" -#endif - -#endif // not EIGEN_WARNINGS_DISABLED diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/util/ForwardDeclarations.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/util/ForwardDeclarations.h deleted file mode 100644 index f2777200..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Core/util/ForwardDeclarations.h +++ /dev/null @@ -1,302 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2007-2010 Benoit Jacob -// Copyright (C) 2008-2009 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_FORWARDDECLARATIONS_H -#define EIGEN_FORWARDDECLARATIONS_H - -namespace Eigen { -namespace internal { - -template struct traits; - -// here we say once and for all that traits == traits -// When constness must affect traits, it has to be constness on template parameters on which T itself depends. -// For example, traits > != traits >, but -// traits > == traits > -template struct traits : traits {}; - -template struct has_direct_access -{ - enum { ret = (traits::Flags & DirectAccessBit) ? 1 : 0 }; -}; - -template struct accessors_level -{ - enum { has_direct_access = (traits::Flags & DirectAccessBit) ? 1 : 0, - has_write_access = (traits::Flags & LvalueBit) ? 1 : 0, - value = has_direct_access ? (has_write_access ? DirectWriteAccessors : DirectAccessors) - : (has_write_access ? WriteAccessors : ReadOnlyAccessors) - }; -}; - -} // end namespace internal - -template struct NumTraits; - -template struct EigenBase; -template class DenseBase; -template class PlainObjectBase; - - -template::value > -class DenseCoeffsBase; - -template class Matrix; - -template class MatrixBase; -template class ArrayBase; - -template class Flagged; -template class StorageBase > class NoAlias; -template class NestByValue; -template class ForceAlignedAccess; -template class SwapWrapper; - -template class Block; - -template class VectorBlock; -template class Transpose; -template class Conjugate; -template class CwiseNullaryOp; -template class CwiseUnaryOp; -template class CwiseUnaryView; -template class CwiseBinaryOp; -template class SelfCwiseBinaryOp; -template class ProductBase; -template class GeneralProduct; -template class CoeffBasedProduct; - -template class DiagonalBase; -template class DiagonalWrapper; -template class DiagonalMatrix; -template class DiagonalProduct; -template class Diagonal; -template class PermutationMatrix; -template class Transpositions; -template class PermutationBase; -template class TranspositionsBase; -template class PermutationWrapper; -template class TranspositionsWrapper; - -template::has_write_access ? WriteAccessors : ReadOnlyAccessors -> class MapBase; -template class Stride; -template > class Map; - -template class TriangularBase; -template class TriangularView; -template class SelfAdjointView; -template class SparseView; -template class WithFormat; -template struct CommaInitializer; -template class ReturnByValue; -template class ArrayWrapper; -template class MatrixWrapper; - -namespace internal { -template struct solve_retval_base; -template struct solve_retval; -template struct kernel_retval_base; -template struct kernel_retval; -template struct image_retval_base; -template struct image_retval; -} // end namespace internal - -namespace internal { -template class BandMatrix; -} - -namespace internal { -template struct product_type; -} - -template::value> -struct ProductReturnType; - -// this is a workaround for sun CC -template struct LazyProductReturnType; - -namespace internal { - -// Provides scalar/packet-wise product and product with accumulation -// with optional conjugation of the arguments. -template struct conj_helper; - -template struct scalar_sum_op; -template struct scalar_difference_op; -template struct scalar_conj_product_op; -template struct scalar_opposite_op; -template struct scalar_conjugate_op; -template struct scalar_real_op; -template struct scalar_imag_op; -template struct scalar_abs_op; -template struct scalar_abs2_op; -template struct scalar_sqrt_op; -template struct scalar_exp_op; -template struct scalar_log_op; -template struct scalar_cos_op; -template struct scalar_sin_op; -template struct scalar_acos_op; -template struct scalar_asin_op; -template struct scalar_tan_op; -template struct scalar_pow_op; -template struct scalar_inverse_op; -template struct scalar_square_op; -template struct scalar_cube_op; -template struct scalar_cast_op; -template struct scalar_multiple_op; -template struct scalar_quotient1_op; -template struct scalar_min_op; -template struct scalar_max_op; -template struct scalar_random_op; -template struct scalar_add_op; -template struct scalar_constant_op; -template struct scalar_identity_op; - -template struct scalar_product_op; -template struct scalar_multiple2_op; -template struct scalar_quotient_op; - -} // end namespace internal - -struct IOFormat; - -// Array module -template class Array; -template class Select; -template class PartialReduxExpr; -template class VectorwiseOp; -template class Replicate; -template class Reverse; - -template class FullPivLU; -template class PartialPivLU; -namespace internal { -template struct inverse_impl; -} -template class HouseholderQR; -template class ColPivHouseholderQR; -template class FullPivHouseholderQR; -template class JacobiSVD; -template class LLT; -template class LDLT; -template class HouseholderSequence; -template class JacobiRotation; - -// Geometry module: -template class RotationBase; -template class Cross; -template class QuaternionBase; -template class Rotation2D; -template class AngleAxis; -template class Translation; - -// Sparse module: -template class SparseMatrixBase; - -#ifdef EIGEN2_SUPPORT -template class eigen2_RotationBase; -template class eigen2_Cross; -template class eigen2_Quaternion; -template class eigen2_Rotation2D; -template class eigen2_AngleAxis; -template class eigen2_Transform; -template class eigen2_ParametrizedLine; -template class eigen2_Hyperplane; -template class eigen2_Translation; -template class eigen2_Scaling; -#endif - -#if EIGEN2_SUPPORT_STAGE < STAGE20_RESOLVE_API_CONFLICTS -template class Quaternion; -template class Transform; -template class ParametrizedLine; -template class Hyperplane; -template class Scaling; -#endif - -#if EIGEN2_SUPPORT_STAGE > STAGE20_RESOLVE_API_CONFLICTS -template class Quaternion; -template class Transform; -template class ParametrizedLine; -template class Hyperplane; -template class UniformScaling; -template class Homogeneous; -#endif - -// MatrixFunctions module -template struct MatrixExponentialReturnValue; -template class MatrixFunctionReturnValue; -template class MatrixSquareRootReturnValue; -template class MatrixLogarithmReturnValue; -template class MatrixPowerReturnValue; -template class MatrixPowerProduct; - -namespace internal { -template -struct stem_function -{ - typedef std::complex::Real> ComplexScalar; - typedef ComplexScalar type(ComplexScalar, int); -}; -} - - -#ifdef EIGEN2_SUPPORT -template class Cwise; -template class Minor; -template class LU; -template class QR; -template class SVD; -namespace internal { -template struct eigen2_part_return_type; -} -#endif - -} // end namespace Eigen - -#endif // EIGEN_FORWARDDECLARATIONS_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/util/MKL_support.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/util/MKL_support.h deleted file mode 100644 index 1ef3b61d..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Core/util/MKL_support.h +++ /dev/null @@ -1,158 +0,0 @@ -/* - Copyright (c) 2011, Intel Corporation. All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of Intel Corporation nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - ******************************************************************************** - * Content : Eigen bindings to Intel(R) MKL - * Include file with common MKL declarations - ******************************************************************************** -*/ - -#ifndef EIGEN_MKL_SUPPORT_H -#define EIGEN_MKL_SUPPORT_H - -#ifdef EIGEN_USE_MKL_ALL - #ifndef EIGEN_USE_BLAS - #define EIGEN_USE_BLAS - #endif - #ifndef EIGEN_USE_LAPACKE - #define EIGEN_USE_LAPACKE - #endif - #ifndef EIGEN_USE_MKL_VML - #define EIGEN_USE_MKL_VML - #endif -#endif - -#ifdef EIGEN_USE_LAPACKE_STRICT - #define EIGEN_USE_LAPACKE -#endif - -#if defined(EIGEN_USE_BLAS) || defined(EIGEN_USE_LAPACKE) || defined(EIGEN_USE_MKL_VML) - #define EIGEN_USE_MKL -#endif - -#if defined EIGEN_USE_MKL -# include -/*Check IMKL version for compatibility: < 10.3 is not usable with Eigen*/ -# ifndef INTEL_MKL_VERSION -# undef EIGEN_USE_MKL /* INTEL_MKL_VERSION is not even defined on older versions */ -# elif INTEL_MKL_VERSION < 100305 /* the intel-mkl-103-release-notes say this was when the lapacke.h interface was added*/ -# undef EIGEN_USE_MKL -# endif -# ifndef EIGEN_USE_MKL - /*If the MKL version is too old, undef everything*/ -# undef EIGEN_USE_MKL_ALL -# undef EIGEN_USE_BLAS -# undef EIGEN_USE_LAPACKE -# undef EIGEN_USE_MKL_VML -# undef EIGEN_USE_LAPACKE_STRICT -# undef EIGEN_USE_LAPACKE -# endif -#endif - -#if defined EIGEN_USE_MKL -#include -#define EIGEN_MKL_VML_THRESHOLD 128 - -/* MKL_DOMAIN_BLAS, etc are defined only in 10.3 update 7 */ -/* MKL_BLAS, etc are not defined in 11.2 */ -#ifdef MKL_DOMAIN_ALL -#define EIGEN_MKL_DOMAIN_ALL MKL_DOMAIN_ALL -#else -#define EIGEN_MKL_DOMAIN_ALL MKL_ALL -#endif - -#ifdef MKL_DOMAIN_BLAS -#define EIGEN_MKL_DOMAIN_BLAS MKL_DOMAIN_BLAS -#else -#define EIGEN_MKL_DOMAIN_BLAS MKL_BLAS -#endif - -#ifdef MKL_DOMAIN_FFT -#define EIGEN_MKL_DOMAIN_FFT MKL_DOMAIN_FFT -#else -#define EIGEN_MKL_DOMAIN_FFT MKL_FFT -#endif - -#ifdef MKL_DOMAIN_VML -#define EIGEN_MKL_DOMAIN_VML MKL_DOMAIN_VML -#else -#define EIGEN_MKL_DOMAIN_VML MKL_VML -#endif - -#ifdef MKL_DOMAIN_PARDISO -#define EIGEN_MKL_DOMAIN_PARDISO MKL_DOMAIN_PARDISO -#else -#define EIGEN_MKL_DOMAIN_PARDISO MKL_PARDISO -#endif - -namespace Eigen { - -typedef std::complex dcomplex; -typedef std::complex scomplex; - -namespace internal { - -template -static inline void assign_scalar_eig2mkl(MKLType& mklScalar, const EigenType& eigenScalar) { - mklScalar=eigenScalar; -} - -template -static inline void assign_conj_scalar_eig2mkl(MKLType& mklScalar, const EigenType& eigenScalar) { - mklScalar=eigenScalar; -} - -template <> -inline void assign_scalar_eig2mkl(MKL_Complex16& mklScalar, const dcomplex& eigenScalar) { - mklScalar.real=eigenScalar.real(); - mklScalar.imag=eigenScalar.imag(); -} - -template <> -inline void assign_scalar_eig2mkl(MKL_Complex8& mklScalar, const scomplex& eigenScalar) { - mklScalar.real=eigenScalar.real(); - mklScalar.imag=eigenScalar.imag(); -} - -template <> -inline void assign_conj_scalar_eig2mkl(MKL_Complex16& mklScalar, const dcomplex& eigenScalar) { - mklScalar.real=eigenScalar.real(); - mklScalar.imag=-eigenScalar.imag(); -} - -template <> -inline void assign_conj_scalar_eig2mkl(MKL_Complex8& mklScalar, const scomplex& eigenScalar) { - mklScalar.real=eigenScalar.real(); - mklScalar.imag=-eigenScalar.imag(); -} - -} // end namespace internal - -} // end namespace Eigen - -#endif - -#endif // EIGEN_MKL_SUPPORT_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/util/Macros.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/util/Macros.h deleted file mode 100644 index 53fb5fae..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Core/util/Macros.h +++ /dev/null @@ -1,451 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2010 Gael Guennebaud -// Copyright (C) 2006-2008 Benoit Jacob -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_MACROS_H -#define EIGEN_MACROS_H - -#define EIGEN_WORLD_VERSION 3 -#define EIGEN_MAJOR_VERSION 2 -#define EIGEN_MINOR_VERSION 7 - -#define EIGEN_VERSION_AT_LEAST(x,y,z) (EIGEN_WORLD_VERSION>x || (EIGEN_WORLD_VERSION>=x && \ - (EIGEN_MAJOR_VERSION>y || (EIGEN_MAJOR_VERSION>=y && \ - EIGEN_MINOR_VERSION>=z)))) -#ifdef __GNUC__ - #define EIGEN_GNUC_AT_LEAST(x,y) ((__GNUC__==x && __GNUC_MINOR__>=y) || __GNUC__>x) -#else - #define EIGEN_GNUC_AT_LEAST(x,y) 0 -#endif - -#ifdef __GNUC__ - #define EIGEN_GNUC_AT_MOST(x,y) ((__GNUC__==x && __GNUC_MINOR__<=y) || __GNUC__= 1600)) - #define EIGEN_HAVE_RVALUE_REFERENCES -#endif - - -// Cross compiler wrapper around LLVM's __has_builtin -#ifdef __has_builtin -# define EIGEN_HAS_BUILTIN(x) __has_builtin(x) -#else -# define EIGEN_HAS_BUILTIN(x) 0 -#endif - -/** Allows to disable some optimizations which might affect the accuracy of the result. - * Such optimization are enabled by default, and set EIGEN_FAST_MATH to 0 to disable them. - * They currently include: - * - single precision Cwise::sin() and Cwise::cos() when SSE vectorization is enabled. - */ -#ifndef EIGEN_FAST_MATH -#define EIGEN_FAST_MATH 1 -#endif - -#define EIGEN_DEBUG_VAR(x) std::cerr << #x << " = " << x << std::endl; - -// concatenate two tokens -#define EIGEN_CAT2(a,b) a ## b -#define EIGEN_CAT(a,b) EIGEN_CAT2(a,b) - -// convert a token to a string -#define EIGEN_MAKESTRING2(a) #a -#define EIGEN_MAKESTRING(a) EIGEN_MAKESTRING2(a) - -// EIGEN_STRONG_INLINE is a stronger version of the inline, using __forceinline on MSVC, -// but it still doesn't use GCC's always_inline. This is useful in (common) situations where MSVC needs forceinline -// but GCC is still doing fine with just inline. -#if (defined _MSC_VER) || (defined __INTEL_COMPILER) -#define EIGEN_STRONG_INLINE __forceinline -#else -#define EIGEN_STRONG_INLINE inline -#endif - -// EIGEN_ALWAYS_INLINE is the stronget, it has the effect of making the function inline and adding every possible -// attribute to maximize inlining. This should only be used when really necessary: in particular, -// it uses __attribute__((always_inline)) on GCC, which most of the time is useless and can severely harm compile times. -// FIXME with the always_inline attribute, -// gcc 3.4.x reports the following compilation error: -// Eval.h:91: sorry, unimplemented: inlining failed in call to 'const Eigen::Eval Eigen::MatrixBase::eval() const' -// : function body not available -#if EIGEN_GNUC_AT_LEAST(4,0) -#define EIGEN_ALWAYS_INLINE __attribute__((always_inline)) inline -#else -#define EIGEN_ALWAYS_INLINE EIGEN_STRONG_INLINE -#endif - -#if (defined __GNUC__) -#define EIGEN_DONT_INLINE __attribute__((noinline)) -#elif (defined _MSC_VER) -#define EIGEN_DONT_INLINE __declspec(noinline) -#else -#define EIGEN_DONT_INLINE -#endif - -#if (defined __GNUC__) -#define EIGEN_PERMISSIVE_EXPR __extension__ -#else -#define EIGEN_PERMISSIVE_EXPR -#endif - -// this macro allows to get rid of linking errors about multiply defined functions. -// - static is not very good because it prevents definitions from different object files to be merged. -// So static causes the resulting linked executable to be bloated with multiple copies of the same function. -// - inline is not perfect either as it unwantedly hints the compiler toward inlining the function. -#define EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS -#define EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS inline - -#ifdef NDEBUG -# ifndef EIGEN_NO_DEBUG -# define EIGEN_NO_DEBUG -# endif -#endif - -// eigen_plain_assert is where we implement the workaround for the assert() bug in GCC <= 4.3, see bug 89 -#ifdef EIGEN_NO_DEBUG - #define eigen_plain_assert(x) -#else - #if EIGEN_SAFE_TO_USE_STANDARD_ASSERT_MACRO - namespace Eigen { - namespace internal { - inline bool copy_bool(bool b) { return b; } - } - } - #define eigen_plain_assert(x) assert(x) - #else - // work around bug 89 - #include // for abort - #include // for std::cerr - - namespace Eigen { - namespace internal { - // trivial function copying a bool. Must be EIGEN_DONT_INLINE, so we implement it after including Eigen headers. - // see bug 89. - namespace { - EIGEN_DONT_INLINE bool copy_bool(bool b) { return b; } - } - inline void assert_fail(const char *condition, const char *function, const char *file, int line) - { - std::cerr << "assertion failed: " << condition << " in function " << function << " at " << file << ":" << line << std::endl; - abort(); - } - } - } - #define eigen_plain_assert(x) \ - do { \ - if(!Eigen::internal::copy_bool(x)) \ - Eigen::internal::assert_fail(EIGEN_MAKESTRING(x), __PRETTY_FUNCTION__, __FILE__, __LINE__); \ - } while(false) - #endif -#endif - -// eigen_assert can be overridden -#ifndef eigen_assert -#define eigen_assert(x) eigen_plain_assert(x) -#endif - -#ifdef EIGEN_INTERNAL_DEBUGGING -#define eigen_internal_assert(x) eigen_assert(x) -#else -#define eigen_internal_assert(x) -#endif - -#ifdef EIGEN_NO_DEBUG -#define EIGEN_ONLY_USED_FOR_DEBUG(x) (void)x -#else -#define EIGEN_ONLY_USED_FOR_DEBUG(x) -#endif - -#ifndef EIGEN_NO_DEPRECATED_WARNING - #if (defined __GNUC__) - #define EIGEN_DEPRECATED __attribute__((deprecated)) - #elif (defined _MSC_VER) - #define EIGEN_DEPRECATED __declspec(deprecated) - #else - #define EIGEN_DEPRECATED - #endif -#else - #define EIGEN_DEPRECATED -#endif - -#if (defined __GNUC__) -#define EIGEN_UNUSED __attribute__((unused)) -#else -#define EIGEN_UNUSED -#endif - -// Suppresses 'unused variable' warnings. -namespace Eigen { - namespace internal { - template void ignore_unused_variable(const T&) {} - } -} -#define EIGEN_UNUSED_VARIABLE(var) Eigen::internal::ignore_unused_variable(var); - -#if !defined(EIGEN_ASM_COMMENT) - #if (defined __GNUC__) && ( defined(__i386__) || defined(__x86_64__) ) - #define EIGEN_ASM_COMMENT(X) __asm__("#" X) - #else - #define EIGEN_ASM_COMMENT(X) - #endif -#endif - -/* EIGEN_ALIGN_TO_BOUNDARY(n) forces data to be n-byte aligned. This is used to satisfy SIMD requirements. - * However, we do that EVEN if vectorization (EIGEN_VECTORIZE) is disabled, - * so that vectorization doesn't affect binary compatibility. - * - * If we made alignment depend on whether or not EIGEN_VECTORIZE is defined, it would be impossible to link - * vectorized and non-vectorized code. - */ -#if (defined __GNUC__) || (defined __PGI) || (defined __IBMCPP__) || (defined __ARMCC_VERSION) - #define EIGEN_ALIGN_TO_BOUNDARY(n) __attribute__((aligned(n))) -#elif (defined _MSC_VER) - #define EIGEN_ALIGN_TO_BOUNDARY(n) __declspec(align(n)) -#elif (defined __SUNPRO_CC) - // FIXME not sure about this one: - #define EIGEN_ALIGN_TO_BOUNDARY(n) __attribute__((aligned(n))) -#else - #error Please tell me what is the equivalent of __attribute__((aligned(n))) for your compiler -#endif - -#define EIGEN_ALIGN8 EIGEN_ALIGN_TO_BOUNDARY(8) -#define EIGEN_ALIGN16 EIGEN_ALIGN_TO_BOUNDARY(16) - -#if EIGEN_ALIGN_STATICALLY -#define EIGEN_USER_ALIGN_TO_BOUNDARY(n) EIGEN_ALIGN_TO_BOUNDARY(n) -#define EIGEN_USER_ALIGN16 EIGEN_ALIGN16 -#else -#define EIGEN_USER_ALIGN_TO_BOUNDARY(n) -#define EIGEN_USER_ALIGN16 -#endif - -#ifdef EIGEN_DONT_USE_RESTRICT_KEYWORD - #define EIGEN_RESTRICT -#endif -#ifndef EIGEN_RESTRICT - #define EIGEN_RESTRICT __restrict -#endif - -#ifndef EIGEN_STACK_ALLOCATION_LIMIT -// 131072 == 128 KB -#define EIGEN_STACK_ALLOCATION_LIMIT 131072 -#endif - -#ifndef EIGEN_DEFAULT_IO_FORMAT -#ifdef EIGEN_MAKING_DOCS -// format used in Eigen's documentation -// needed to define it here as escaping characters in CMake add_definition's argument seems very problematic. -#define EIGEN_DEFAULT_IO_FORMAT Eigen::IOFormat(3, 0, " ", "\n", "", "") -#else -#define EIGEN_DEFAULT_IO_FORMAT Eigen::IOFormat() -#endif -#endif - -// just an empty macro ! -#define EIGEN_EMPTY - -#if defined(_MSC_VER) && (_MSC_VER < 1900) && (!defined(__INTEL_COMPILER)) -#define EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived) \ - using Base::operator =; -#elif defined(__clang__) // workaround clang bug (see http://forum.kde.org/viewtopic.php?f=74&t=102653) -#define EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived) \ - using Base::operator =; \ - EIGEN_STRONG_INLINE Derived& operator=(const Derived& other) { Base::operator=(other); return *this; } \ - template \ - EIGEN_STRONG_INLINE Derived& operator=(const DenseBase& other) { Base::operator=(other.derived()); return *this; } -#else -#define EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived) \ - using Base::operator =; \ - EIGEN_STRONG_INLINE Derived& operator=(const Derived& other) \ - { \ - Base::operator=(other); \ - return *this; \ - } -#endif - -/** \internal - * \brief Macro to manually inherit assignment operators. - * This is necessary, because the implicitly defined assignment operator gets deleted when a custom operator= is defined. - */ -#define EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Derived) EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived) - -/** -* Just a side note. Commenting within defines works only by documenting -* behind the object (via '!<'). Comments cannot be multi-line and thus -* we have these extra long lines. What is confusing doxygen over here is -* that we use '\' and basically have a bunch of typedefs with their -* documentation in a single line. -**/ - -#define EIGEN_GENERIC_PUBLIC_INTERFACE(Derived) \ - typedef typename Eigen::internal::traits::Scalar Scalar; /*!< \brief Numeric type, e.g. float, double, int or std::complex. */ \ - typedef typename Eigen::NumTraits::Real RealScalar; /*!< \brief The underlying numeric type for composed scalar types. \details In cases where Scalar is e.g. std::complex, T were corresponding to RealScalar. */ \ - typedef typename Base::CoeffReturnType CoeffReturnType; /*!< \brief The return type for coefficient access. \details Depending on whether the object allows direct coefficient access (e.g. for a MatrixXd), this type is either 'const Scalar&' or simply 'Scalar' for objects that do not allow direct coefficient access. */ \ - typedef typename Eigen::internal::nested::type Nested; \ - typedef typename Eigen::internal::traits::StorageKind StorageKind; \ - typedef typename Eigen::internal::traits::Index Index; \ - enum { RowsAtCompileTime = Eigen::internal::traits::RowsAtCompileTime, \ - ColsAtCompileTime = Eigen::internal::traits::ColsAtCompileTime, \ - Flags = Eigen::internal::traits::Flags, \ - CoeffReadCost = Eigen::internal::traits::CoeffReadCost, \ - SizeAtCompileTime = Base::SizeAtCompileTime, \ - MaxSizeAtCompileTime = Base::MaxSizeAtCompileTime, \ - IsVectorAtCompileTime = Base::IsVectorAtCompileTime }; - - -#define EIGEN_DENSE_PUBLIC_INTERFACE(Derived) \ - typedef typename Eigen::internal::traits::Scalar Scalar; /*!< \brief Numeric type, e.g. float, double, int or std::complex. */ \ - typedef typename Eigen::NumTraits::Real RealScalar; /*!< \brief The underlying numeric type for composed scalar types. \details In cases where Scalar is e.g. std::complex, T were corresponding to RealScalar. */ \ - typedef typename Base::PacketScalar PacketScalar; \ - typedef typename Base::CoeffReturnType CoeffReturnType; /*!< \brief The return type for coefficient access. \details Depending on whether the object allows direct coefficient access (e.g. for a MatrixXd), this type is either 'const Scalar&' or simply 'Scalar' for objects that do not allow direct coefficient access. */ \ - typedef typename Eigen::internal::nested::type Nested; \ - typedef typename Eigen::internal::traits::StorageKind StorageKind; \ - typedef typename Eigen::internal::traits::Index Index; \ - enum { RowsAtCompileTime = Eigen::internal::traits::RowsAtCompileTime, \ - ColsAtCompileTime = Eigen::internal::traits::ColsAtCompileTime, \ - MaxRowsAtCompileTime = Eigen::internal::traits::MaxRowsAtCompileTime, \ - MaxColsAtCompileTime = Eigen::internal::traits::MaxColsAtCompileTime, \ - Flags = Eigen::internal::traits::Flags, \ - CoeffReadCost = Eigen::internal::traits::CoeffReadCost, \ - SizeAtCompileTime = Base::SizeAtCompileTime, \ - MaxSizeAtCompileTime = Base::MaxSizeAtCompileTime, \ - IsVectorAtCompileTime = Base::IsVectorAtCompileTime }; \ - using Base::derived; \ - using Base::const_cast_derived; - - -#define EIGEN_PLAIN_ENUM_MIN(a,b) (((int)a <= (int)b) ? (int)a : (int)b) -#define EIGEN_PLAIN_ENUM_MAX(a,b) (((int)a >= (int)b) ? (int)a : (int)b) - -// EIGEN_SIZE_MIN_PREFER_DYNAMIC gives the min between compile-time sizes. 0 has absolute priority, followed by 1, -// followed by Dynamic, followed by other finite values. The reason for giving Dynamic the priority over -// finite values is that min(3, Dynamic) should be Dynamic, since that could be anything between 0 and 3. -#define EIGEN_SIZE_MIN_PREFER_DYNAMIC(a,b) (((int)a == 0 || (int)b == 0) ? 0 \ - : ((int)a == 1 || (int)b == 1) ? 1 \ - : ((int)a == Dynamic || (int)b == Dynamic) ? Dynamic \ - : ((int)a <= (int)b) ? (int)a : (int)b) - -// EIGEN_SIZE_MIN_PREFER_FIXED is a variant of EIGEN_SIZE_MIN_PREFER_DYNAMIC comparing MaxSizes. The difference is that finite values -// now have priority over Dynamic, so that min(3, Dynamic) gives 3. Indeed, whatever the actual value is -// (between 0 and 3), it is not more than 3. -#define EIGEN_SIZE_MIN_PREFER_FIXED(a,b) (((int)a == 0 || (int)b == 0) ? 0 \ - : ((int)a == 1 || (int)b == 1) ? 1 \ - : ((int)a == Dynamic && (int)b == Dynamic) ? Dynamic \ - : ((int)a == Dynamic) ? (int)b \ - : ((int)b == Dynamic) ? (int)a \ - : ((int)a <= (int)b) ? (int)a : (int)b) - -// see EIGEN_SIZE_MIN_PREFER_DYNAMIC. No need for a separate variant for MaxSizes here. -#define EIGEN_SIZE_MAX(a,b) (((int)a == Dynamic || (int)b == Dynamic) ? Dynamic \ - : ((int)a >= (int)b) ? (int)a : (int)b) - -#define EIGEN_ADD_COST(a,b) int(a)==Dynamic || int(b)==Dynamic ? Dynamic : int(a)+int(b) - -#define EIGEN_LOGICAL_XOR(a,b) (((a) || (b)) && !((a) && (b))) - -#define EIGEN_IMPLIES(a,b) (!(a) || (b)) - -#define EIGEN_MAKE_CWISE_BINARY_OP(METHOD,FUNCTOR) \ - template \ - EIGEN_STRONG_INLINE const CwiseBinaryOp, const Derived, const OtherDerived> \ - (METHOD)(const EIGEN_CURRENT_STORAGE_BASE_CLASS &other) const \ - { \ - return CwiseBinaryOp, const Derived, const OtherDerived>(derived(), other.derived()); \ - } - -// the expression type of a cwise product -#define EIGEN_CWISE_PRODUCT_RETURN_TYPE(LHS,RHS) \ - CwiseBinaryOp< \ - internal::scalar_product_op< \ - typename internal::traits::Scalar, \ - typename internal::traits::Scalar \ - >, \ - const LHS, \ - const RHS \ - > - -#endif // EIGEN_MACROS_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/util/Memory.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/util/Memory.h deleted file mode 100644 index b9af5cf8..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Core/util/Memory.h +++ /dev/null @@ -1,977 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2010 Gael Guennebaud -// Copyright (C) 2008-2009 Benoit Jacob -// Copyright (C) 2009 Kenneth Riddile -// Copyright (C) 2010 Hauke Heibel -// Copyright (C) 2010 Thomas Capricelli -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - - -/***************************************************************************** -*** Platform checks for aligned malloc functions *** -*****************************************************************************/ - -#ifndef EIGEN_MEMORY_H -#define EIGEN_MEMORY_H - -#ifndef EIGEN_MALLOC_ALREADY_ALIGNED - -// Try to determine automatically if malloc is already aligned. - -// On 64-bit systems, glibc's malloc returns 16-byte-aligned pointers, see: -// http://www.gnu.org/s/libc/manual/html_node/Aligned-Memory-Blocks.html -// This is true at least since glibc 2.8. -// This leaves the question how to detect 64-bit. According to this document, -// http://gcc.fyxm.net/summit/2003/Porting%20to%2064%20bit.pdf -// page 114, "[The] LP64 model [...] is used by all 64-bit UNIX ports" so it's indeed -// quite safe, at least within the context of glibc, to equate 64-bit with LP64. -#if defined(__GLIBC__) && ((__GLIBC__>=2 && __GLIBC_MINOR__ >= 8) || __GLIBC__>2) \ - && defined(__LP64__) && ! defined( __SANITIZE_ADDRESS__ ) - #define EIGEN_GLIBC_MALLOC_ALREADY_ALIGNED 1 -#else - #define EIGEN_GLIBC_MALLOC_ALREADY_ALIGNED 0 -#endif - -// FreeBSD 6 seems to have 16-byte aligned malloc -// See http://svn.freebsd.org/viewvc/base/stable/6/lib/libc/stdlib/malloc.c?view=markup -// FreeBSD 7 seems to have 16-byte aligned malloc except on ARM and MIPS architectures -// See http://svn.freebsd.org/viewvc/base/stable/7/lib/libc/stdlib/malloc.c?view=markup -#if defined(__FreeBSD__) && !defined(__arm__) && !defined(__mips__) - #define EIGEN_FREEBSD_MALLOC_ALREADY_ALIGNED 1 -#else - #define EIGEN_FREEBSD_MALLOC_ALREADY_ALIGNED 0 -#endif - -#if defined(__APPLE__) \ - || defined(_WIN64) \ - || EIGEN_GLIBC_MALLOC_ALREADY_ALIGNED \ - || EIGEN_FREEBSD_MALLOC_ALREADY_ALIGNED - #define EIGEN_MALLOC_ALREADY_ALIGNED 1 -#else - #define EIGEN_MALLOC_ALREADY_ALIGNED 0 -#endif - -#endif - -// See bug 554 (http://eigen.tuxfamily.org/bz/show_bug.cgi?id=554) -// It seems to be unsafe to check _POSIX_ADVISORY_INFO without including unistd.h first. -// Currently, let's include it only on unix systems: -#if defined(__unix__) || defined(__unix) - #include - #if ((defined __QNXNTO__) || (defined _GNU_SOURCE) || (defined __PGI) || ((defined _XOPEN_SOURCE) && (_XOPEN_SOURCE >= 600))) && (defined _POSIX_ADVISORY_INFO) && (_POSIX_ADVISORY_INFO > 0) - #define EIGEN_HAS_POSIX_MEMALIGN 1 - #endif -#endif - -#ifndef EIGEN_HAS_POSIX_MEMALIGN - #define EIGEN_HAS_POSIX_MEMALIGN 0 -#endif - -#ifdef EIGEN_VECTORIZE_SSE - #define EIGEN_HAS_MM_MALLOC 1 -#else - #define EIGEN_HAS_MM_MALLOC 0 -#endif - -namespace Eigen { - -namespace internal { - -inline void throw_std_bad_alloc() -{ - #ifdef EIGEN_EXCEPTIONS - throw std::bad_alloc(); - #else - std::size_t huge = -1; - new int[huge]; - #endif -} - -/***************************************************************************** -*** Implementation of handmade aligned functions *** -*****************************************************************************/ - -/* ----- Hand made implementations of aligned malloc/free and realloc ----- */ - -/** \internal Like malloc, but the returned pointer is guaranteed to be 16-byte aligned. - * Fast, but wastes 16 additional bytes of memory. Does not throw any exception. - */ -inline void* handmade_aligned_malloc(std::size_t size) -{ - void *original = std::malloc(size+16); - if (original == 0) return 0; - void *aligned = reinterpret_cast((reinterpret_cast(original) & ~(std::size_t(15))) + 16); - *(reinterpret_cast(aligned) - 1) = original; - return aligned; -} - -/** \internal Frees memory allocated with handmade_aligned_malloc */ -inline void handmade_aligned_free(void *ptr) -{ - if (ptr) std::free(*(reinterpret_cast(ptr) - 1)); -} - -/** \internal - * \brief Reallocates aligned memory. - * Since we know that our handmade version is based on std::realloc - * we can use std::realloc to implement efficient reallocation. - */ -inline void* handmade_aligned_realloc(void* ptr, std::size_t size, std::size_t = 0) -{ - if (ptr == 0) return handmade_aligned_malloc(size); - void *original = *(reinterpret_cast(ptr) - 1); - std::ptrdiff_t previous_offset = static_cast(ptr)-static_cast(original); - original = std::realloc(original,size+16); - if (original == 0) return 0; - void *aligned = reinterpret_cast((reinterpret_cast(original) & ~(std::size_t(15))) + 16); - void *previous_aligned = static_cast(original)+previous_offset; - if(aligned!=previous_aligned) - std::memmove(aligned, previous_aligned, size); - - *(reinterpret_cast(aligned) - 1) = original; - return aligned; -} - -/***************************************************************************** -*** Implementation of generic aligned realloc (when no realloc can be used)*** -*****************************************************************************/ - -void* aligned_malloc(std::size_t size); -void aligned_free(void *ptr); - -/** \internal - * \brief Reallocates aligned memory. - * Allows reallocation with aligned ptr types. This implementation will - * always create a new memory chunk and copy the old data. - */ -inline void* generic_aligned_realloc(void* ptr, size_t size, size_t old_size) -{ - if (ptr==0) - return aligned_malloc(size); - - if (size==0) - { - aligned_free(ptr); - return 0; - } - - void* newptr = aligned_malloc(size); - if (newptr == 0) - { - #ifdef EIGEN_HAS_ERRNO - errno = ENOMEM; // according to the standard - #endif - return 0; - } - - if (ptr != 0) - { - std::memcpy(newptr, ptr, (std::min)(size,old_size)); - aligned_free(ptr); - } - - return newptr; -} - -/***************************************************************************** -*** Implementation of portable aligned versions of malloc/free/realloc *** -*****************************************************************************/ - -#ifdef EIGEN_NO_MALLOC -inline void check_that_malloc_is_allowed() -{ - eigen_assert(false && "heap allocation is forbidden (EIGEN_NO_MALLOC is defined)"); -} -#elif defined EIGEN_RUNTIME_NO_MALLOC -inline bool is_malloc_allowed_impl(bool update, bool new_value = false) -{ - static bool value = true; - if (update == 1) - value = new_value; - return value; -} -inline bool is_malloc_allowed() { return is_malloc_allowed_impl(false); } -inline bool set_is_malloc_allowed(bool new_value) { return is_malloc_allowed_impl(true, new_value); } -inline void check_that_malloc_is_allowed() -{ - eigen_assert(is_malloc_allowed() && "heap allocation is forbidden (EIGEN_RUNTIME_NO_MALLOC is defined and g_is_malloc_allowed is false)"); -} -#else -inline void check_that_malloc_is_allowed() -{} -#endif - -/** \internal Allocates \a size bytes. The returned pointer is guaranteed to have 16 bytes alignment. - * On allocation error, the returned pointer is null, and std::bad_alloc is thrown. - */ -inline void* aligned_malloc(size_t size) -{ - check_that_malloc_is_allowed(); - - void *result; - #if !EIGEN_ALIGN - result = std::malloc(size); - #elif EIGEN_MALLOC_ALREADY_ALIGNED - result = std::malloc(size); - #elif EIGEN_HAS_POSIX_MEMALIGN - if(posix_memalign(&result, 16, size)) result = 0; - #elif EIGEN_HAS_MM_MALLOC - result = _mm_malloc(size, 16); - #elif defined(_MSC_VER) && (!defined(_WIN32_WCE)) - result = _aligned_malloc(size, 16); - #else - result = handmade_aligned_malloc(size); - #endif - - if(!result && size) - throw_std_bad_alloc(); - - return result; -} - -/** \internal Frees memory allocated with aligned_malloc. */ -inline void aligned_free(void *ptr) -{ - #if !EIGEN_ALIGN - std::free(ptr); - #elif EIGEN_MALLOC_ALREADY_ALIGNED - std::free(ptr); - #elif EIGEN_HAS_POSIX_MEMALIGN - std::free(ptr); - #elif EIGEN_HAS_MM_MALLOC - _mm_free(ptr); - #elif defined(_MSC_VER) && (!defined(_WIN32_WCE)) - _aligned_free(ptr); - #else - handmade_aligned_free(ptr); - #endif -} - -/** -* \internal -* \brief Reallocates an aligned block of memory. -* \throws std::bad_alloc on allocation failure -**/ -inline void* aligned_realloc(void *ptr, size_t new_size, size_t old_size) -{ - EIGEN_UNUSED_VARIABLE(old_size); - - void *result; -#if !EIGEN_ALIGN - result = std::realloc(ptr,new_size); -#elif EIGEN_MALLOC_ALREADY_ALIGNED - result = std::realloc(ptr,new_size); -#elif EIGEN_HAS_POSIX_MEMALIGN - result = generic_aligned_realloc(ptr,new_size,old_size); -#elif EIGEN_HAS_MM_MALLOC - // The defined(_mm_free) is just here to verify that this MSVC version - // implements _mm_malloc/_mm_free based on the corresponding _aligned_ - // functions. This may not always be the case and we just try to be safe. - #if defined(_MSC_VER) && (!defined(_WIN32_WCE)) && defined(_mm_free) - result = _aligned_realloc(ptr,new_size,16); - #else - result = generic_aligned_realloc(ptr,new_size,old_size); - #endif -#elif defined(_MSC_VER) && (!defined(_WIN32_WCE)) - result = _aligned_realloc(ptr,new_size,16); -#else - result = handmade_aligned_realloc(ptr,new_size,old_size); -#endif - - if (!result && new_size) - throw_std_bad_alloc(); - - return result; -} - -/***************************************************************************** -*** Implementation of conditionally aligned functions *** -*****************************************************************************/ - -/** \internal Allocates \a size bytes. If Align is true, then the returned ptr is 16-byte-aligned. - * On allocation error, the returned pointer is null, and a std::bad_alloc is thrown. - */ -template inline void* conditional_aligned_malloc(size_t size) -{ - return aligned_malloc(size); -} - -template<> inline void* conditional_aligned_malloc(size_t size) -{ - check_that_malloc_is_allowed(); - - void *result = std::malloc(size); - if(!result && size) - throw_std_bad_alloc(); - return result; -} - -/** \internal Frees memory allocated with conditional_aligned_malloc */ -template inline void conditional_aligned_free(void *ptr) -{ - aligned_free(ptr); -} - -template<> inline void conditional_aligned_free(void *ptr) -{ - std::free(ptr); -} - -template inline void* conditional_aligned_realloc(void* ptr, size_t new_size, size_t old_size) -{ - return aligned_realloc(ptr, new_size, old_size); -} - -template<> inline void* conditional_aligned_realloc(void* ptr, size_t new_size, size_t) -{ - return std::realloc(ptr, new_size); -} - -/***************************************************************************** -*** Construction/destruction of array elements *** -*****************************************************************************/ - -/** \internal Constructs the elements of an array. - * The \a size parameter tells on how many objects to call the constructor of T. - */ -template inline T* construct_elements_of_array(T *ptr, size_t size) -{ - for (size_t i=0; i < size; ++i) ::new (ptr + i) T; - return ptr; -} - -/** \internal Destructs the elements of an array. - * The \a size parameters tells on how many objects to call the destructor of T. - */ -template inline void destruct_elements_of_array(T *ptr, size_t size) -{ - // always destruct an array starting from the end. - if(ptr) - while(size) ptr[--size].~T(); -} - -/***************************************************************************** -*** Implementation of aligned new/delete-like functions *** -*****************************************************************************/ - -template -EIGEN_ALWAYS_INLINE void check_size_for_overflow(size_t size) -{ - if(size > size_t(-1) / sizeof(T)) - throw_std_bad_alloc(); -} - -/** \internal Allocates \a size objects of type T. The returned pointer is guaranteed to have 16 bytes alignment. - * On allocation error, the returned pointer is undefined, but a std::bad_alloc is thrown. - * The default constructor of T is called. - */ -template inline T* aligned_new(size_t size) -{ - check_size_for_overflow(size); - T *result = reinterpret_cast(aligned_malloc(sizeof(T)*size)); - return construct_elements_of_array(result, size); -} - -template inline T* conditional_aligned_new(size_t size) -{ - check_size_for_overflow(size); - T *result = reinterpret_cast(conditional_aligned_malloc(sizeof(T)*size)); - return construct_elements_of_array(result, size); -} - -/** \internal Deletes objects constructed with aligned_new - * The \a size parameters tells on how many objects to call the destructor of T. - */ -template inline void aligned_delete(T *ptr, size_t size) -{ - destruct_elements_of_array(ptr, size); - aligned_free(ptr); -} - -/** \internal Deletes objects constructed with conditional_aligned_new - * The \a size parameters tells on how many objects to call the destructor of T. - */ -template inline void conditional_aligned_delete(T *ptr, size_t size) -{ - destruct_elements_of_array(ptr, size); - conditional_aligned_free(ptr); -} - -template inline T* conditional_aligned_realloc_new(T* pts, size_t new_size, size_t old_size) -{ - check_size_for_overflow(new_size); - check_size_for_overflow(old_size); - if(new_size < old_size) - destruct_elements_of_array(pts+new_size, old_size-new_size); - T *result = reinterpret_cast(conditional_aligned_realloc(reinterpret_cast(pts), sizeof(T)*new_size, sizeof(T)*old_size)); - if(new_size > old_size) - construct_elements_of_array(result+old_size, new_size-old_size); - return result; -} - - -template inline T* conditional_aligned_new_auto(size_t size) -{ - if(size==0) - return 0; // short-cut. Also fixes Bug 884 - check_size_for_overflow(size); - T *result = reinterpret_cast(conditional_aligned_malloc(sizeof(T)*size)); - if(NumTraits::RequireInitialization) - construct_elements_of_array(result, size); - return result; -} - -template inline T* conditional_aligned_realloc_new_auto(T* pts, size_t new_size, size_t old_size) -{ - check_size_for_overflow(new_size); - check_size_for_overflow(old_size); - if(NumTraits::RequireInitialization && (new_size < old_size)) - destruct_elements_of_array(pts+new_size, old_size-new_size); - T *result = reinterpret_cast(conditional_aligned_realloc(reinterpret_cast(pts), sizeof(T)*new_size, sizeof(T)*old_size)); - if(NumTraits::RequireInitialization && (new_size > old_size)) - construct_elements_of_array(result+old_size, new_size-old_size); - return result; -} - -template inline void conditional_aligned_delete_auto(T *ptr, size_t size) -{ - if(NumTraits::RequireInitialization) - destruct_elements_of_array(ptr, size); - conditional_aligned_free(ptr); -} - -/****************************************************************************/ - -/** \internal Returns the index of the first element of the array that is well aligned for vectorization. - * - * \param array the address of the start of the array - * \param size the size of the array - * - * \note If no element of the array is well aligned, the size of the array is returned. Typically, - * for example with SSE, "well aligned" means 16-byte-aligned. If vectorization is disabled or if the - * packet size for the given scalar type is 1, then everything is considered well-aligned. - * - * \note If the scalar type is vectorizable, we rely on the following assumptions: sizeof(Scalar) is a - * power of 2, the packet size in bytes is also a power of 2, and is a multiple of sizeof(Scalar). On the - * other hand, we do not assume that the array address is a multiple of sizeof(Scalar), as that fails for - * example with Scalar=double on certain 32-bit platforms, see bug #79. - * - * There is also the variant first_aligned(const MatrixBase&) defined in DenseCoeffsBase.h. - */ -template -static inline Index first_aligned(const Scalar* array, Index size) -{ - static const Index PacketSize = packet_traits::size; - static const Index PacketAlignedMask = PacketSize-1; - - if(PacketSize==1) - { - // Either there is no vectorization, or a packet consists of exactly 1 scalar so that all elements - // of the array have the same alignment. - return 0; - } - else if(size_t(array) & (sizeof(Scalar)-1)) - { - // There is vectorization for this scalar type, but the array is not aligned to the size of a single scalar. - // Consequently, no element of the array is well aligned. - return size; - } - else - { - return std::min( (PacketSize - (Index((size_t(array)/sizeof(Scalar))) & PacketAlignedMask)) - & PacketAlignedMask, size); - } -} - -/** \internal Returns the smallest integer multiple of \a base and greater or equal to \a size - */ -template -inline static Index first_multiple(Index size, Index base) -{ - return ((size+base-1)/base)*base; -} - -// std::copy is much slower than memcpy, so let's introduce a smart_copy which -// use memcpy on trivial types, i.e., on types that does not require an initialization ctor. -template struct smart_copy_helper; - -template void smart_copy(const T* start, const T* end, T* target) -{ - smart_copy_helper::RequireInitialization>::run(start, end, target); -} - -template struct smart_copy_helper { - static inline void run(const T* start, const T* end, T* target) - { memcpy(target, start, std::ptrdiff_t(end)-std::ptrdiff_t(start)); } -}; - -template struct smart_copy_helper { - static inline void run(const T* start, const T* end, T* target) - { std::copy(start, end, target); } -}; - - -/***************************************************************************** -*** Implementation of runtime stack allocation (falling back to malloc) *** -*****************************************************************************/ - -// you can overwrite Eigen's default behavior regarding alloca by defining EIGEN_ALLOCA -// to the appropriate stack allocation function -#ifndef EIGEN_ALLOCA - #if (defined __linux__) || (defined __APPLE__) || (defined alloca) - #define EIGEN_ALLOCA alloca - #elif defined(_MSC_VER) - #define EIGEN_ALLOCA _alloca - #endif -#endif - -// This helper class construct the allocated memory, and takes care of destructing and freeing the handled data -// at destruction time. In practice this helper class is mainly useful to avoid memory leak in case of exceptions. -template class aligned_stack_memory_handler -{ - public: - /* Creates a stack_memory_handler responsible for the buffer \a ptr of size \a size. - * Note that \a ptr can be 0 regardless of the other parameters. - * This constructor takes care of constructing/initializing the elements of the buffer if required by the scalar type T (see NumTraits::RequireInitialization). - * In this case, the buffer elements will also be destructed when this handler will be destructed. - * Finally, if \a dealloc is true, then the pointer \a ptr is freed. - **/ - aligned_stack_memory_handler(T* ptr, size_t size, bool dealloc) - : m_ptr(ptr), m_size(size), m_deallocate(dealloc) - { - if(NumTraits::RequireInitialization && m_ptr) - Eigen::internal::construct_elements_of_array(m_ptr, size); - } - ~aligned_stack_memory_handler() - { - if(NumTraits::RequireInitialization && m_ptr) - Eigen::internal::destruct_elements_of_array(m_ptr, m_size); - if(m_deallocate) - Eigen::internal::aligned_free(m_ptr); - } - protected: - T* m_ptr; - size_t m_size; - bool m_deallocate; -}; - -} // end namespace internal - -/** \internal - * Declares, allocates and construct an aligned buffer named NAME of SIZE elements of type TYPE on the stack - * if SIZE is smaller than EIGEN_STACK_ALLOCATION_LIMIT, and if stack allocation is supported by the platform - * (currently, this is Linux and Visual Studio only). Otherwise the memory is allocated on the heap. - * The allocated buffer is automatically deleted when exiting the scope of this declaration. - * If BUFFER is non null, then the declared variable is simply an alias for BUFFER, and no allocation/deletion occurs. - * Here is an example: - * \code - * { - * ei_declare_aligned_stack_constructed_variable(float,data,size,0); - * // use data[0] to data[size-1] - * } - * \endcode - * The underlying stack allocation function can controlled with the EIGEN_ALLOCA preprocessor token. - */ -#ifdef EIGEN_ALLOCA - - #if defined(__arm__) || defined(_WIN32) - #define EIGEN_ALIGNED_ALLOCA(SIZE) reinterpret_cast((reinterpret_cast(EIGEN_ALLOCA(SIZE+16)) & ~(size_t(15))) + 16) - #else - #define EIGEN_ALIGNED_ALLOCA EIGEN_ALLOCA - #endif - - #define ei_declare_aligned_stack_constructed_variable(TYPE,NAME,SIZE,BUFFER) \ - Eigen::internal::check_size_for_overflow(SIZE); \ - TYPE* NAME = (BUFFER)!=0 ? (BUFFER) \ - : reinterpret_cast( \ - (sizeof(TYPE)*SIZE<=EIGEN_STACK_ALLOCATION_LIMIT) ? EIGEN_ALIGNED_ALLOCA(sizeof(TYPE)*SIZE) \ - : Eigen::internal::aligned_malloc(sizeof(TYPE)*SIZE) ); \ - Eigen::internal::aligned_stack_memory_handler EIGEN_CAT(NAME,_stack_memory_destructor)((BUFFER)==0 ? NAME : 0,SIZE,sizeof(TYPE)*SIZE>EIGEN_STACK_ALLOCATION_LIMIT) - -#else - - #define ei_declare_aligned_stack_constructed_variable(TYPE,NAME,SIZE,BUFFER) \ - Eigen::internal::check_size_for_overflow(SIZE); \ - TYPE* NAME = (BUFFER)!=0 ? BUFFER : reinterpret_cast(Eigen::internal::aligned_malloc(sizeof(TYPE)*SIZE)); \ - Eigen::internal::aligned_stack_memory_handler EIGEN_CAT(NAME,_stack_memory_destructor)((BUFFER)==0 ? NAME : 0,SIZE,true) - -#endif - - -/***************************************************************************** -*** Implementation of EIGEN_MAKE_ALIGNED_OPERATOR_NEW [_IF] *** -*****************************************************************************/ - -#if EIGEN_ALIGN - #ifdef EIGEN_EXCEPTIONS - #define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_NOTHROW(NeedsToAlign) \ - void* operator new(size_t size, const std::nothrow_t&) throw() { \ - try { return Eigen::internal::conditional_aligned_malloc(size); } \ - catch (...) { return 0; } \ - } - #else - #define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_NOTHROW(NeedsToAlign) \ - void* operator new(size_t size, const std::nothrow_t&) throw() { \ - return Eigen::internal::conditional_aligned_malloc(size); \ - } - #endif - - #define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign) \ - void *operator new(size_t size) { \ - return Eigen::internal::conditional_aligned_malloc(size); \ - } \ - void *operator new[](size_t size) { \ - return Eigen::internal::conditional_aligned_malloc(size); \ - } \ - void operator delete(void * ptr) throw() { Eigen::internal::conditional_aligned_free(ptr); } \ - void operator delete[](void * ptr) throw() { Eigen::internal::conditional_aligned_free(ptr); } \ - /* in-place new and delete. since (at least afaik) there is no actual */ \ - /* memory allocated we can safely let the default implementation handle */ \ - /* this particular case. */ \ - static void *operator new(size_t size, void *ptr) { return ::operator new(size,ptr); } \ - static void *operator new[](size_t size, void* ptr) { return ::operator new[](size,ptr); } \ - void operator delete(void * memory, void *ptr) throw() { return ::operator delete(memory,ptr); } \ - void operator delete[](void * memory, void *ptr) throw() { return ::operator delete[](memory,ptr); } \ - /* nothrow-new (returns zero instead of std::bad_alloc) */ \ - EIGEN_MAKE_ALIGNED_OPERATOR_NEW_NOTHROW(NeedsToAlign) \ - void operator delete(void *ptr, const std::nothrow_t&) throw() { \ - Eigen::internal::conditional_aligned_free(ptr); \ - } \ - typedef void eigen_aligned_operator_new_marker_type; -#else - #define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign) -#endif - -#define EIGEN_MAKE_ALIGNED_OPERATOR_NEW EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(true) -#define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(Scalar,Size) \ - EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(bool(((Size)!=Eigen::Dynamic) && ((sizeof(Scalar)*(Size))%16==0))) - -/****************************************************************************/ - -/** \class aligned_allocator -* \ingroup Core_Module -* -* \brief STL compatible allocator to use with with 16 byte aligned types -* -* Example: -* \code -* // Matrix4f requires 16 bytes alignment: -* std::map< int, Matrix4f, std::less, -* aligned_allocator > > my_map_mat4; -* // Vector3f does not require 16 bytes alignment, no need to use Eigen's allocator: -* std::map< int, Vector3f > my_map_vec3; -* \endcode -* -* \sa \ref TopicStlContainers. -*/ -template -class aligned_allocator -{ -public: - typedef size_t size_type; - typedef std::ptrdiff_t difference_type; - typedef T* pointer; - typedef const T* const_pointer; - typedef T& reference; - typedef const T& const_reference; - typedef T value_type; - - template - struct rebind - { - typedef aligned_allocator other; - }; - - pointer address( reference value ) const - { - return &value; - } - - const_pointer address( const_reference value ) const - { - return &value; - } - - aligned_allocator() - { - } - - aligned_allocator( const aligned_allocator& ) - { - } - - template - aligned_allocator( const aligned_allocator& ) - { - } - - ~aligned_allocator() - { - } - - size_type max_size() const - { - return (std::numeric_limits::max)(); - } - - pointer allocate( size_type num, const void* hint = 0 ) - { - EIGEN_UNUSED_VARIABLE(hint); - internal::check_size_for_overflow(num); - return static_cast( internal::aligned_malloc( num * sizeof(T) ) ); - } - - void construct( pointer p, const T& value ) - { - ::new( p ) T( value ); - } - - void destroy( pointer p ) - { - p->~T(); - } - - void deallocate( pointer p, size_type /*num*/ ) - { - internal::aligned_free( p ); - } - - bool operator!=(const aligned_allocator& ) const - { return false; } - - bool operator==(const aligned_allocator& ) const - { return true; } -}; - -//---------- Cache sizes ---------- - -#if !defined(EIGEN_NO_CPUID) -# if defined(__GNUC__) && ( defined(__i386__) || defined(__x86_64__) ) -# if defined(__PIC__) && defined(__i386__) - // Case for x86 with PIC -# define EIGEN_CPUID(abcd,func,id) \ - __asm__ __volatile__ ("xchgl %%ebx, %k1;cpuid; xchgl %%ebx,%k1": "=a" (abcd[0]), "=&r" (abcd[1]), "=c" (abcd[2]), "=d" (abcd[3]) : "a" (func), "c" (id)); -# elif defined(__PIC__) && defined(__x86_64__) - // Case for x64 with PIC. In theory this is only a problem with recent gcc and with medium or large code model, not with the default small code model. - // However, we cannot detect which code model is used, and the xchg overhead is negligible anyway. -# define EIGEN_CPUID(abcd,func,id) \ - __asm__ __volatile__ ("xchg{q}\t{%%}rbx, %q1; cpuid; xchg{q}\t{%%}rbx, %q1": "=a" (abcd[0]), "=&r" (abcd[1]), "=c" (abcd[2]), "=d" (abcd[3]) : "0" (func), "2" (id)); -# else - // Case for x86_64 or x86 w/o PIC -# define EIGEN_CPUID(abcd,func,id) \ - __asm__ __volatile__ ("cpuid": "=a" (abcd[0]), "=b" (abcd[1]), "=c" (abcd[2]), "=d" (abcd[3]) : "0" (func), "2" (id) ); -# endif -# elif defined(_MSC_VER) -# if (_MSC_VER > 1500) && ( defined(_M_IX86) || defined(_M_X64) ) -# define EIGEN_CPUID(abcd,func,id) __cpuidex((int*)abcd,func,id) -# endif -# endif -#endif - -namespace internal { - -#ifdef EIGEN_CPUID - -inline bool cpuid_is_vendor(int abcd[4], const int vendor[3]) -{ - return abcd[1]==vendor[0] && abcd[3]==vendor[1] && abcd[2]==vendor[2]; -} - -inline void queryCacheSizes_intel_direct(int& l1, int& l2, int& l3) -{ - int abcd[4]; - l1 = l2 = l3 = 0; - int cache_id = 0; - int cache_type = 0; - do { - abcd[0] = abcd[1] = abcd[2] = abcd[3] = 0; - EIGEN_CPUID(abcd,0x4,cache_id); - cache_type = (abcd[0] & 0x0F) >> 0; - if(cache_type==1||cache_type==3) // data or unified cache - { - int cache_level = (abcd[0] & 0xE0) >> 5; // A[7:5] - int ways = (abcd[1] & 0xFFC00000) >> 22; // B[31:22] - int partitions = (abcd[1] & 0x003FF000) >> 12; // B[21:12] - int line_size = (abcd[1] & 0x00000FFF) >> 0; // B[11:0] - int sets = (abcd[2]); // C[31:0] - - int cache_size = (ways+1) * (partitions+1) * (line_size+1) * (sets+1); - - switch(cache_level) - { - case 1: l1 = cache_size; break; - case 2: l2 = cache_size; break; - case 3: l3 = cache_size; break; - default: break; - } - } - cache_id++; - } while(cache_type>0 && cache_id<16); -} - -inline void queryCacheSizes_intel_codes(int& l1, int& l2, int& l3) -{ - int abcd[4]; - abcd[0] = abcd[1] = abcd[2] = abcd[3] = 0; - l1 = l2 = l3 = 0; - EIGEN_CPUID(abcd,0x00000002,0); - unsigned char * bytes = reinterpret_cast(abcd)+2; - bool check_for_p2_core2 = false; - for(int i=0; i<14; ++i) - { - switch(bytes[i]) - { - case 0x0A: l1 = 8; break; // 0Ah data L1 cache, 8 KB, 2 ways, 32 byte lines - case 0x0C: l1 = 16; break; // 0Ch data L1 cache, 16 KB, 4 ways, 32 byte lines - case 0x0E: l1 = 24; break; // 0Eh data L1 cache, 24 KB, 6 ways, 64 byte lines - case 0x10: l1 = 16; break; // 10h data L1 cache, 16 KB, 4 ways, 32 byte lines (IA-64) - case 0x15: l1 = 16; break; // 15h code L1 cache, 16 KB, 4 ways, 32 byte lines (IA-64) - case 0x2C: l1 = 32; break; // 2Ch data L1 cache, 32 KB, 8 ways, 64 byte lines - case 0x30: l1 = 32; break; // 30h code L1 cache, 32 KB, 8 ways, 64 byte lines - case 0x60: l1 = 16; break; // 60h data L1 cache, 16 KB, 8 ways, 64 byte lines, sectored - case 0x66: l1 = 8; break; // 66h data L1 cache, 8 KB, 4 ways, 64 byte lines, sectored - case 0x67: l1 = 16; break; // 67h data L1 cache, 16 KB, 4 ways, 64 byte lines, sectored - case 0x68: l1 = 32; break; // 68h data L1 cache, 32 KB, 4 ways, 64 byte lines, sectored - case 0x1A: l2 = 96; break; // code and data L2 cache, 96 KB, 6 ways, 64 byte lines (IA-64) - case 0x22: l3 = 512; break; // code and data L3 cache, 512 KB, 4 ways (!), 64 byte lines, dual-sectored - case 0x23: l3 = 1024; break; // code and data L3 cache, 1024 KB, 8 ways, 64 byte lines, dual-sectored - case 0x25: l3 = 2048; break; // code and data L3 cache, 2048 KB, 8 ways, 64 byte lines, dual-sectored - case 0x29: l3 = 4096; break; // code and data L3 cache, 4096 KB, 8 ways, 64 byte lines, dual-sectored - case 0x39: l2 = 128; break; // code and data L2 cache, 128 KB, 4 ways, 64 byte lines, sectored - case 0x3A: l2 = 192; break; // code and data L2 cache, 192 KB, 6 ways, 64 byte lines, sectored - case 0x3B: l2 = 128; break; // code and data L2 cache, 128 KB, 2 ways, 64 byte lines, sectored - case 0x3C: l2 = 256; break; // code and data L2 cache, 256 KB, 4 ways, 64 byte lines, sectored - case 0x3D: l2 = 384; break; // code and data L2 cache, 384 KB, 6 ways, 64 byte lines, sectored - case 0x3E: l2 = 512; break; // code and data L2 cache, 512 KB, 4 ways, 64 byte lines, sectored - case 0x40: l2 = 0; break; // no integrated L2 cache (P6 core) or L3 cache (P4 core) - case 0x41: l2 = 128; break; // code and data L2 cache, 128 KB, 4 ways, 32 byte lines - case 0x42: l2 = 256; break; // code and data L2 cache, 256 KB, 4 ways, 32 byte lines - case 0x43: l2 = 512; break; // code and data L2 cache, 512 KB, 4 ways, 32 byte lines - case 0x44: l2 = 1024; break; // code and data L2 cache, 1024 KB, 4 ways, 32 byte lines - case 0x45: l2 = 2048; break; // code and data L2 cache, 2048 KB, 4 ways, 32 byte lines - case 0x46: l3 = 4096; break; // code and data L3 cache, 4096 KB, 4 ways, 64 byte lines - case 0x47: l3 = 8192; break; // code and data L3 cache, 8192 KB, 8 ways, 64 byte lines - case 0x48: l2 = 3072; break; // code and data L2 cache, 3072 KB, 12 ways, 64 byte lines - case 0x49: if(l2!=0) l3 = 4096; else {check_for_p2_core2=true; l3 = l2 = 4096;} break;// code and data L3 cache, 4096 KB, 16 ways, 64 byte lines (P4) or L2 for core2 - case 0x4A: l3 = 6144; break; // code and data L3 cache, 6144 KB, 12 ways, 64 byte lines - case 0x4B: l3 = 8192; break; // code and data L3 cache, 8192 KB, 16 ways, 64 byte lines - case 0x4C: l3 = 12288; break; // code and data L3 cache, 12288 KB, 12 ways, 64 byte lines - case 0x4D: l3 = 16384; break; // code and data L3 cache, 16384 KB, 16 ways, 64 byte lines - case 0x4E: l2 = 6144; break; // code and data L2 cache, 6144 KB, 24 ways, 64 byte lines - case 0x78: l2 = 1024; break; // code and data L2 cache, 1024 KB, 4 ways, 64 byte lines - case 0x79: l2 = 128; break; // code and data L2 cache, 128 KB, 8 ways, 64 byte lines, dual-sectored - case 0x7A: l2 = 256; break; // code and data L2 cache, 256 KB, 8 ways, 64 byte lines, dual-sectored - case 0x7B: l2 = 512; break; // code and data L2 cache, 512 KB, 8 ways, 64 byte lines, dual-sectored - case 0x7C: l2 = 1024; break; // code and data L2 cache, 1024 KB, 8 ways, 64 byte lines, dual-sectored - case 0x7D: l2 = 2048; break; // code and data L2 cache, 2048 KB, 8 ways, 64 byte lines - case 0x7E: l2 = 256; break; // code and data L2 cache, 256 KB, 8 ways, 128 byte lines, sect. (IA-64) - case 0x7F: l2 = 512; break; // code and data L2 cache, 512 KB, 2 ways, 64 byte lines - case 0x80: l2 = 512; break; // code and data L2 cache, 512 KB, 8 ways, 64 byte lines - case 0x81: l2 = 128; break; // code and data L2 cache, 128 KB, 8 ways, 32 byte lines - case 0x82: l2 = 256; break; // code and data L2 cache, 256 KB, 8 ways, 32 byte lines - case 0x83: l2 = 512; break; // code and data L2 cache, 512 KB, 8 ways, 32 byte lines - case 0x84: l2 = 1024; break; // code and data L2 cache, 1024 KB, 8 ways, 32 byte lines - case 0x85: l2 = 2048; break; // code and data L2 cache, 2048 KB, 8 ways, 32 byte lines - case 0x86: l2 = 512; break; // code and data L2 cache, 512 KB, 4 ways, 64 byte lines - case 0x87: l2 = 1024; break; // code and data L2 cache, 1024 KB, 8 ways, 64 byte lines - case 0x88: l3 = 2048; break; // code and data L3 cache, 2048 KB, 4 ways, 64 byte lines (IA-64) - case 0x89: l3 = 4096; break; // code and data L3 cache, 4096 KB, 4 ways, 64 byte lines (IA-64) - case 0x8A: l3 = 8192; break; // code and data L3 cache, 8192 KB, 4 ways, 64 byte lines (IA-64) - case 0x8D: l3 = 3072; break; // code and data L3 cache, 3072 KB, 12 ways, 128 byte lines (IA-64) - - default: break; - } - } - if(check_for_p2_core2 && l2 == l3) - l3 = 0; - l1 *= 1024; - l2 *= 1024; - l3 *= 1024; -} - -inline void queryCacheSizes_intel(int& l1, int& l2, int& l3, int max_std_funcs) -{ - if(max_std_funcs>=4) - queryCacheSizes_intel_direct(l1,l2,l3); - else - queryCacheSizes_intel_codes(l1,l2,l3); -} - -inline void queryCacheSizes_amd(int& l1, int& l2, int& l3) -{ - int abcd[4]; - abcd[0] = abcd[1] = abcd[2] = abcd[3] = 0; - EIGEN_CPUID(abcd,0x80000005,0); - l1 = (abcd[2] >> 24) * 1024; // C[31:24] = L1 size in KB - abcd[0] = abcd[1] = abcd[2] = abcd[3] = 0; - EIGEN_CPUID(abcd,0x80000006,0); - l2 = (abcd[2] >> 16) * 1024; // C[31;16] = l2 cache size in KB - l3 = ((abcd[3] & 0xFFFC000) >> 18) * 512 * 1024; // D[31;18] = l3 cache size in 512KB -} -#endif - -/** \internal - * Queries and returns the cache sizes in Bytes of the L1, L2, and L3 data caches respectively */ -inline void queryCacheSizes(int& l1, int& l2, int& l3) -{ - #ifdef EIGEN_CPUID - int abcd[4]; - const int GenuineIntel[] = {0x756e6547, 0x49656e69, 0x6c65746e}; - const int AuthenticAMD[] = {0x68747541, 0x69746e65, 0x444d4163}; - const int AMDisbetter_[] = {0x69444d41, 0x74656273, 0x21726574}; // "AMDisbetter!" - - // identify the CPU vendor - EIGEN_CPUID(abcd,0x0,0); - int max_std_funcs = abcd[1]; - if(cpuid_is_vendor(abcd,GenuineIntel)) - queryCacheSizes_intel(l1,l2,l3,max_std_funcs); - else if(cpuid_is_vendor(abcd,AuthenticAMD) || cpuid_is_vendor(abcd,AMDisbetter_)) - queryCacheSizes_amd(l1,l2,l3); - else - // by default let's use Intel's API - queryCacheSizes_intel(l1,l2,l3,max_std_funcs); - - // here is the list of other vendors: -// ||cpuid_is_vendor(abcd,"VIA VIA VIA ") -// ||cpuid_is_vendor(abcd,"CyrixInstead") -// ||cpuid_is_vendor(abcd,"CentaurHauls") -// ||cpuid_is_vendor(abcd,"GenuineTMx86") -// ||cpuid_is_vendor(abcd,"TransmetaCPU") -// ||cpuid_is_vendor(abcd,"RiseRiseRise") -// ||cpuid_is_vendor(abcd,"Geode by NSC") -// ||cpuid_is_vendor(abcd,"SiS SiS SiS ") -// ||cpuid_is_vendor(abcd,"UMC UMC UMC ") -// ||cpuid_is_vendor(abcd,"NexGenDriven") - #else - l1 = l2 = l3 = -1; - #endif -} - -/** \internal - * \returns the size in Bytes of the L1 data cache */ -inline int queryL1CacheSize() -{ - int l1(-1), l2, l3; - queryCacheSizes(l1,l2,l3); - return l1; -} - -/** \internal - * \returns the size in Bytes of the L2 or L3 cache if this later is present */ -inline int queryTopLevelCacheSize() -{ - int l1, l2(-1), l3(-1); - queryCacheSizes(l1,l2,l3); - return (std::max)(l2,l3); -} - -} // end namespace internal - -} // end namespace Eigen - -#endif // EIGEN_MEMORY_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/util/Meta.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/util/Meta.h deleted file mode 100644 index 71d58710..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Core/util/Meta.h +++ /dev/null @@ -1,243 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2009 Gael Guennebaud -// Copyright (C) 2006-2008 Benoit Jacob -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_META_H -#define EIGEN_META_H - -namespace Eigen { - -namespace internal { - -/** \internal - * \file Meta.h - * This file contains generic metaprogramming classes which are not specifically related to Eigen. - * \note In case you wonder, yes we're aware that Boost already provides all these features, - * we however don't want to add a dependency to Boost. - */ - -struct true_type { enum { value = 1 }; }; -struct false_type { enum { value = 0 }; }; - -template -struct conditional { typedef Then type; }; - -template -struct conditional { typedef Else type; }; - -template struct is_same { enum { value = 0 }; }; -template struct is_same { enum { value = 1 }; }; - -template struct remove_reference { typedef T type; }; -template struct remove_reference { typedef T type; }; - -template struct remove_pointer { typedef T type; }; -template struct remove_pointer { typedef T type; }; -template struct remove_pointer { typedef T type; }; - -template struct remove_const { typedef T type; }; -template struct remove_const { typedef T type; }; -template struct remove_const { typedef T type[]; }; -template struct remove_const { typedef T type[Size]; }; - -template struct remove_all { typedef T type; }; -template struct remove_all { typedef typename remove_all::type type; }; -template struct remove_all { typedef typename remove_all::type type; }; -template struct remove_all { typedef typename remove_all::type type; }; -template struct remove_all { typedef typename remove_all::type type; }; -template struct remove_all { typedef typename remove_all::type type; }; - -template struct is_arithmetic { enum { value = false }; }; -template<> struct is_arithmetic { enum { value = true }; }; -template<> struct is_arithmetic { enum { value = true }; }; -template<> struct is_arithmetic { enum { value = true }; }; -template<> struct is_arithmetic { enum { value = true }; }; -template<> struct is_arithmetic { enum { value = true }; }; -template<> struct is_arithmetic { enum { value = true }; }; -template<> struct is_arithmetic { enum { value = true }; }; -template<> struct is_arithmetic { enum { value = true }; }; -template<> struct is_arithmetic{ enum { value = true }; }; -template<> struct is_arithmetic { enum { value = true }; }; -template<> struct is_arithmetic { enum { value = true }; }; -template<> struct is_arithmetic { enum { value = true }; }; -template<> struct is_arithmetic { enum { value = true }; }; - -template struct add_const { typedef const T type; }; -template struct add_const { typedef T& type; }; - -template struct is_const { enum { value = 0 }; }; -template struct is_const { enum { value = 1 }; }; - -template struct add_const_on_value_type { typedef const T type; }; -template struct add_const_on_value_type { typedef T const& type; }; -template struct add_const_on_value_type { typedef T const* type; }; -template struct add_const_on_value_type { typedef T const* const type; }; -template struct add_const_on_value_type { typedef T const* const type; }; - -/** \internal Allows to enable/disable an overload - * according to a compile time condition. - */ -template struct enable_if; - -template struct enable_if -{ typedef T type; }; - - - -/** \internal - * A base class do disable default copy ctor and copy assignement operator. - */ -class noncopyable -{ - noncopyable(const noncopyable&); - const noncopyable& operator=(const noncopyable&); -protected: - noncopyable() {} - ~noncopyable() {} -}; - - -/** \internal - * Convenient struct to get the result type of a unary or binary functor. - * - * It supports both the current STL mechanism (using the result_type member) as well as - * upcoming next STL generation (using a templated result member). - * If none of these members is provided, then the type of the first argument is returned. FIXME, that behavior is a pretty bad hack. - */ -template struct result_of {}; - -struct has_none {int a[1];}; -struct has_std_result_type {int a[2];}; -struct has_tr1_result {int a[3];}; - -template -struct unary_result_of_select {typedef ArgType type;}; - -template -struct unary_result_of_select {typedef typename Func::result_type type;}; - -template -struct unary_result_of_select {typedef typename Func::template result::type type;}; - -template -struct result_of { - template - static has_std_result_type testFunctor(T const *, typename T::result_type const * = 0); - template - static has_tr1_result testFunctor(T const *, typename T::template result::type const * = 0); - static has_none testFunctor(...); - - // note that the following indirection is needed for gcc-3.3 - enum {FunctorType = sizeof(testFunctor(static_cast(0)))}; - typedef typename unary_result_of_select::type type; -}; - -template -struct binary_result_of_select {typedef ArgType0 type;}; - -template -struct binary_result_of_select -{typedef typename Func::result_type type;}; - -template -struct binary_result_of_select -{typedef typename Func::template result::type type;}; - -template -struct result_of { - template - static has_std_result_type testFunctor(T const *, typename T::result_type const * = 0); - template - static has_tr1_result testFunctor(T const *, typename T::template result::type const * = 0); - static has_none testFunctor(...); - - // note that the following indirection is needed for gcc-3.3 - enum {FunctorType = sizeof(testFunctor(static_cast(0)))}; - typedef typename binary_result_of_select::type type; -}; - -/** \internal In short, it computes int(sqrt(\a Y)) with \a Y an integer. - * Usage example: \code meta_sqrt<1023>::ret \endcode - */ -template Y))) > - // use ?: instead of || just to shut up a stupid gcc 4.3 warning -class meta_sqrt -{ - enum { - MidX = (InfX+SupX)/2, - TakeInf = MidX*MidX > Y ? 1 : 0, - NewInf = int(TakeInf) ? InfX : int(MidX), - NewSup = int(TakeInf) ? int(MidX) : SupX - }; - public: - enum { ret = meta_sqrt::ret }; -}; - -template -class meta_sqrt { public: enum { ret = (SupX*SupX <= Y) ? SupX : InfX }; }; - -/** \internal determines whether the product of two numeric types is allowed and what the return type is */ -template struct scalar_product_traits -{ - enum { Defined = 0 }; -}; - -template struct scalar_product_traits -{ - enum { - // Cost = NumTraits::MulCost, - Defined = 1 - }; - typedef T ReturnType; -}; - -template struct scalar_product_traits > -{ - enum { - // Cost = 2*NumTraits::MulCost, - Defined = 1 - }; - typedef std::complex ReturnType; -}; - -template struct scalar_product_traits, T> -{ - enum { - // Cost = 2*NumTraits::MulCost, - Defined = 1 - }; - typedef std::complex ReturnType; -}; - -// FIXME quick workaround around current limitation of result_of -// template -// struct result_of(ArgType0,ArgType1)> { -// typedef typename scalar_product_traits::type, typename remove_all::type>::ReturnType type; -// }; - -template struct is_diagonal -{ enum { ret = false }; }; - -template struct is_diagonal > -{ enum { ret = true }; }; - -template struct is_diagonal > -{ enum { ret = true }; }; - -template struct is_diagonal > -{ enum { ret = true }; }; - -} // end namespace internal - -} // end namespace Eigen - -#endif // EIGEN_META_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/util/NonMPL2.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/util/NonMPL2.h deleted file mode 100644 index 1af67cf1..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Core/util/NonMPL2.h +++ /dev/null @@ -1,3 +0,0 @@ -#ifdef EIGEN_MPL2_ONLY -#error Including non-MPL2 code in EIGEN_MPL2_ONLY mode -#endif diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/util/ReenableStupidWarnings.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/util/ReenableStupidWarnings.h deleted file mode 100644 index 5ddfbd4a..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Core/util/ReenableStupidWarnings.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifdef EIGEN_WARNINGS_DISABLED -#undef EIGEN_WARNINGS_DISABLED - -#ifndef EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS - #ifdef _MSC_VER - #pragma warning( pop ) - #elif defined __INTEL_COMPILER - #pragma warning pop - #elif defined __clang__ - #pragma clang diagnostic pop - #endif -#endif - -#endif // EIGEN_WARNINGS_DISABLED diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/util/StaticAssert.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/util/StaticAssert.h deleted file mode 100644 index bac5d9fe..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Core/util/StaticAssert.h +++ /dev/null @@ -1,208 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud -// Copyright (C) 2008 Benoit Jacob -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_STATIC_ASSERT_H -#define EIGEN_STATIC_ASSERT_H - -/* Some notes on Eigen's static assertion mechanism: - * - * - in EIGEN_STATIC_ASSERT(CONDITION,MSG) the parameter CONDITION must be a compile time boolean - * expression, and MSG an enum listed in struct internal::static_assertion - * - * - define EIGEN_NO_STATIC_ASSERT to disable them (and save compilation time) - * in that case, the static assertion is converted to the following runtime assert: - * eigen_assert(CONDITION && "MSG") - * - * - currently EIGEN_STATIC_ASSERT can only be used in function scope - * - */ - -#ifndef EIGEN_NO_STATIC_ASSERT - - #if defined(__GXX_EXPERIMENTAL_CXX0X__) || (defined(_MSC_VER) && (_MSC_VER >= 1600)) - - // if native static_assert is enabled, let's use it - #define EIGEN_STATIC_ASSERT(X,MSG) static_assert(X,#MSG); - - #else // not CXX0X - - namespace Eigen { - - namespace internal { - - template - struct static_assertion {}; - - template<> - struct static_assertion - { - enum { - YOU_TRIED_CALLING_A_VECTOR_METHOD_ON_A_MATRIX, - YOU_MIXED_VECTORS_OF_DIFFERENT_SIZES, - YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES, - THIS_METHOD_IS_ONLY_FOR_VECTORS_OF_A_SPECIFIC_SIZE, - THIS_METHOD_IS_ONLY_FOR_MATRICES_OF_A_SPECIFIC_SIZE, - THIS_METHOD_IS_ONLY_FOR_OBJECTS_OF_A_SPECIFIC_SIZE, - YOU_MADE_A_PROGRAMMING_MISTAKE, - EIGEN_INTERNAL_ERROR_PLEASE_FILE_A_BUG_REPORT, - EIGEN_INTERNAL_COMPILATION_ERROR_OR_YOU_MADE_A_PROGRAMMING_MISTAKE, - YOU_CALLED_A_FIXED_SIZE_METHOD_ON_A_DYNAMIC_SIZE_MATRIX_OR_VECTOR, - YOU_CALLED_A_DYNAMIC_SIZE_METHOD_ON_A_FIXED_SIZE_MATRIX_OR_VECTOR, - UNALIGNED_LOAD_AND_STORE_OPERATIONS_UNIMPLEMENTED_ON_ALTIVEC, - THIS_FUNCTION_IS_NOT_FOR_INTEGER_NUMERIC_TYPES, - FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED, - NUMERIC_TYPE_MUST_BE_REAL, - COEFFICIENT_WRITE_ACCESS_TO_SELFADJOINT_NOT_SUPPORTED, - WRITING_TO_TRIANGULAR_PART_WITH_UNIT_DIAGONAL_IS_NOT_SUPPORTED, - THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE, - INVALID_MATRIX_PRODUCT, - INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS, - INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION, - YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY, - THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES, - THIS_METHOD_IS_ONLY_FOR_ROW_MAJOR_MATRICES, - INVALID_MATRIX_TEMPLATE_PARAMETERS, - INVALID_MATRIXBASE_TEMPLATE_PARAMETERS, - BOTH_MATRICES_MUST_HAVE_THE_SAME_STORAGE_ORDER, - THIS_METHOD_IS_ONLY_FOR_DIAGONAL_MATRIX, - THE_MATRIX_OR_EXPRESSION_THAT_YOU_PASSED_DOES_NOT_HAVE_THE_EXPECTED_TYPE, - THIS_METHOD_IS_ONLY_FOR_EXPRESSIONS_WITH_DIRECT_MEMORY_ACCESS_SUCH_AS_MAP_OR_PLAIN_MATRICES, - YOU_ALREADY_SPECIFIED_THIS_STRIDE, - INVALID_STORAGE_ORDER_FOR_THIS_VECTOR_EXPRESSION, - THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD, - PACKET_ACCESS_REQUIRES_TO_HAVE_INNER_STRIDE_FIXED_TO_1, - THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS, - YOU_CANNOT_MIX_ARRAYS_AND_MATRICES, - YOU_PERFORMED_AN_INVALID_TRANSFORMATION_CONVERSION, - THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY, - YOU_ARE_TRYING_TO_USE_AN_INDEX_BASED_ACCESSOR_ON_AN_EXPRESSION_THAT_DOES_NOT_SUPPORT_THAT, - THIS_METHOD_IS_ONLY_FOR_1x1_EXPRESSIONS, - THIS_METHOD_IS_ONLY_FOR_EXPRESSIONS_OF_BOOL, - THIS_METHOD_IS_ONLY_FOR_ARRAYS_NOT_MATRICES, - YOU_PASSED_A_ROW_VECTOR_BUT_A_COLUMN_VECTOR_WAS_EXPECTED, - YOU_PASSED_A_COLUMN_VECTOR_BUT_A_ROW_VECTOR_WAS_EXPECTED, - THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE, - THE_STORAGE_ORDER_OF_BOTH_SIDES_MUST_MATCH, - OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG, - IMPLICIT_CONVERSION_TO_SCALAR_IS_FOR_INNER_PRODUCT_ONLY, - STORAGE_LAYOUT_DOES_NOT_MATCH - }; - }; - - } // end namespace internal - - } // end namespace Eigen - - // Specialized implementation for MSVC to avoid "conditional - // expression is constant" warnings. This implementation doesn't - // appear to work under GCC, hence the multiple implementations. - #ifdef _MSC_VER - - #define EIGEN_STATIC_ASSERT(CONDITION,MSG) \ - {Eigen::internal::static_assertion::MSG;} - - #else - - #define EIGEN_STATIC_ASSERT(CONDITION,MSG) \ - if (Eigen::internal::static_assertion::MSG) {} - - #endif - - #endif // not CXX0X - -#else // EIGEN_NO_STATIC_ASSERT - - #define EIGEN_STATIC_ASSERT(CONDITION,MSG) eigen_assert((CONDITION) && #MSG); - -#endif // EIGEN_NO_STATIC_ASSERT - - -// static assertion failing if the type \a TYPE is not a vector type -#define EIGEN_STATIC_ASSERT_VECTOR_ONLY(TYPE) \ - EIGEN_STATIC_ASSERT(TYPE::IsVectorAtCompileTime, \ - YOU_TRIED_CALLING_A_VECTOR_METHOD_ON_A_MATRIX) - -// static assertion failing if the type \a TYPE is not fixed-size -#define EIGEN_STATIC_ASSERT_FIXED_SIZE(TYPE) \ - EIGEN_STATIC_ASSERT(TYPE::SizeAtCompileTime!=Eigen::Dynamic, \ - YOU_CALLED_A_FIXED_SIZE_METHOD_ON_A_DYNAMIC_SIZE_MATRIX_OR_VECTOR) - -// static assertion failing if the type \a TYPE is not dynamic-size -#define EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(TYPE) \ - EIGEN_STATIC_ASSERT(TYPE::SizeAtCompileTime==Eigen::Dynamic, \ - YOU_CALLED_A_DYNAMIC_SIZE_METHOD_ON_A_FIXED_SIZE_MATRIX_OR_VECTOR) - -// static assertion failing if the type \a TYPE is not a vector type of the given size -#define EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(TYPE, SIZE) \ - EIGEN_STATIC_ASSERT(TYPE::IsVectorAtCompileTime && TYPE::SizeAtCompileTime==SIZE, \ - THIS_METHOD_IS_ONLY_FOR_VECTORS_OF_A_SPECIFIC_SIZE) - -// static assertion failing if the type \a TYPE is not a vector type of the given size -#define EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(TYPE, ROWS, COLS) \ - EIGEN_STATIC_ASSERT(TYPE::RowsAtCompileTime==ROWS && TYPE::ColsAtCompileTime==COLS, \ - THIS_METHOD_IS_ONLY_FOR_MATRICES_OF_A_SPECIFIC_SIZE) - -// static assertion failing if the two vector expression types are not compatible (same fixed-size or dynamic size) -#define EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(TYPE0,TYPE1) \ - EIGEN_STATIC_ASSERT( \ - (int(TYPE0::SizeAtCompileTime)==Eigen::Dynamic \ - || int(TYPE1::SizeAtCompileTime)==Eigen::Dynamic \ - || int(TYPE0::SizeAtCompileTime)==int(TYPE1::SizeAtCompileTime)),\ - YOU_MIXED_VECTORS_OF_DIFFERENT_SIZES) - -#define EIGEN_PREDICATE_SAME_MATRIX_SIZE(TYPE0,TYPE1) \ - ( \ - (int(TYPE0::SizeAtCompileTime)==0 && int(TYPE1::SizeAtCompileTime)==0) \ - || (\ - (int(TYPE0::RowsAtCompileTime)==Eigen::Dynamic \ - || int(TYPE1::RowsAtCompileTime)==Eigen::Dynamic \ - || int(TYPE0::RowsAtCompileTime)==int(TYPE1::RowsAtCompileTime)) \ - && (int(TYPE0::ColsAtCompileTime)==Eigen::Dynamic \ - || int(TYPE1::ColsAtCompileTime)==Eigen::Dynamic \ - || int(TYPE0::ColsAtCompileTime)==int(TYPE1::ColsAtCompileTime))\ - ) \ - ) - -#ifdef EIGEN2_SUPPORT - #define EIGEN_STATIC_ASSERT_NON_INTEGER(TYPE) \ - eigen_assert(!NumTraits::IsInteger); -#else - #define EIGEN_STATIC_ASSERT_NON_INTEGER(TYPE) \ - EIGEN_STATIC_ASSERT(!NumTraits::IsInteger, THIS_FUNCTION_IS_NOT_FOR_INTEGER_NUMERIC_TYPES) -#endif - - -// static assertion failing if it is guaranteed at compile-time that the two matrix expression types have different sizes -#define EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(TYPE0,TYPE1) \ - EIGEN_STATIC_ASSERT( \ - EIGEN_PREDICATE_SAME_MATRIX_SIZE(TYPE0,TYPE1),\ - YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES) - -#define EIGEN_STATIC_ASSERT_SIZE_1x1(TYPE) \ - EIGEN_STATIC_ASSERT((TYPE::RowsAtCompileTime == 1 || TYPE::RowsAtCompileTime == Dynamic) && \ - (TYPE::ColsAtCompileTime == 1 || TYPE::ColsAtCompileTime == Dynamic), \ - THIS_METHOD_IS_ONLY_FOR_1x1_EXPRESSIONS) - -#define EIGEN_STATIC_ASSERT_LVALUE(Derived) \ - EIGEN_STATIC_ASSERT(internal::is_lvalue::value, \ - THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY) - -#define EIGEN_STATIC_ASSERT_ARRAYXPR(Derived) \ - EIGEN_STATIC_ASSERT((internal::is_same::XprKind, ArrayXpr>::value), \ - THIS_METHOD_IS_ONLY_FOR_ARRAYS_NOT_MATRICES) - -#define EIGEN_STATIC_ASSERT_SAME_XPR_KIND(Derived1, Derived2) \ - EIGEN_STATIC_ASSERT((internal::is_same::XprKind, \ - typename internal::traits::XprKind \ - >::value), \ - YOU_CANNOT_MIX_ARRAYS_AND_MATRICES) - - -#endif // EIGEN_STATIC_ASSERT_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/util/XprHelper.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/util/XprHelper.h deleted file mode 100644 index d05f8e5f..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Core/util/XprHelper.h +++ /dev/null @@ -1,469 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud -// Copyright (C) 2006-2008 Benoit Jacob -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_XPRHELPER_H -#define EIGEN_XPRHELPER_H - -// just a workaround because GCC seems to not really like empty structs -// FIXME: gcc 4.3 generates bad code when strict-aliasing is enabled -// so currently we simply disable this optimization for gcc 4.3 -#if (defined __GNUG__) && !((__GNUC__==4) && (__GNUC_MINOR__==3)) - #define EIGEN_EMPTY_STRUCT_CTOR(X) \ - EIGEN_STRONG_INLINE X() {} \ - EIGEN_STRONG_INLINE X(const X& ) {} -#else - #define EIGEN_EMPTY_STRUCT_CTOR(X) -#endif - -namespace Eigen { - -typedef EIGEN_DEFAULT_DENSE_INDEX_TYPE DenseIndex; - -namespace internal { - -//classes inheriting no_assignment_operator don't generate a default operator=. -class no_assignment_operator -{ - private: - no_assignment_operator& operator=(const no_assignment_operator&); -}; - -/** \internal return the index type with the largest number of bits */ -template -struct promote_index_type -{ - typedef typename conditional<(sizeof(I1)::type type; -}; - -/** \internal If the template parameter Value is Dynamic, this class is just a wrapper around a T variable that - * can be accessed using value() and setValue(). - * Otherwise, this class is an empty structure and value() just returns the template parameter Value. - */ -template class variable_if_dynamic -{ - public: - EIGEN_EMPTY_STRUCT_CTOR(variable_if_dynamic) - explicit variable_if_dynamic(T v) { EIGEN_ONLY_USED_FOR_DEBUG(v); assert(v == T(Value)); } - static T value() { return T(Value); } - void setValue(T) {} -}; - -template class variable_if_dynamic -{ - T m_value; - variable_if_dynamic() { assert(false); } - public: - explicit variable_if_dynamic(T value) : m_value(value) {} - T value() const { return m_value; } - void setValue(T value) { m_value = value; } -}; - -/** \internal like variable_if_dynamic but for DynamicIndex - */ -template class variable_if_dynamicindex -{ - public: - EIGEN_EMPTY_STRUCT_CTOR(variable_if_dynamicindex) - explicit variable_if_dynamicindex(T v) { EIGEN_ONLY_USED_FOR_DEBUG(v); assert(v == T(Value)); } - static T value() { return T(Value); } - void setValue(T) {} -}; - -template class variable_if_dynamicindex -{ - T m_value; - variable_if_dynamicindex() { assert(false); } - public: - explicit variable_if_dynamicindex(T value) : m_value(value) {} - T value() const { return m_value; } - void setValue(T value) { m_value = value; } -}; - -template struct functor_traits -{ - enum - { - Cost = 10, - PacketAccess = false, - IsRepeatable = false - }; -}; - -template struct packet_traits; - -template struct unpacket_traits -{ - typedef T type; - enum {size=1}; -}; - -template class make_proper_matrix_type -{ - enum { - IsColVector = _Cols==1 && _Rows!=1, - IsRowVector = _Rows==1 && _Cols!=1, - Options = IsColVector ? (_Options | ColMajor) & ~RowMajor - : IsRowVector ? (_Options | RowMajor) & ~ColMajor - : _Options - }; - public: - typedef Matrix<_Scalar, _Rows, _Cols, Options, _MaxRows, _MaxCols> type; -}; - -template -class compute_matrix_flags -{ - enum { - row_major_bit = Options&RowMajor ? RowMajorBit : 0, - is_dynamic_size_storage = MaxRows==Dynamic || MaxCols==Dynamic, - - aligned_bit = - ( - ((Options&DontAlign)==0) - && ( -#if EIGEN_ALIGN_STATICALLY - ((!is_dynamic_size_storage) && (((MaxCols*MaxRows*int(sizeof(Scalar))) % 16) == 0)) -#else - 0 -#endif - - || - -#if EIGEN_ALIGN - is_dynamic_size_storage -#else - 0 -#endif - - ) - ) ? AlignedBit : 0, - packet_access_bit = packet_traits::Vectorizable && aligned_bit ? PacketAccessBit : 0 - }; - - public: - enum { ret = LinearAccessBit | LvalueBit | DirectAccessBit | NestByRefBit | packet_access_bit | row_major_bit | aligned_bit }; -}; - -template struct size_at_compile_time -{ - enum { ret = (_Rows==Dynamic || _Cols==Dynamic) ? Dynamic : _Rows * _Cols }; -}; - -/* plain_matrix_type : the difference from eval is that plain_matrix_type is always a plain matrix type, - * whereas eval is a const reference in the case of a matrix - */ - -template::StorageKind> struct plain_matrix_type; -template struct plain_matrix_type_dense; -template struct plain_matrix_type -{ - typedef typename plain_matrix_type_dense::XprKind>::type type; -}; - -template struct plain_matrix_type_dense -{ - typedef Matrix::Scalar, - traits::RowsAtCompileTime, - traits::ColsAtCompileTime, - AutoAlign | (traits::Flags&RowMajorBit ? RowMajor : ColMajor), - traits::MaxRowsAtCompileTime, - traits::MaxColsAtCompileTime - > type; -}; - -template struct plain_matrix_type_dense -{ - typedef Array::Scalar, - traits::RowsAtCompileTime, - traits::ColsAtCompileTime, - AutoAlign | (traits::Flags&RowMajorBit ? RowMajor : ColMajor), - traits::MaxRowsAtCompileTime, - traits::MaxColsAtCompileTime - > type; -}; - -/* eval : the return type of eval(). For matrices, this is just a const reference - * in order to avoid a useless copy - */ - -template::StorageKind> struct eval; - -template struct eval -{ - typedef typename plain_matrix_type::type type; -// typedef typename T::PlainObject type; -// typedef T::Matrix::Scalar, -// traits::RowsAtCompileTime, -// traits::ColsAtCompileTime, -// AutoAlign | (traits::Flags&RowMajorBit ? RowMajor : ColMajor), -// traits::MaxRowsAtCompileTime, -// traits::MaxColsAtCompileTime -// > type; -}; - -// for matrices, no need to evaluate, just use a const reference to avoid a useless copy -template -struct eval, Dense> -{ - typedef const Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>& type; -}; - -template -struct eval, Dense> -{ - typedef const Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>& type; -}; - - - -/* plain_matrix_type_column_major : same as plain_matrix_type but guaranteed to be column-major - */ -template struct plain_matrix_type_column_major -{ - enum { Rows = traits::RowsAtCompileTime, - Cols = traits::ColsAtCompileTime, - MaxRows = traits::MaxRowsAtCompileTime, - MaxCols = traits::MaxColsAtCompileTime - }; - typedef Matrix::Scalar, - Rows, - Cols, - (MaxRows==1&&MaxCols!=1) ? RowMajor : ColMajor, - MaxRows, - MaxCols - > type; -}; - -/* plain_matrix_type_row_major : same as plain_matrix_type but guaranteed to be row-major - */ -template struct plain_matrix_type_row_major -{ - enum { Rows = traits::RowsAtCompileTime, - Cols = traits::ColsAtCompileTime, - MaxRows = traits::MaxRowsAtCompileTime, - MaxCols = traits::MaxColsAtCompileTime - }; - typedef Matrix::Scalar, - Rows, - Cols, - (MaxCols==1&&MaxRows!=1) ? RowMajor : ColMajor, - MaxRows, - MaxCols - > type; -}; - -// we should be able to get rid of this one too -template struct must_nest_by_value { enum { ret = false }; }; - -/** \internal The reference selector for template expressions. The idea is that we don't - * need to use references for expressions since they are light weight proxy - * objects which should generate no copying overhead. */ -template -struct ref_selector -{ - typedef typename conditional< - bool(traits::Flags & NestByRefBit), - T const&, - const T - >::type type; -}; - -/** \internal Adds the const qualifier on the value-type of T2 if and only if T1 is a const type */ -template -struct transfer_constness -{ - typedef typename conditional< - bool(internal::is_const::value), - typename internal::add_const_on_value_type::type, - T2 - >::type type; -}; - -/** \internal Determines how a given expression should be nested into another one. - * For example, when you do a * (b+c), Eigen will determine how the expression b+c should be - * nested into the bigger product expression. The choice is between nesting the expression b+c as-is, or - * evaluating that expression b+c into a temporary variable d, and nest d so that the resulting expression is - * a*d. Evaluating can be beneficial for example if every coefficient access in the resulting expression causes - * many coefficient accesses in the nested expressions -- as is the case with matrix product for example. - * - * \param T the type of the expression being nested - * \param n the number of coefficient accesses in the nested expression for each coefficient access in the bigger expression. - * - * Note that if no evaluation occur, then the constness of T is preserved. - * - * Example. Suppose that a, b, and c are of type Matrix3d. The user forms the expression a*(b+c). - * b+c is an expression "sum of matrices", which we will denote by S. In order to determine how to nest it, - * the Product expression uses: nested::ret, which turns out to be Matrix3d because the internal logic of - * nested determined that in this case it was better to evaluate the expression b+c into a temporary. On the other hand, - * since a is of type Matrix3d, the Product expression nests it as nested::ret, which turns out to be - * const Matrix3d&, because the internal logic of nested determined that since a was already a matrix, there was no point - * in copying it into another matrix. - */ -template::type> struct nested -{ - enum { - // for the purpose of this test, to keep it reasonably simple, we arbitrarily choose a value of Dynamic values. - // the choice of 10000 makes it larger than any practical fixed value and even most dynamic values. - // in extreme cases where these assumptions would be wrong, we would still at worst suffer performance issues - // (poor choice of temporaries). - // it's important that this value can still be squared without integer overflowing. - DynamicAsInteger = 10000, - ScalarReadCost = NumTraits::Scalar>::ReadCost, - ScalarReadCostAsInteger = ScalarReadCost == Dynamic ? int(DynamicAsInteger) : int(ScalarReadCost), - CoeffReadCost = traits::CoeffReadCost, - CoeffReadCostAsInteger = CoeffReadCost == Dynamic ? int(DynamicAsInteger) : int(CoeffReadCost), - NAsInteger = n == Dynamic ? int(DynamicAsInteger) : n, - CostEvalAsInteger = (NAsInteger+1) * ScalarReadCostAsInteger + CoeffReadCostAsInteger, - CostNoEvalAsInteger = NAsInteger * CoeffReadCostAsInteger - }; - - typedef typename conditional< - ( (int(traits::Flags) & EvalBeforeNestingBit) || - int(CostEvalAsInteger) < int(CostNoEvalAsInteger) - ), - PlainObject, - typename ref_selector::type - >::type type; -}; - -template -inline T* const_cast_ptr(const T* ptr) -{ - return const_cast(ptr); -} - -template::XprKind> -struct dense_xpr_base -{ - /* dense_xpr_base should only ever be used on dense expressions, thus falling either into the MatrixXpr or into the ArrayXpr cases */ -}; - -template -struct dense_xpr_base -{ - typedef MatrixBase type; -}; - -template -struct dense_xpr_base -{ - typedef ArrayBase type; -}; - -/** \internal Helper base class to add a scalar multiple operator - * overloads for complex types */ -template::value > -struct special_scalar_op_base : public BaseType -{ - // dummy operator* so that the - // "using special_scalar_op_base::operator*" compiles - void operator*() const; -}; - -template -struct special_scalar_op_base : public BaseType -{ - const CwiseUnaryOp, Derived> - operator*(const OtherScalar& scalar) const - { - return CwiseUnaryOp, Derived> - (*static_cast(this), scalar_multiple2_op(scalar)); - } - - inline friend const CwiseUnaryOp, Derived> - operator*(const OtherScalar& scalar, const Derived& matrix) - { return static_cast(matrix).operator*(scalar); } -}; - -template struct cast_return_type -{ - typedef typename XprType::Scalar CurrentScalarType; - typedef typename remove_all::type _CastType; - typedef typename _CastType::Scalar NewScalarType; - typedef typename conditional::value, - const XprType&,CastType>::type type; -}; - -template struct promote_storage_type; - -template struct promote_storage_type -{ - typedef A ret; -}; - -/** \internal gives the plain matrix or array type to store a row/column/diagonal of a matrix type. - * \param Scalar optional parameter allowing to pass a different scalar type than the one of the MatrixType. - */ -template -struct plain_row_type -{ - typedef Matrix MatrixRowType; - typedef Array ArrayRowType; - - typedef typename conditional< - is_same< typename traits::XprKind, MatrixXpr >::value, - MatrixRowType, - ArrayRowType - >::type type; -}; - -template -struct plain_col_type -{ - typedef Matrix MatrixColType; - typedef Array ArrayColType; - - typedef typename conditional< - is_same< typename traits::XprKind, MatrixXpr >::value, - MatrixColType, - ArrayColType - >::type type; -}; - -template -struct plain_diag_type -{ - enum { diag_size = EIGEN_SIZE_MIN_PREFER_DYNAMIC(ExpressionType::RowsAtCompileTime, ExpressionType::ColsAtCompileTime), - max_diag_size = EIGEN_SIZE_MIN_PREFER_FIXED(ExpressionType::MaxRowsAtCompileTime, ExpressionType::MaxColsAtCompileTime) - }; - typedef Matrix MatrixDiagType; - typedef Array ArrayDiagType; - - typedef typename conditional< - is_same< typename traits::XprKind, MatrixXpr >::value, - MatrixDiagType, - ArrayDiagType - >::type type; -}; - -template -struct is_lvalue -{ - enum { value = !bool(is_const::value) && - bool(traits::Flags & LvalueBit) }; -}; - -} // end namespace internal - -} // end namespace Eigen - -#endif // EIGEN_XPRHELPER_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Block.h b/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Block.h deleted file mode 100644 index 604456f4..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Block.h +++ /dev/null @@ -1,126 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2009 Gael Guennebaud -// Copyright (C) 2006-2008 Benoit Jacob -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_BLOCK2_H -#define EIGEN_BLOCK2_H - -namespace Eigen { - -/** \returns a dynamic-size expression of a corner of *this. - * - * \param type the type of corner. Can be \a Eigen::TopLeft, \a Eigen::TopRight, - * \a Eigen::BottomLeft, \a Eigen::BottomRight. - * \param cRows the number of rows in the corner - * \param cCols the number of columns in the corner - * - * Example: \include MatrixBase_corner_enum_int_int.cpp - * Output: \verbinclude MatrixBase_corner_enum_int_int.out - * - * \note Even though the returned expression has dynamic size, in the case - * when it is applied to a fixed-size matrix, it inherits a fixed maximal size, - * which means that evaluating it does not cause a dynamic memory allocation. - * - * \sa class Block, block(Index,Index,Index,Index) - */ -template -inline Block DenseBase - ::corner(CornerType type, Index cRows, Index cCols) -{ - switch(type) - { - default: - eigen_assert(false && "Bad corner type."); - case TopLeft: - return Block(derived(), 0, 0, cRows, cCols); - case TopRight: - return Block(derived(), 0, cols() - cCols, cRows, cCols); - case BottomLeft: - return Block(derived(), rows() - cRows, 0, cRows, cCols); - case BottomRight: - return Block(derived(), rows() - cRows, cols() - cCols, cRows, cCols); - } -} - -/** This is the const version of corner(CornerType, Index, Index).*/ -template -inline const Block -DenseBase::corner(CornerType type, Index cRows, Index cCols) const -{ - switch(type) - { - default: - eigen_assert(false && "Bad corner type."); - case TopLeft: - return Block(derived(), 0, 0, cRows, cCols); - case TopRight: - return Block(derived(), 0, cols() - cCols, cRows, cCols); - case BottomLeft: - return Block(derived(), rows() - cRows, 0, cRows, cCols); - case BottomRight: - return Block(derived(), rows() - cRows, cols() - cCols, cRows, cCols); - } -} - -/** \returns a fixed-size expression of a corner of *this. - * - * \param type the type of corner. Can be \a Eigen::TopLeft, \a Eigen::TopRight, - * \a Eigen::BottomLeft, \a Eigen::BottomRight. - * - * The template parameters CRows and CCols arethe number of rows and columns in the corner. - * - * Example: \include MatrixBase_template_int_int_corner_enum.cpp - * Output: \verbinclude MatrixBase_template_int_int_corner_enum.out - * - * \sa class Block, block(Index,Index,Index,Index) - */ -template -template -inline Block -DenseBase::corner(CornerType type) -{ - switch(type) - { - default: - eigen_assert(false && "Bad corner type."); - case TopLeft: - return Block(derived(), 0, 0); - case TopRight: - return Block(derived(), 0, cols() - CCols); - case BottomLeft: - return Block(derived(), rows() - CRows, 0); - case BottomRight: - return Block(derived(), rows() - CRows, cols() - CCols); - } -} - -/** This is the const version of corner(CornerType).*/ -template -template -inline const Block -DenseBase::corner(CornerType type) const -{ - switch(type) - { - default: - eigen_assert(false && "Bad corner type."); - case TopLeft: - return Block(derived(), 0, 0); - case TopRight: - return Block(derived(), 0, cols() - CCols); - case BottomLeft: - return Block(derived(), rows() - CRows, 0); - case BottomRight: - return Block(derived(), rows() - CRows, cols() - CCols); - } -} - -} // end namespace Eigen - -#endif // EIGEN_BLOCK2_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Cwise.h b/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Cwise.h deleted file mode 100644 index d95009b6..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Cwise.h +++ /dev/null @@ -1,192 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud -// Copyright (C) 2008 Benoit Jacob -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_CWISE_H -#define EIGEN_CWISE_H - -namespace Eigen { - -/** \internal - * convenient macro to defined the return type of a cwise binary operation */ -#define EIGEN_CWISE_BINOP_RETURN_TYPE(OP) \ - CwiseBinaryOp::Scalar>, ExpressionType, OtherDerived> - -/** \internal - * convenient macro to defined the return type of a cwise unary operation */ -#define EIGEN_CWISE_UNOP_RETURN_TYPE(OP) \ - CwiseUnaryOp::Scalar>, ExpressionType> - -/** \internal - * convenient macro to defined the return type of a cwise comparison to a scalar */ -#define EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(OP) \ - CwiseBinaryOp::Scalar>, ExpressionType, \ - typename ExpressionType::ConstantReturnType > - -/** \class Cwise - * - * \brief Pseudo expression providing additional coefficient-wise operations - * - * \param ExpressionType the type of the object on which to do coefficient-wise operations - * - * This class represents an expression with additional coefficient-wise features. - * It is the return type of MatrixBase::cwise() - * and most of the time this is the only way it is used. - * - * Example: \include MatrixBase_cwise_const.cpp - * Output: \verbinclude MatrixBase_cwise_const.out - * - * This class can be extended with the help of the plugin mechanism described on the page - * \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_CWISE_PLUGIN. - * - * \sa MatrixBase::cwise() const, MatrixBase::cwise() - */ -template class Cwise -{ - public: - - typedef typename internal::traits::Scalar Scalar; - typedef typename internal::conditional::ret, - ExpressionType, const ExpressionType&>::type ExpressionTypeNested; - typedef CwiseUnaryOp, ExpressionType> ScalarAddReturnType; - - inline Cwise(const ExpressionType& matrix) : m_matrix(matrix) {} - - /** \internal */ - inline const ExpressionType& _expression() const { return m_matrix; } - - template - const EIGEN_CWISE_PRODUCT_RETURN_TYPE(ExpressionType,OtherDerived) - operator*(const MatrixBase &other) const; - - template - const EIGEN_CWISE_BINOP_RETURN_TYPE(internal::scalar_quotient_op) - operator/(const MatrixBase &other) const; - - /** \deprecated ArrayBase::min() */ - template - const EIGEN_CWISE_BINOP_RETURN_TYPE(internal::scalar_min_op) - (min)(const MatrixBase &other) const - { return EIGEN_CWISE_BINOP_RETURN_TYPE(internal::scalar_min_op)(_expression(), other.derived()); } - - /** \deprecated ArrayBase::max() */ - template - const EIGEN_CWISE_BINOP_RETURN_TYPE(internal::scalar_max_op) - (max)(const MatrixBase &other) const - { return EIGEN_CWISE_BINOP_RETURN_TYPE(internal::scalar_max_op)(_expression(), other.derived()); } - - const EIGEN_CWISE_UNOP_RETURN_TYPE(internal::scalar_abs_op) abs() const; - const EIGEN_CWISE_UNOP_RETURN_TYPE(internal::scalar_abs2_op) abs2() const; - const EIGEN_CWISE_UNOP_RETURN_TYPE(internal::scalar_square_op) square() const; - const EIGEN_CWISE_UNOP_RETURN_TYPE(internal::scalar_cube_op) cube() const; - const EIGEN_CWISE_UNOP_RETURN_TYPE(internal::scalar_inverse_op) inverse() const; - const EIGEN_CWISE_UNOP_RETURN_TYPE(internal::scalar_sqrt_op) sqrt() const; - const EIGEN_CWISE_UNOP_RETURN_TYPE(internal::scalar_exp_op) exp() const; - const EIGEN_CWISE_UNOP_RETURN_TYPE(internal::scalar_log_op) log() const; - const EIGEN_CWISE_UNOP_RETURN_TYPE(internal::scalar_cos_op) cos() const; - const EIGEN_CWISE_UNOP_RETURN_TYPE(internal::scalar_sin_op) sin() const; - const EIGEN_CWISE_UNOP_RETURN_TYPE(internal::scalar_pow_op) pow(const Scalar& exponent) const; - - const ScalarAddReturnType - operator+(const Scalar& scalar) const; - - /** \relates Cwise */ - friend const ScalarAddReturnType - operator+(const Scalar& scalar, const Cwise& mat) - { return mat + scalar; } - - ExpressionType& operator+=(const Scalar& scalar); - - const ScalarAddReturnType - operator-(const Scalar& scalar) const; - - ExpressionType& operator-=(const Scalar& scalar); - - template - inline ExpressionType& operator*=(const MatrixBase &other); - - template - inline ExpressionType& operator/=(const MatrixBase &other); - - template const EIGEN_CWISE_BINOP_RETURN_TYPE(std::less) - operator<(const MatrixBase& other) const; - - template const EIGEN_CWISE_BINOP_RETURN_TYPE(std::less_equal) - operator<=(const MatrixBase& other) const; - - template const EIGEN_CWISE_BINOP_RETURN_TYPE(std::greater) - operator>(const MatrixBase& other) const; - - template const EIGEN_CWISE_BINOP_RETURN_TYPE(std::greater_equal) - operator>=(const MatrixBase& other) const; - - template const EIGEN_CWISE_BINOP_RETURN_TYPE(std::equal_to) - operator==(const MatrixBase& other) const; - - template const EIGEN_CWISE_BINOP_RETURN_TYPE(std::not_equal_to) - operator!=(const MatrixBase& other) const; - - // comparisons to a scalar value - const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::less) - operator<(Scalar s) const; - - const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::less_equal) - operator<=(Scalar s) const; - - const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::greater) - operator>(Scalar s) const; - - const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::greater_equal) - operator>=(Scalar s) const; - - const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::equal_to) - operator==(Scalar s) const; - - const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::not_equal_to) - operator!=(Scalar s) const; - - // allow to extend Cwise outside Eigen - #ifdef EIGEN_CWISE_PLUGIN - #include EIGEN_CWISE_PLUGIN - #endif - - protected: - ExpressionTypeNested m_matrix; -}; - - -/** \returns a Cwise wrapper of *this providing additional coefficient-wise operations - * - * Example: \include MatrixBase_cwise_const.cpp - * Output: \verbinclude MatrixBase_cwise_const.out - * - * \sa class Cwise, cwise() - */ -template -inline const Cwise MatrixBase::cwise() const -{ - return derived(); -} - -/** \returns a Cwise wrapper of *this providing additional coefficient-wise operations - * - * Example: \include MatrixBase_cwise.cpp - * Output: \verbinclude MatrixBase_cwise.out - * - * \sa class Cwise, cwise() const - */ -template -inline Cwise MatrixBase::cwise() -{ - return derived(); -} - -} // end namespace Eigen - -#endif // EIGEN_CWISE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/CwiseOperators.h b/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/CwiseOperators.h deleted file mode 100644 index 482f3064..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/CwiseOperators.h +++ /dev/null @@ -1,298 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_ARRAY_CWISE_OPERATORS_H -#define EIGEN_ARRAY_CWISE_OPERATORS_H - -namespace Eigen { - -/*************************************************************************** -* The following functions were defined in Core -***************************************************************************/ - - -/** \deprecated ArrayBase::abs() */ -template -EIGEN_STRONG_INLINE const EIGEN_CWISE_UNOP_RETURN_TYPE(internal::scalar_abs_op) -Cwise::abs() const -{ - return _expression(); -} - -/** \deprecated ArrayBase::abs2() */ -template -EIGEN_STRONG_INLINE const EIGEN_CWISE_UNOP_RETURN_TYPE(internal::scalar_abs2_op) -Cwise::abs2() const -{ - return _expression(); -} - -/** \deprecated ArrayBase::exp() */ -template -inline const EIGEN_CWISE_UNOP_RETURN_TYPE(internal::scalar_exp_op) -Cwise::exp() const -{ - return _expression(); -} - -/** \deprecated ArrayBase::log() */ -template -inline const EIGEN_CWISE_UNOP_RETURN_TYPE(internal::scalar_log_op) -Cwise::log() const -{ - return _expression(); -} - -/** \deprecated ArrayBase::operator*() */ -template -template -EIGEN_STRONG_INLINE const EIGEN_CWISE_PRODUCT_RETURN_TYPE(ExpressionType,OtherDerived) -Cwise::operator*(const MatrixBase &other) const -{ - return EIGEN_CWISE_PRODUCT_RETURN_TYPE(ExpressionType,OtherDerived)(_expression(), other.derived()); -} - -/** \deprecated ArrayBase::operator/() */ -template -template -EIGEN_STRONG_INLINE const EIGEN_CWISE_BINOP_RETURN_TYPE(internal::scalar_quotient_op) -Cwise::operator/(const MatrixBase &other) const -{ - return EIGEN_CWISE_BINOP_RETURN_TYPE(internal::scalar_quotient_op)(_expression(), other.derived()); -} - -/** \deprecated ArrayBase::operator*=() */ -template -template -inline ExpressionType& Cwise::operator*=(const MatrixBase &other) -{ - return m_matrix.const_cast_derived() = *this * other; -} - -/** \deprecated ArrayBase::operator/=() */ -template -template -inline ExpressionType& Cwise::operator/=(const MatrixBase &other) -{ - return m_matrix.const_cast_derived() = *this / other; -} - -/*************************************************************************** -* The following functions were defined in Array -***************************************************************************/ - -// -- unary operators -- - -/** \deprecated ArrayBase::sqrt() */ -template -inline const EIGEN_CWISE_UNOP_RETURN_TYPE(internal::scalar_sqrt_op) -Cwise::sqrt() const -{ - return _expression(); -} - -/** \deprecated ArrayBase::cos() */ -template -inline const EIGEN_CWISE_UNOP_RETURN_TYPE(internal::scalar_cos_op) -Cwise::cos() const -{ - return _expression(); -} - - -/** \deprecated ArrayBase::sin() */ -template -inline const EIGEN_CWISE_UNOP_RETURN_TYPE(internal::scalar_sin_op) -Cwise::sin() const -{ - return _expression(); -} - - -/** \deprecated ArrayBase::log() */ -template -inline const EIGEN_CWISE_UNOP_RETURN_TYPE(internal::scalar_pow_op) -Cwise::pow(const Scalar& exponent) const -{ - return EIGEN_CWISE_UNOP_RETURN_TYPE(internal::scalar_pow_op)(_expression(), internal::scalar_pow_op(exponent)); -} - - -/** \deprecated ArrayBase::inverse() */ -template -inline const EIGEN_CWISE_UNOP_RETURN_TYPE(internal::scalar_inverse_op) -Cwise::inverse() const -{ - return _expression(); -} - -/** \deprecated ArrayBase::square() */ -template -inline const EIGEN_CWISE_UNOP_RETURN_TYPE(internal::scalar_square_op) -Cwise::square() const -{ - return _expression(); -} - -/** \deprecated ArrayBase::cube() */ -template -inline const EIGEN_CWISE_UNOP_RETURN_TYPE(internal::scalar_cube_op) -Cwise::cube() const -{ - return _expression(); -} - - -// -- binary operators -- - -/** \deprecated ArrayBase::operator<() */ -template -template -inline const EIGEN_CWISE_BINOP_RETURN_TYPE(std::less) -Cwise::operator<(const MatrixBase &other) const -{ - return EIGEN_CWISE_BINOP_RETURN_TYPE(std::less)(_expression(), other.derived()); -} - -/** \deprecated ArrayBase::<=() */ -template -template -inline const EIGEN_CWISE_BINOP_RETURN_TYPE(std::less_equal) -Cwise::operator<=(const MatrixBase &other) const -{ - return EIGEN_CWISE_BINOP_RETURN_TYPE(std::less_equal)(_expression(), other.derived()); -} - -/** \deprecated ArrayBase::operator>() */ -template -template -inline const EIGEN_CWISE_BINOP_RETURN_TYPE(std::greater) -Cwise::operator>(const MatrixBase &other) const -{ - return EIGEN_CWISE_BINOP_RETURN_TYPE(std::greater)(_expression(), other.derived()); -} - -/** \deprecated ArrayBase::operator>=() */ -template -template -inline const EIGEN_CWISE_BINOP_RETURN_TYPE(std::greater_equal) -Cwise::operator>=(const MatrixBase &other) const -{ - return EIGEN_CWISE_BINOP_RETURN_TYPE(std::greater_equal)(_expression(), other.derived()); -} - -/** \deprecated ArrayBase::operator==() */ -template -template -inline const EIGEN_CWISE_BINOP_RETURN_TYPE(std::equal_to) -Cwise::operator==(const MatrixBase &other) const -{ - return EIGEN_CWISE_BINOP_RETURN_TYPE(std::equal_to)(_expression(), other.derived()); -} - -/** \deprecated ArrayBase::operator!=() */ -template -template -inline const EIGEN_CWISE_BINOP_RETURN_TYPE(std::not_equal_to) -Cwise::operator!=(const MatrixBase &other) const -{ - return EIGEN_CWISE_BINOP_RETURN_TYPE(std::not_equal_to)(_expression(), other.derived()); -} - -// comparisons to scalar value - -/** \deprecated ArrayBase::operator<(Scalar) */ -template -inline const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::less) -Cwise::operator<(Scalar s) const -{ - return EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::less)(_expression(), - typename ExpressionType::ConstantReturnType(_expression().rows(), _expression().cols(), s)); -} - -/** \deprecated ArrayBase::operator<=(Scalar) */ -template -inline const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::less_equal) -Cwise::operator<=(Scalar s) const -{ - return EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::less_equal)(_expression(), - typename ExpressionType::ConstantReturnType(_expression().rows(), _expression().cols(), s)); -} - -/** \deprecated ArrayBase::operator>(Scalar) */ -template -inline const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::greater) -Cwise::operator>(Scalar s) const -{ - return EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::greater)(_expression(), - typename ExpressionType::ConstantReturnType(_expression().rows(), _expression().cols(), s)); -} - -/** \deprecated ArrayBase::operator>=(Scalar) */ -template -inline const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::greater_equal) -Cwise::operator>=(Scalar s) const -{ - return EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::greater_equal)(_expression(), - typename ExpressionType::ConstantReturnType(_expression().rows(), _expression().cols(), s)); -} - -/** \deprecated ArrayBase::operator==(Scalar) */ -template -inline const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::equal_to) -Cwise::operator==(Scalar s) const -{ - return EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::equal_to)(_expression(), - typename ExpressionType::ConstantReturnType(_expression().rows(), _expression().cols(), s)); -} - -/** \deprecated ArrayBase::operator!=(Scalar) */ -template -inline const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::not_equal_to) -Cwise::operator!=(Scalar s) const -{ - return EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::not_equal_to)(_expression(), - typename ExpressionType::ConstantReturnType(_expression().rows(), _expression().cols(), s)); -} - -// scalar addition - -/** \deprecated ArrayBase::operator+(Scalar) */ -template -inline const typename Cwise::ScalarAddReturnType -Cwise::operator+(const Scalar& scalar) const -{ - return typename Cwise::ScalarAddReturnType(m_matrix, internal::scalar_add_op(scalar)); -} - -/** \deprecated ArrayBase::operator+=(Scalar) */ -template -inline ExpressionType& Cwise::operator+=(const Scalar& scalar) -{ - return m_matrix.const_cast_derived() = *this + scalar; -} - -/** \deprecated ArrayBase::operator-(Scalar) */ -template -inline const typename Cwise::ScalarAddReturnType -Cwise::operator-(const Scalar& scalar) const -{ - return *this + (-scalar); -} - -/** \deprecated ArrayBase::operator-=(Scalar) */ -template -inline ExpressionType& Cwise::operator-=(const Scalar& scalar) -{ - return m_matrix.const_cast_derived() = *this - scalar; -} - -} // end namespace Eigen - -#endif // EIGEN_ARRAY_CWISE_OPERATORS_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/AlignedBox.h b/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/AlignedBox.h deleted file mode 100644 index 2e4309dd..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/AlignedBox.h +++ /dev/null @@ -1,159 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -// no include guard, we'll include this twice from All.h from Eigen2Support, and it's internal anyway - -namespace Eigen { - -/** \geometry_module \ingroup Geometry_Module - * \nonstableyet - * - * \class AlignedBox - * - * \brief An axis aligned box - * - * \param _Scalar the type of the scalar coefficients - * \param _AmbientDim the dimension of the ambient space, can be a compile time value or Dynamic. - * - * This class represents an axis aligned box as a pair of the minimal and maximal corners. - */ -template -class AlignedBox -{ -public: -EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim==Dynamic ? Dynamic : _AmbientDim+1) - enum { AmbientDimAtCompileTime = _AmbientDim }; - typedef _Scalar Scalar; - typedef typename NumTraits::Real RealScalar; - typedef Matrix VectorType; - - /** Default constructor initializing a null box. */ - inline AlignedBox() - { if (AmbientDimAtCompileTime!=Dynamic) setNull(); } - - /** Constructs a null box with \a _dim the dimension of the ambient space. */ - inline explicit AlignedBox(int _dim) : m_min(_dim), m_max(_dim) - { setNull(); } - - /** Constructs a box with extremities \a _min and \a _max. */ - inline AlignedBox(const VectorType& _min, const VectorType& _max) : m_min(_min), m_max(_max) {} - - /** Constructs a box containing a single point \a p. */ - inline explicit AlignedBox(const VectorType& p) : m_min(p), m_max(p) {} - - ~AlignedBox() {} - - /** \returns the dimension in which the box holds */ - inline int dim() const { return AmbientDimAtCompileTime==Dynamic ? m_min.size()-1 : AmbientDimAtCompileTime; } - - /** \returns true if the box is null, i.e, empty. */ - inline bool isNull() const { return (m_min.cwise() > m_max).any(); } - - /** Makes \c *this a null/empty box. */ - inline void setNull() - { - m_min.setConstant( (std::numeric_limits::max)()); - m_max.setConstant(-(std::numeric_limits::max)()); - } - - /** \returns the minimal corner */ - inline const VectorType& (min)() const { return m_min; } - /** \returns a non const reference to the minimal corner */ - inline VectorType& (min)() { return m_min; } - /** \returns the maximal corner */ - inline const VectorType& (max)() const { return m_max; } - /** \returns a non const reference to the maximal corner */ - inline VectorType& (max)() { return m_max; } - - /** \returns true if the point \a p is inside the box \c *this. */ - inline bool contains(const VectorType& p) const - { return (m_min.cwise()<=p).all() && (p.cwise()<=m_max).all(); } - - /** \returns true if the box \a b is entirely inside the box \c *this. */ - inline bool contains(const AlignedBox& b) const - { return (m_min.cwise()<=(b.min)()).all() && ((b.max)().cwise()<=m_max).all(); } - - /** Extends \c *this such that it contains the point \a p and returns a reference to \c *this. */ - inline AlignedBox& extend(const VectorType& p) - { m_min = (m_min.cwise().min)(p); m_max = (m_max.cwise().max)(p); return *this; } - - /** Extends \c *this such that it contains the box \a b and returns a reference to \c *this. */ - inline AlignedBox& extend(const AlignedBox& b) - { m_min = (m_min.cwise().min)(b.m_min); m_max = (m_max.cwise().max)(b.m_max); return *this; } - - /** Clamps \c *this by the box \a b and returns a reference to \c *this. */ - inline AlignedBox& clamp(const AlignedBox& b) - { m_min = (m_min.cwise().max)(b.m_min); m_max = (m_max.cwise().min)(b.m_max); return *this; } - - /** Translate \c *this by the vector \a t and returns a reference to \c *this. */ - inline AlignedBox& translate(const VectorType& t) - { m_min += t; m_max += t; return *this; } - - /** \returns the squared distance between the point \a p and the box \c *this, - * and zero if \a p is inside the box. - * \sa exteriorDistance() - */ - inline Scalar squaredExteriorDistance(const VectorType& p) const; - - /** \returns the distance between the point \a p and the box \c *this, - * and zero if \a p is inside the box. - * \sa squaredExteriorDistance() - */ - inline Scalar exteriorDistance(const VectorType& p) const - { return ei_sqrt(squaredExteriorDistance(p)); } - - /** \returns \c *this with scalar type casted to \a NewScalarType - * - * Note that if \a NewScalarType is equal to the current scalar type of \c *this - * then this function smartly returns a const reference to \c *this. - */ - template - inline typename internal::cast_return_type >::type cast() const - { - return typename internal::cast_return_type >::type(*this); - } - - /** Copy constructor with scalar type conversion */ - template - inline explicit AlignedBox(const AlignedBox& other) - { - m_min = (other.min)().template cast(); - m_max = (other.max)().template cast(); - } - - /** \returns \c true if \c *this is approximately equal to \a other, within the precision - * determined by \a prec. - * - * \sa MatrixBase::isApprox() */ - bool isApprox(const AlignedBox& other, typename NumTraits::Real prec = precision()) const - { return m_min.isApprox(other.m_min, prec) && m_max.isApprox(other.m_max, prec); } - -protected: - - VectorType m_min, m_max; -}; - -template -inline Scalar AlignedBox::squaredExteriorDistance(const VectorType& p) const -{ - Scalar dist2(0); - Scalar aux; - for (int k=0; k - -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif - -#if EIGEN2_SUPPORT_STAGE < STAGE20_RESOLVE_API_CONFLICTS -#include "RotationBase.h" -#include "Rotation2D.h" -#include "Quaternion.h" -#include "AngleAxis.h" -#include "Transform.h" -#include "Translation.h" -#include "Scaling.h" -#include "AlignedBox.h" -#include "Hyperplane.h" -#include "ParametrizedLine.h" -#endif - - -#define RotationBase eigen2_RotationBase -#define Rotation2D eigen2_Rotation2D -#define Rotation2Df eigen2_Rotation2Df -#define Rotation2Dd eigen2_Rotation2Dd - -#define Quaternion eigen2_Quaternion -#define Quaternionf eigen2_Quaternionf -#define Quaterniond eigen2_Quaterniond - -#define AngleAxis eigen2_AngleAxis -#define AngleAxisf eigen2_AngleAxisf -#define AngleAxisd eigen2_AngleAxisd - -#define Transform eigen2_Transform -#define Transform2f eigen2_Transform2f -#define Transform2d eigen2_Transform2d -#define Transform3f eigen2_Transform3f -#define Transform3d eigen2_Transform3d - -#define Translation eigen2_Translation -#define Translation2f eigen2_Translation2f -#define Translation2d eigen2_Translation2d -#define Translation3f eigen2_Translation3f -#define Translation3d eigen2_Translation3d - -#define Scaling eigen2_Scaling -#define Scaling2f eigen2_Scaling2f -#define Scaling2d eigen2_Scaling2d -#define Scaling3f eigen2_Scaling3f -#define Scaling3d eigen2_Scaling3d - -#define AlignedBox eigen2_AlignedBox - -#define Hyperplane eigen2_Hyperplane -#define ParametrizedLine eigen2_ParametrizedLine - -#define ei_toRotationMatrix eigen2_ei_toRotationMatrix -#define ei_quaternion_assign_impl eigen2_ei_quaternion_assign_impl -#define ei_transform_product_impl eigen2_ei_transform_product_impl - -#include "RotationBase.h" -#include "Rotation2D.h" -#include "Quaternion.h" -#include "AngleAxis.h" -#include "Transform.h" -#include "Translation.h" -#include "Scaling.h" -#include "AlignedBox.h" -#include "Hyperplane.h" -#include "ParametrizedLine.h" - -#undef ei_toRotationMatrix -#undef ei_quaternion_assign_impl -#undef ei_transform_product_impl - -#undef RotationBase -#undef Rotation2D -#undef Rotation2Df -#undef Rotation2Dd - -#undef Quaternion -#undef Quaternionf -#undef Quaterniond - -#undef AngleAxis -#undef AngleAxisf -#undef AngleAxisd - -#undef Transform -#undef Transform2f -#undef Transform2d -#undef Transform3f -#undef Transform3d - -#undef Translation -#undef Translation2f -#undef Translation2d -#undef Translation3f -#undef Translation3d - -#undef Scaling -#undef Scaling2f -#undef Scaling2d -#undef Scaling3f -#undef Scaling3d - -#undef AlignedBox - -#undef Hyperplane -#undef ParametrizedLine - -#endif // EIGEN2_GEOMETRY_MODULE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/AngleAxis.h b/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/AngleAxis.h deleted file mode 100644 index af598a40..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/AngleAxis.h +++ /dev/null @@ -1,214 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -// no include guard, we'll include this twice from All.h from Eigen2Support, and it's internal anyway - -namespace Eigen { - -/** \geometry_module \ingroup Geometry_Module - * - * \class AngleAxis - * - * \brief Represents a 3D rotation as a rotation angle around an arbitrary 3D axis - * - * \param _Scalar the scalar type, i.e., the type of the coefficients. - * - * The following two typedefs are provided for convenience: - * \li \c AngleAxisf for \c float - * \li \c AngleAxisd for \c double - * - * \addexample AngleAxisForEuler \label How to define a rotation from Euler-angles - * - * Combined with MatrixBase::Unit{X,Y,Z}, AngleAxis can be used to easily - * mimic Euler-angles. Here is an example: - * \include AngleAxis_mimic_euler.cpp - * Output: \verbinclude AngleAxis_mimic_euler.out - * - * \note This class is not aimed to be used to store a rotation transformation, - * but rather to make easier the creation of other rotation (Quaternion, rotation Matrix) - * and transformation objects. - * - * \sa class Quaternion, class Transform, MatrixBase::UnitX() - */ - -template struct ei_traits > -{ - typedef _Scalar Scalar; -}; - -template -class AngleAxis : public RotationBase,3> -{ - typedef RotationBase,3> Base; - -public: - - using Base::operator*; - - enum { Dim = 3 }; - /** the scalar type of the coefficients */ - typedef _Scalar Scalar; - typedef Matrix Matrix3; - typedef Matrix Vector3; - typedef Quaternion QuaternionType; - -protected: - - Vector3 m_axis; - Scalar m_angle; - -public: - - /** Default constructor without initialization. */ - AngleAxis() {} - /** Constructs and initialize the angle-axis rotation from an \a angle in radian - * and an \a axis which must be normalized. */ - template - inline AngleAxis(Scalar angle, const MatrixBase& axis) : m_axis(axis), m_angle(angle) {} - /** Constructs and initialize the angle-axis rotation from a quaternion \a q. */ - inline AngleAxis(const QuaternionType& q) { *this = q; } - /** Constructs and initialize the angle-axis rotation from a 3x3 rotation matrix. */ - template - inline explicit AngleAxis(const MatrixBase& m) { *this = m; } - - Scalar angle() const { return m_angle; } - Scalar& angle() { return m_angle; } - - const Vector3& axis() const { return m_axis; } - Vector3& axis() { return m_axis; } - - /** Concatenates two rotations */ - inline QuaternionType operator* (const AngleAxis& other) const - { return QuaternionType(*this) * QuaternionType(other); } - - /** Concatenates two rotations */ - inline QuaternionType operator* (const QuaternionType& other) const - { return QuaternionType(*this) * other; } - - /** Concatenates two rotations */ - friend inline QuaternionType operator* (const QuaternionType& a, const AngleAxis& b) - { return a * QuaternionType(b); } - - /** Concatenates two rotations */ - inline Matrix3 operator* (const Matrix3& other) const - { return toRotationMatrix() * other; } - - /** Concatenates two rotations */ - inline friend Matrix3 operator* (const Matrix3& a, const AngleAxis& b) - { return a * b.toRotationMatrix(); } - - /** Applies rotation to vector */ - inline Vector3 operator* (const Vector3& other) const - { return toRotationMatrix() * other; } - - /** \returns the inverse rotation, i.e., an angle-axis with opposite rotation angle */ - AngleAxis inverse() const - { return AngleAxis(-m_angle, m_axis); } - - AngleAxis& operator=(const QuaternionType& q); - template - AngleAxis& operator=(const MatrixBase& m); - - template - AngleAxis& fromRotationMatrix(const MatrixBase& m); - Matrix3 toRotationMatrix(void) const; - - /** \returns \c *this with scalar type casted to \a NewScalarType - * - * Note that if \a NewScalarType is equal to the current scalar type of \c *this - * then this function smartly returns a const reference to \c *this. - */ - template - inline typename internal::cast_return_type >::type cast() const - { return typename internal::cast_return_type >::type(*this); } - - /** Copy constructor with scalar type conversion */ - template - inline explicit AngleAxis(const AngleAxis& other) - { - m_axis = other.axis().template cast(); - m_angle = Scalar(other.angle()); - } - - /** \returns \c true if \c *this is approximately equal to \a other, within the precision - * determined by \a prec. - * - * \sa MatrixBase::isApprox() */ - bool isApprox(const AngleAxis& other, typename NumTraits::Real prec = precision()) const - { return m_axis.isApprox(other.m_axis, prec) && ei_isApprox(m_angle,other.m_angle, prec); } -}; - -/** \ingroup Geometry_Module - * single precision angle-axis type */ -typedef AngleAxis AngleAxisf; -/** \ingroup Geometry_Module - * double precision angle-axis type */ -typedef AngleAxis AngleAxisd; - -/** Set \c *this from a quaternion. - * The axis is normalized. - */ -template -AngleAxis& AngleAxis::operator=(const QuaternionType& q) -{ - Scalar n2 = q.vec().squaredNorm(); - if (n2 < precision()*precision()) - { - m_angle = 0; - m_axis << 1, 0, 0; - } - else - { - m_angle = 2*std::acos(q.w()); - m_axis = q.vec() / ei_sqrt(n2); - } - return *this; -} - -/** Set \c *this from a 3x3 rotation matrix \a mat. - */ -template -template -AngleAxis& AngleAxis::operator=(const MatrixBase& mat) -{ - // Since a direct conversion would not be really faster, - // let's use the robust Quaternion implementation: - return *this = QuaternionType(mat); -} - -/** Constructs and \returns an equivalent 3x3 rotation matrix. - */ -template -typename AngleAxis::Matrix3 -AngleAxis::toRotationMatrix(void) const -{ - Matrix3 res; - Vector3 sin_axis = ei_sin(m_angle) * m_axis; - Scalar c = ei_cos(m_angle); - Vector3 cos1_axis = (Scalar(1)-c) * m_axis; - - Scalar tmp; - tmp = cos1_axis.x() * m_axis.y(); - res.coeffRef(0,1) = tmp - sin_axis.z(); - res.coeffRef(1,0) = tmp + sin_axis.z(); - - tmp = cos1_axis.x() * m_axis.z(); - res.coeffRef(0,2) = tmp + sin_axis.y(); - res.coeffRef(2,0) = tmp - sin_axis.y(); - - tmp = cos1_axis.y() * m_axis.z(); - res.coeffRef(1,2) = tmp - sin_axis.x(); - res.coeffRef(2,1) = tmp + sin_axis.x(); - - res.diagonal() = (cos1_axis.cwise() * m_axis).cwise() + c; - - return res; -} - -} // end namespace Eigen diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/Hyperplane.h b/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/Hyperplane.h deleted file mode 100644 index b95bf00e..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/Hyperplane.h +++ /dev/null @@ -1,254 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud -// Copyright (C) 2008 Benoit Jacob -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -// no include guard, we'll include this twice from All.h from Eigen2Support, and it's internal anyway - -namespace Eigen { - -/** \geometry_module \ingroup Geometry_Module - * - * \class Hyperplane - * - * \brief A hyperplane - * - * A hyperplane is an affine subspace of dimension n-1 in a space of dimension n. - * For example, a hyperplane in a plane is a line; a hyperplane in 3-space is a plane. - * - * \param _Scalar the scalar type, i.e., the type of the coefficients - * \param _AmbientDim the dimension of the ambient space, can be a compile time value or Dynamic. - * Notice that the dimension of the hyperplane is _AmbientDim-1. - * - * This class represents an hyperplane as the zero set of the implicit equation - * \f$ n \cdot x + d = 0 \f$ where \f$ n \f$ is a unit normal vector of the plane (linear part) - * and \f$ d \f$ is the distance (offset) to the origin. - */ -template -class Hyperplane -{ -public: - EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim==Dynamic ? Dynamic : _AmbientDim+1) - enum { AmbientDimAtCompileTime = _AmbientDim }; - typedef _Scalar Scalar; - typedef typename NumTraits::Real RealScalar; - typedef Matrix VectorType; - typedef Matrix Coefficients; - typedef Block NormalReturnType; - - /** Default constructor without initialization */ - inline Hyperplane() {} - - /** Constructs a dynamic-size hyperplane with \a _dim the dimension - * of the ambient space */ - inline explicit Hyperplane(int _dim) : m_coeffs(_dim+1) {} - - /** Construct a plane from its normal \a n and a point \a e onto the plane. - * \warning the vector normal is assumed to be normalized. - */ - inline Hyperplane(const VectorType& n, const VectorType& e) - : m_coeffs(n.size()+1) - { - normal() = n; - offset() = -e.eigen2_dot(n); - } - - /** Constructs a plane from its normal \a n and distance to the origin \a d - * such that the algebraic equation of the plane is \f$ n \cdot x + d = 0 \f$. - * \warning the vector normal is assumed to be normalized. - */ - inline Hyperplane(const VectorType& n, Scalar d) - : m_coeffs(n.size()+1) - { - normal() = n; - offset() = d; - } - - /** Constructs a hyperplane passing through the two points. If the dimension of the ambient space - * is greater than 2, then there isn't uniqueness, so an arbitrary choice is made. - */ - static inline Hyperplane Through(const VectorType& p0, const VectorType& p1) - { - Hyperplane result(p0.size()); - result.normal() = (p1 - p0).unitOrthogonal(); - result.offset() = -result.normal().eigen2_dot(p0); - return result; - } - - /** Constructs a hyperplane passing through the three points. The dimension of the ambient space - * is required to be exactly 3. - */ - static inline Hyperplane Through(const VectorType& p0, const VectorType& p1, const VectorType& p2) - { - EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(VectorType, 3) - Hyperplane result(p0.size()); - result.normal() = (p2 - p0).cross(p1 - p0).normalized(); - result.offset() = -result.normal().eigen2_dot(p0); - return result; - } - - /** Constructs a hyperplane passing through the parametrized line \a parametrized. - * If the dimension of the ambient space is greater than 2, then there isn't uniqueness, - * so an arbitrary choice is made. - */ - // FIXME to be consitent with the rest this could be implemented as a static Through function ?? - explicit Hyperplane(const ParametrizedLine& parametrized) - { - normal() = parametrized.direction().unitOrthogonal(); - offset() = -normal().eigen2_dot(parametrized.origin()); - } - - ~Hyperplane() {} - - /** \returns the dimension in which the plane holds */ - inline int dim() const { return int(AmbientDimAtCompileTime)==Dynamic ? m_coeffs.size()-1 : int(AmbientDimAtCompileTime); } - - /** normalizes \c *this */ - void normalize(void) - { - m_coeffs /= normal().norm(); - } - - /** \returns the signed distance between the plane \c *this and a point \a p. - * \sa absDistance() - */ - inline Scalar signedDistance(const VectorType& p) const { return p.eigen2_dot(normal()) + offset(); } - - /** \returns the absolute distance between the plane \c *this and a point \a p. - * \sa signedDistance() - */ - inline Scalar absDistance(const VectorType& p) const { return ei_abs(signedDistance(p)); } - - /** \returns the projection of a point \a p onto the plane \c *this. - */ - inline VectorType projection(const VectorType& p) const { return p - signedDistance(p) * normal(); } - - /** \returns a constant reference to the unit normal vector of the plane, which corresponds - * to the linear part of the implicit equation. - */ - inline const NormalReturnType normal() const { return NormalReturnType(*const_cast(&m_coeffs),0,0,dim(),1); } - - /** \returns a non-constant reference to the unit normal vector of the plane, which corresponds - * to the linear part of the implicit equation. - */ - inline NormalReturnType normal() { return NormalReturnType(m_coeffs,0,0,dim(),1); } - - /** \returns the distance to the origin, which is also the "constant term" of the implicit equation - * \warning the vector normal is assumed to be normalized. - */ - inline const Scalar& offset() const { return m_coeffs.coeff(dim()); } - - /** \returns a non-constant reference to the distance to the origin, which is also the constant part - * of the implicit equation */ - inline Scalar& offset() { return m_coeffs(dim()); } - - /** \returns a constant reference to the coefficients c_i of the plane equation: - * \f$ c_0*x_0 + ... + c_{d-1}*x_{d-1} + c_d = 0 \f$ - */ - inline const Coefficients& coeffs() const { return m_coeffs; } - - /** \returns a non-constant reference to the coefficients c_i of the plane equation: - * \f$ c_0*x_0 + ... + c_{d-1}*x_{d-1} + c_d = 0 \f$ - */ - inline Coefficients& coeffs() { return m_coeffs; } - - /** \returns the intersection of *this with \a other. - * - * \warning The ambient space must be a plane, i.e. have dimension 2, so that \c *this and \a other are lines. - * - * \note If \a other is approximately parallel to *this, this method will return any point on *this. - */ - VectorType intersection(const Hyperplane& other) - { - EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(VectorType, 2) - Scalar det = coeffs().coeff(0) * other.coeffs().coeff(1) - coeffs().coeff(1) * other.coeffs().coeff(0); - // since the line equations ax+by=c are normalized with a^2+b^2=1, the following tests - // whether the two lines are approximately parallel. - if(ei_isMuchSmallerThan(det, Scalar(1))) - { // special case where the two lines are approximately parallel. Pick any point on the first line. - if(ei_abs(coeffs().coeff(1))>ei_abs(coeffs().coeff(0))) - return VectorType(coeffs().coeff(1), -coeffs().coeff(2)/coeffs().coeff(1)-coeffs().coeff(0)); - else - return VectorType(-coeffs().coeff(2)/coeffs().coeff(0)-coeffs().coeff(1), coeffs().coeff(0)); - } - else - { // general case - Scalar invdet = Scalar(1) / det; - return VectorType(invdet*(coeffs().coeff(1)*other.coeffs().coeff(2)-other.coeffs().coeff(1)*coeffs().coeff(2)), - invdet*(other.coeffs().coeff(0)*coeffs().coeff(2)-coeffs().coeff(0)*other.coeffs().coeff(2))); - } - } - - /** Applies the transformation matrix \a mat to \c *this and returns a reference to \c *this. - * - * \param mat the Dim x Dim transformation matrix - * \param traits specifies whether the matrix \a mat represents an Isometry - * or a more generic Affine transformation. The default is Affine. - */ - template - inline Hyperplane& transform(const MatrixBase& mat, TransformTraits traits = Affine) - { - if (traits==Affine) - normal() = mat.inverse().transpose() * normal(); - else if (traits==Isometry) - normal() = mat * normal(); - else - { - ei_assert("invalid traits value in Hyperplane::transform()"); - } - return *this; - } - - /** Applies the transformation \a t to \c *this and returns a reference to \c *this. - * - * \param t the transformation of dimension Dim - * \param traits specifies whether the transformation \a t represents an Isometry - * or a more generic Affine transformation. The default is Affine. - * Other kind of transformations are not supported. - */ - inline Hyperplane& transform(const Transform& t, - TransformTraits traits = Affine) - { - transform(t.linear(), traits); - offset() -= t.translation().eigen2_dot(normal()); - return *this; - } - - /** \returns \c *this with scalar type casted to \a NewScalarType - * - * Note that if \a NewScalarType is equal to the current scalar type of \c *this - * then this function smartly returns a const reference to \c *this. - */ - template - inline typename internal::cast_return_type >::type cast() const - { - return typename internal::cast_return_type >::type(*this); - } - - /** Copy constructor with scalar type conversion */ - template - inline explicit Hyperplane(const Hyperplane& other) - { m_coeffs = other.coeffs().template cast(); } - - /** \returns \c true if \c *this is approximately equal to \a other, within the precision - * determined by \a prec. - * - * \sa MatrixBase::isApprox() */ - bool isApprox(const Hyperplane& other, typename NumTraits::Real prec = precision()) const - { return m_coeffs.isApprox(other.m_coeffs, prec); } - -protected: - - Coefficients m_coeffs; -}; - -} // end namespace Eigen diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/ParametrizedLine.h b/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/ParametrizedLine.h deleted file mode 100644 index 9b57b7e0..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/ParametrizedLine.h +++ /dev/null @@ -1,141 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud -// Copyright (C) 2008 Benoit Jacob -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -// no include guard, we'll include this twice from All.h from Eigen2Support, and it's internal anyway - -namespace Eigen { - -/** \geometry_module \ingroup Geometry_Module - * - * \class ParametrizedLine - * - * \brief A parametrized line - * - * A parametrized line is defined by an origin point \f$ \mathbf{o} \f$ and a unit - * direction vector \f$ \mathbf{d} \f$ such that the line corresponds to - * the set \f$ l(t) = \mathbf{o} + t \mathbf{d} \f$, \f$ l \in \mathbf{R} \f$. - * - * \param _Scalar the scalar type, i.e., the type of the coefficients - * \param _AmbientDim the dimension of the ambient space, can be a compile time value or Dynamic. - */ -template -class ParametrizedLine -{ -public: - EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim) - enum { AmbientDimAtCompileTime = _AmbientDim }; - typedef _Scalar Scalar; - typedef typename NumTraits::Real RealScalar; - typedef Matrix VectorType; - - /** Default constructor without initialization */ - inline ParametrizedLine() {} - - /** Constructs a dynamic-size line with \a _dim the dimension - * of the ambient space */ - inline explicit ParametrizedLine(int _dim) : m_origin(_dim), m_direction(_dim) {} - - /** Initializes a parametrized line of direction \a direction and origin \a origin. - * \warning the vector direction is assumed to be normalized. - */ - ParametrizedLine(const VectorType& origin, const VectorType& direction) - : m_origin(origin), m_direction(direction) {} - - explicit ParametrizedLine(const Hyperplane<_Scalar, _AmbientDim>& hyperplane); - - /** Constructs a parametrized line going from \a p0 to \a p1. */ - static inline ParametrizedLine Through(const VectorType& p0, const VectorType& p1) - { return ParametrizedLine(p0, (p1-p0).normalized()); } - - ~ParametrizedLine() {} - - /** \returns the dimension in which the line holds */ - inline int dim() const { return m_direction.size(); } - - const VectorType& origin() const { return m_origin; } - VectorType& origin() { return m_origin; } - - const VectorType& direction() const { return m_direction; } - VectorType& direction() { return m_direction; } - - /** \returns the squared distance of a point \a p to its projection onto the line \c *this. - * \sa distance() - */ - RealScalar squaredDistance(const VectorType& p) const - { - VectorType diff = p-origin(); - return (diff - diff.eigen2_dot(direction())* direction()).squaredNorm(); - } - /** \returns the distance of a point \a p to its projection onto the line \c *this. - * \sa squaredDistance() - */ - RealScalar distance(const VectorType& p) const { return ei_sqrt(squaredDistance(p)); } - - /** \returns the projection of a point \a p onto the line \c *this. */ - VectorType projection(const VectorType& p) const - { return origin() + (p-origin()).eigen2_dot(direction()) * direction(); } - - Scalar intersection(const Hyperplane<_Scalar, _AmbientDim>& hyperplane); - - /** \returns \c *this with scalar type casted to \a NewScalarType - * - * Note that if \a NewScalarType is equal to the current scalar type of \c *this - * then this function smartly returns a const reference to \c *this. - */ - template - inline typename internal::cast_return_type >::type cast() const - { - return typename internal::cast_return_type >::type(*this); - } - - /** Copy constructor with scalar type conversion */ - template - inline explicit ParametrizedLine(const ParametrizedLine& other) - { - m_origin = other.origin().template cast(); - m_direction = other.direction().template cast(); - } - - /** \returns \c true if \c *this is approximately equal to \a other, within the precision - * determined by \a prec. - * - * \sa MatrixBase::isApprox() */ - bool isApprox(const ParametrizedLine& other, typename NumTraits::Real prec = precision()) const - { return m_origin.isApprox(other.m_origin, prec) && m_direction.isApprox(other.m_direction, prec); } - -protected: - - VectorType m_origin, m_direction; -}; - -/** Constructs a parametrized line from a 2D hyperplane - * - * \warning the ambient space must have dimension 2 such that the hyperplane actually describes a line - */ -template -inline ParametrizedLine<_Scalar, _AmbientDim>::ParametrizedLine(const Hyperplane<_Scalar, _AmbientDim>& hyperplane) -{ - EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(VectorType, 2) - direction() = hyperplane.normal().unitOrthogonal(); - origin() = -hyperplane.normal()*hyperplane.offset(); -} - -/** \returns the parameter value of the intersection between \c *this and the given hyperplane - */ -template -inline _Scalar ParametrizedLine<_Scalar, _AmbientDim>::intersection(const Hyperplane<_Scalar, _AmbientDim>& hyperplane) -{ - return -(hyperplane.offset()+origin().eigen2_dot(hyperplane.normal())) - /(direction().eigen2_dot(hyperplane.normal())); -} - -} // end namespace Eigen diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/Quaternion.h b/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/Quaternion.h deleted file mode 100644 index 4b6390cf..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/Quaternion.h +++ /dev/null @@ -1,495 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -// no include guard, we'll include this twice from All.h from Eigen2Support, and it's internal anyway - -namespace Eigen { - -template -struct ei_quaternion_assign_impl; - -/** \geometry_module \ingroup Geometry_Module - * - * \class Quaternion - * - * \brief The quaternion class used to represent 3D orientations and rotations - * - * \param _Scalar the scalar type, i.e., the type of the coefficients - * - * This class represents a quaternion \f$ w+xi+yj+zk \f$ that is a convenient representation of - * orientations and rotations of objects in three dimensions. Compared to other representations - * like Euler angles or 3x3 matrices, quatertions offer the following advantages: - * \li \b compact storage (4 scalars) - * \li \b efficient to compose (28 flops), - * \li \b stable spherical interpolation - * - * The following two typedefs are provided for convenience: - * \li \c Quaternionf for \c float - * \li \c Quaterniond for \c double - * - * \sa class AngleAxis, class Transform - */ - -template struct ei_traits > -{ - typedef _Scalar Scalar; -}; - -template -class Quaternion : public RotationBase,3> -{ - typedef RotationBase,3> Base; - -public: - EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,4) - - using Base::operator*; - - /** the scalar type of the coefficients */ - typedef _Scalar Scalar; - - /** the type of the Coefficients 4-vector */ - typedef Matrix Coefficients; - /** the type of a 3D vector */ - typedef Matrix Vector3; - /** the equivalent rotation matrix type */ - typedef Matrix Matrix3; - /** the equivalent angle-axis type */ - typedef AngleAxis AngleAxisType; - - /** \returns the \c x coefficient */ - inline Scalar x() const { return m_coeffs.coeff(0); } - /** \returns the \c y coefficient */ - inline Scalar y() const { return m_coeffs.coeff(1); } - /** \returns the \c z coefficient */ - inline Scalar z() const { return m_coeffs.coeff(2); } - /** \returns the \c w coefficient */ - inline Scalar w() const { return m_coeffs.coeff(3); } - - /** \returns a reference to the \c x coefficient */ - inline Scalar& x() { return m_coeffs.coeffRef(0); } - /** \returns a reference to the \c y coefficient */ - inline Scalar& y() { return m_coeffs.coeffRef(1); } - /** \returns a reference to the \c z coefficient */ - inline Scalar& z() { return m_coeffs.coeffRef(2); } - /** \returns a reference to the \c w coefficient */ - inline Scalar& w() { return m_coeffs.coeffRef(3); } - - /** \returns a read-only vector expression of the imaginary part (x,y,z) */ - inline const Block vec() const { return m_coeffs.template start<3>(); } - - /** \returns a vector expression of the imaginary part (x,y,z) */ - inline Block vec() { return m_coeffs.template start<3>(); } - - /** \returns a read-only vector expression of the coefficients (x,y,z,w) */ - inline const Coefficients& coeffs() const { return m_coeffs; } - - /** \returns a vector expression of the coefficients (x,y,z,w) */ - inline Coefficients& coeffs() { return m_coeffs; } - - /** Default constructor leaving the quaternion uninitialized. */ - inline Quaternion() {} - - /** Constructs and initializes the quaternion \f$ w+xi+yj+zk \f$ from - * its four coefficients \a w, \a x, \a y and \a z. - * - * \warning Note the order of the arguments: the real \a w coefficient first, - * while internally the coefficients are stored in the following order: - * [\c x, \c y, \c z, \c w] - */ - inline Quaternion(Scalar w, Scalar x, Scalar y, Scalar z) - { m_coeffs << x, y, z, w; } - - /** Copy constructor */ - inline Quaternion(const Quaternion& other) { m_coeffs = other.m_coeffs; } - - /** Constructs and initializes a quaternion from the angle-axis \a aa */ - explicit inline Quaternion(const AngleAxisType& aa) { *this = aa; } - - /** Constructs and initializes a quaternion from either: - * - a rotation matrix expression, - * - a 4D vector expression representing quaternion coefficients. - * \sa operator=(MatrixBase) - */ - template - explicit inline Quaternion(const MatrixBase& other) { *this = other; } - - Quaternion& operator=(const Quaternion& other); - Quaternion& operator=(const AngleAxisType& aa); - template - Quaternion& operator=(const MatrixBase& m); - - /** \returns a quaternion representing an identity rotation - * \sa MatrixBase::Identity() - */ - static inline Quaternion Identity() { return Quaternion(1, 0, 0, 0); } - - /** \sa Quaternion::Identity(), MatrixBase::setIdentity() - */ - inline Quaternion& setIdentity() { m_coeffs << 0, 0, 0, 1; return *this; } - - /** \returns the squared norm of the quaternion's coefficients - * \sa Quaternion::norm(), MatrixBase::squaredNorm() - */ - inline Scalar squaredNorm() const { return m_coeffs.squaredNorm(); } - - /** \returns the norm of the quaternion's coefficients - * \sa Quaternion::squaredNorm(), MatrixBase::norm() - */ - inline Scalar norm() const { return m_coeffs.norm(); } - - /** Normalizes the quaternion \c *this - * \sa normalized(), MatrixBase::normalize() */ - inline void normalize() { m_coeffs.normalize(); } - /** \returns a normalized version of \c *this - * \sa normalize(), MatrixBase::normalized() */ - inline Quaternion normalized() const { return Quaternion(m_coeffs.normalized()); } - - /** \returns the dot product of \c *this and \a other - * Geometrically speaking, the dot product of two unit quaternions - * corresponds to the cosine of half the angle between the two rotations. - * \sa angularDistance() - */ - inline Scalar eigen2_dot(const Quaternion& other) const { return m_coeffs.eigen2_dot(other.m_coeffs); } - - inline Scalar angularDistance(const Quaternion& other) const; - - Matrix3 toRotationMatrix(void) const; - - template - Quaternion& setFromTwoVectors(const MatrixBase& a, const MatrixBase& b); - - inline Quaternion operator* (const Quaternion& q) const; - inline Quaternion& operator*= (const Quaternion& q); - - Quaternion inverse(void) const; - Quaternion conjugate(void) const; - - Quaternion slerp(Scalar t, const Quaternion& other) const; - - template - Vector3 operator* (const MatrixBase& vec) const; - - /** \returns \c *this with scalar type casted to \a NewScalarType - * - * Note that if \a NewScalarType is equal to the current scalar type of \c *this - * then this function smartly returns a const reference to \c *this. - */ - template - inline typename internal::cast_return_type >::type cast() const - { return typename internal::cast_return_type >::type(*this); } - - /** Copy constructor with scalar type conversion */ - template - inline explicit Quaternion(const Quaternion& other) - { m_coeffs = other.coeffs().template cast(); } - - /** \returns \c true if \c *this is approximately equal to \a other, within the precision - * determined by \a prec. - * - * \sa MatrixBase::isApprox() */ - bool isApprox(const Quaternion& other, typename NumTraits::Real prec = precision()) const - { return m_coeffs.isApprox(other.m_coeffs, prec); } - -protected: - Coefficients m_coeffs; -}; - -/** \ingroup Geometry_Module - * single precision quaternion type */ -typedef Quaternion Quaternionf; -/** \ingroup Geometry_Module - * double precision quaternion type */ -typedef Quaternion Quaterniond; - -// Generic Quaternion * Quaternion product -template inline Quaternion -ei_quaternion_product(const Quaternion& a, const Quaternion& b) -{ - return Quaternion - ( - a.w() * b.w() - a.x() * b.x() - a.y() * b.y() - a.z() * b.z(), - a.w() * b.x() + a.x() * b.w() + a.y() * b.z() - a.z() * b.y(), - a.w() * b.y() + a.y() * b.w() + a.z() * b.x() - a.x() * b.z(), - a.w() * b.z() + a.z() * b.w() + a.x() * b.y() - a.y() * b.x() - ); -} - -/** \returns the concatenation of two rotations as a quaternion-quaternion product */ -template -inline Quaternion Quaternion::operator* (const Quaternion& other) const -{ - return ei_quaternion_product(*this,other); -} - -/** \sa operator*(Quaternion) */ -template -inline Quaternion& Quaternion::operator*= (const Quaternion& other) -{ - return (*this = *this * other); -} - -/** Rotation of a vector by a quaternion. - * \remarks If the quaternion is used to rotate several points (>1) - * then it is much more efficient to first convert it to a 3x3 Matrix. - * Comparison of the operation cost for n transformations: - * - Quaternion: 30n - * - Via a Matrix3: 24 + 15n - */ -template -template -inline typename Quaternion::Vector3 -Quaternion::operator* (const MatrixBase& v) const -{ - // Note that this algorithm comes from the optimization by hand - // of the conversion to a Matrix followed by a Matrix/Vector product. - // It appears to be much faster than the common algorithm found - // in the litterature (30 versus 39 flops). It also requires two - // Vector3 as temporaries. - Vector3 uv; - uv = 2 * this->vec().cross(v); - return v + this->w() * uv + this->vec().cross(uv); -} - -template -inline Quaternion& Quaternion::operator=(const Quaternion& other) -{ - m_coeffs = other.m_coeffs; - return *this; -} - -/** Set \c *this from an angle-axis \a aa and returns a reference to \c *this - */ -template -inline Quaternion& Quaternion::operator=(const AngleAxisType& aa) -{ - Scalar ha = Scalar(0.5)*aa.angle(); // Scalar(0.5) to suppress precision loss warnings - this->w() = ei_cos(ha); - this->vec() = ei_sin(ha) * aa.axis(); - return *this; -} - -/** Set \c *this from the expression \a xpr: - * - if \a xpr is a 4x1 vector, then \a xpr is assumed to be a quaternion - * - if \a xpr is a 3x3 matrix, then \a xpr is assumed to be rotation matrix - * and \a xpr is converted to a quaternion - */ -template -template -inline Quaternion& Quaternion::operator=(const MatrixBase& xpr) -{ - ei_quaternion_assign_impl::run(*this, xpr.derived()); - return *this; -} - -/** Convert the quaternion to a 3x3 rotation matrix */ -template -inline typename Quaternion::Matrix3 -Quaternion::toRotationMatrix(void) const -{ - // NOTE if inlined, then gcc 4.2 and 4.4 get rid of the temporary (not gcc 4.3 !!) - // if not inlined then the cost of the return by value is huge ~ +35%, - // however, not inlining this function is an order of magnitude slower, so - // it has to be inlined, and so the return by value is not an issue - Matrix3 res; - - const Scalar tx = Scalar(2)*this->x(); - const Scalar ty = Scalar(2)*this->y(); - const Scalar tz = Scalar(2)*this->z(); - const Scalar twx = tx*this->w(); - const Scalar twy = ty*this->w(); - const Scalar twz = tz*this->w(); - const Scalar txx = tx*this->x(); - const Scalar txy = ty*this->x(); - const Scalar txz = tz*this->x(); - const Scalar tyy = ty*this->y(); - const Scalar tyz = tz*this->y(); - const Scalar tzz = tz*this->z(); - - res.coeffRef(0,0) = Scalar(1)-(tyy+tzz); - res.coeffRef(0,1) = txy-twz; - res.coeffRef(0,2) = txz+twy; - res.coeffRef(1,0) = txy+twz; - res.coeffRef(1,1) = Scalar(1)-(txx+tzz); - res.coeffRef(1,2) = tyz-twx; - res.coeffRef(2,0) = txz-twy; - res.coeffRef(2,1) = tyz+twx; - res.coeffRef(2,2) = Scalar(1)-(txx+tyy); - - return res; -} - -/** Sets *this to be a quaternion representing a rotation sending the vector \a a to the vector \a b. - * - * \returns a reference to *this. - * - * Note that the two input vectors do \b not have to be normalized. - */ -template -template -inline Quaternion& Quaternion::setFromTwoVectors(const MatrixBase& a, const MatrixBase& b) -{ - Vector3 v0 = a.normalized(); - Vector3 v1 = b.normalized(); - Scalar c = v0.eigen2_dot(v1); - - // if dot == 1, vectors are the same - if (ei_isApprox(c,Scalar(1))) - { - // set to identity - this->w() = 1; this->vec().setZero(); - return *this; - } - // if dot == -1, vectors are opposites - if (ei_isApprox(c,Scalar(-1))) - { - this->vec() = v0.unitOrthogonal(); - this->w() = 0; - return *this; - } - - Vector3 axis = v0.cross(v1); - Scalar s = ei_sqrt((Scalar(1)+c)*Scalar(2)); - Scalar invs = Scalar(1)/s; - this->vec() = axis * invs; - this->w() = s * Scalar(0.5); - - return *this; -} - -/** \returns the multiplicative inverse of \c *this - * Note that in most cases, i.e., if you simply want the opposite rotation, - * and/or the quaternion is normalized, then it is enough to use the conjugate. - * - * \sa Quaternion::conjugate() - */ -template -inline Quaternion Quaternion::inverse() const -{ - // FIXME should this function be called multiplicativeInverse and conjugate() be called inverse() or opposite() ?? - Scalar n2 = this->squaredNorm(); - if (n2 > 0) - return Quaternion(conjugate().coeffs() / n2); - else - { - // return an invalid result to flag the error - return Quaternion(Coefficients::Zero()); - } -} - -/** \returns the conjugate of the \c *this which is equal to the multiplicative inverse - * if the quaternion is normalized. - * The conjugate of a quaternion represents the opposite rotation. - * - * \sa Quaternion::inverse() - */ -template -inline Quaternion Quaternion::conjugate() const -{ - return Quaternion(this->w(),-this->x(),-this->y(),-this->z()); -} - -/** \returns the angle (in radian) between two rotations - * \sa eigen2_dot() - */ -template -inline Scalar Quaternion::angularDistance(const Quaternion& other) const -{ - double d = ei_abs(this->eigen2_dot(other)); - if (d>=1.0) - return 0; - return Scalar(2) * std::acos(d); -} - -/** \returns the spherical linear interpolation between the two quaternions - * \c *this and \a other at the parameter \a t - */ -template -Quaternion Quaternion::slerp(Scalar t, const Quaternion& other) const -{ - static const Scalar one = Scalar(1) - machine_epsilon(); - Scalar d = this->eigen2_dot(other); - Scalar absD = ei_abs(d); - - Scalar scale0; - Scalar scale1; - - if (absD>=one) - { - scale0 = Scalar(1) - t; - scale1 = t; - } - else - { - // theta is the angle between the 2 quaternions - Scalar theta = std::acos(absD); - Scalar sinTheta = ei_sin(theta); - - scale0 = ei_sin( ( Scalar(1) - t ) * theta) / sinTheta; - scale1 = ei_sin( ( t * theta) ) / sinTheta; - if (d<0) - scale1 = -scale1; - } - - return Quaternion(scale0 * coeffs() + scale1 * other.coeffs()); -} - -// set from a rotation matrix -template -struct ei_quaternion_assign_impl -{ - typedef typename Other::Scalar Scalar; - static inline void run(Quaternion& q, const Other& mat) - { - // This algorithm comes from "Quaternion Calculus and Fast Animation", - // Ken Shoemake, 1987 SIGGRAPH course notes - Scalar t = mat.trace(); - if (t > 0) - { - t = ei_sqrt(t + Scalar(1.0)); - q.w() = Scalar(0.5)*t; - t = Scalar(0.5)/t; - q.x() = (mat.coeff(2,1) - mat.coeff(1,2)) * t; - q.y() = (mat.coeff(0,2) - mat.coeff(2,0)) * t; - q.z() = (mat.coeff(1,0) - mat.coeff(0,1)) * t; - } - else - { - int i = 0; - if (mat.coeff(1,1) > mat.coeff(0,0)) - i = 1; - if (mat.coeff(2,2) > mat.coeff(i,i)) - i = 2; - int j = (i+1)%3; - int k = (j+1)%3; - - t = ei_sqrt(mat.coeff(i,i)-mat.coeff(j,j)-mat.coeff(k,k) + Scalar(1.0)); - q.coeffs().coeffRef(i) = Scalar(0.5) * t; - t = Scalar(0.5)/t; - q.w() = (mat.coeff(k,j)-mat.coeff(j,k))*t; - q.coeffs().coeffRef(j) = (mat.coeff(j,i)+mat.coeff(i,j))*t; - q.coeffs().coeffRef(k) = (mat.coeff(k,i)+mat.coeff(i,k))*t; - } - } -}; - -// set from a vector of coefficients assumed to be a quaternion -template -struct ei_quaternion_assign_impl -{ - typedef typename Other::Scalar Scalar; - static inline void run(Quaternion& q, const Other& vec) - { - q.coeffs() = vec; - } -}; - -} // end namespace Eigen diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/Rotation2D.h b/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/Rotation2D.h deleted file mode 100644 index 19b8582a..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/Rotation2D.h +++ /dev/null @@ -1,145 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -// no include guard, we'll include this twice from All.h from Eigen2Support, and it's internal anyway - -namespace Eigen { - -/** \geometry_module \ingroup Geometry_Module - * - * \class Rotation2D - * - * \brief Represents a rotation/orientation in a 2 dimensional space. - * - * \param _Scalar the scalar type, i.e., the type of the coefficients - * - * This class is equivalent to a single scalar representing a counter clock wise rotation - * as a single angle in radian. It provides some additional features such as the automatic - * conversion from/to a 2x2 rotation matrix. Moreover this class aims to provide a similar - * interface to Quaternion in order to facilitate the writing of generic algorithms - * dealing with rotations. - * - * \sa class Quaternion, class Transform - */ -template struct ei_traits > -{ - typedef _Scalar Scalar; -}; - -template -class Rotation2D : public RotationBase,2> -{ - typedef RotationBase,2> Base; - -public: - - using Base::operator*; - - enum { Dim = 2 }; - /** the scalar type of the coefficients */ - typedef _Scalar Scalar; - typedef Matrix Vector2; - typedef Matrix Matrix2; - -protected: - - Scalar m_angle; - -public: - - /** Construct a 2D counter clock wise rotation from the angle \a a in radian. */ - inline Rotation2D(Scalar a) : m_angle(a) {} - - /** \returns the rotation angle */ - inline Scalar angle() const { return m_angle; } - - /** \returns a read-write reference to the rotation angle */ - inline Scalar& angle() { return m_angle; } - - /** \returns the inverse rotation */ - inline Rotation2D inverse() const { return -m_angle; } - - /** Concatenates two rotations */ - inline Rotation2D operator*(const Rotation2D& other) const - { return m_angle + other.m_angle; } - - /** Concatenates two rotations */ - inline Rotation2D& operator*=(const Rotation2D& other) - { return m_angle += other.m_angle; return *this; } - - /** Applies the rotation to a 2D vector */ - Vector2 operator* (const Vector2& vec) const - { return toRotationMatrix() * vec; } - - template - Rotation2D& fromRotationMatrix(const MatrixBase& m); - Matrix2 toRotationMatrix(void) const; - - /** \returns the spherical interpolation between \c *this and \a other using - * parameter \a t. It is in fact equivalent to a linear interpolation. - */ - inline Rotation2D slerp(Scalar t, const Rotation2D& other) const - { return m_angle * (1-t) + other.angle() * t; } - - /** \returns \c *this with scalar type casted to \a NewScalarType - * - * Note that if \a NewScalarType is equal to the current scalar type of \c *this - * then this function smartly returns a const reference to \c *this. - */ - template - inline typename internal::cast_return_type >::type cast() const - { return typename internal::cast_return_type >::type(*this); } - - /** Copy constructor with scalar type conversion */ - template - inline explicit Rotation2D(const Rotation2D& other) - { - m_angle = Scalar(other.angle()); - } - - /** \returns \c true if \c *this is approximately equal to \a other, within the precision - * determined by \a prec. - * - * \sa MatrixBase::isApprox() */ - bool isApprox(const Rotation2D& other, typename NumTraits::Real prec = precision()) const - { return ei_isApprox(m_angle,other.m_angle, prec); } -}; - -/** \ingroup Geometry_Module - * single precision 2D rotation type */ -typedef Rotation2D Rotation2Df; -/** \ingroup Geometry_Module - * double precision 2D rotation type */ -typedef Rotation2D Rotation2Dd; - -/** Set \c *this from a 2x2 rotation matrix \a mat. - * In other words, this function extract the rotation angle - * from the rotation matrix. - */ -template -template -Rotation2D& Rotation2D::fromRotationMatrix(const MatrixBase& mat) -{ - EIGEN_STATIC_ASSERT(Derived::RowsAtCompileTime==2 && Derived::ColsAtCompileTime==2,YOU_MADE_A_PROGRAMMING_MISTAKE) - m_angle = ei_atan2(mat.coeff(1,0), mat.coeff(0,0)); - return *this; -} - -/** Constructs and \returns an equivalent 2x2 rotation matrix. - */ -template -typename Rotation2D::Matrix2 -Rotation2D::toRotationMatrix(void) const -{ - Scalar sinA = ei_sin(m_angle); - Scalar cosA = ei_cos(m_angle); - return (Matrix2() << cosA, -sinA, sinA, cosA).finished(); -} - -} // end namespace Eigen diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/RotationBase.h b/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/RotationBase.h deleted file mode 100644 index b1c8f38d..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/RotationBase.h +++ /dev/null @@ -1,123 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -// no include guard, we'll include this twice from All.h from Eigen2Support, and it's internal anyway - -namespace Eigen { - -// this file aims to contains the various representations of rotation/orientation -// in 2D and 3D space excepted Matrix and Quaternion. - -/** \class RotationBase - * - * \brief Common base class for compact rotation representations - * - * \param Derived is the derived type, i.e., a rotation type - * \param _Dim the dimension of the space - */ -template -class RotationBase -{ - public: - enum { Dim = _Dim }; - /** the scalar type of the coefficients */ - typedef typename ei_traits::Scalar Scalar; - - /** corresponding linear transformation matrix type */ - typedef Matrix RotationMatrixType; - - inline const Derived& derived() const { return *static_cast(this); } - inline Derived& derived() { return *static_cast(this); } - - /** \returns an equivalent rotation matrix */ - inline RotationMatrixType toRotationMatrix() const { return derived().toRotationMatrix(); } - - /** \returns the inverse rotation */ - inline Derived inverse() const { return derived().inverse(); } - - /** \returns the concatenation of the rotation \c *this with a translation \a t */ - inline Transform operator*(const Translation& t) const - { return toRotationMatrix() * t; } - - /** \returns the concatenation of the rotation \c *this with a scaling \a s */ - inline RotationMatrixType operator*(const Scaling& s) const - { return toRotationMatrix() * s; } - - /** \returns the concatenation of the rotation \c *this with an affine transformation \a t */ - inline Transform operator*(const Transform& t) const - { return toRotationMatrix() * t; } -}; - -/** \geometry_module - * - * Constructs a Dim x Dim rotation matrix from the rotation \a r - */ -template -template -Matrix<_Scalar, _Rows, _Cols, _Storage, _MaxRows, _MaxCols> -::Matrix(const RotationBase& r) -{ - EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Matrix,int(OtherDerived::Dim),int(OtherDerived::Dim)) - *this = r.toRotationMatrix(); -} - -/** \geometry_module - * - * Set a Dim x Dim rotation matrix from the rotation \a r - */ -template -template -Matrix<_Scalar, _Rows, _Cols, _Storage, _MaxRows, _MaxCols>& -Matrix<_Scalar, _Rows, _Cols, _Storage, _MaxRows, _MaxCols> -::operator=(const RotationBase& r) -{ - EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Matrix,int(OtherDerived::Dim),int(OtherDerived::Dim)) - return *this = r.toRotationMatrix(); -} - -/** \internal - * - * Helper function to return an arbitrary rotation object to a rotation matrix. - * - * \param Scalar the numeric type of the matrix coefficients - * \param Dim the dimension of the current space - * - * It returns a Dim x Dim fixed size matrix. - * - * Default specializations are provided for: - * - any scalar type (2D), - * - any matrix expression, - * - any type based on RotationBase (e.g., Quaternion, AngleAxis, Rotation2D) - * - * Currently ei_toRotationMatrix is only used by Transform. - * - * \sa class Transform, class Rotation2D, class Quaternion, class AngleAxis - */ -template -static inline Matrix ei_toRotationMatrix(const Scalar& s) -{ - EIGEN_STATIC_ASSERT(Dim==2,YOU_MADE_A_PROGRAMMING_MISTAKE) - return Rotation2D(s).toRotationMatrix(); -} - -template -static inline Matrix ei_toRotationMatrix(const RotationBase& r) -{ - return r.toRotationMatrix(); -} - -template -static inline const MatrixBase& ei_toRotationMatrix(const MatrixBase& mat) -{ - EIGEN_STATIC_ASSERT(OtherDerived::RowsAtCompileTime==Dim && OtherDerived::ColsAtCompileTime==Dim, - YOU_MADE_A_PROGRAMMING_MISTAKE) - return mat; -} - -} // end namespace Eigen diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/Scaling.h b/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/Scaling.h deleted file mode 100644 index b8fa6cd3..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/Scaling.h +++ /dev/null @@ -1,167 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -// no include guard, we'll include this twice from All.h from Eigen2Support, and it's internal anyway - -namespace Eigen { - -/** \geometry_module \ingroup Geometry_Module - * - * \class Scaling - * - * \brief Represents a possibly non uniform scaling transformation - * - * \param _Scalar the scalar type, i.e., the type of the coefficients. - * \param _Dim the dimension of the space, can be a compile time value or Dynamic - * - * \note This class is not aimed to be used to store a scaling transformation, - * but rather to make easier the constructions and updates of Transform objects. - * - * \sa class Translation, class Transform - */ -template -class Scaling -{ -public: - EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_Dim) - /** dimension of the space */ - enum { Dim = _Dim }; - /** the scalar type of the coefficients */ - typedef _Scalar Scalar; - /** corresponding vector type */ - typedef Matrix VectorType; - /** corresponding linear transformation matrix type */ - typedef Matrix LinearMatrixType; - /** corresponding translation type */ - typedef Translation TranslationType; - /** corresponding affine transformation type */ - typedef Transform TransformType; - -protected: - - VectorType m_coeffs; - -public: - - /** Default constructor without initialization. */ - Scaling() {} - /** Constructs and initialize a uniform scaling transformation */ - explicit inline Scaling(const Scalar& s) { m_coeffs.setConstant(s); } - /** 2D only */ - inline Scaling(const Scalar& sx, const Scalar& sy) - { - ei_assert(Dim==2); - m_coeffs.x() = sx; - m_coeffs.y() = sy; - } - /** 3D only */ - inline Scaling(const Scalar& sx, const Scalar& sy, const Scalar& sz) - { - ei_assert(Dim==3); - m_coeffs.x() = sx; - m_coeffs.y() = sy; - m_coeffs.z() = sz; - } - /** Constructs and initialize the scaling transformation from a vector of scaling coefficients */ - explicit inline Scaling(const VectorType& coeffs) : m_coeffs(coeffs) {} - - const VectorType& coeffs() const { return m_coeffs; } - VectorType& coeffs() { return m_coeffs; } - - /** Concatenates two scaling */ - inline Scaling operator* (const Scaling& other) const - { return Scaling(coeffs().cwise() * other.coeffs()); } - - /** Concatenates a scaling and a translation */ - inline TransformType operator* (const TranslationType& t) const; - - /** Concatenates a scaling and an affine transformation */ - inline TransformType operator* (const TransformType& t) const; - - /** Concatenates a scaling and a linear transformation matrix */ - // TODO returns an expression - inline LinearMatrixType operator* (const LinearMatrixType& other) const - { return coeffs().asDiagonal() * other; } - - /** Concatenates a linear transformation matrix and a scaling */ - // TODO returns an expression - friend inline LinearMatrixType operator* (const LinearMatrixType& other, const Scaling& s) - { return other * s.coeffs().asDiagonal(); } - - template - inline LinearMatrixType operator*(const RotationBase& r) const - { return *this * r.toRotationMatrix(); } - - /** Applies scaling to vector */ - inline VectorType operator* (const VectorType& other) const - { return coeffs().asDiagonal() * other; } - - /** \returns the inverse scaling */ - inline Scaling inverse() const - { return Scaling(coeffs().cwise().inverse()); } - - inline Scaling& operator=(const Scaling& other) - { - m_coeffs = other.m_coeffs; - return *this; - } - - /** \returns \c *this with scalar type casted to \a NewScalarType - * - * Note that if \a NewScalarType is equal to the current scalar type of \c *this - * then this function smartly returns a const reference to \c *this. - */ - template - inline typename internal::cast_return_type >::type cast() const - { return typename internal::cast_return_type >::type(*this); } - - /** Copy constructor with scalar type conversion */ - template - inline explicit Scaling(const Scaling& other) - { m_coeffs = other.coeffs().template cast(); } - - /** \returns \c true if \c *this is approximately equal to \a other, within the precision - * determined by \a prec. - * - * \sa MatrixBase::isApprox() */ - bool isApprox(const Scaling& other, typename NumTraits::Real prec = precision()) const - { return m_coeffs.isApprox(other.m_coeffs, prec); } - -}; - -/** \addtogroup Geometry_Module */ -//@{ -typedef Scaling Scaling2f; -typedef Scaling Scaling2d; -typedef Scaling Scaling3f; -typedef Scaling Scaling3d; -//@} - -template -inline typename Scaling::TransformType -Scaling::operator* (const TranslationType& t) const -{ - TransformType res; - res.matrix().setZero(); - res.linear().diagonal() = coeffs(); - res.translation() = m_coeffs.cwise() * t.vector(); - res(Dim,Dim) = Scalar(1); - return res; -} - -template -inline typename Scaling::TransformType -Scaling::operator* (const TransformType& t) const -{ - TransformType res = t; - res.prescale(m_coeffs); - return res; -} - -} // end namespace Eigen diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/Transform.h b/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/Transform.h deleted file mode 100644 index fab60b25..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/Transform.h +++ /dev/null @@ -1,786 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud -// Copyright (C) 2009 Benoit Jacob -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -// no include guard, we'll include this twice from All.h from Eigen2Support, and it's internal anyway - -namespace Eigen { - -// Note that we have to pass Dim and HDim because it is not allowed to use a template -// parameter to define a template specialization. To be more precise, in the following -// specializations, it is not allowed to use Dim+1 instead of HDim. -template< typename Other, - int Dim, - int HDim, - int OtherRows=Other::RowsAtCompileTime, - int OtherCols=Other::ColsAtCompileTime> -struct ei_transform_product_impl; - -/** \geometry_module \ingroup Geometry_Module - * - * \class Transform - * - * \brief Represents an homogeneous transformation in a N dimensional space - * - * \param _Scalar the scalar type, i.e., the type of the coefficients - * \param _Dim the dimension of the space - * - * The homography is internally represented and stored as a (Dim+1)^2 matrix which - * is available through the matrix() method. - * - * Conversion methods from/to Qt's QMatrix and QTransform are available if the - * preprocessor token EIGEN_QT_SUPPORT is defined. - * - * \sa class Matrix, class Quaternion - */ -template -class Transform -{ -public: - EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_Dim==Dynamic ? Dynamic : (_Dim+1)*(_Dim+1)) - enum { - Dim = _Dim, ///< space dimension in which the transformation holds - HDim = _Dim+1 ///< size of a respective homogeneous vector - }; - /** the scalar type of the coefficients */ - typedef _Scalar Scalar; - /** type of the matrix used to represent the transformation */ - typedef Matrix MatrixType; - /** type of the matrix used to represent the linear part of the transformation */ - typedef Matrix LinearMatrixType; - /** type of read/write reference to the linear part of the transformation */ - typedef Block LinearPart; - /** type of read/write reference to the linear part of the transformation */ - typedef const Block ConstLinearPart; - /** type of a vector */ - typedef Matrix VectorType; - /** type of a read/write reference to the translation part of the rotation */ - typedef Block TranslationPart; - /** type of a read/write reference to the translation part of the rotation */ - typedef const Block ConstTranslationPart; - /** corresponding translation type */ - typedef Translation TranslationType; - /** corresponding scaling transformation type */ - typedef Scaling ScalingType; - -protected: - - MatrixType m_matrix; - -public: - - /** Default constructor without initialization of the coefficients. */ - inline Transform() { } - - inline Transform(const Transform& other) - { - m_matrix = other.m_matrix; - } - - inline explicit Transform(const TranslationType& t) { *this = t; } - inline explicit Transform(const ScalingType& s) { *this = s; } - template - inline explicit Transform(const RotationBase& r) { *this = r; } - - inline Transform& operator=(const Transform& other) - { m_matrix = other.m_matrix; return *this; } - - template // MSVC 2005 will commit suicide if BigMatrix has a default value - struct construct_from_matrix - { - static inline void run(Transform *transform, const MatrixBase& other) - { - transform->matrix() = other; - } - }; - - template struct construct_from_matrix - { - static inline void run(Transform *transform, const MatrixBase& other) - { - transform->linear() = other; - transform->translation().setZero(); - transform->matrix()(Dim,Dim) = Scalar(1); - transform->matrix().template block<1,Dim>(Dim,0).setZero(); - } - }; - - /** Constructs and initializes a transformation from a Dim^2 or a (Dim+1)^2 matrix. */ - template - inline explicit Transform(const MatrixBase& other) - { - construct_from_matrix::run(this, other); - } - - /** Set \c *this from a (Dim+1)^2 matrix. */ - template - inline Transform& operator=(const MatrixBase& other) - { m_matrix = other; return *this; } - - #ifdef EIGEN_QT_SUPPORT - inline Transform(const QMatrix& other); - inline Transform& operator=(const QMatrix& other); - inline QMatrix toQMatrix(void) const; - inline Transform(const QTransform& other); - inline Transform& operator=(const QTransform& other); - inline QTransform toQTransform(void) const; - #endif - - /** shortcut for m_matrix(row,col); - * \sa MatrixBase::operaror(int,int) const */ - inline Scalar operator() (int row, int col) const { return m_matrix(row,col); } - /** shortcut for m_matrix(row,col); - * \sa MatrixBase::operaror(int,int) */ - inline Scalar& operator() (int row, int col) { return m_matrix(row,col); } - - /** \returns a read-only expression of the transformation matrix */ - inline const MatrixType& matrix() const { return m_matrix; } - /** \returns a writable expression of the transformation matrix */ - inline MatrixType& matrix() { return m_matrix; } - - /** \returns a read-only expression of the linear (linear) part of the transformation */ - inline ConstLinearPart linear() const { return m_matrix.template block(0,0); } - /** \returns a writable expression of the linear (linear) part of the transformation */ - inline LinearPart linear() { return m_matrix.template block(0,0); } - - /** \returns a read-only expression of the translation vector of the transformation */ - inline ConstTranslationPart translation() const { return m_matrix.template block(0,Dim); } - /** \returns a writable expression of the translation vector of the transformation */ - inline TranslationPart translation() { return m_matrix.template block(0,Dim); } - - /** \returns an expression of the product between the transform \c *this and a matrix expression \a other - * - * The right hand side \a other might be either: - * \li a vector of size Dim, - * \li an homogeneous vector of size Dim+1, - * \li a transformation matrix of size Dim+1 x Dim+1. - */ - // note: this function is defined here because some compilers cannot find the respective declaration - template - inline const typename ei_transform_product_impl::ResultType - operator * (const MatrixBase &other) const - { return ei_transform_product_impl::run(*this,other.derived()); } - - /** \returns the product expression of a transformation matrix \a a times a transform \a b - * The transformation matrix \a a must have a Dim+1 x Dim+1 sizes. */ - template - friend inline const typename ProductReturnType::Type - operator * (const MatrixBase &a, const Transform &b) - { return a.derived() * b.matrix(); } - - /** Contatenates two transformations */ - inline const Transform - operator * (const Transform& other) const - { return Transform(m_matrix * other.matrix()); } - - /** \sa MatrixBase::setIdentity() */ - void setIdentity() { m_matrix.setIdentity(); } - static const typename MatrixType::IdentityReturnType Identity() - { - return MatrixType::Identity(); - } - - template - inline Transform& scale(const MatrixBase &other); - - template - inline Transform& prescale(const MatrixBase &other); - - inline Transform& scale(Scalar s); - inline Transform& prescale(Scalar s); - - template - inline Transform& translate(const MatrixBase &other); - - template - inline Transform& pretranslate(const MatrixBase &other); - - template - inline Transform& rotate(const RotationType& rotation); - - template - inline Transform& prerotate(const RotationType& rotation); - - Transform& shear(Scalar sx, Scalar sy); - Transform& preshear(Scalar sx, Scalar sy); - - inline Transform& operator=(const TranslationType& t); - inline Transform& operator*=(const TranslationType& t) { return translate(t.vector()); } - inline Transform operator*(const TranslationType& t) const; - - inline Transform& operator=(const ScalingType& t); - inline Transform& operator*=(const ScalingType& s) { return scale(s.coeffs()); } - inline Transform operator*(const ScalingType& s) const; - friend inline Transform operator*(const LinearMatrixType& mat, const Transform& t) - { - Transform res = t; - res.matrix().row(Dim) = t.matrix().row(Dim); - res.matrix().template block(0,0) = (mat * t.matrix().template block(0,0)).lazy(); - return res; - } - - template - inline Transform& operator=(const RotationBase& r); - template - inline Transform& operator*=(const RotationBase& r) { return rotate(r.toRotationMatrix()); } - template - inline Transform operator*(const RotationBase& r) const; - - LinearMatrixType rotation() const; - template - void computeRotationScaling(RotationMatrixType *rotation, ScalingMatrixType *scaling) const; - template - void computeScalingRotation(ScalingMatrixType *scaling, RotationMatrixType *rotation) const; - - template - Transform& fromPositionOrientationScale(const MatrixBase &position, - const OrientationType& orientation, const MatrixBase &scale); - - inline const MatrixType inverse(TransformTraits traits = Affine) const; - - /** \returns a const pointer to the column major internal matrix */ - const Scalar* data() const { return m_matrix.data(); } - /** \returns a non-const pointer to the column major internal matrix */ - Scalar* data() { return m_matrix.data(); } - - /** \returns \c *this with scalar type casted to \a NewScalarType - * - * Note that if \a NewScalarType is equal to the current scalar type of \c *this - * then this function smartly returns a const reference to \c *this. - */ - template - inline typename internal::cast_return_type >::type cast() const - { return typename internal::cast_return_type >::type(*this); } - - /** Copy constructor with scalar type conversion */ - template - inline explicit Transform(const Transform& other) - { m_matrix = other.matrix().template cast(); } - - /** \returns \c true if \c *this is approximately equal to \a other, within the precision - * determined by \a prec. - * - * \sa MatrixBase::isApprox() */ - bool isApprox(const Transform& other, typename NumTraits::Real prec = precision()) const - { return m_matrix.isApprox(other.m_matrix, prec); } - - #ifdef EIGEN_TRANSFORM_PLUGIN - #include EIGEN_TRANSFORM_PLUGIN - #endif - -protected: - -}; - -/** \ingroup Geometry_Module */ -typedef Transform Transform2f; -/** \ingroup Geometry_Module */ -typedef Transform Transform3f; -/** \ingroup Geometry_Module */ -typedef Transform Transform2d; -/** \ingroup Geometry_Module */ -typedef Transform Transform3d; - -/************************** -*** Optional QT support *** -**************************/ - -#ifdef EIGEN_QT_SUPPORT -/** Initialises \c *this from a QMatrix assuming the dimension is 2. - * - * This function is available only if the token EIGEN_QT_SUPPORT is defined. - */ -template -Transform::Transform(const QMatrix& other) -{ - *this = other; -} - -/** Set \c *this from a QMatrix assuming the dimension is 2. - * - * This function is available only if the token EIGEN_QT_SUPPORT is defined. - */ -template -Transform& Transform::operator=(const QMatrix& other) -{ - EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE) - m_matrix << other.m11(), other.m21(), other.dx(), - other.m12(), other.m22(), other.dy(), - 0, 0, 1; - return *this; -} - -/** \returns a QMatrix from \c *this assuming the dimension is 2. - * - * \warning this convertion might loss data if \c *this is not affine - * - * This function is available only if the token EIGEN_QT_SUPPORT is defined. - */ -template -QMatrix Transform::toQMatrix(void) const -{ - EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE) - return QMatrix(m_matrix.coeff(0,0), m_matrix.coeff(1,0), - m_matrix.coeff(0,1), m_matrix.coeff(1,1), - m_matrix.coeff(0,2), m_matrix.coeff(1,2)); -} - -/** Initialises \c *this from a QTransform assuming the dimension is 2. - * - * This function is available only if the token EIGEN_QT_SUPPORT is defined. - */ -template -Transform::Transform(const QTransform& other) -{ - *this = other; -} - -/** Set \c *this from a QTransform assuming the dimension is 2. - * - * This function is available only if the token EIGEN_QT_SUPPORT is defined. - */ -template -Transform& Transform::operator=(const QTransform& other) -{ - EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE) - m_matrix << other.m11(), other.m21(), other.dx(), - other.m12(), other.m22(), other.dy(), - other.m13(), other.m23(), other.m33(); - return *this; -} - -/** \returns a QTransform from \c *this assuming the dimension is 2. - * - * This function is available only if the token EIGEN_QT_SUPPORT is defined. - */ -template -QTransform Transform::toQTransform(void) const -{ - EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE) - return QTransform(m_matrix.coeff(0,0), m_matrix.coeff(1,0), m_matrix.coeff(2,0), - m_matrix.coeff(0,1), m_matrix.coeff(1,1), m_matrix.coeff(2,1), - m_matrix.coeff(0,2), m_matrix.coeff(1,2), m_matrix.coeff(2,2)); -} -#endif - -/********************* -*** Procedural API *** -*********************/ - -/** Applies on the right the non uniform scale transformation represented - * by the vector \a other to \c *this and returns a reference to \c *this. - * \sa prescale() - */ -template -template -Transform& -Transform::scale(const MatrixBase &other) -{ - EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim)) - linear() = (linear() * other.asDiagonal()).lazy(); - return *this; -} - -/** Applies on the right a uniform scale of a factor \a c to \c *this - * and returns a reference to \c *this. - * \sa prescale(Scalar) - */ -template -inline Transform& Transform::scale(Scalar s) -{ - linear() *= s; - return *this; -} - -/** Applies on the left the non uniform scale transformation represented - * by the vector \a other to \c *this and returns a reference to \c *this. - * \sa scale() - */ -template -template -Transform& -Transform::prescale(const MatrixBase &other) -{ - EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim)) - m_matrix.template block(0,0) = (other.asDiagonal() * m_matrix.template block(0,0)).lazy(); - return *this; -} - -/** Applies on the left a uniform scale of a factor \a c to \c *this - * and returns a reference to \c *this. - * \sa scale(Scalar) - */ -template -inline Transform& Transform::prescale(Scalar s) -{ - m_matrix.template corner(TopLeft) *= s; - return *this; -} - -/** Applies on the right the translation matrix represented by the vector \a other - * to \c *this and returns a reference to \c *this. - * \sa pretranslate() - */ -template -template -Transform& -Transform::translate(const MatrixBase &other) -{ - EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim)) - translation() += linear() * other; - return *this; -} - -/** Applies on the left the translation matrix represented by the vector \a other - * to \c *this and returns a reference to \c *this. - * \sa translate() - */ -template -template -Transform& -Transform::pretranslate(const MatrixBase &other) -{ - EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim)) - translation() += other; - return *this; -} - -/** Applies on the right the rotation represented by the rotation \a rotation - * to \c *this and returns a reference to \c *this. - * - * The template parameter \a RotationType is the type of the rotation which - * must be known by ei_toRotationMatrix<>. - * - * Natively supported types includes: - * - any scalar (2D), - * - a Dim x Dim matrix expression, - * - a Quaternion (3D), - * - a AngleAxis (3D) - * - * This mechanism is easily extendable to support user types such as Euler angles, - * or a pair of Quaternion for 4D rotations. - * - * \sa rotate(Scalar), class Quaternion, class AngleAxis, prerotate(RotationType) - */ -template -template -Transform& -Transform::rotate(const RotationType& rotation) -{ - linear() *= ei_toRotationMatrix(rotation); - return *this; -} - -/** Applies on the left the rotation represented by the rotation \a rotation - * to \c *this and returns a reference to \c *this. - * - * See rotate() for further details. - * - * \sa rotate() - */ -template -template -Transform& -Transform::prerotate(const RotationType& rotation) -{ - m_matrix.template block(0,0) = ei_toRotationMatrix(rotation) - * m_matrix.template block(0,0); - return *this; -} - -/** Applies on the right the shear transformation represented - * by the vector \a other to \c *this and returns a reference to \c *this. - * \warning 2D only. - * \sa preshear() - */ -template -Transform& -Transform::shear(Scalar sx, Scalar sy) -{ - EIGEN_STATIC_ASSERT(int(Dim)==2, YOU_MADE_A_PROGRAMMING_MISTAKE) - VectorType tmp = linear().col(0)*sy + linear().col(1); - linear() << linear().col(0) + linear().col(1)*sx, tmp; - return *this; -} - -/** Applies on the left the shear transformation represented - * by the vector \a other to \c *this and returns a reference to \c *this. - * \warning 2D only. - * \sa shear() - */ -template -Transform& -Transform::preshear(Scalar sx, Scalar sy) -{ - EIGEN_STATIC_ASSERT(int(Dim)==2, YOU_MADE_A_PROGRAMMING_MISTAKE) - m_matrix.template block(0,0) = LinearMatrixType(1, sx, sy, 1) * m_matrix.template block(0,0); - return *this; -} - -/****************************************************** -*** Scaling, Translation and Rotation compatibility *** -******************************************************/ - -template -inline Transform& Transform::operator=(const TranslationType& t) -{ - linear().setIdentity(); - translation() = t.vector(); - m_matrix.template block<1,Dim>(Dim,0).setZero(); - m_matrix(Dim,Dim) = Scalar(1); - return *this; -} - -template -inline Transform Transform::operator*(const TranslationType& t) const -{ - Transform res = *this; - res.translate(t.vector()); - return res; -} - -template -inline Transform& Transform::operator=(const ScalingType& s) -{ - m_matrix.setZero(); - linear().diagonal() = s.coeffs(); - m_matrix.coeffRef(Dim,Dim) = Scalar(1); - return *this; -} - -template -inline Transform Transform::operator*(const ScalingType& s) const -{ - Transform res = *this; - res.scale(s.coeffs()); - return res; -} - -template -template -inline Transform& Transform::operator=(const RotationBase& r) -{ - linear() = ei_toRotationMatrix(r); - translation().setZero(); - m_matrix.template block<1,Dim>(Dim,0).setZero(); - m_matrix.coeffRef(Dim,Dim) = Scalar(1); - return *this; -} - -template -template -inline Transform Transform::operator*(const RotationBase& r) const -{ - Transform res = *this; - res.rotate(r.derived()); - return res; -} - -/************************ -*** Special functions *** -************************/ - -/** \returns the rotation part of the transformation - * \nonstableyet - * - * \svd_module - * - * \sa computeRotationScaling(), computeScalingRotation(), class SVD - */ -template -typename Transform::LinearMatrixType -Transform::rotation() const -{ - LinearMatrixType result; - computeRotationScaling(&result, (LinearMatrixType*)0); - return result; -} - - -/** decomposes the linear part of the transformation as a product rotation x scaling, the scaling being - * not necessarily positive. - * - * If either pointer is zero, the corresponding computation is skipped. - * - * \nonstableyet - * - * \svd_module - * - * \sa computeScalingRotation(), rotation(), class SVD - */ -template -template -void Transform::computeRotationScaling(RotationMatrixType *rotation, ScalingMatrixType *scaling) const -{ - JacobiSVD svd(linear(), ComputeFullU|ComputeFullV); - Scalar x = (svd.matrixU() * svd.matrixV().adjoint()).determinant(); // so x has absolute value 1 - Matrix sv(svd.singularValues()); - sv.coeffRef(0) *= x; - if(scaling) - { - scaling->noalias() = svd.matrixV() * sv.asDiagonal() * svd.matrixV().adjoint(); - } - if(rotation) - { - LinearMatrixType m(svd.matrixU()); - m.col(0) /= x; - rotation->noalias() = m * svd.matrixV().adjoint(); - } -} - -/** decomposes the linear part of the transformation as a product rotation x scaling, the scaling being - * not necessarily positive. - * - * If either pointer is zero, the corresponding computation is skipped. - * - * \nonstableyet - * - * \svd_module - * - * \sa computeRotationScaling(), rotation(), class SVD - */ -template -template -void Transform::computeScalingRotation(ScalingMatrixType *scaling, RotationMatrixType *rotation) const -{ - JacobiSVD svd(linear(), ComputeFullU|ComputeFullV); - Scalar x = (svd.matrixU() * svd.matrixV().adjoint()).determinant(); // so x has absolute value 1 - Matrix sv(svd.singularValues()); - sv.coeffRef(0) *= x; - if(scaling) - { - scaling->noalias() = svd.matrixU() * sv.asDiagonal() * svd.matrixU().adjoint(); - } - if(rotation) - { - LinearMatrixType m(svd.matrixU()); - m.col(0) /= x; - rotation->noalias() = m * svd.matrixV().adjoint(); - } -} - -/** Convenient method to set \c *this from a position, orientation and scale - * of a 3D object. - */ -template -template -Transform& -Transform::fromPositionOrientationScale(const MatrixBase &position, - const OrientationType& orientation, const MatrixBase &scale) -{ - linear() = ei_toRotationMatrix(orientation); - linear() *= scale.asDiagonal(); - translation() = position; - m_matrix.template block<1,Dim>(Dim,0).setZero(); - m_matrix(Dim,Dim) = Scalar(1); - return *this; -} - -/** \nonstableyet - * - * \returns the inverse transformation matrix according to some given knowledge - * on \c *this. - * - * \param traits allows to optimize the inversion process when the transformion - * is known to be not a general transformation. The possible values are: - * - Projective if the transformation is not necessarily affine, i.e., if the - * last row is not guaranteed to be [0 ... 0 1] - * - Affine is the default, the last row is assumed to be [0 ... 0 1] - * - Isometry if the transformation is only a concatenations of translations - * and rotations. - * - * \warning unless \a traits is always set to NoShear or NoScaling, this function - * requires the generic inverse method of MatrixBase defined in the LU module. If - * you forget to include this module, then you will get hard to debug linking errors. - * - * \sa MatrixBase::inverse() - */ -template -inline const typename Transform::MatrixType -Transform::inverse(TransformTraits traits) const -{ - if (traits == Projective) - { - return m_matrix.inverse(); - } - else - { - MatrixType res; - if (traits == Affine) - { - res.template corner(TopLeft) = linear().inverse(); - } - else if (traits == Isometry) - { - res.template corner(TopLeft) = linear().transpose(); - } - else - { - ei_assert("invalid traits value in Transform::inverse()"); - } - // translation and remaining parts - res.template corner(TopRight) = - res.template corner(TopLeft) * translation(); - res.template corner<1,Dim>(BottomLeft).setZero(); - res.coeffRef(Dim,Dim) = Scalar(1); - return res; - } -} - -/***************************************************** -*** Specializations of operator* with a MatrixBase *** -*****************************************************/ - -template -struct ei_transform_product_impl -{ - typedef Transform TransformType; - typedef typename TransformType::MatrixType MatrixType; - typedef typename ProductReturnType::Type ResultType; - static ResultType run(const TransformType& tr, const Other& other) - { return tr.matrix() * other; } -}; - -template -struct ei_transform_product_impl -{ - typedef Transform TransformType; - typedef typename TransformType::MatrixType MatrixType; - typedef TransformType ResultType; - static ResultType run(const TransformType& tr, const Other& other) - { - TransformType res; - res.translation() = tr.translation(); - res.matrix().row(Dim) = tr.matrix().row(Dim); - res.linear() = (tr.linear() * other).lazy(); - return res; - } -}; - -template -struct ei_transform_product_impl -{ - typedef Transform TransformType; - typedef typename TransformType::MatrixType MatrixType; - typedef typename ProductReturnType::Type ResultType; - static ResultType run(const TransformType& tr, const Other& other) - { return tr.matrix() * other; } -}; - -template -struct ei_transform_product_impl -{ - typedef typename Other::Scalar Scalar; - typedef Transform TransformType; - typedef Matrix ResultType; - static ResultType run(const TransformType& tr, const Other& other) - { return ((tr.linear() * other) + tr.translation()) - * (Scalar(1) / ( (tr.matrix().template block<1,Dim>(Dim,0) * other).coeff(0) + tr.matrix().coeff(Dim,Dim))); } -}; - -} // end namespace Eigen diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/Translation.h b/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/Translation.h deleted file mode 100644 index 2b9859f6..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/Translation.h +++ /dev/null @@ -1,184 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -// no include guard, we'll include this twice from All.h from Eigen2Support, and it's internal anyway - -namespace Eigen { - -/** \geometry_module \ingroup Geometry_Module - * - * \class Translation - * - * \brief Represents a translation transformation - * - * \param _Scalar the scalar type, i.e., the type of the coefficients. - * \param _Dim the dimension of the space, can be a compile time value or Dynamic - * - * \note This class is not aimed to be used to store a translation transformation, - * but rather to make easier the constructions and updates of Transform objects. - * - * \sa class Scaling, class Transform - */ -template -class Translation -{ -public: - EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_Dim) - /** dimension of the space */ - enum { Dim = _Dim }; - /** the scalar type of the coefficients */ - typedef _Scalar Scalar; - /** corresponding vector type */ - typedef Matrix VectorType; - /** corresponding linear transformation matrix type */ - typedef Matrix LinearMatrixType; - /** corresponding scaling transformation type */ - typedef Scaling ScalingType; - /** corresponding affine transformation type */ - typedef Transform TransformType; - -protected: - - VectorType m_coeffs; - -public: - - /** Default constructor without initialization. */ - Translation() {} - /** */ - inline Translation(const Scalar& sx, const Scalar& sy) - { - ei_assert(Dim==2); - m_coeffs.x() = sx; - m_coeffs.y() = sy; - } - /** */ - inline Translation(const Scalar& sx, const Scalar& sy, const Scalar& sz) - { - ei_assert(Dim==3); - m_coeffs.x() = sx; - m_coeffs.y() = sy; - m_coeffs.z() = sz; - } - /** Constructs and initialize the scaling transformation from a vector of scaling coefficients */ - explicit inline Translation(const VectorType& vector) : m_coeffs(vector) {} - - const VectorType& vector() const { return m_coeffs; } - VectorType& vector() { return m_coeffs; } - - /** Concatenates two translation */ - inline Translation operator* (const Translation& other) const - { return Translation(m_coeffs + other.m_coeffs); } - - /** Concatenates a translation and a scaling */ - inline TransformType operator* (const ScalingType& other) const; - - /** Concatenates a translation and a linear transformation */ - inline TransformType operator* (const LinearMatrixType& linear) const; - - template - inline TransformType operator*(const RotationBase& r) const - { return *this * r.toRotationMatrix(); } - - /** Concatenates a linear transformation and a translation */ - // its a nightmare to define a templated friend function outside its declaration - friend inline TransformType operator* (const LinearMatrixType& linear, const Translation& t) - { - TransformType res; - res.matrix().setZero(); - res.linear() = linear; - res.translation() = linear * t.m_coeffs; - res.matrix().row(Dim).setZero(); - res(Dim,Dim) = Scalar(1); - return res; - } - - /** Concatenates a translation and an affine transformation */ - inline TransformType operator* (const TransformType& t) const; - - /** Applies translation to vector */ - inline VectorType operator* (const VectorType& other) const - { return m_coeffs + other; } - - /** \returns the inverse translation (opposite) */ - Translation inverse() const { return Translation(-m_coeffs); } - - Translation& operator=(const Translation& other) - { - m_coeffs = other.m_coeffs; - return *this; - } - - /** \returns \c *this with scalar type casted to \a NewScalarType - * - * Note that if \a NewScalarType is equal to the current scalar type of \c *this - * then this function smartly returns a const reference to \c *this. - */ - template - inline typename internal::cast_return_type >::type cast() const - { return typename internal::cast_return_type >::type(*this); } - - /** Copy constructor with scalar type conversion */ - template - inline explicit Translation(const Translation& other) - { m_coeffs = other.vector().template cast(); } - - /** \returns \c true if \c *this is approximately equal to \a other, within the precision - * determined by \a prec. - * - * \sa MatrixBase::isApprox() */ - bool isApprox(const Translation& other, typename NumTraits::Real prec = precision()) const - { return m_coeffs.isApprox(other.m_coeffs, prec); } - -}; - -/** \addtogroup Geometry_Module */ -//@{ -typedef Translation Translation2f; -typedef Translation Translation2d; -typedef Translation Translation3f; -typedef Translation Translation3d; -//@} - - -template -inline typename Translation::TransformType -Translation::operator* (const ScalingType& other) const -{ - TransformType res; - res.matrix().setZero(); - res.linear().diagonal() = other.coeffs(); - res.translation() = m_coeffs; - res(Dim,Dim) = Scalar(1); - return res; -} - -template -inline typename Translation::TransformType -Translation::operator* (const LinearMatrixType& linear) const -{ - TransformType res; - res.matrix().setZero(); - res.linear() = linear; - res.translation() = m_coeffs; - res.matrix().row(Dim).setZero(); - res(Dim,Dim) = Scalar(1); - return res; -} - -template -inline typename Translation::TransformType -Translation::operator* (const TransformType& t) const -{ - TransformType res = t; - res.pretranslate(m_coeffs); - return res; -} - -} // end namespace Eigen diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/LU.h b/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/LU.h deleted file mode 100644 index 49f19ad7..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/LU.h +++ /dev/null @@ -1,120 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2011 Benoit Jacob -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN2_LU_H -#define EIGEN2_LU_H - -namespace Eigen { - -template -class LU : public FullPivLU -{ - public: - - typedef typename MatrixType::Scalar Scalar; - typedef typename NumTraits::Real RealScalar; - typedef Matrix IntRowVectorType; - typedef Matrix IntColVectorType; - typedef Matrix RowVectorType; - typedef Matrix ColVectorType; - - typedef Matrix KernelResultType; - - typedef Matrix ImageResultType; - - typedef FullPivLU Base; - - template - explicit LU(const T& t) : Base(t), m_originalMatrix(t) {} - - template - bool solve(const MatrixBase& b, ResultType *result) const - { - *result = static_cast(this)->solve(b); - return true; - } - - template - inline void computeInverse(ResultType *result) const - { - solve(MatrixType::Identity(this->rows(), this->cols()), result); - } - - template - void computeKernel(KernelMatrixType *result) const - { - *result = static_cast(this)->kernel(); - } - - template - void computeImage(ImageMatrixType *result) const - { - *result = static_cast(this)->image(m_originalMatrix); - } - - const ImageResultType image() const - { - return static_cast(this)->image(m_originalMatrix); - } - - const MatrixType& m_originalMatrix; -}; - -#if EIGEN2_SUPPORT_STAGE < STAGE20_RESOLVE_API_CONFLICTS -/** \lu_module - * - * Synonym of partialPivLu(). - * - * \return the partial-pivoting LU decomposition of \c *this. - * - * \sa class PartialPivLU - */ -template -inline const LU::PlainObject> -MatrixBase::lu() const -{ - return LU(eval()); -} -#endif - -#ifdef EIGEN2_SUPPORT -/** \lu_module - * - * Synonym of partialPivLu(). - * - * \return the partial-pivoting LU decomposition of \c *this. - * - * \sa class PartialPivLU - */ -template -inline const LU::PlainObject> -MatrixBase::eigen2_lu() const -{ - return LU(eval()); -} -#endif - -} // end namespace Eigen - -#endif // EIGEN2_LU_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Lazy.h b/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Lazy.h deleted file mode 100644 index 593fc78e..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Lazy.h +++ /dev/null @@ -1,71 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Benoit Jacob -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_LAZY_H -#define EIGEN_LAZY_H - -namespace Eigen { - -/** \deprecated it is only used by lazy() which is deprecated - * - * \returns an expression of *this with added flags - * - * Example: \include MatrixBase_marked.cpp - * Output: \verbinclude MatrixBase_marked.out - * - * \sa class Flagged, extract(), part() - */ -template -template -inline const Flagged -MatrixBase::marked() const -{ - return derived(); -} - -/** \deprecated use MatrixBase::noalias() - * - * \returns an expression of *this with the EvalBeforeAssigningBit flag removed. - * - * Example: \include MatrixBase_lazy.cpp - * Output: \verbinclude MatrixBase_lazy.out - * - * \sa class Flagged, marked() - */ -template -inline const Flagged -MatrixBase::lazy() const -{ - return derived(); -} - - -/** \internal - * Overloaded to perform an efficient C += (A*B).lazy() */ -template -template -Derived& MatrixBase::operator+=(const Flagged, 0, - EvalBeforeAssigningBit>& other) -{ - other._expression().derived().addTo(derived()); return derived(); -} - -/** \internal - * Overloaded to perform an efficient C -= (A*B).lazy() */ -template -template -Derived& MatrixBase::operator-=(const Flagged, 0, - EvalBeforeAssigningBit>& other) -{ - other._expression().derived().subTo(derived()); return derived(); -} - -} // end namespace Eigen - -#endif // EIGEN_LAZY_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/LeastSquares.h b/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/LeastSquares.h deleted file mode 100644 index 7992d494..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/LeastSquares.h +++ /dev/null @@ -1,169 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2006-2009 Benoit Jacob -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN2_LEASTSQUARES_H -#define EIGEN2_LEASTSQUARES_H - -namespace Eigen { - -/** \ingroup LeastSquares_Module - * - * \leastsquares_module - * - * For a set of points, this function tries to express - * one of the coords as a linear (affine) function of the other coords. - * - * This is best explained by an example. This function works in full - * generality, for points in a space of arbitrary dimension, and also over - * the complex numbers, but for this example we will work in dimension 3 - * over the real numbers (doubles). - * - * So let us work with the following set of 5 points given by their - * \f$(x,y,z)\f$ coordinates: - * @code - Vector3d points[5]; - points[0] = Vector3d( 3.02, 6.89, -4.32 ); - points[1] = Vector3d( 2.01, 5.39, -3.79 ); - points[2] = Vector3d( 2.41, 6.01, -4.01 ); - points[3] = Vector3d( 2.09, 5.55, -3.86 ); - points[4] = Vector3d( 2.58, 6.32, -4.10 ); - * @endcode - * Suppose that we want to express the second coordinate (\f$y\f$) as a linear - * expression in \f$x\f$ and \f$z\f$, that is, - * \f[ y=ax+bz+c \f] - * for some constants \f$a,b,c\f$. Thus, we want to find the best possible - * constants \f$a,b,c\f$ so that the plane of equation \f$y=ax+bz+c\f$ fits - * best the five above points. To do that, call this function as follows: - * @code - Vector3d coeffs; // will store the coefficients a, b, c - linearRegression( - 5, - &points, - &coeffs, - 1 // the coord to express as a function of - // the other ones. 0 means x, 1 means y, 2 means z. - ); - * @endcode - * Now the vector \a coeffs is approximately - * \f$( 0.495 , -1.927 , -2.906 )\f$. - * Thus, we get \f$a=0.495, b = -1.927, c = -2.906\f$. Let us check for - * instance how near points[0] is from the plane of equation \f$y=ax+bz+c\f$. - * Looking at the coords of points[0], we see that: - * \f[ax+bz+c = 0.495 * 3.02 + (-1.927) * (-4.32) + (-2.906) = 6.91.\f] - * On the other hand, we have \f$y=6.89\f$. We see that the values - * \f$6.91\f$ and \f$6.89\f$ - * are near, so points[0] is very near the plane of equation \f$y=ax+bz+c\f$. - * - * Let's now describe precisely the parameters: - * @param numPoints the number of points - * @param points the array of pointers to the points on which to perform the linear regression - * @param result pointer to the vector in which to store the result. - This vector must be of the same type and size as the - data points. The meaning of its coords is as follows. - For brevity, let \f$n=Size\f$, - \f$r_i=result[i]\f$, - and \f$f=funcOfOthers\f$. Denote by - \f$x_0,\ldots,x_{n-1}\f$ - the n coordinates in the n-dimensional space. - Then the resulting equation is: - \f[ x_f = r_0 x_0 + \cdots + r_{f-1}x_{f-1} - + r_{f+1}x_{f+1} + \cdots + r_{n-1}x_{n-1} + r_n. \f] - * @param funcOfOthers Determines which coord to express as a function of the - others. Coords are numbered starting from 0, so that a - value of 0 means \f$x\f$, 1 means \f$y\f$, - 2 means \f$z\f$, ... - * - * \sa fitHyperplane() - */ -template -void linearRegression(int numPoints, - VectorType **points, - VectorType *result, - int funcOfOthers ) -{ - typedef typename VectorType::Scalar Scalar; - typedef Hyperplane HyperplaneType; - const int size = points[0]->size(); - result->resize(size); - HyperplaneType h(size); - fitHyperplane(numPoints, points, &h); - for(int i = 0; i < funcOfOthers; i++) - result->coeffRef(i) = - h.coeffs()[i] / h.coeffs()[funcOfOthers]; - for(int i = funcOfOthers; i < size; i++) - result->coeffRef(i) = - h.coeffs()[i+1] / h.coeffs()[funcOfOthers]; -} - -/** \ingroup LeastSquares_Module - * - * \leastsquares_module - * - * This function is quite similar to linearRegression(), so we refer to the - * documentation of this function and only list here the differences. - * - * The main difference from linearRegression() is that this function doesn't - * take a \a funcOfOthers argument. Instead, it finds a general equation - * of the form - * \f[ r_0 x_0 + \cdots + r_{n-1}x_{n-1} + r_n = 0, \f] - * where \f$n=Size\f$, \f$r_i=retCoefficients[i]\f$, and we denote by - * \f$x_0,\ldots,x_{n-1}\f$ the n coordinates in the n-dimensional space. - * - * Thus, the vector \a retCoefficients has size \f$n+1\f$, which is another - * difference from linearRegression(). - * - * In practice, this function performs an hyper-plane fit in a total least square sense - * via the following steps: - * 1 - center the data to the mean - * 2 - compute the covariance matrix - * 3 - pick the eigenvector corresponding to the smallest eigenvalue of the covariance matrix - * The ratio of the smallest eigenvalue and the second one gives us a hint about the relevance - * of the solution. This value is optionally returned in \a soundness. - * - * \sa linearRegression() - */ -template -void fitHyperplane(int numPoints, - VectorType **points, - HyperplaneType *result, - typename NumTraits::Real* soundness = 0) -{ - typedef typename VectorType::Scalar Scalar; - typedef Matrix CovMatrixType; - EIGEN_STATIC_ASSERT_VECTOR_ONLY(VectorType) - ei_assert(numPoints >= 1); - int size = points[0]->size(); - ei_assert(size+1 == result->coeffs().size()); - - // compute the mean of the data - VectorType mean = VectorType::Zero(size); - for(int i = 0; i < numPoints; ++i) - mean += *(points[i]); - mean /= numPoints; - - // compute the covariance matrix - CovMatrixType covMat = CovMatrixType::Zero(size, size); - for(int i = 0; i < numPoints; ++i) - { - VectorType diff = (*(points[i]) - mean).conjugate(); - covMat += diff * diff.adjoint(); - } - - // now we just have to pick the eigen vector with smallest eigen value - SelfAdjointEigenSolver eig(covMat); - result->normal() = eig.eigenvectors().col(0); - if (soundness) - *soundness = eig.eigenvalues().coeff(0)/eig.eigenvalues().coeff(1); - - // let's compute the constant coefficient such that the - // plane pass trough the mean point: - result->offset() = - (result->normal().cwise()* mean).sum(); -} - -} // end namespace Eigen - -#endif // EIGEN2_LEASTSQUARES_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Macros.h b/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Macros.h deleted file mode 100644 index 351c32af..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Macros.h +++ /dev/null @@ -1,20 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2011 Benoit Jacob -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN2_MACROS_H -#define EIGEN2_MACROS_H - -#define ei_assert eigen_assert -#define ei_internal_assert eigen_internal_assert - -#define EIGEN_ALIGN_128 EIGEN_ALIGN16 - -#define EIGEN_ARCH_WANTS_ALIGNMENT EIGEN_ALIGN_STATICALLY - -#endif // EIGEN2_MACROS_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/MathFunctions.h b/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/MathFunctions.h deleted file mode 100644 index 3544af25..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/MathFunctions.h +++ /dev/null @@ -1,57 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2010 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN2_MATH_FUNCTIONS_H -#define EIGEN2_MATH_FUNCTIONS_H - -namespace Eigen { - -template inline typename NumTraits::Real ei_real(const T& x) { return numext::real(x); } -template inline typename NumTraits::Real ei_imag(const T& x) { return numext::imag(x); } -template inline T ei_conj(const T& x) { return numext::conj(x); } -template inline typename NumTraits::Real ei_abs (const T& x) { using std::abs; return abs(x); } -template inline typename NumTraits::Real ei_abs2(const T& x) { return numext::abs2(x); } -template inline T ei_sqrt(const T& x) { using std::sqrt; return sqrt(x); } -template inline T ei_exp (const T& x) { using std::exp; return exp(x); } -template inline T ei_log (const T& x) { using std::log; return log(x); } -template inline T ei_sin (const T& x) { using std::sin; return sin(x); } -template inline T ei_cos (const T& x) { using std::cos; return cos(x); } -template inline T ei_atan2(const T& x,const T& y) { using std::atan2; return atan2(x,y); } -template inline T ei_pow (const T& x,const T& y) { return numext::pow(x,y); } -template inline T ei_random () { return internal::random(); } -template inline T ei_random (const T& x, const T& y) { return internal::random(x, y); } - -template inline T precision () { return NumTraits::dummy_precision(); } -template inline T machine_epsilon () { return NumTraits::epsilon(); } - - -template -inline bool ei_isMuchSmallerThan(const Scalar& x, const OtherScalar& y, - typename NumTraits::Real precision = NumTraits::dummy_precision()) -{ - return internal::isMuchSmallerThan(x, y, precision); -} - -template -inline bool ei_isApprox(const Scalar& x, const Scalar& y, - typename NumTraits::Real precision = NumTraits::dummy_precision()) -{ - return internal::isApprox(x, y, precision); -} - -template -inline bool ei_isApproxOrLessThan(const Scalar& x, const Scalar& y, - typename NumTraits::Real precision = NumTraits::dummy_precision()) -{ - return internal::isApproxOrLessThan(x, y, precision); -} - -} // end namespace Eigen - -#endif // EIGEN2_MATH_FUNCTIONS_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Memory.h b/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Memory.h deleted file mode 100644 index f86372b6..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Memory.h +++ /dev/null @@ -1,45 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2011 Benoit Jacob -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN2_MEMORY_H -#define EIGEN2_MEMORY_H - -namespace Eigen { - -inline void* ei_aligned_malloc(size_t size) { return internal::aligned_malloc(size); } -inline void ei_aligned_free(void *ptr) { internal::aligned_free(ptr); } -inline void* ei_aligned_realloc(void *ptr, size_t new_size, size_t old_size) { return internal::aligned_realloc(ptr, new_size, old_size); } -inline void* ei_handmade_aligned_malloc(size_t size) { return internal::handmade_aligned_malloc(size); } -inline void ei_handmade_aligned_free(void *ptr) { internal::handmade_aligned_free(ptr); } - -template inline void* ei_conditional_aligned_malloc(size_t size) -{ - return internal::conditional_aligned_malloc(size); -} -template inline void ei_conditional_aligned_free(void *ptr) -{ - internal::conditional_aligned_free(ptr); -} -template inline void* ei_conditional_aligned_realloc(void* ptr, size_t new_size, size_t old_size) -{ - return internal::conditional_aligned_realloc(ptr, new_size, old_size); -} - -template inline T* ei_aligned_new(size_t size) -{ - return internal::aligned_new(size); -} -template inline void ei_aligned_delete(T *ptr, size_t size) -{ - return internal::aligned_delete(ptr, size); -} - -} // end namespace Eigen - -#endif // EIGEN2_MACROS_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Meta.h b/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Meta.h deleted file mode 100644 index fa37cfc9..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Meta.h +++ /dev/null @@ -1,75 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2011 Benoit Jacob -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN2_META_H -#define EIGEN2_META_H - -namespace Eigen { - -template -struct ei_traits : internal::traits -{}; - -struct ei_meta_true { enum { ret = 1 }; }; -struct ei_meta_false { enum { ret = 0 }; }; - -template -struct ei_meta_if { typedef Then ret; }; - -template -struct ei_meta_if { typedef Else ret; }; - -template struct ei_is_same_type { enum { ret = 0 }; }; -template struct ei_is_same_type { enum { ret = 1 }; }; - -template struct ei_unref { typedef T type; }; -template struct ei_unref { typedef T type; }; - -template struct ei_unpointer { typedef T type; }; -template struct ei_unpointer { typedef T type; }; -template struct ei_unpointer { typedef T type; }; - -template struct ei_unconst { typedef T type; }; -template struct ei_unconst { typedef T type; }; -template struct ei_unconst { typedef T & type; }; -template struct ei_unconst { typedef T * type; }; - -template struct ei_cleantype { typedef T type; }; -template struct ei_cleantype { typedef typename ei_cleantype::type type; }; -template struct ei_cleantype { typedef typename ei_cleantype::type type; }; -template struct ei_cleantype { typedef typename ei_cleantype::type type; }; -template struct ei_cleantype { typedef typename ei_cleantype::type type; }; -template struct ei_cleantype { typedef typename ei_cleantype::type type; }; - -/** \internal In short, it computes int(sqrt(\a Y)) with \a Y an integer. - * Usage example: \code ei_meta_sqrt<1023>::ret \endcode - */ -template Y))) > - // use ?: instead of || just to shut up a stupid gcc 4.3 warning -class ei_meta_sqrt -{ - enum { - MidX = (InfX+SupX)/2, - TakeInf = MidX*MidX > Y ? 1 : 0, - NewInf = int(TakeInf) ? InfX : int(MidX), - NewSup = int(TakeInf) ? int(MidX) : SupX - }; - public: - enum { ret = ei_meta_sqrt::ret }; -}; - -template -class ei_meta_sqrt { public: enum { ret = (SupX*SupX <= Y) ? SupX : InfX }; }; - -} // end namespace Eigen - -#endif // EIGEN2_META_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Minor.h b/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Minor.h deleted file mode 100644 index 4cded573..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Minor.h +++ /dev/null @@ -1,117 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2006-2009 Benoit Jacob -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_MINOR_H -#define EIGEN_MINOR_H - -namespace Eigen { - -/** - * \class Minor - * - * \brief Expression of a minor - * - * \param MatrixType the type of the object in which we are taking a minor - * - * This class represents an expression of a minor. It is the return - * type of MatrixBase::minor() and most of the time this is the only way it - * is used. - * - * \sa MatrixBase::minor() - */ - -namespace internal { -template -struct traits > - : traits -{ - typedef typename nested::type MatrixTypeNested; - typedef typename remove_reference::type _MatrixTypeNested; - typedef typename MatrixType::StorageKind StorageKind; - enum { - RowsAtCompileTime = (MatrixType::RowsAtCompileTime != Dynamic) ? - int(MatrixType::RowsAtCompileTime) - 1 : Dynamic, - ColsAtCompileTime = (MatrixType::ColsAtCompileTime != Dynamic) ? - int(MatrixType::ColsAtCompileTime) - 1 : Dynamic, - MaxRowsAtCompileTime = (MatrixType::MaxRowsAtCompileTime != Dynamic) ? - int(MatrixType::MaxRowsAtCompileTime) - 1 : Dynamic, - MaxColsAtCompileTime = (MatrixType::MaxColsAtCompileTime != Dynamic) ? - int(MatrixType::MaxColsAtCompileTime) - 1 : Dynamic, - Flags = _MatrixTypeNested::Flags & (HereditaryBits | LvalueBit), - CoeffReadCost = _MatrixTypeNested::CoeffReadCost // minor is used typically on tiny matrices, - // where loops are unrolled and the 'if' evaluates at compile time - }; -}; -} - -template class Minor - : public MatrixBase > -{ - public: - - typedef MatrixBase Base; - EIGEN_DENSE_PUBLIC_INTERFACE(Minor) - - inline Minor(const MatrixType& matrix, - Index row, Index col) - : m_matrix(matrix), m_row(row), m_col(col) - { - eigen_assert(row >= 0 && row < matrix.rows() - && col >= 0 && col < matrix.cols()); - } - - EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Minor) - - inline Index rows() const { return m_matrix.rows() - 1; } - inline Index cols() const { return m_matrix.cols() - 1; } - - inline Scalar& coeffRef(Index row, Index col) - { - return m_matrix.const_cast_derived().coeffRef(row + (row >= m_row), col + (col >= m_col)); - } - - inline const Scalar coeff(Index row, Index col) const - { - return m_matrix.coeff(row + (row >= m_row), col + (col >= m_col)); - } - - protected: - const typename MatrixType::Nested m_matrix; - const Index m_row, m_col; -}; - -/** - * \return an expression of the (\a row, \a col)-minor of *this, - * i.e. an expression constructed from *this by removing the specified - * row and column. - * - * Example: \include MatrixBase_minor.cpp - * Output: \verbinclude MatrixBase_minor.out - * - * \sa class Minor - */ -template -inline Minor -MatrixBase::minor(Index row, Index col) -{ - return Minor(derived(), row, col); -} - -/** - * This is the const version of minor(). */ -template -inline const Minor -MatrixBase::minor(Index row, Index col) const -{ - return Minor(derived(), row, col); -} - -} // end namespace Eigen - -#endif // EIGEN_MINOR_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/QR.h b/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/QR.h deleted file mode 100644 index 2042c985..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/QR.h +++ /dev/null @@ -1,67 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud -// Copyright (C) 2011 Benoit Jacob -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN2_QR_H -#define EIGEN2_QR_H - -namespace Eigen { - -template -class QR : public HouseholderQR -{ - public: - - typedef HouseholderQR Base; - typedef Block MatrixRBlockType; - - QR() : Base() {} - - template - explicit QR(const T& t) : Base(t) {} - - template - bool solve(const MatrixBase& b, ResultType *result) const - { - *result = static_cast(this)->solve(b); - return true; - } - - MatrixType matrixQ(void) const { - MatrixType ret = MatrixType::Identity(this->rows(), this->cols()); - ret = this->householderQ() * ret; - return ret; - } - - bool isFullRank() const { - return true; - } - - const TriangularView - matrixR(void) const - { - int cols = this->cols(); - return MatrixRBlockType(this->matrixQR(), 0, 0, cols, cols).template triangularView(); - } -}; - -/** \return the QR decomposition of \c *this. - * - * \sa class QR - */ -template -const QR::PlainObject> -MatrixBase::qr() const -{ - return QR(eval()); -} - -} // end namespace Eigen - -#endif // EIGEN2_QR_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/SVD.h b/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/SVD.h deleted file mode 100644 index 3d03d228..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/SVD.h +++ /dev/null @@ -1,637 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN2_SVD_H -#define EIGEN2_SVD_H - -namespace Eigen { - -/** \ingroup SVD_Module - * \nonstableyet - * - * \class SVD - * - * \brief Standard SVD decomposition of a matrix and associated features - * - * \param MatrixType the type of the matrix of which we are computing the SVD decomposition - * - * This class performs a standard SVD decomposition of a real matrix A of size \c M x \c N - * with \c M \>= \c N. - * - * - * \sa MatrixBase::SVD() - */ -template class SVD -{ - private: - typedef typename MatrixType::Scalar Scalar; - typedef typename NumTraits::Real RealScalar; - - enum { - PacketSize = internal::packet_traits::size, - AlignmentMask = int(PacketSize)-1, - MinSize = EIGEN_SIZE_MIN_PREFER_DYNAMIC(MatrixType::RowsAtCompileTime, MatrixType::ColsAtCompileTime) - }; - - typedef Matrix ColVector; - typedef Matrix RowVector; - - typedef Matrix MatrixUType; - typedef Matrix MatrixVType; - typedef Matrix SingularValuesType; - - public: - - SVD() {} // a user who relied on compiler-generated default compiler reported problems with MSVC in 2.0.7 - - SVD(const MatrixType& matrix) - : m_matU(matrix.rows(), (std::min)(matrix.rows(), matrix.cols())), - m_matV(matrix.cols(),matrix.cols()), - m_sigma((std::min)(matrix.rows(),matrix.cols())) - { - compute(matrix); - } - - template - bool solve(const MatrixBase &b, ResultType* result) const; - - const MatrixUType& matrixU() const { return m_matU; } - const SingularValuesType& singularValues() const { return m_sigma; } - const MatrixVType& matrixV() const { return m_matV; } - - void compute(const MatrixType& matrix); - SVD& sort(); - - template - void computeUnitaryPositive(UnitaryType *unitary, PositiveType *positive) const; - template - void computePositiveUnitary(PositiveType *positive, UnitaryType *unitary) const; - template - void computeRotationScaling(RotationType *unitary, ScalingType *positive) const; - template - void computeScalingRotation(ScalingType *positive, RotationType *unitary) const; - - protected: - /** \internal */ - MatrixUType m_matU; - /** \internal */ - MatrixVType m_matV; - /** \internal */ - SingularValuesType m_sigma; -}; - -/** Computes / recomputes the SVD decomposition A = U S V^* of \a matrix - * - * \note this code has been adapted from JAMA (public domain) - */ -template -void SVD::compute(const MatrixType& matrix) -{ - const int m = matrix.rows(); - const int n = matrix.cols(); - const int nu = (std::min)(m,n); - ei_assert(m>=n && "In Eigen 2.0, SVD only works for MxN matrices with M>=N. Sorry!"); - ei_assert(m>1 && "In Eigen 2.0, SVD doesn't work on 1x1 matrices"); - - m_matU.resize(m, nu); - m_matU.setZero(); - m_sigma.resize((std::min)(m,n)); - m_matV.resize(n,n); - - RowVector e(n); - ColVector work(m); - MatrixType matA(matrix); - const bool wantu = true; - const bool wantv = true; - int i=0, j=0, k=0; - - // Reduce A to bidiagonal form, storing the diagonal elements - // in s and the super-diagonal elements in e. - int nct = (std::min)(m-1,n); - int nrt = (std::max)(0,(std::min)(n-2,m)); - for (k = 0; k < (std::max)(nct,nrt); ++k) - { - if (k < nct) - { - // Compute the transformation for the k-th column and - // place the k-th diagonal in m_sigma[k]. - m_sigma[k] = matA.col(k).end(m-k).norm(); - if (m_sigma[k] != 0.0) // FIXME - { - if (matA(k,k) < 0.0) - m_sigma[k] = -m_sigma[k]; - matA.col(k).end(m-k) /= m_sigma[k]; - matA(k,k) += 1.0; - } - m_sigma[k] = -m_sigma[k]; - } - - for (j = k+1; j < n; ++j) - { - if ((k < nct) && (m_sigma[k] != 0.0)) - { - // Apply the transformation. - Scalar t = matA.col(k).end(m-k).eigen2_dot(matA.col(j).end(m-k)); // FIXME dot product or cwise prod + .sum() ?? - t = -t/matA(k,k); - matA.col(j).end(m-k) += t * matA.col(k).end(m-k); - } - - // Place the k-th row of A into e for the - // subsequent calculation of the row transformation. - e[j] = matA(k,j); - } - - // Place the transformation in U for subsequent back multiplication. - if (wantu & (k < nct)) - m_matU.col(k).end(m-k) = matA.col(k).end(m-k); - - if (k < nrt) - { - // Compute the k-th row transformation and place the - // k-th super-diagonal in e[k]. - e[k] = e.end(n-k-1).norm(); - if (e[k] != 0.0) - { - if (e[k+1] < 0.0) - e[k] = -e[k]; - e.end(n-k-1) /= e[k]; - e[k+1] += 1.0; - } - e[k] = -e[k]; - if ((k+1 < m) & (e[k] != 0.0)) - { - // Apply the transformation. - work.end(m-k-1) = matA.corner(BottomRight,m-k-1,n-k-1) * e.end(n-k-1); - for (j = k+1; j < n; ++j) - matA.col(j).end(m-k-1) += (-e[j]/e[k+1]) * work.end(m-k-1); - } - - // Place the transformation in V for subsequent back multiplication. - if (wantv) - m_matV.col(k).end(n-k-1) = e.end(n-k-1); - } - } - - - // Set up the final bidiagonal matrix or order p. - int p = (std::min)(n,m+1); - if (nct < n) - m_sigma[nct] = matA(nct,nct); - if (m < p) - m_sigma[p-1] = 0.0; - if (nrt+1 < p) - e[nrt] = matA(nrt,p-1); - e[p-1] = 0.0; - - // If required, generate U. - if (wantu) - { - for (j = nct; j < nu; ++j) - { - m_matU.col(j).setZero(); - m_matU(j,j) = 1.0; - } - for (k = nct-1; k >= 0; k--) - { - if (m_sigma[k] != 0.0) - { - for (j = k+1; j < nu; ++j) - { - Scalar t = m_matU.col(k).end(m-k).eigen2_dot(m_matU.col(j).end(m-k)); // FIXME is it really a dot product we want ? - t = -t/m_matU(k,k); - m_matU.col(j).end(m-k) += t * m_matU.col(k).end(m-k); - } - m_matU.col(k).end(m-k) = - m_matU.col(k).end(m-k); - m_matU(k,k) = Scalar(1) + m_matU(k,k); - if (k-1>0) - m_matU.col(k).start(k-1).setZero(); - } - else - { - m_matU.col(k).setZero(); - m_matU(k,k) = 1.0; - } - } - } - - // If required, generate V. - if (wantv) - { - for (k = n-1; k >= 0; k--) - { - if ((k < nrt) & (e[k] != 0.0)) - { - for (j = k+1; j < nu; ++j) - { - Scalar t = m_matV.col(k).end(n-k-1).eigen2_dot(m_matV.col(j).end(n-k-1)); // FIXME is it really a dot product we want ? - t = -t/m_matV(k+1,k); - m_matV.col(j).end(n-k-1) += t * m_matV.col(k).end(n-k-1); - } - } - m_matV.col(k).setZero(); - m_matV(k,k) = 1.0; - } - } - - // Main iteration loop for the singular values. - int pp = p-1; - int iter = 0; - Scalar eps = ei_pow(Scalar(2),ei_is_same_type::ret ? Scalar(-23) : Scalar(-52)); - while (p > 0) - { - int k=0; - int kase=0; - - // Here is where a test for too many iterations would go. - - // This section of the program inspects for - // negligible elements in the s and e arrays. On - // completion the variables kase and k are set as follows. - - // kase = 1 if s(p) and e[k-1] are negligible and k

= -1; --k) - { - if (k == -1) - break; - if (ei_abs(e[k]) <= eps*(ei_abs(m_sigma[k]) + ei_abs(m_sigma[k+1]))) - { - e[k] = 0.0; - break; - } - } - if (k == p-2) - { - kase = 4; - } - else - { - int ks; - for (ks = p-1; ks >= k; --ks) - { - if (ks == k) - break; - Scalar t = (ks != p ? ei_abs(e[ks]) : Scalar(0)) + (ks != k+1 ? ei_abs(e[ks-1]) : Scalar(0)); - if (ei_abs(m_sigma[ks]) <= eps*t) - { - m_sigma[ks] = 0.0; - break; - } - } - if (ks == k) - { - kase = 3; - } - else if (ks == p-1) - { - kase = 1; - } - else - { - kase = 2; - k = ks; - } - } - ++k; - - // Perform the task indicated by kase. - switch (kase) - { - - // Deflate negligible s(p). - case 1: - { - Scalar f(e[p-2]); - e[p-2] = 0.0; - for (j = p-2; j >= k; --j) - { - Scalar t(numext::hypot(m_sigma[j],f)); - Scalar cs(m_sigma[j]/t); - Scalar sn(f/t); - m_sigma[j] = t; - if (j != k) - { - f = -sn*e[j-1]; - e[j-1] = cs*e[j-1]; - } - if (wantv) - { - for (i = 0; i < n; ++i) - { - t = cs*m_matV(i,j) + sn*m_matV(i,p-1); - m_matV(i,p-1) = -sn*m_matV(i,j) + cs*m_matV(i,p-1); - m_matV(i,j) = t; - } - } - } - } - break; - - // Split at negligible s(k). - case 2: - { - Scalar f(e[k-1]); - e[k-1] = 0.0; - for (j = k; j < p; ++j) - { - Scalar t(numext::hypot(m_sigma[j],f)); - Scalar cs( m_sigma[j]/t); - Scalar sn(f/t); - m_sigma[j] = t; - f = -sn*e[j]; - e[j] = cs*e[j]; - if (wantu) - { - for (i = 0; i < m; ++i) - { - t = cs*m_matU(i,j) + sn*m_matU(i,k-1); - m_matU(i,k-1) = -sn*m_matU(i,j) + cs*m_matU(i,k-1); - m_matU(i,j) = t; - } - } - } - } - break; - - // Perform one qr step. - case 3: - { - // Calculate the shift. - Scalar scale = (std::max)((std::max)((std::max)((std::max)( - ei_abs(m_sigma[p-1]),ei_abs(m_sigma[p-2])),ei_abs(e[p-2])), - ei_abs(m_sigma[k])),ei_abs(e[k])); - Scalar sp = m_sigma[p-1]/scale; - Scalar spm1 = m_sigma[p-2]/scale; - Scalar epm1 = e[p-2]/scale; - Scalar sk = m_sigma[k]/scale; - Scalar ek = e[k]/scale; - Scalar b = ((spm1 + sp)*(spm1 - sp) + epm1*epm1)/Scalar(2); - Scalar c = (sp*epm1)*(sp*epm1); - Scalar shift(0); - if ((b != 0.0) || (c != 0.0)) - { - shift = ei_sqrt(b*b + c); - if (b < 0.0) - shift = -shift; - shift = c/(b + shift); - } - Scalar f = (sk + sp)*(sk - sp) + shift; - Scalar g = sk*ek; - - // Chase zeros. - - for (j = k; j < p-1; ++j) - { - Scalar t = numext::hypot(f,g); - Scalar cs = f/t; - Scalar sn = g/t; - if (j != k) - e[j-1] = t; - f = cs*m_sigma[j] + sn*e[j]; - e[j] = cs*e[j] - sn*m_sigma[j]; - g = sn*m_sigma[j+1]; - m_sigma[j+1] = cs*m_sigma[j+1]; - if (wantv) - { - for (i = 0; i < n; ++i) - { - t = cs*m_matV(i,j) + sn*m_matV(i,j+1); - m_matV(i,j+1) = -sn*m_matV(i,j) + cs*m_matV(i,j+1); - m_matV(i,j) = t; - } - } - t = numext::hypot(f,g); - cs = f/t; - sn = g/t; - m_sigma[j] = t; - f = cs*e[j] + sn*m_sigma[j+1]; - m_sigma[j+1] = -sn*e[j] + cs*m_sigma[j+1]; - g = sn*e[j+1]; - e[j+1] = cs*e[j+1]; - if (wantu && (j < m-1)) - { - for (i = 0; i < m; ++i) - { - t = cs*m_matU(i,j) + sn*m_matU(i,j+1); - m_matU(i,j+1) = -sn*m_matU(i,j) + cs*m_matU(i,j+1); - m_matU(i,j) = t; - } - } - } - e[p-2] = f; - iter = iter + 1; - } - break; - - // Convergence. - case 4: - { - // Make the singular values positive. - if (m_sigma[k] <= 0.0) - { - m_sigma[k] = m_sigma[k] < Scalar(0) ? -m_sigma[k] : Scalar(0); - if (wantv) - m_matV.col(k).start(pp+1) = -m_matV.col(k).start(pp+1); - } - - // Order the singular values. - while (k < pp) - { - if (m_sigma[k] >= m_sigma[k+1]) - break; - Scalar t = m_sigma[k]; - m_sigma[k] = m_sigma[k+1]; - m_sigma[k+1] = t; - if (wantv && (k < n-1)) - m_matV.col(k).swap(m_matV.col(k+1)); - if (wantu && (k < m-1)) - m_matU.col(k).swap(m_matU.col(k+1)); - ++k; - } - iter = 0; - p--; - } - break; - } // end big switch - } // end iterations -} - -template -SVD& SVD::sort() -{ - int mu = m_matU.rows(); - int mv = m_matV.rows(); - int n = m_matU.cols(); - - for (int i=0; i p) - { - k = j; - p = m_sigma.coeff(j); - } - } - if (k != i) - { - m_sigma.coeffRef(k) = m_sigma.coeff(i); // i.e. - m_sigma.coeffRef(i) = p; // swaps the i-th and the k-th elements - - int j = mu; - for(int s=0; j!=0; ++s, --j) - std::swap(m_matU.coeffRef(s,i), m_matU.coeffRef(s,k)); - - j = mv; - for (int s=0; j!=0; ++s, --j) - std::swap(m_matV.coeffRef(s,i), m_matV.coeffRef(s,k)); - } - } - return *this; -} - -/** \returns the solution of \f$ A x = b \f$ using the current SVD decomposition of A. - * The parts of the solution corresponding to zero singular values are ignored. - * - * \sa MatrixBase::svd(), LU::solve(), LLT::solve() - */ -template -template -bool SVD::solve(const MatrixBase &b, ResultType* result) const -{ - ei_assert(b.rows() == m_matU.rows()); - - Scalar maxVal = m_sigma.cwise().abs().maxCoeff(); - for (int j=0; j aux = m_matU.transpose() * b.col(j); - - for (int i = 0; i col(j) = m_matV * aux; - } - return true; -} - -/** Computes the polar decomposition of the matrix, as a product unitary x positive. - * - * If either pointer is zero, the corresponding computation is skipped. - * - * Only for square matrices. - * - * \sa computePositiveUnitary(), computeRotationScaling() - */ -template -template -void SVD::computeUnitaryPositive(UnitaryType *unitary, - PositiveType *positive) const -{ - ei_assert(m_matU.cols() == m_matV.cols() && "Polar decomposition is only for square matrices"); - if(unitary) *unitary = m_matU * m_matV.adjoint(); - if(positive) *positive = m_matV * m_sigma.asDiagonal() * m_matV.adjoint(); -} - -/** Computes the polar decomposition of the matrix, as a product positive x unitary. - * - * If either pointer is zero, the corresponding computation is skipped. - * - * Only for square matrices. - * - * \sa computeUnitaryPositive(), computeRotationScaling() - */ -template -template -void SVD::computePositiveUnitary(UnitaryType *positive, - PositiveType *unitary) const -{ - ei_assert(m_matU.rows() == m_matV.rows() && "Polar decomposition is only for square matrices"); - if(unitary) *unitary = m_matU * m_matV.adjoint(); - if(positive) *positive = m_matU * m_sigma.asDiagonal() * m_matU.adjoint(); -} - -/** decomposes the matrix as a product rotation x scaling, the scaling being - * not necessarily positive. - * - * If either pointer is zero, the corresponding computation is skipped. - * - * This method requires the Geometry module. - * - * \sa computeScalingRotation(), computeUnitaryPositive() - */ -template -template -void SVD::computeRotationScaling(RotationType *rotation, ScalingType *scaling) const -{ - ei_assert(m_matU.rows() == m_matV.rows() && "Polar decomposition is only for square matrices"); - Scalar x = (m_matU * m_matV.adjoint()).determinant(); // so x has absolute value 1 - Matrix sv(m_sigma); - sv.coeffRef(0) *= x; - if(scaling) scaling->lazyAssign(m_matV * sv.asDiagonal() * m_matV.adjoint()); - if(rotation) - { - MatrixType m(m_matU); - m.col(0) /= x; - rotation->lazyAssign(m * m_matV.adjoint()); - } -} - -/** decomposes the matrix as a product scaling x rotation, the scaling being - * not necessarily positive. - * - * If either pointer is zero, the corresponding computation is skipped. - * - * This method requires the Geometry module. - * - * \sa computeRotationScaling(), computeUnitaryPositive() - */ -template -template -void SVD::computeScalingRotation(ScalingType *scaling, RotationType *rotation) const -{ - ei_assert(m_matU.rows() == m_matV.rows() && "Polar decomposition is only for square matrices"); - Scalar x = (m_matU * m_matV.adjoint()).determinant(); // so x has absolute value 1 - Matrix sv(m_sigma); - sv.coeffRef(0) *= x; - if(scaling) scaling->lazyAssign(m_matU * sv.asDiagonal() * m_matU.adjoint()); - if(rotation) - { - MatrixType m(m_matU); - m.col(0) /= x; - rotation->lazyAssign(m * m_matV.adjoint()); - } -} - - -/** \svd_module - * \returns the SVD decomposition of \c *this - */ -template -inline SVD::PlainObject> -MatrixBase::svd() const -{ - return SVD(derived()); -} - -} // end namespace Eigen - -#endif // EIGEN2_SVD_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/TriangularSolver.h b/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/TriangularSolver.h deleted file mode 100644 index ebbeb3b4..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/TriangularSolver.h +++ /dev/null @@ -1,42 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2010 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_TRIANGULAR_SOLVER2_H -#define EIGEN_TRIANGULAR_SOLVER2_H - -namespace Eigen { - -const unsigned int UnitDiagBit = UnitDiag; -const unsigned int SelfAdjointBit = SelfAdjoint; -const unsigned int UpperTriangularBit = Upper; -const unsigned int LowerTriangularBit = Lower; - -const unsigned int UpperTriangular = Upper; -const unsigned int LowerTriangular = Lower; -const unsigned int UnitUpperTriangular = UnitUpper; -const unsigned int UnitLowerTriangular = UnitLower; - -template -template -typename ExpressionType::PlainObject -Flagged::solveTriangular(const MatrixBase& other) const -{ - return m_matrix.template triangularView().solve(other.derived()); -} - -template -template -void Flagged::solveTriangularInPlace(const MatrixBase& other) const -{ - m_matrix.template triangularView().solveInPlace(other.derived()); -} - -} // end namespace Eigen - -#endif // EIGEN_TRIANGULAR_SOLVER2_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/VectorBlock.h b/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/VectorBlock.h deleted file mode 100644 index 71a8080a..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/VectorBlock.h +++ /dev/null @@ -1,94 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2009 Gael Guennebaud -// Copyright (C) 2006-2008 Benoit Jacob -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN2_VECTORBLOCK_H -#define EIGEN2_VECTORBLOCK_H - -namespace Eigen { - -/** \deprecated use DenseMase::head(Index) */ -template -inline VectorBlock -MatrixBase::start(Index size) -{ - EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) - return VectorBlock(derived(), 0, size); -} - -/** \deprecated use DenseMase::head(Index) */ -template -inline const VectorBlock -MatrixBase::start(Index size) const -{ - EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) - return VectorBlock(derived(), 0, size); -} - -/** \deprecated use DenseMase::tail(Index) */ -template -inline VectorBlock -MatrixBase::end(Index size) -{ - EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) - return VectorBlock(derived(), this->size() - size, size); -} - -/** \deprecated use DenseMase::tail(Index) */ -template -inline const VectorBlock -MatrixBase::end(Index size) const -{ - EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) - return VectorBlock(derived(), this->size() - size, size); -} - -/** \deprecated use DenseMase::head() */ -template -template -inline VectorBlock -MatrixBase::start() -{ - EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) - return VectorBlock(derived(), 0); -} - -/** \deprecated use DenseMase::head() */ -template -template -inline const VectorBlock -MatrixBase::start() const -{ - EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) - return VectorBlock(derived(), 0); -} - -/** \deprecated use DenseMase::tail() */ -template -template -inline VectorBlock -MatrixBase::end() -{ - EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) - return VectorBlock(derived(), size() - Size); -} - -/** \deprecated use DenseMase::tail() */ -template -template -inline const VectorBlock -MatrixBase::end() const -{ - EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) - return VectorBlock(derived(), size() - Size); -} - -} // end namespace Eigen - -#endif // EIGEN2_VECTORBLOCK_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/ComplexEigenSolver.h b/thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/ComplexEigenSolver.h deleted file mode 100644 index 417c7294..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/ComplexEigenSolver.h +++ /dev/null @@ -1,341 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2009 Claire Maurice -// Copyright (C) 2009 Gael Guennebaud -// Copyright (C) 2010,2012 Jitse Niesen -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_COMPLEX_EIGEN_SOLVER_H -#define EIGEN_COMPLEX_EIGEN_SOLVER_H - -#include "./ComplexSchur.h" - -namespace Eigen { - -/** \eigenvalues_module \ingroup Eigenvalues_Module - * - * - * \class ComplexEigenSolver - * - * \brief Computes eigenvalues and eigenvectors of general complex matrices - * - * \tparam _MatrixType the type of the matrix of which we are - * computing the eigendecomposition; this is expected to be an - * instantiation of the Matrix class template. - * - * The eigenvalues and eigenvectors of a matrix \f$ A \f$ are scalars - * \f$ \lambda \f$ and vectors \f$ v \f$ such that \f$ Av = \lambda v - * \f$. If \f$ D \f$ is a diagonal matrix with the eigenvalues on - * the diagonal, and \f$ V \f$ is a matrix with the eigenvectors as - * its columns, then \f$ A V = V D \f$. The matrix \f$ V \f$ is - * almost always invertible, in which case we have \f$ A = V D V^{-1} - * \f$. This is called the eigendecomposition. - * - * The main function in this class is compute(), which computes the - * eigenvalues and eigenvectors of a given function. The - * documentation for that function contains an example showing the - * main features of the class. - * - * \sa class EigenSolver, class SelfAdjointEigenSolver - */ -template class ComplexEigenSolver -{ - public: - - /** \brief Synonym for the template parameter \p _MatrixType. */ - typedef _MatrixType MatrixType; - - enum { - RowsAtCompileTime = MatrixType::RowsAtCompileTime, - ColsAtCompileTime = MatrixType::ColsAtCompileTime, - Options = MatrixType::Options, - MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime, - MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime - }; - - /** \brief Scalar type for matrices of type #MatrixType. */ - typedef typename MatrixType::Scalar Scalar; - typedef typename NumTraits::Real RealScalar; - typedef typename MatrixType::Index Index; - - /** \brief Complex scalar type for #MatrixType. - * - * This is \c std::complex if #Scalar is real (e.g., - * \c float or \c double) and just \c Scalar if #Scalar is - * complex. - */ - typedef std::complex ComplexScalar; - - /** \brief Type for vector of eigenvalues as returned by eigenvalues(). - * - * This is a column vector with entries of type #ComplexScalar. - * The length of the vector is the size of #MatrixType. - */ - typedef Matrix EigenvalueType; - - /** \brief Type for matrix of eigenvectors as returned by eigenvectors(). - * - * This is a square matrix with entries of type #ComplexScalar. - * The size is the same as the size of #MatrixType. - */ - typedef Matrix EigenvectorType; - - /** \brief Default constructor. - * - * The default constructor is useful in cases in which the user intends to - * perform decompositions via compute(). - */ - ComplexEigenSolver() - : m_eivec(), - m_eivalues(), - m_schur(), - m_isInitialized(false), - m_eigenvectorsOk(false), - m_matX() - {} - - /** \brief Default Constructor with memory preallocation - * - * Like the default constructor but with preallocation of the internal data - * according to the specified problem \a size. - * \sa ComplexEigenSolver() - */ - ComplexEigenSolver(Index size) - : m_eivec(size, size), - m_eivalues(size), - m_schur(size), - m_isInitialized(false), - m_eigenvectorsOk(false), - m_matX(size, size) - {} - - /** \brief Constructor; computes eigendecomposition of given matrix. - * - * \param[in] matrix Square matrix whose eigendecomposition is to be computed. - * \param[in] computeEigenvectors If true, both the eigenvectors and the - * eigenvalues are computed; if false, only the eigenvalues are - * computed. - * - * This constructor calls compute() to compute the eigendecomposition. - */ - ComplexEigenSolver(const MatrixType& matrix, bool computeEigenvectors = true) - : m_eivec(matrix.rows(),matrix.cols()), - m_eivalues(matrix.cols()), - m_schur(matrix.rows()), - m_isInitialized(false), - m_eigenvectorsOk(false), - m_matX(matrix.rows(),matrix.cols()) - { - compute(matrix, computeEigenvectors); - } - - /** \brief Returns the eigenvectors of given matrix. - * - * \returns A const reference to the matrix whose columns are the eigenvectors. - * - * \pre Either the constructor - * ComplexEigenSolver(const MatrixType& matrix, bool) or the member - * function compute(const MatrixType& matrix, bool) has been called before - * to compute the eigendecomposition of a matrix, and - * \p computeEigenvectors was set to true (the default). - * - * This function returns a matrix whose columns are the eigenvectors. Column - * \f$ k \f$ is an eigenvector corresponding to eigenvalue number \f$ k - * \f$ as returned by eigenvalues(). The eigenvectors are normalized to - * have (Euclidean) norm equal to one. The matrix returned by this - * function is the matrix \f$ V \f$ in the eigendecomposition \f$ A = V D - * V^{-1} \f$, if it exists. - * - * Example: \include ComplexEigenSolver_eigenvectors.cpp - * Output: \verbinclude ComplexEigenSolver_eigenvectors.out - */ - const EigenvectorType& eigenvectors() const - { - eigen_assert(m_isInitialized && "ComplexEigenSolver is not initialized."); - eigen_assert(m_eigenvectorsOk && "The eigenvectors have not been computed together with the eigenvalues."); - return m_eivec; - } - - /** \brief Returns the eigenvalues of given matrix. - * - * \returns A const reference to the column vector containing the eigenvalues. - * - * \pre Either the constructor - * ComplexEigenSolver(const MatrixType& matrix, bool) or the member - * function compute(const MatrixType& matrix, bool) has been called before - * to compute the eigendecomposition of a matrix. - * - * This function returns a column vector containing the - * eigenvalues. Eigenvalues are repeated according to their - * algebraic multiplicity, so there are as many eigenvalues as - * rows in the matrix. The eigenvalues are not sorted in any particular - * order. - * - * Example: \include ComplexEigenSolver_eigenvalues.cpp - * Output: \verbinclude ComplexEigenSolver_eigenvalues.out - */ - const EigenvalueType& eigenvalues() const - { - eigen_assert(m_isInitialized && "ComplexEigenSolver is not initialized."); - return m_eivalues; - } - - /** \brief Computes eigendecomposition of given matrix. - * - * \param[in] matrix Square matrix whose eigendecomposition is to be computed. - * \param[in] computeEigenvectors If true, both the eigenvectors and the - * eigenvalues are computed; if false, only the eigenvalues are - * computed. - * \returns Reference to \c *this - * - * This function computes the eigenvalues of the complex matrix \p matrix. - * The eigenvalues() function can be used to retrieve them. If - * \p computeEigenvectors is true, then the eigenvectors are also computed - * and can be retrieved by calling eigenvectors(). - * - * The matrix is first reduced to Schur form using the - * ComplexSchur class. The Schur decomposition is then used to - * compute the eigenvalues and eigenvectors. - * - * The cost of the computation is dominated by the cost of the - * Schur decomposition, which is \f$ O(n^3) \f$ where \f$ n \f$ - * is the size of the matrix. - * - * Example: \include ComplexEigenSolver_compute.cpp - * Output: \verbinclude ComplexEigenSolver_compute.out - */ - ComplexEigenSolver& compute(const MatrixType& matrix, bool computeEigenvectors = true); - - /** \brief Reports whether previous computation was successful. - * - * \returns \c Success if computation was succesful, \c NoConvergence otherwise. - */ - ComputationInfo info() const - { - eigen_assert(m_isInitialized && "ComplexEigenSolver is not initialized."); - return m_schur.info(); - } - - /** \brief Sets the maximum number of iterations allowed. */ - ComplexEigenSolver& setMaxIterations(Index maxIters) - { - m_schur.setMaxIterations(maxIters); - return *this; - } - - /** \brief Returns the maximum number of iterations. */ - Index getMaxIterations() - { - return m_schur.getMaxIterations(); - } - - protected: - - static void check_template_parameters() - { - EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar); - } - - EigenvectorType m_eivec; - EigenvalueType m_eivalues; - ComplexSchur m_schur; - bool m_isInitialized; - bool m_eigenvectorsOk; - EigenvectorType m_matX; - - private: - void doComputeEigenvectors(const RealScalar& matrixnorm); - void sortEigenvalues(bool computeEigenvectors); -}; - - -template -ComplexEigenSolver& -ComplexEigenSolver::compute(const MatrixType& matrix, bool computeEigenvectors) -{ - check_template_parameters(); - - // this code is inspired from Jampack - eigen_assert(matrix.cols() == matrix.rows()); - - // Do a complex Schur decomposition, A = U T U^* - // The eigenvalues are on the diagonal of T. - m_schur.compute(matrix, computeEigenvectors); - - if(m_schur.info() == Success) - { - m_eivalues = m_schur.matrixT().diagonal(); - if(computeEigenvectors) - doComputeEigenvectors(matrix.norm()); - sortEigenvalues(computeEigenvectors); - } - - m_isInitialized = true; - m_eigenvectorsOk = computeEigenvectors; - return *this; -} - - -template -void ComplexEigenSolver::doComputeEigenvectors(const RealScalar& matrixnorm) -{ - const Index n = m_eivalues.size(); - - // Compute X such that T = X D X^(-1), where D is the diagonal of T. - // The matrix X is unit triangular. - m_matX = EigenvectorType::Zero(n, n); - for(Index k=n-1 ; k>=0 ; k--) - { - m_matX.coeffRef(k,k) = ComplexScalar(1.0,0.0); - // Compute X(i,k) using the (i,k) entry of the equation X T = D X - for(Index i=k-1 ; i>=0 ; i--) - { - m_matX.coeffRef(i,k) = -m_schur.matrixT().coeff(i,k); - if(k-i-1>0) - m_matX.coeffRef(i,k) -= (m_schur.matrixT().row(i).segment(i+1,k-i-1) * m_matX.col(k).segment(i+1,k-i-1)).value(); - ComplexScalar z = m_schur.matrixT().coeff(i,i) - m_schur.matrixT().coeff(k,k); - if(z==ComplexScalar(0)) - { - // If the i-th and k-th eigenvalue are equal, then z equals 0. - // Use a small value instead, to prevent division by zero. - numext::real_ref(z) = NumTraits::epsilon() * matrixnorm; - } - m_matX.coeffRef(i,k) = m_matX.coeff(i,k) / z; - } - } - - // Compute V as V = U X; now A = U T U^* = U X D X^(-1) U^* = V D V^(-1) - m_eivec.noalias() = m_schur.matrixU() * m_matX; - // .. and normalize the eigenvectors - for(Index k=0 ; k -void ComplexEigenSolver::sortEigenvalues(bool computeEigenvectors) -{ - const Index n = m_eivalues.size(); - for (Index i=0; i -// Copyright (C) 2010,2012 Jitse Niesen -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_COMPLEX_SCHUR_H -#define EIGEN_COMPLEX_SCHUR_H - -#include "./HessenbergDecomposition.h" - -namespace Eigen { - -namespace internal { -template struct complex_schur_reduce_to_hessenberg; -} - -/** \eigenvalues_module \ingroup Eigenvalues_Module - * - * - * \class ComplexSchur - * - * \brief Performs a complex Schur decomposition of a real or complex square matrix - * - * \tparam _MatrixType the type of the matrix of which we are - * computing the Schur decomposition; this is expected to be an - * instantiation of the Matrix class template. - * - * Given a real or complex square matrix A, this class computes the - * Schur decomposition: \f$ A = U T U^*\f$ where U is a unitary - * complex matrix, and T is a complex upper triangular matrix. The - * diagonal of the matrix T corresponds to the eigenvalues of the - * matrix A. - * - * Call the function compute() to compute the Schur decomposition of - * a given matrix. Alternatively, you can use the - * ComplexSchur(const MatrixType&, bool) constructor which computes - * the Schur decomposition at construction time. Once the - * decomposition is computed, you can use the matrixU() and matrixT() - * functions to retrieve the matrices U and V in the decomposition. - * - * \note This code is inspired from Jampack - * - * \sa class RealSchur, class EigenSolver, class ComplexEigenSolver - */ -template class ComplexSchur -{ - public: - typedef _MatrixType MatrixType; - enum { - RowsAtCompileTime = MatrixType::RowsAtCompileTime, - ColsAtCompileTime = MatrixType::ColsAtCompileTime, - Options = MatrixType::Options, - MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime, - MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime - }; - - /** \brief Scalar type for matrices of type \p _MatrixType. */ - typedef typename MatrixType::Scalar Scalar; - typedef typename NumTraits::Real RealScalar; - typedef typename MatrixType::Index Index; - - /** \brief Complex scalar type for \p _MatrixType. - * - * This is \c std::complex if #Scalar is real (e.g., - * \c float or \c double) and just \c Scalar if #Scalar is - * complex. - */ - typedef std::complex ComplexScalar; - - /** \brief Type for the matrices in the Schur decomposition. - * - * This is a square matrix with entries of type #ComplexScalar. - * The size is the same as the size of \p _MatrixType. - */ - typedef Matrix ComplexMatrixType; - - /** \brief Default constructor. - * - * \param [in] size Positive integer, size of the matrix whose Schur decomposition will be computed. - * - * The default constructor is useful in cases in which the user - * intends to perform decompositions via compute(). The \p size - * parameter is only used as a hint. It is not an error to give a - * wrong \p size, but it may impair performance. - * - * \sa compute() for an example. - */ - ComplexSchur(Index size = RowsAtCompileTime==Dynamic ? 1 : RowsAtCompileTime) - : m_matT(size,size), - m_matU(size,size), - m_hess(size), - m_isInitialized(false), - m_matUisUptodate(false), - m_maxIters(-1) - {} - - /** \brief Constructor; computes Schur decomposition of given matrix. - * - * \param[in] matrix Square matrix whose Schur decomposition is to be computed. - * \param[in] computeU If true, both T and U are computed; if false, only T is computed. - * - * This constructor calls compute() to compute the Schur decomposition. - * - * \sa matrixT() and matrixU() for examples. - */ - ComplexSchur(const MatrixType& matrix, bool computeU = true) - : m_matT(matrix.rows(),matrix.cols()), - m_matU(matrix.rows(),matrix.cols()), - m_hess(matrix.rows()), - m_isInitialized(false), - m_matUisUptodate(false), - m_maxIters(-1) - { - compute(matrix, computeU); - } - - /** \brief Returns the unitary matrix in the Schur decomposition. - * - * \returns A const reference to the matrix U. - * - * It is assumed that either the constructor - * ComplexSchur(const MatrixType& matrix, bool computeU) or the - * member function compute(const MatrixType& matrix, bool computeU) - * has been called before to compute the Schur decomposition of a - * matrix, and that \p computeU was set to true (the default - * value). - * - * Example: \include ComplexSchur_matrixU.cpp - * Output: \verbinclude ComplexSchur_matrixU.out - */ - const ComplexMatrixType& matrixU() const - { - eigen_assert(m_isInitialized && "ComplexSchur is not initialized."); - eigen_assert(m_matUisUptodate && "The matrix U has not been computed during the ComplexSchur decomposition."); - return m_matU; - } - - /** \brief Returns the triangular matrix in the Schur decomposition. - * - * \returns A const reference to the matrix T. - * - * It is assumed that either the constructor - * ComplexSchur(const MatrixType& matrix, bool computeU) or the - * member function compute(const MatrixType& matrix, bool computeU) - * has been called before to compute the Schur decomposition of a - * matrix. - * - * Note that this function returns a plain square matrix. If you want to reference - * only the upper triangular part, use: - * \code schur.matrixT().triangularView() \endcode - * - * Example: \include ComplexSchur_matrixT.cpp - * Output: \verbinclude ComplexSchur_matrixT.out - */ - const ComplexMatrixType& matrixT() const - { - eigen_assert(m_isInitialized && "ComplexSchur is not initialized."); - return m_matT; - } - - /** \brief Computes Schur decomposition of given matrix. - * - * \param[in] matrix Square matrix whose Schur decomposition is to be computed. - * \param[in] computeU If true, both T and U are computed; if false, only T is computed. - - * \returns Reference to \c *this - * - * The Schur decomposition is computed by first reducing the - * matrix to Hessenberg form using the class - * HessenbergDecomposition. The Hessenberg matrix is then reduced - * to triangular form by performing QR iterations with a single - * shift. The cost of computing the Schur decomposition depends - * on the number of iterations; as a rough guide, it may be taken - * on the number of iterations; as a rough guide, it may be taken - * to be \f$25n^3\f$ complex flops, or \f$10n^3\f$ complex flops - * if \a computeU is false. - * - * Example: \include ComplexSchur_compute.cpp - * Output: \verbinclude ComplexSchur_compute.out - * - * \sa compute(const MatrixType&, bool, Index) - */ - ComplexSchur& compute(const MatrixType& matrix, bool computeU = true); - - /** \brief Compute Schur decomposition from a given Hessenberg matrix - * \param[in] matrixH Matrix in Hessenberg form H - * \param[in] matrixQ orthogonal matrix Q that transform a matrix A to H : A = Q H Q^T - * \param computeU Computes the matriX U of the Schur vectors - * \return Reference to \c *this - * - * This routine assumes that the matrix is already reduced in Hessenberg form matrixH - * using either the class HessenbergDecomposition or another mean. - * It computes the upper quasi-triangular matrix T of the Schur decomposition of H - * When computeU is true, this routine computes the matrix U such that - * A = U T U^T = (QZ) T (QZ)^T = Q H Q^T where A is the initial matrix - * - * NOTE Q is referenced if computeU is true; so, if the initial orthogonal matrix - * is not available, the user should give an identity matrix (Q.setIdentity()) - * - * \sa compute(const MatrixType&, bool) - */ - template - ComplexSchur& computeFromHessenberg(const HessMatrixType& matrixH, const OrthMatrixType& matrixQ, bool computeU=true); - - /** \brief Reports whether previous computation was successful. - * - * \returns \c Success if computation was succesful, \c NoConvergence otherwise. - */ - ComputationInfo info() const - { - eigen_assert(m_isInitialized && "ComplexSchur is not initialized."); - return m_info; - } - - /** \brief Sets the maximum number of iterations allowed. - * - * If not specified by the user, the maximum number of iterations is m_maxIterationsPerRow times the size - * of the matrix. - */ - ComplexSchur& setMaxIterations(Index maxIters) - { - m_maxIters = maxIters; - return *this; - } - - /** \brief Returns the maximum number of iterations. */ - Index getMaxIterations() - { - return m_maxIters; - } - - /** \brief Maximum number of iterations per row. - * - * If not otherwise specified, the maximum number of iterations is this number times the size of the - * matrix. It is currently set to 30. - */ - static const int m_maxIterationsPerRow = 30; - - protected: - ComplexMatrixType m_matT, m_matU; - HessenbergDecomposition m_hess; - ComputationInfo m_info; - bool m_isInitialized; - bool m_matUisUptodate; - Index m_maxIters; - - private: - bool subdiagonalEntryIsNeglegible(Index i); - ComplexScalar computeShift(Index iu, Index iter); - void reduceToTriangularForm(bool computeU); - friend struct internal::complex_schur_reduce_to_hessenberg::IsComplex>; -}; - -/** If m_matT(i+1,i) is neglegible in floating point arithmetic - * compared to m_matT(i,i) and m_matT(j,j), then set it to zero and - * return true, else return false. */ -template -inline bool ComplexSchur::subdiagonalEntryIsNeglegible(Index i) -{ - RealScalar d = numext::norm1(m_matT.coeff(i,i)) + numext::norm1(m_matT.coeff(i+1,i+1)); - RealScalar sd = numext::norm1(m_matT.coeff(i+1,i)); - if (internal::isMuchSmallerThan(sd, d, NumTraits::epsilon())) - { - m_matT.coeffRef(i+1,i) = ComplexScalar(0); - return true; - } - return false; -} - - -/** Compute the shift in the current QR iteration. */ -template -typename ComplexSchur::ComplexScalar ComplexSchur::computeShift(Index iu, Index iter) -{ - using std::abs; - if (iter == 10 || iter == 20) - { - // exceptional shift, taken from http://www.netlib.org/eispack/comqr.f - return abs(numext::real(m_matT.coeff(iu,iu-1))) + abs(numext::real(m_matT.coeff(iu-1,iu-2))); - } - - // compute the shift as one of the eigenvalues of t, the 2x2 - // diagonal block on the bottom of the active submatrix - Matrix t = m_matT.template block<2,2>(iu-1,iu-1); - RealScalar normt = t.cwiseAbs().sum(); - t /= normt; // the normalization by sf is to avoid under/overflow - - ComplexScalar b = t.coeff(0,1) * t.coeff(1,0); - ComplexScalar c = t.coeff(0,0) - t.coeff(1,1); - ComplexScalar disc = sqrt(c*c + RealScalar(4)*b); - ComplexScalar det = t.coeff(0,0) * t.coeff(1,1) - b; - ComplexScalar trace = t.coeff(0,0) + t.coeff(1,1); - ComplexScalar eival1 = (trace + disc) / RealScalar(2); - ComplexScalar eival2 = (trace - disc) / RealScalar(2); - - if(numext::norm1(eival1) > numext::norm1(eival2)) - eival2 = det / eival1; - else - eival1 = det / eival2; - - // choose the eigenvalue closest to the bottom entry of the diagonal - if(numext::norm1(eival1-t.coeff(1,1)) < numext::norm1(eival2-t.coeff(1,1))) - return normt * eival1; - else - return normt * eival2; -} - - -template -ComplexSchur& ComplexSchur::compute(const MatrixType& matrix, bool computeU) -{ - m_matUisUptodate = false; - eigen_assert(matrix.cols() == matrix.rows()); - - if(matrix.cols() == 1) - { - m_matT = matrix.template cast(); - if(computeU) m_matU = ComplexMatrixType::Identity(1,1); - m_info = Success; - m_isInitialized = true; - m_matUisUptodate = computeU; - return *this; - } - - internal::complex_schur_reduce_to_hessenberg::IsComplex>::run(*this, matrix, computeU); - computeFromHessenberg(m_matT, m_matU, computeU); - return *this; -} - -template -template -ComplexSchur& ComplexSchur::computeFromHessenberg(const HessMatrixType& matrixH, const OrthMatrixType& matrixQ, bool computeU) -{ - m_matT = matrixH; - if(computeU) - m_matU = matrixQ; - reduceToTriangularForm(computeU); - return *this; -} -namespace internal { - -/* Reduce given matrix to Hessenberg form */ -template -struct complex_schur_reduce_to_hessenberg -{ - // this is the implementation for the case IsComplex = true - static void run(ComplexSchur& _this, const MatrixType& matrix, bool computeU) - { - _this.m_hess.compute(matrix); - _this.m_matT = _this.m_hess.matrixH(); - if(computeU) _this.m_matU = _this.m_hess.matrixQ(); - } -}; - -template -struct complex_schur_reduce_to_hessenberg -{ - static void run(ComplexSchur& _this, const MatrixType& matrix, bool computeU) - { - typedef typename ComplexSchur::ComplexScalar ComplexScalar; - - // Note: m_hess is over RealScalar; m_matT and m_matU is over ComplexScalar - _this.m_hess.compute(matrix); - _this.m_matT = _this.m_hess.matrixH().template cast(); - if(computeU) - { - // This may cause an allocation which seems to be avoidable - MatrixType Q = _this.m_hess.matrixQ(); - _this.m_matU = Q.template cast(); - } - } -}; - -} // end namespace internal - -// Reduce the Hessenberg matrix m_matT to triangular form by QR iteration. -template -void ComplexSchur::reduceToTriangularForm(bool computeU) -{ - Index maxIters = m_maxIters; - if (maxIters == -1) - maxIters = m_maxIterationsPerRow * m_matT.rows(); - - // The matrix m_matT is divided in three parts. - // Rows 0,...,il-1 are decoupled from the rest because m_matT(il,il-1) is zero. - // Rows il,...,iu is the part we are working on (the active submatrix). - // Rows iu+1,...,end are already brought in triangular form. - Index iu = m_matT.cols() - 1; - Index il; - Index iter = 0; // number of iterations we are working on the (iu,iu) element - Index totalIter = 0; // number of iterations for whole matrix - - while(true) - { - // find iu, the bottom row of the active submatrix - while(iu > 0) - { - if(!subdiagonalEntryIsNeglegible(iu-1)) break; - iter = 0; - --iu; - } - - // if iu is zero then we are done; the whole matrix is triangularized - if(iu==0) break; - - // if we spent too many iterations, we give up - iter++; - totalIter++; - if(totalIter > maxIters) break; - - // find il, the top row of the active submatrix - il = iu-1; - while(il > 0 && !subdiagonalEntryIsNeglegible(il-1)) - { - --il; - } - - /* perform the QR step using Givens rotations. The first rotation - creates a bulge; the (il+2,il) element becomes nonzero. This - bulge is chased down to the bottom of the active submatrix. */ - - ComplexScalar shift = computeShift(iu, iter); - JacobiRotation rot; - rot.makeGivens(m_matT.coeff(il,il) - shift, m_matT.coeff(il+1,il)); - m_matT.rightCols(m_matT.cols()-il).applyOnTheLeft(il, il+1, rot.adjoint()); - m_matT.topRows((std::min)(il+2,iu)+1).applyOnTheRight(il, il+1, rot); - if(computeU) m_matU.applyOnTheRight(il, il+1, rot); - - for(Index i=il+1 ; i inline \ -ComplexSchur >& \ -ComplexSchur >::compute(const Matrix& matrix, bool computeU) \ -{ \ - typedef Matrix MatrixType; \ - typedef MatrixType::Scalar Scalar; \ - typedef MatrixType::RealScalar RealScalar; \ - typedef std::complex ComplexScalar; \ -\ - eigen_assert(matrix.cols() == matrix.rows()); \ -\ - m_matUisUptodate = false; \ - if(matrix.cols() == 1) \ - { \ - m_matT = matrix.cast(); \ - if(computeU) m_matU = ComplexMatrixType::Identity(1,1); \ - m_info = Success; \ - m_isInitialized = true; \ - m_matUisUptodate = computeU; \ - return *this; \ - } \ - lapack_int n = matrix.cols(), sdim, info; \ - lapack_int lda = matrix.outerStride(); \ - lapack_int matrix_order = MKLCOLROW; \ - char jobvs, sort='N'; \ - LAPACK_##MKLPREFIX_U##_SELECT1 select = 0; \ - jobvs = (computeU) ? 'V' : 'N'; \ - m_matU.resize(n, n); \ - lapack_int ldvs = m_matU.outerStride(); \ - m_matT = matrix; \ - Matrix w; \ - w.resize(n, 1);\ - info = LAPACKE_##MKLPREFIX##gees( matrix_order, jobvs, sort, select, n, (MKLTYPE*)m_matT.data(), lda, &sdim, (MKLTYPE*)w.data(), (MKLTYPE*)m_matU.data(), ldvs ); \ - if(info == 0) \ - m_info = Success; \ - else \ - m_info = NoConvergence; \ -\ - m_isInitialized = true; \ - m_matUisUptodate = computeU; \ - return *this; \ -\ -} - -EIGEN_MKL_SCHUR_COMPLEX(dcomplex, MKL_Complex16, z, Z, ColMajor, LAPACK_COL_MAJOR) -EIGEN_MKL_SCHUR_COMPLEX(scomplex, MKL_Complex8, c, C, ColMajor, LAPACK_COL_MAJOR) -EIGEN_MKL_SCHUR_COMPLEX(dcomplex, MKL_Complex16, z, Z, RowMajor, LAPACK_ROW_MAJOR) -EIGEN_MKL_SCHUR_COMPLEX(scomplex, MKL_Complex8, c, C, RowMajor, LAPACK_ROW_MAJOR) - -} // end namespace Eigen - -#endif // EIGEN_COMPLEX_SCHUR_MKL_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/EigenSolver.h b/thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/EigenSolver.h deleted file mode 100644 index 20c59a7a..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/EigenSolver.h +++ /dev/null @@ -1,607 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud -// Copyright (C) 2010,2012 Jitse Niesen -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_EIGENSOLVER_H -#define EIGEN_EIGENSOLVER_H - -#include "./RealSchur.h" - -namespace Eigen { - -/** \eigenvalues_module \ingroup Eigenvalues_Module - * - * - * \class EigenSolver - * - * \brief Computes eigenvalues and eigenvectors of general matrices - * - * \tparam _MatrixType the type of the matrix of which we are computing the - * eigendecomposition; this is expected to be an instantiation of the Matrix - * class template. Currently, only real matrices are supported. - * - * The eigenvalues and eigenvectors of a matrix \f$ A \f$ are scalars - * \f$ \lambda \f$ and vectors \f$ v \f$ such that \f$ Av = \lambda v \f$. If - * \f$ D \f$ is a diagonal matrix with the eigenvalues on the diagonal, and - * \f$ V \f$ is a matrix with the eigenvectors as its columns, then \f$ A V = - * V D \f$. The matrix \f$ V \f$ is almost always invertible, in which case we - * have \f$ A = V D V^{-1} \f$. This is called the eigendecomposition. - * - * The eigenvalues and eigenvectors of a matrix may be complex, even when the - * matrix is real. However, we can choose real matrices \f$ V \f$ and \f$ D - * \f$ satisfying \f$ A V = V D \f$, just like the eigendecomposition, if the - * matrix \f$ D \f$ is not required to be diagonal, but if it is allowed to - * have blocks of the form - * \f[ \begin{bmatrix} u & v \\ -v & u \end{bmatrix} \f] - * (where \f$ u \f$ and \f$ v \f$ are real numbers) on the diagonal. These - * blocks correspond to complex eigenvalue pairs \f$ u \pm iv \f$. We call - * this variant of the eigendecomposition the pseudo-eigendecomposition. - * - * Call the function compute() to compute the eigenvalues and eigenvectors of - * a given matrix. Alternatively, you can use the - * EigenSolver(const MatrixType&, bool) constructor which computes the - * eigenvalues and eigenvectors at construction time. Once the eigenvalue and - * eigenvectors are computed, they can be retrieved with the eigenvalues() and - * eigenvectors() functions. The pseudoEigenvalueMatrix() and - * pseudoEigenvectors() methods allow the construction of the - * pseudo-eigendecomposition. - * - * The documentation for EigenSolver(const MatrixType&, bool) contains an - * example of the typical use of this class. - * - * \note The implementation is adapted from - * JAMA (public domain). - * Their code is based on EISPACK. - * - * \sa MatrixBase::eigenvalues(), class ComplexEigenSolver, class SelfAdjointEigenSolver - */ -template class EigenSolver -{ - public: - - /** \brief Synonym for the template parameter \p _MatrixType. */ - typedef _MatrixType MatrixType; - - enum { - RowsAtCompileTime = MatrixType::RowsAtCompileTime, - ColsAtCompileTime = MatrixType::ColsAtCompileTime, - Options = MatrixType::Options, - MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime, - MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime - }; - - /** \brief Scalar type for matrices of type #MatrixType. */ - typedef typename MatrixType::Scalar Scalar; - typedef typename NumTraits::Real RealScalar; - typedef typename MatrixType::Index Index; - - /** \brief Complex scalar type for #MatrixType. - * - * This is \c std::complex if #Scalar is real (e.g., - * \c float or \c double) and just \c Scalar if #Scalar is - * complex. - */ - typedef std::complex ComplexScalar; - - /** \brief Type for vector of eigenvalues as returned by eigenvalues(). - * - * This is a column vector with entries of type #ComplexScalar. - * The length of the vector is the size of #MatrixType. - */ - typedef Matrix EigenvalueType; - - /** \brief Type for matrix of eigenvectors as returned by eigenvectors(). - * - * This is a square matrix with entries of type #ComplexScalar. - * The size is the same as the size of #MatrixType. - */ - typedef Matrix EigenvectorsType; - - /** \brief Default constructor. - * - * The default constructor is useful in cases in which the user intends to - * perform decompositions via EigenSolver::compute(const MatrixType&, bool). - * - * \sa compute() for an example. - */ - EigenSolver() : m_eivec(), m_eivalues(), m_isInitialized(false), m_realSchur(), m_matT(), m_tmp() {} - - /** \brief Default constructor with memory preallocation - * - * Like the default constructor but with preallocation of the internal data - * according to the specified problem \a size. - * \sa EigenSolver() - */ - EigenSolver(Index size) - : m_eivec(size, size), - m_eivalues(size), - m_isInitialized(false), - m_eigenvectorsOk(false), - m_realSchur(size), - m_matT(size, size), - m_tmp(size) - {} - - /** \brief Constructor; computes eigendecomposition of given matrix. - * - * \param[in] matrix Square matrix whose eigendecomposition is to be computed. - * \param[in] computeEigenvectors If true, both the eigenvectors and the - * eigenvalues are computed; if false, only the eigenvalues are - * computed. - * - * This constructor calls compute() to compute the eigenvalues - * and eigenvectors. - * - * Example: \include EigenSolver_EigenSolver_MatrixType.cpp - * Output: \verbinclude EigenSolver_EigenSolver_MatrixType.out - * - * \sa compute() - */ - EigenSolver(const MatrixType& matrix, bool computeEigenvectors = true) - : m_eivec(matrix.rows(), matrix.cols()), - m_eivalues(matrix.cols()), - m_isInitialized(false), - m_eigenvectorsOk(false), - m_realSchur(matrix.cols()), - m_matT(matrix.rows(), matrix.cols()), - m_tmp(matrix.cols()) - { - compute(matrix, computeEigenvectors); - } - - /** \brief Returns the eigenvectors of given matrix. - * - * \returns %Matrix whose columns are the (possibly complex) eigenvectors. - * - * \pre Either the constructor - * EigenSolver(const MatrixType&,bool) or the member function - * compute(const MatrixType&, bool) has been called before, and - * \p computeEigenvectors was set to true (the default). - * - * Column \f$ k \f$ of the returned matrix is an eigenvector corresponding - * to eigenvalue number \f$ k \f$ as returned by eigenvalues(). The - * eigenvectors are normalized to have (Euclidean) norm equal to one. The - * matrix returned by this function is the matrix \f$ V \f$ in the - * eigendecomposition \f$ A = V D V^{-1} \f$, if it exists. - * - * Example: \include EigenSolver_eigenvectors.cpp - * Output: \verbinclude EigenSolver_eigenvectors.out - * - * \sa eigenvalues(), pseudoEigenvectors() - */ - EigenvectorsType eigenvectors() const; - - /** \brief Returns the pseudo-eigenvectors of given matrix. - * - * \returns Const reference to matrix whose columns are the pseudo-eigenvectors. - * - * \pre Either the constructor - * EigenSolver(const MatrixType&,bool) or the member function - * compute(const MatrixType&, bool) has been called before, and - * \p computeEigenvectors was set to true (the default). - * - * The real matrix \f$ V \f$ returned by this function and the - * block-diagonal matrix \f$ D \f$ returned by pseudoEigenvalueMatrix() - * satisfy \f$ AV = VD \f$. - * - * Example: \include EigenSolver_pseudoEigenvectors.cpp - * Output: \verbinclude EigenSolver_pseudoEigenvectors.out - * - * \sa pseudoEigenvalueMatrix(), eigenvectors() - */ - const MatrixType& pseudoEigenvectors() const - { - eigen_assert(m_isInitialized && "EigenSolver is not initialized."); - eigen_assert(m_eigenvectorsOk && "The eigenvectors have not been computed together with the eigenvalues."); - return m_eivec; - } - - /** \brief Returns the block-diagonal matrix in the pseudo-eigendecomposition. - * - * \returns A block-diagonal matrix. - * - * \pre Either the constructor - * EigenSolver(const MatrixType&,bool) or the member function - * compute(const MatrixType&, bool) has been called before. - * - * The matrix \f$ D \f$ returned by this function is real and - * block-diagonal. The blocks on the diagonal are either 1-by-1 or 2-by-2 - * blocks of the form - * \f$ \begin{bmatrix} u & v \\ -v & u \end{bmatrix} \f$. - * These blocks are not sorted in any particular order. - * The matrix \f$ D \f$ and the matrix \f$ V \f$ returned by - * pseudoEigenvectors() satisfy \f$ AV = VD \f$. - * - * \sa pseudoEigenvectors() for an example, eigenvalues() - */ - MatrixType pseudoEigenvalueMatrix() const; - - /** \brief Returns the eigenvalues of given matrix. - * - * \returns A const reference to the column vector containing the eigenvalues. - * - * \pre Either the constructor - * EigenSolver(const MatrixType&,bool) or the member function - * compute(const MatrixType&, bool) has been called before. - * - * The eigenvalues are repeated according to their algebraic multiplicity, - * so there are as many eigenvalues as rows in the matrix. The eigenvalues - * are not sorted in any particular order. - * - * Example: \include EigenSolver_eigenvalues.cpp - * Output: \verbinclude EigenSolver_eigenvalues.out - * - * \sa eigenvectors(), pseudoEigenvalueMatrix(), - * MatrixBase::eigenvalues() - */ - const EigenvalueType& eigenvalues() const - { - eigen_assert(m_isInitialized && "EigenSolver is not initialized."); - return m_eivalues; - } - - /** \brief Computes eigendecomposition of given matrix. - * - * \param[in] matrix Square matrix whose eigendecomposition is to be computed. - * \param[in] computeEigenvectors If true, both the eigenvectors and the - * eigenvalues are computed; if false, only the eigenvalues are - * computed. - * \returns Reference to \c *this - * - * This function computes the eigenvalues of the real matrix \p matrix. - * The eigenvalues() function can be used to retrieve them. If - * \p computeEigenvectors is true, then the eigenvectors are also computed - * and can be retrieved by calling eigenvectors(). - * - * The matrix is first reduced to real Schur form using the RealSchur - * class. The Schur decomposition is then used to compute the eigenvalues - * and eigenvectors. - * - * The cost of the computation is dominated by the cost of the - * Schur decomposition, which is very approximately \f$ 25n^3 \f$ - * (where \f$ n \f$ is the size of the matrix) if \p computeEigenvectors - * is true, and \f$ 10n^3 \f$ if \p computeEigenvectors is false. - * - * This method reuses of the allocated data in the EigenSolver object. - * - * Example: \include EigenSolver_compute.cpp - * Output: \verbinclude EigenSolver_compute.out - */ - EigenSolver& compute(const MatrixType& matrix, bool computeEigenvectors = true); - - ComputationInfo info() const - { - eigen_assert(m_isInitialized && "EigenSolver is not initialized."); - return m_realSchur.info(); - } - - /** \brief Sets the maximum number of iterations allowed. */ - EigenSolver& setMaxIterations(Index maxIters) - { - m_realSchur.setMaxIterations(maxIters); - return *this; - } - - /** \brief Returns the maximum number of iterations. */ - Index getMaxIterations() - { - return m_realSchur.getMaxIterations(); - } - - private: - void doComputeEigenvectors(); - - protected: - - static void check_template_parameters() - { - EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar); - EIGEN_STATIC_ASSERT(!NumTraits::IsComplex, NUMERIC_TYPE_MUST_BE_REAL); - } - - MatrixType m_eivec; - EigenvalueType m_eivalues; - bool m_isInitialized; - bool m_eigenvectorsOk; - RealSchur m_realSchur; - MatrixType m_matT; - - typedef Matrix ColumnVectorType; - ColumnVectorType m_tmp; -}; - -template -MatrixType EigenSolver::pseudoEigenvalueMatrix() const -{ - eigen_assert(m_isInitialized && "EigenSolver is not initialized."); - Index n = m_eivalues.rows(); - MatrixType matD = MatrixType::Zero(n,n); - for (Index i=0; i(i,i) << numext::real(m_eivalues.coeff(i)), numext::imag(m_eivalues.coeff(i)), - -numext::imag(m_eivalues.coeff(i)), numext::real(m_eivalues.coeff(i)); - ++i; - } - } - return matD; -} - -template -typename EigenSolver::EigenvectorsType EigenSolver::eigenvectors() const -{ - eigen_assert(m_isInitialized && "EigenSolver is not initialized."); - eigen_assert(m_eigenvectorsOk && "The eigenvectors have not been computed together with the eigenvalues."); - Index n = m_eivec.cols(); - EigenvectorsType matV(n,n); - for (Index j=0; j(); - matV.col(j).normalize(); - } - else - { - // we have a pair of complex eigen values - for (Index i=0; i -EigenSolver& -EigenSolver::compute(const MatrixType& matrix, bool computeEigenvectors) -{ - check_template_parameters(); - - using std::sqrt; - using std::abs; - eigen_assert(matrix.cols() == matrix.rows()); - - // Reduce to real Schur form. - m_realSchur.compute(matrix, computeEigenvectors); - - if (m_realSchur.info() == Success) - { - m_matT = m_realSchur.matrixT(); - if (computeEigenvectors) - m_eivec = m_realSchur.matrixU(); - - // Compute eigenvalues from matT - m_eivalues.resize(matrix.cols()); - Index i = 0; - while (i < matrix.cols()) - { - if (i == matrix.cols() - 1 || m_matT.coeff(i+1, i) == Scalar(0)) - { - m_eivalues.coeffRef(i) = m_matT.coeff(i, i); - ++i; - } - else - { - Scalar p = Scalar(0.5) * (m_matT.coeff(i, i) - m_matT.coeff(i+1, i+1)); - Scalar z = sqrt(abs(p * p + m_matT.coeff(i+1, i) * m_matT.coeff(i, i+1))); - m_eivalues.coeffRef(i) = ComplexScalar(m_matT.coeff(i+1, i+1) + p, z); - m_eivalues.coeffRef(i+1) = ComplexScalar(m_matT.coeff(i+1, i+1) + p, -z); - i += 2; - } - } - - // Compute eigenvectors. - if (computeEigenvectors) - doComputeEigenvectors(); - } - - m_isInitialized = true; - m_eigenvectorsOk = computeEigenvectors; - - return *this; -} - -// Complex scalar division. -template -std::complex cdiv(const Scalar& xr, const Scalar& xi, const Scalar& yr, const Scalar& yi) -{ - using std::abs; - Scalar r,d; - if (abs(yr) > abs(yi)) - { - r = yi/yr; - d = yr + r*yi; - return std::complex((xr + r*xi)/d, (xi - r*xr)/d); - } - else - { - r = yr/yi; - d = yi + r*yr; - return std::complex((r*xr + xi)/d, (r*xi - xr)/d); - } -} - - -template -void EigenSolver::doComputeEigenvectors() -{ - using std::abs; - const Index size = m_eivec.cols(); - const Scalar eps = NumTraits::epsilon(); - - // inefficient! this is already computed in RealSchur - Scalar norm(0); - for (Index j = 0; j < size; ++j) - { - norm += m_matT.row(j).segment((std::max)(j-1,Index(0)), size-(std::max)(j-1,Index(0))).cwiseAbs().sum(); - } - - // Backsubstitute to find vectors of upper triangular form - if (norm == 0.0) - { - return; - } - - for (Index n = size-1; n >= 0; n--) - { - Scalar p = m_eivalues.coeff(n).real(); - Scalar q = m_eivalues.coeff(n).imag(); - - // Scalar vector - if (q == Scalar(0)) - { - Scalar lastr(0), lastw(0); - Index l = n; - - m_matT.coeffRef(n,n) = 1.0; - for (Index i = n-1; i >= 0; i--) - { - Scalar w = m_matT.coeff(i,i) - p; - Scalar r = m_matT.row(i).segment(l,n-l+1).dot(m_matT.col(n).segment(l, n-l+1)); - - if (m_eivalues.coeff(i).imag() < 0.0) - { - lastw = w; - lastr = r; - } - else - { - l = i; - if (m_eivalues.coeff(i).imag() == 0.0) - { - if (w != 0.0) - m_matT.coeffRef(i,n) = -r / w; - else - m_matT.coeffRef(i,n) = -r / (eps * norm); - } - else // Solve real equations - { - Scalar x = m_matT.coeff(i,i+1); - Scalar y = m_matT.coeff(i+1,i); - Scalar denom = (m_eivalues.coeff(i).real() - p) * (m_eivalues.coeff(i).real() - p) + m_eivalues.coeff(i).imag() * m_eivalues.coeff(i).imag(); - Scalar t = (x * lastr - lastw * r) / denom; - m_matT.coeffRef(i,n) = t; - if (abs(x) > abs(lastw)) - m_matT.coeffRef(i+1,n) = (-r - w * t) / x; - else - m_matT.coeffRef(i+1,n) = (-lastr - y * t) / lastw; - } - - // Overflow control - Scalar t = abs(m_matT.coeff(i,n)); - if ((eps * t) * t > Scalar(1)) - m_matT.col(n).tail(size-i) /= t; - } - } - } - else if (q < Scalar(0) && n > 0) // Complex vector - { - Scalar lastra(0), lastsa(0), lastw(0); - Index l = n-1; - - // Last vector component imaginary so matrix is triangular - if (abs(m_matT.coeff(n,n-1)) > abs(m_matT.coeff(n-1,n))) - { - m_matT.coeffRef(n-1,n-1) = q / m_matT.coeff(n,n-1); - m_matT.coeffRef(n-1,n) = -(m_matT.coeff(n,n) - p) / m_matT.coeff(n,n-1); - } - else - { - std::complex cc = cdiv(0.0,-m_matT.coeff(n-1,n),m_matT.coeff(n-1,n-1)-p,q); - m_matT.coeffRef(n-1,n-1) = numext::real(cc); - m_matT.coeffRef(n-1,n) = numext::imag(cc); - } - m_matT.coeffRef(n,n-1) = 0.0; - m_matT.coeffRef(n,n) = 1.0; - for (Index i = n-2; i >= 0; i--) - { - Scalar ra = m_matT.row(i).segment(l, n-l+1).dot(m_matT.col(n-1).segment(l, n-l+1)); - Scalar sa = m_matT.row(i).segment(l, n-l+1).dot(m_matT.col(n).segment(l, n-l+1)); - Scalar w = m_matT.coeff(i,i) - p; - - if (m_eivalues.coeff(i).imag() < 0.0) - { - lastw = w; - lastra = ra; - lastsa = sa; - } - else - { - l = i; - if (m_eivalues.coeff(i).imag() == RealScalar(0)) - { - std::complex cc = cdiv(-ra,-sa,w,q); - m_matT.coeffRef(i,n-1) = numext::real(cc); - m_matT.coeffRef(i,n) = numext::imag(cc); - } - else - { - // Solve complex equations - Scalar x = m_matT.coeff(i,i+1); - Scalar y = m_matT.coeff(i+1,i); - Scalar vr = (m_eivalues.coeff(i).real() - p) * (m_eivalues.coeff(i).real() - p) + m_eivalues.coeff(i).imag() * m_eivalues.coeff(i).imag() - q * q; - Scalar vi = (m_eivalues.coeff(i).real() - p) * Scalar(2) * q; - if ((vr == 0.0) && (vi == 0.0)) - vr = eps * norm * (abs(w) + abs(q) + abs(x) + abs(y) + abs(lastw)); - - std::complex cc = cdiv(x*lastra-lastw*ra+q*sa,x*lastsa-lastw*sa-q*ra,vr,vi); - m_matT.coeffRef(i,n-1) = numext::real(cc); - m_matT.coeffRef(i,n) = numext::imag(cc); - if (abs(x) > (abs(lastw) + abs(q))) - { - m_matT.coeffRef(i+1,n-1) = (-ra - w * m_matT.coeff(i,n-1) + q * m_matT.coeff(i,n)) / x; - m_matT.coeffRef(i+1,n) = (-sa - w * m_matT.coeff(i,n) - q * m_matT.coeff(i,n-1)) / x; - } - else - { - cc = cdiv(-lastra-y*m_matT.coeff(i,n-1),-lastsa-y*m_matT.coeff(i,n),lastw,q); - m_matT.coeffRef(i+1,n-1) = numext::real(cc); - m_matT.coeffRef(i+1,n) = numext::imag(cc); - } - } - - // Overflow control - using std::max; - Scalar t = (max)(abs(m_matT.coeff(i,n-1)),abs(m_matT.coeff(i,n))); - if ((eps * t) * t > Scalar(1)) - m_matT.block(i, n-1, size-i, 2) /= t; - - } - } - - // We handled a pair of complex conjugate eigenvalues, so need to skip them both - n--; - } - else - { - eigen_assert(0 && "Internal bug in EigenSolver"); // this should not happen - } - } - - // Back transformation to get eigenvectors of original matrix - for (Index j = size-1; j >= 0; j--) - { - m_tmp.noalias() = m_eivec.leftCols(j+1) * m_matT.col(j).segment(0, j+1); - m_eivec.col(j) = m_tmp; - } -} - -} // end namespace Eigen - -#endif // EIGEN_EIGENSOLVER_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h b/thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h deleted file mode 100644 index 956e80d9..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h +++ /dev/null @@ -1,350 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2012 Gael Guennebaud -// Copyright (C) 2010,2012 Jitse Niesen -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_GENERALIZEDEIGENSOLVER_H -#define EIGEN_GENERALIZEDEIGENSOLVER_H - -#include "./RealQZ.h" - -namespace Eigen { - -/** \eigenvalues_module \ingroup Eigenvalues_Module - * - * - * \class GeneralizedEigenSolver - * - * \brief Computes the generalized eigenvalues and eigenvectors of a pair of general matrices - * - * \tparam _MatrixType the type of the matrices of which we are computing the - * eigen-decomposition; this is expected to be an instantiation of the Matrix - * class template. Currently, only real matrices are supported. - * - * The generalized eigenvalues and eigenvectors of a matrix pair \f$ A \f$ and \f$ B \f$ are scalars - * \f$ \lambda \f$ and vectors \f$ v \f$ such that \f$ Av = \lambda Bv \f$. If - * \f$ D \f$ is a diagonal matrix with the eigenvalues on the diagonal, and - * \f$ V \f$ is a matrix with the eigenvectors as its columns, then \f$ A V = - * B V D \f$. The matrix \f$ V \f$ is almost always invertible, in which case we - * have \f$ A = B V D V^{-1} \f$. This is called the generalized eigen-decomposition. - * - * The generalized eigenvalues and eigenvectors of a matrix pair may be complex, even when the - * matrices are real. Moreover, the generalized eigenvalue might be infinite if the matrix B is - * singular. To workaround this difficulty, the eigenvalues are provided as a pair of complex \f$ \alpha \f$ - * and real \f$ \beta \f$ such that: \f$ \lambda_i = \alpha_i / \beta_i \f$. If \f$ \beta_i \f$ is (nearly) zero, - * then one can consider the well defined left eigenvalue \f$ \mu = \beta_i / \alpha_i\f$ such that: - * \f$ \mu_i A v_i = B v_i \f$, or even \f$ \mu_i u_i^T A = u_i^T B \f$ where \f$ u_i \f$ is - * called the left eigenvector. - * - * Call the function compute() to compute the generalized eigenvalues and eigenvectors of - * a given matrix pair. Alternatively, you can use the - * GeneralizedEigenSolver(const MatrixType&, const MatrixType&, bool) constructor which computes the - * eigenvalues and eigenvectors at construction time. Once the eigenvalue and - * eigenvectors are computed, they can be retrieved with the eigenvalues() and - * eigenvectors() functions. - * - * Here is an usage example of this class: - * Example: \include GeneralizedEigenSolver.cpp - * Output: \verbinclude GeneralizedEigenSolver.out - * - * \sa MatrixBase::eigenvalues(), class ComplexEigenSolver, class SelfAdjointEigenSolver - */ -template class GeneralizedEigenSolver -{ - public: - - /** \brief Synonym for the template parameter \p _MatrixType. */ - typedef _MatrixType MatrixType; - - enum { - RowsAtCompileTime = MatrixType::RowsAtCompileTime, - ColsAtCompileTime = MatrixType::ColsAtCompileTime, - Options = MatrixType::Options, - MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime, - MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime - }; - - /** \brief Scalar type for matrices of type #MatrixType. */ - typedef typename MatrixType::Scalar Scalar; - typedef typename NumTraits::Real RealScalar; - typedef typename MatrixType::Index Index; - - /** \brief Complex scalar type for #MatrixType. - * - * This is \c std::complex if #Scalar is real (e.g., - * \c float or \c double) and just \c Scalar if #Scalar is - * complex. - */ - typedef std::complex ComplexScalar; - - /** \brief Type for vector of real scalar values eigenvalues as returned by betas(). - * - * This is a column vector with entries of type #Scalar. - * The length of the vector is the size of #MatrixType. - */ - typedef Matrix VectorType; - - /** \brief Type for vector of complex scalar values eigenvalues as returned by betas(). - * - * This is a column vector with entries of type #ComplexScalar. - * The length of the vector is the size of #MatrixType. - */ - typedef Matrix ComplexVectorType; - - /** \brief Expression type for the eigenvalues as returned by eigenvalues(). - */ - typedef CwiseBinaryOp,ComplexVectorType,VectorType> EigenvalueType; - - /** \brief Type for matrix of eigenvectors as returned by eigenvectors(). - * - * This is a square matrix with entries of type #ComplexScalar. - * The size is the same as the size of #MatrixType. - */ - typedef Matrix EigenvectorsType; - - /** \brief Default constructor. - * - * The default constructor is useful in cases in which the user intends to - * perform decompositions via EigenSolver::compute(const MatrixType&, bool). - * - * \sa compute() for an example. - */ - GeneralizedEigenSolver() : m_eivec(), m_alphas(), m_betas(), m_isInitialized(false), m_realQZ(), m_matS(), m_tmp() {} - - /** \brief Default constructor with memory preallocation - * - * Like the default constructor but with preallocation of the internal data - * according to the specified problem \a size. - * \sa GeneralizedEigenSolver() - */ - GeneralizedEigenSolver(Index size) - : m_eivec(size, size), - m_alphas(size), - m_betas(size), - m_isInitialized(false), - m_eigenvectorsOk(false), - m_realQZ(size), - m_matS(size, size), - m_tmp(size) - {} - - /** \brief Constructor; computes the generalized eigendecomposition of given matrix pair. - * - * \param[in] A Square matrix whose eigendecomposition is to be computed. - * \param[in] B Square matrix whose eigendecomposition is to be computed. - * \param[in] computeEigenvectors If true, both the eigenvectors and the - * eigenvalues are computed; if false, only the eigenvalues are computed. - * - * This constructor calls compute() to compute the generalized eigenvalues - * and eigenvectors. - * - * \sa compute() - */ - GeneralizedEigenSolver(const MatrixType& A, const MatrixType& B, bool computeEigenvectors = true) - : m_eivec(A.rows(), A.cols()), - m_alphas(A.cols()), - m_betas(A.cols()), - m_isInitialized(false), - m_eigenvectorsOk(false), - m_realQZ(A.cols()), - m_matS(A.rows(), A.cols()), - m_tmp(A.cols()) - { - compute(A, B, computeEigenvectors); - } - - /* \brief Returns the computed generalized eigenvectors. - * - * \returns %Matrix whose columns are the (possibly complex) eigenvectors. - * - * \pre Either the constructor - * GeneralizedEigenSolver(const MatrixType&,const MatrixType&, bool) or the member function - * compute(const MatrixType&, const MatrixType& bool) has been called before, and - * \p computeEigenvectors was set to true (the default). - * - * Column \f$ k \f$ of the returned matrix is an eigenvector corresponding - * to eigenvalue number \f$ k \f$ as returned by eigenvalues(). The - * eigenvectors are normalized to have (Euclidean) norm equal to one. The - * matrix returned by this function is the matrix \f$ V \f$ in the - * generalized eigendecomposition \f$ A = B V D V^{-1} \f$, if it exists. - * - * \sa eigenvalues() - */ -// EigenvectorsType eigenvectors() const; - - /** \brief Returns an expression of the computed generalized eigenvalues. - * - * \returns An expression of the column vector containing the eigenvalues. - * - * It is a shortcut for \code this->alphas().cwiseQuotient(this->betas()); \endcode - * Not that betas might contain zeros. It is therefore not recommended to use this function, - * but rather directly deal with the alphas and betas vectors. - * - * \pre Either the constructor - * GeneralizedEigenSolver(const MatrixType&,const MatrixType&,bool) or the member function - * compute(const MatrixType&,const MatrixType&,bool) has been called before. - * - * The eigenvalues are repeated according to their algebraic multiplicity, - * so there are as many eigenvalues as rows in the matrix. The eigenvalues - * are not sorted in any particular order. - * - * \sa alphas(), betas(), eigenvectors() - */ - EigenvalueType eigenvalues() const - { - eigen_assert(m_isInitialized && "GeneralizedEigenSolver is not initialized."); - return EigenvalueType(m_alphas,m_betas); - } - - /** \returns A const reference to the vectors containing the alpha values - * - * This vector permits to reconstruct the j-th eigenvalues as alphas(i)/betas(j). - * - * \sa betas(), eigenvalues() */ - ComplexVectorType alphas() const - { - eigen_assert(m_isInitialized && "GeneralizedEigenSolver is not initialized."); - return m_alphas; - } - - /** \returns A const reference to the vectors containing the beta values - * - * This vector permits to reconstruct the j-th eigenvalues as alphas(i)/betas(j). - * - * \sa alphas(), eigenvalues() */ - VectorType betas() const - { - eigen_assert(m_isInitialized && "GeneralizedEigenSolver is not initialized."); - return m_betas; - } - - /** \brief Computes generalized eigendecomposition of given matrix. - * - * \param[in] A Square matrix whose eigendecomposition is to be computed. - * \param[in] B Square matrix whose eigendecomposition is to be computed. - * \param[in] computeEigenvectors If true, both the eigenvectors and the - * eigenvalues are computed; if false, only the eigenvalues are - * computed. - * \returns Reference to \c *this - * - * This function computes the eigenvalues of the real matrix \p matrix. - * The eigenvalues() function can be used to retrieve them. If - * \p computeEigenvectors is true, then the eigenvectors are also computed - * and can be retrieved by calling eigenvectors(). - * - * The matrix is first reduced to real generalized Schur form using the RealQZ - * class. The generalized Schur decomposition is then used to compute the eigenvalues - * and eigenvectors. - * - * The cost of the computation is dominated by the cost of the - * generalized Schur decomposition. - * - * This method reuses of the allocated data in the GeneralizedEigenSolver object. - */ - GeneralizedEigenSolver& compute(const MatrixType& A, const MatrixType& B, bool computeEigenvectors = true); - - ComputationInfo info() const - { - eigen_assert(m_isInitialized && "EigenSolver is not initialized."); - return m_realQZ.info(); - } - - /** Sets the maximal number of iterations allowed. - */ - GeneralizedEigenSolver& setMaxIterations(Index maxIters) - { - m_realQZ.setMaxIterations(maxIters); - return *this; - } - - protected: - - static void check_template_parameters() - { - EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar); - EIGEN_STATIC_ASSERT(!NumTraits::IsComplex, NUMERIC_TYPE_MUST_BE_REAL); - } - - MatrixType m_eivec; - ComplexVectorType m_alphas; - VectorType m_betas; - bool m_isInitialized; - bool m_eigenvectorsOk; - RealQZ m_realQZ; - MatrixType m_matS; - - typedef Matrix ColumnVectorType; - ColumnVectorType m_tmp; -}; - -//template -//typename GeneralizedEigenSolver::EigenvectorsType GeneralizedEigenSolver::eigenvectors() const -//{ -// eigen_assert(m_isInitialized && "EigenSolver is not initialized."); -// eigen_assert(m_eigenvectorsOk && "The eigenvectors have not been computed together with the eigenvalues."); -// Index n = m_eivec.cols(); -// EigenvectorsType matV(n,n); -// // TODO -// return matV; -//} - -template -GeneralizedEigenSolver& -GeneralizedEigenSolver::compute(const MatrixType& A, const MatrixType& B, bool computeEigenvectors) -{ - check_template_parameters(); - - using std::sqrt; - using std::abs; - eigen_assert(A.cols() == A.rows() && B.cols() == A.rows() && B.cols() == B.rows()); - - // Reduce to generalized real Schur form: - // A = Q S Z and B = Q T Z - m_realQZ.compute(A, B, computeEigenvectors); - - if (m_realQZ.info() == Success) - { - m_matS = m_realQZ.matrixS(); - if (computeEigenvectors) - m_eivec = m_realQZ.matrixZ().transpose(); - - // Compute eigenvalues from matS - m_alphas.resize(A.cols()); - m_betas.resize(A.cols()); - Index i = 0; - while (i < A.cols()) - { - if (i == A.cols() - 1 || m_matS.coeff(i+1, i) == Scalar(0)) - { - m_alphas.coeffRef(i) = m_matS.coeff(i, i); - m_betas.coeffRef(i) = m_realQZ.matrixT().coeff(i,i); - ++i; - } - else - { - Scalar p = Scalar(0.5) * (m_matS.coeff(i, i) - m_matS.coeff(i+1, i+1)); - Scalar z = sqrt(abs(p * p + m_matS.coeff(i+1, i) * m_matS.coeff(i, i+1))); - m_alphas.coeffRef(i) = ComplexScalar(m_matS.coeff(i+1, i+1) + p, z); - m_alphas.coeffRef(i+1) = ComplexScalar(m_matS.coeff(i+1, i+1) + p, -z); - - m_betas.coeffRef(i) = m_realQZ.matrixT().coeff(i,i); - m_betas.coeffRef(i+1) = m_realQZ.matrixT().coeff(i,i); - i += 2; - } - } - } - - m_isInitialized = true; - m_eigenvectorsOk = false;//computeEigenvectors; - - return *this; -} - -} // end namespace Eigen - -#endif // EIGEN_GENERALIZEDEIGENSOLVER_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h b/thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h deleted file mode 100644 index 07bf1ea0..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h +++ /dev/null @@ -1,227 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2010 Gael Guennebaud -// Copyright (C) 2010 Jitse Niesen -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_GENERALIZEDSELFADJOINTEIGENSOLVER_H -#define EIGEN_GENERALIZEDSELFADJOINTEIGENSOLVER_H - -#include "./Tridiagonalization.h" - -namespace Eigen { - -/** \eigenvalues_module \ingroup Eigenvalues_Module - * - * - * \class GeneralizedSelfAdjointEigenSolver - * - * \brief Computes eigenvalues and eigenvectors of the generalized selfadjoint eigen problem - * - * \tparam _MatrixType the type of the matrix of which we are computing the - * eigendecomposition; this is expected to be an instantiation of the Matrix - * class template. - * - * This class solves the generalized eigenvalue problem - * \f$ Av = \lambda Bv \f$. In this case, the matrix \f$ A \f$ should be - * selfadjoint and the matrix \f$ B \f$ should be positive definite. - * - * Only the \b lower \b triangular \b part of the input matrix is referenced. - * - * Call the function compute() to compute the eigenvalues and eigenvectors of - * a given matrix. Alternatively, you can use the - * GeneralizedSelfAdjointEigenSolver(const MatrixType&, const MatrixType&, int) - * constructor which computes the eigenvalues and eigenvectors at construction time. - * Once the eigenvalue and eigenvectors are computed, they can be retrieved with the eigenvalues() - * and eigenvectors() functions. - * - * The documentation for GeneralizedSelfAdjointEigenSolver(const MatrixType&, const MatrixType&, int) - * contains an example of the typical use of this class. - * - * \sa class SelfAdjointEigenSolver, class EigenSolver, class ComplexEigenSolver - */ -template -class GeneralizedSelfAdjointEigenSolver : public SelfAdjointEigenSolver<_MatrixType> -{ - typedef SelfAdjointEigenSolver<_MatrixType> Base; - public: - - typedef typename Base::Index Index; - typedef _MatrixType MatrixType; - - /** \brief Default constructor for fixed-size matrices. - * - * The default constructor is useful in cases in which the user intends to - * perform decompositions via compute(). This constructor - * can only be used if \p _MatrixType is a fixed-size matrix; use - * GeneralizedSelfAdjointEigenSolver(Index) for dynamic-size matrices. - */ - GeneralizedSelfAdjointEigenSolver() : Base() {} - - /** \brief Constructor, pre-allocates memory for dynamic-size matrices. - * - * \param [in] size Positive integer, size of the matrix whose - * eigenvalues and eigenvectors will be computed. - * - * This constructor is useful for dynamic-size matrices, when the user - * intends to perform decompositions via compute(). The \p size - * parameter is only used as a hint. It is not an error to give a wrong - * \p size, but it may impair performance. - * - * \sa compute() for an example - */ - GeneralizedSelfAdjointEigenSolver(Index size) - : Base(size) - {} - - /** \brief Constructor; computes generalized eigendecomposition of given matrix pencil. - * - * \param[in] matA Selfadjoint matrix in matrix pencil. - * Only the lower triangular part of the matrix is referenced. - * \param[in] matB Positive-definite matrix in matrix pencil. - * Only the lower triangular part of the matrix is referenced. - * \param[in] options A or-ed set of flags {#ComputeEigenvectors,#EigenvaluesOnly} | {#Ax_lBx,#ABx_lx,#BAx_lx}. - * Default is #ComputeEigenvectors|#Ax_lBx. - * - * This constructor calls compute(const MatrixType&, const MatrixType&, int) - * to compute the eigenvalues and (if requested) the eigenvectors of the - * generalized eigenproblem \f$ Ax = \lambda B x \f$ with \a matA the - * selfadjoint matrix \f$ A \f$ and \a matB the positive definite matrix - * \f$ B \f$. Each eigenvector \f$ x \f$ satisfies the property - * \f$ x^* B x = 1 \f$. The eigenvectors are computed if - * \a options contains ComputeEigenvectors. - * - * In addition, the two following variants can be solved via \p options: - * - \c ABx_lx: \f$ ABx = \lambda x \f$ - * - \c BAx_lx: \f$ BAx = \lambda x \f$ - * - * Example: \include SelfAdjointEigenSolver_SelfAdjointEigenSolver_MatrixType2.cpp - * Output: \verbinclude SelfAdjointEigenSolver_SelfAdjointEigenSolver_MatrixType2.out - * - * \sa compute(const MatrixType&, const MatrixType&, int) - */ - GeneralizedSelfAdjointEigenSolver(const MatrixType& matA, const MatrixType& matB, - int options = ComputeEigenvectors|Ax_lBx) - : Base(matA.cols()) - { - compute(matA, matB, options); - } - - /** \brief Computes generalized eigendecomposition of given matrix pencil. - * - * \param[in] matA Selfadjoint matrix in matrix pencil. - * Only the lower triangular part of the matrix is referenced. - * \param[in] matB Positive-definite matrix in matrix pencil. - * Only the lower triangular part of the matrix is referenced. - * \param[in] options A or-ed set of flags {#ComputeEigenvectors,#EigenvaluesOnly} | {#Ax_lBx,#ABx_lx,#BAx_lx}. - * Default is #ComputeEigenvectors|#Ax_lBx. - * - * \returns Reference to \c *this - * - * Accoring to \p options, this function computes eigenvalues and (if requested) - * the eigenvectors of one of the following three generalized eigenproblems: - * - \c Ax_lBx: \f$ Ax = \lambda B x \f$ - * - \c ABx_lx: \f$ ABx = \lambda x \f$ - * - \c BAx_lx: \f$ BAx = \lambda x \f$ - * with \a matA the selfadjoint matrix \f$ A \f$ and \a matB the positive definite - * matrix \f$ B \f$. - * In addition, each eigenvector \f$ x \f$ satisfies the property \f$ x^* B x = 1 \f$. - * - * The eigenvalues() function can be used to retrieve - * the eigenvalues. If \p options contains ComputeEigenvectors, then the - * eigenvectors are also computed and can be retrieved by calling - * eigenvectors(). - * - * The implementation uses LLT to compute the Cholesky decomposition - * \f$ B = LL^* \f$ and computes the classical eigendecomposition - * of the selfadjoint matrix \f$ L^{-1} A (L^*)^{-1} \f$ if \p options contains Ax_lBx - * and of \f$ L^{*} A L \f$ otherwise. This solves the - * generalized eigenproblem, because any solution of the generalized - * eigenproblem \f$ Ax = \lambda B x \f$ corresponds to a solution - * \f$ L^{-1} A (L^*)^{-1} (L^* x) = \lambda (L^* x) \f$ of the - * eigenproblem for \f$ L^{-1} A (L^*)^{-1} \f$. Similar statements - * can be made for the two other variants. - * - * Example: \include SelfAdjointEigenSolver_compute_MatrixType2.cpp - * Output: \verbinclude SelfAdjointEigenSolver_compute_MatrixType2.out - * - * \sa GeneralizedSelfAdjointEigenSolver(const MatrixType&, const MatrixType&, int) - */ - GeneralizedSelfAdjointEigenSolver& compute(const MatrixType& matA, const MatrixType& matB, - int options = ComputeEigenvectors|Ax_lBx); - - protected: - -}; - - -template -GeneralizedSelfAdjointEigenSolver& GeneralizedSelfAdjointEigenSolver:: -compute(const MatrixType& matA, const MatrixType& matB, int options) -{ - eigen_assert(matA.cols()==matA.rows() && matB.rows()==matA.rows() && matB.cols()==matB.rows()); - eigen_assert((options&~(EigVecMask|GenEigMask))==0 - && (options&EigVecMask)!=EigVecMask - && ((options&GenEigMask)==0 || (options&GenEigMask)==Ax_lBx - || (options&GenEigMask)==ABx_lx || (options&GenEigMask)==BAx_lx) - && "invalid option parameter"); - - bool computeEigVecs = ((options&EigVecMask)==0) || ((options&EigVecMask)==ComputeEigenvectors); - - // Compute the cholesky decomposition of matB = L L' = U'U - LLT cholB(matB); - - int type = (options&GenEigMask); - if(type==0) - type = Ax_lBx; - - if(type==Ax_lBx) - { - // compute C = inv(L) A inv(L') - MatrixType matC = matA.template selfadjointView(); - cholB.matrixL().template solveInPlace(matC); - cholB.matrixU().template solveInPlace(matC); - - Base::compute(matC, computeEigVecs ? ComputeEigenvectors : EigenvaluesOnly ); - - // transform back the eigen vectors: evecs = inv(U) * evecs - if(computeEigVecs) - cholB.matrixU().solveInPlace(Base::m_eivec); - } - else if(type==ABx_lx) - { - // compute C = L' A L - MatrixType matC = matA.template selfadjointView(); - matC = matC * cholB.matrixL(); - matC = cholB.matrixU() * matC; - - Base::compute(matC, computeEigVecs ? ComputeEigenvectors : EigenvaluesOnly); - - // transform back the eigen vectors: evecs = inv(U) * evecs - if(computeEigVecs) - cholB.matrixU().solveInPlace(Base::m_eivec); - } - else if(type==BAx_lx) - { - // compute C = L' A L - MatrixType matC = matA.template selfadjointView(); - matC = matC * cholB.matrixL(); - matC = cholB.matrixU() * matC; - - Base::compute(matC, computeEigVecs ? ComputeEigenvectors : EigenvaluesOnly); - - // transform back the eigen vectors: evecs = L * evecs - if(computeEigVecs) - Base::m_eivec = cholB.matrixL() * Base::m_eivec; - } - - return *this; -} - -} // end namespace Eigen - -#endif // EIGEN_GENERALIZEDSELFADJOINTEIGENSOLVER_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/HessenbergDecomposition.h b/thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/HessenbergDecomposition.h deleted file mode 100644 index 3db0c010..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/HessenbergDecomposition.h +++ /dev/null @@ -1,373 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2009 Gael Guennebaud -// Copyright (C) 2010 Jitse Niesen -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_HESSENBERGDECOMPOSITION_H -#define EIGEN_HESSENBERGDECOMPOSITION_H - -namespace Eigen { - -namespace internal { - -template struct HessenbergDecompositionMatrixHReturnType; -template -struct traits > -{ - typedef MatrixType ReturnType; -}; - -} - -/** \eigenvalues_module \ingroup Eigenvalues_Module - * - * - * \class HessenbergDecomposition - * - * \brief Reduces a square matrix to Hessenberg form by an orthogonal similarity transformation - * - * \tparam _MatrixType the type of the matrix of which we are computing the Hessenberg decomposition - * - * This class performs an Hessenberg decomposition of a matrix \f$ A \f$. In - * the real case, the Hessenberg decomposition consists of an orthogonal - * matrix \f$ Q \f$ and a Hessenberg matrix \f$ H \f$ such that \f$ A = Q H - * Q^T \f$. An orthogonal matrix is a matrix whose inverse equals its - * transpose (\f$ Q^{-1} = Q^T \f$). A Hessenberg matrix has zeros below the - * subdiagonal, so it is almost upper triangular. The Hessenberg decomposition - * of a complex matrix is \f$ A = Q H Q^* \f$ with \f$ Q \f$ unitary (that is, - * \f$ Q^{-1} = Q^* \f$). - * - * Call the function compute() to compute the Hessenberg decomposition of a - * given matrix. Alternatively, you can use the - * HessenbergDecomposition(const MatrixType&) constructor which computes the - * Hessenberg decomposition at construction time. Once the decomposition is - * computed, you can use the matrixH() and matrixQ() functions to construct - * the matrices H and Q in the decomposition. - * - * The documentation for matrixH() contains an example of the typical use of - * this class. - * - * \sa class ComplexSchur, class Tridiagonalization, \ref QR_Module "QR Module" - */ -template class HessenbergDecomposition -{ - public: - - /** \brief Synonym for the template parameter \p _MatrixType. */ - typedef _MatrixType MatrixType; - - enum { - Size = MatrixType::RowsAtCompileTime, - SizeMinusOne = Size == Dynamic ? Dynamic : Size - 1, - Options = MatrixType::Options, - MaxSize = MatrixType::MaxRowsAtCompileTime, - MaxSizeMinusOne = MaxSize == Dynamic ? Dynamic : MaxSize - 1 - }; - - /** \brief Scalar type for matrices of type #MatrixType. */ - typedef typename MatrixType::Scalar Scalar; - typedef typename MatrixType::Index Index; - - /** \brief Type for vector of Householder coefficients. - * - * This is column vector with entries of type #Scalar. The length of the - * vector is one less than the size of #MatrixType, if it is a fixed-side - * type. - */ - typedef Matrix CoeffVectorType; - - /** \brief Return type of matrixQ() */ - typedef HouseholderSequence::type> HouseholderSequenceType; - - typedef internal::HessenbergDecompositionMatrixHReturnType MatrixHReturnType; - - /** \brief Default constructor; the decomposition will be computed later. - * - * \param [in] size The size of the matrix whose Hessenberg decomposition will be computed. - * - * The default constructor is useful in cases in which the user intends to - * perform decompositions via compute(). The \p size parameter is only - * used as a hint. It is not an error to give a wrong \p size, but it may - * impair performance. - * - * \sa compute() for an example. - */ - HessenbergDecomposition(Index size = Size==Dynamic ? 2 : Size) - : m_matrix(size,size), - m_temp(size), - m_isInitialized(false) - { - if(size>1) - m_hCoeffs.resize(size-1); - } - - /** \brief Constructor; computes Hessenberg decomposition of given matrix. - * - * \param[in] matrix Square matrix whose Hessenberg decomposition is to be computed. - * - * This constructor calls compute() to compute the Hessenberg - * decomposition. - * - * \sa matrixH() for an example. - */ - HessenbergDecomposition(const MatrixType& matrix) - : m_matrix(matrix), - m_temp(matrix.rows()), - m_isInitialized(false) - { - if(matrix.rows()<2) - { - m_isInitialized = true; - return; - } - m_hCoeffs.resize(matrix.rows()-1,1); - _compute(m_matrix, m_hCoeffs, m_temp); - m_isInitialized = true; - } - - /** \brief Computes Hessenberg decomposition of given matrix. - * - * \param[in] matrix Square matrix whose Hessenberg decomposition is to be computed. - * \returns Reference to \c *this - * - * The Hessenberg decomposition is computed by bringing the columns of the - * matrix successively in the required form using Householder reflections - * (see, e.g., Algorithm 7.4.2 in Golub \& Van Loan, %Matrix - * Computations). The cost is \f$ 10n^3/3 \f$ flops, where \f$ n \f$ - * denotes the size of the given matrix. - * - * This method reuses of the allocated data in the HessenbergDecomposition - * object. - * - * Example: \include HessenbergDecomposition_compute.cpp - * Output: \verbinclude HessenbergDecomposition_compute.out - */ - HessenbergDecomposition& compute(const MatrixType& matrix) - { - m_matrix = matrix; - if(matrix.rows()<2) - { - m_isInitialized = true; - return *this; - } - m_hCoeffs.resize(matrix.rows()-1,1); - _compute(m_matrix, m_hCoeffs, m_temp); - m_isInitialized = true; - return *this; - } - - /** \brief Returns the Householder coefficients. - * - * \returns a const reference to the vector of Householder coefficients - * - * \pre Either the constructor HessenbergDecomposition(const MatrixType&) - * or the member function compute(const MatrixType&) has been called - * before to compute the Hessenberg decomposition of a matrix. - * - * The Householder coefficients allow the reconstruction of the matrix - * \f$ Q \f$ in the Hessenberg decomposition from the packed data. - * - * \sa packedMatrix(), \ref Householder_Module "Householder module" - */ - const CoeffVectorType& householderCoefficients() const - { - eigen_assert(m_isInitialized && "HessenbergDecomposition is not initialized."); - return m_hCoeffs; - } - - /** \brief Returns the internal representation of the decomposition - * - * \returns a const reference to a matrix with the internal representation - * of the decomposition. - * - * \pre Either the constructor HessenbergDecomposition(const MatrixType&) - * or the member function compute(const MatrixType&) has been called - * before to compute the Hessenberg decomposition of a matrix. - * - * The returned matrix contains the following information: - * - the upper part and lower sub-diagonal represent the Hessenberg matrix H - * - the rest of the lower part contains the Householder vectors that, combined with - * Householder coefficients returned by householderCoefficients(), - * allows to reconstruct the matrix Q as - * \f$ Q = H_{N-1} \ldots H_1 H_0 \f$. - * Here, the matrices \f$ H_i \f$ are the Householder transformations - * \f$ H_i = (I - h_i v_i v_i^T) \f$ - * where \f$ h_i \f$ is the \f$ i \f$th Householder coefficient and - * \f$ v_i \f$ is the Householder vector defined by - * \f$ v_i = [ 0, \ldots, 0, 1, M(i+2,i), \ldots, M(N-1,i) ]^T \f$ - * with M the matrix returned by this function. - * - * See LAPACK for further details on this packed storage. - * - * Example: \include HessenbergDecomposition_packedMatrix.cpp - * Output: \verbinclude HessenbergDecomposition_packedMatrix.out - * - * \sa householderCoefficients() - */ - const MatrixType& packedMatrix() const - { - eigen_assert(m_isInitialized && "HessenbergDecomposition is not initialized."); - return m_matrix; - } - - /** \brief Reconstructs the orthogonal matrix Q in the decomposition - * - * \returns object representing the matrix Q - * - * \pre Either the constructor HessenbergDecomposition(const MatrixType&) - * or the member function compute(const MatrixType&) has been called - * before to compute the Hessenberg decomposition of a matrix. - * - * This function returns a light-weight object of template class - * HouseholderSequence. You can either apply it directly to a matrix or - * you can convert it to a matrix of type #MatrixType. - * - * \sa matrixH() for an example, class HouseholderSequence - */ - HouseholderSequenceType matrixQ() const - { - eigen_assert(m_isInitialized && "HessenbergDecomposition is not initialized."); - return HouseholderSequenceType(m_matrix, m_hCoeffs.conjugate()) - .setLength(m_matrix.rows() - 1) - .setShift(1); - } - - /** \brief Constructs the Hessenberg matrix H in the decomposition - * - * \returns expression object representing the matrix H - * - * \pre Either the constructor HessenbergDecomposition(const MatrixType&) - * or the member function compute(const MatrixType&) has been called - * before to compute the Hessenberg decomposition of a matrix. - * - * The object returned by this function constructs the Hessenberg matrix H - * when it is assigned to a matrix or otherwise evaluated. The matrix H is - * constructed from the packed matrix as returned by packedMatrix(): The - * upper part (including the subdiagonal) of the packed matrix contains - * the matrix H. It may sometimes be better to directly use the packed - * matrix instead of constructing the matrix H. - * - * Example: \include HessenbergDecomposition_matrixH.cpp - * Output: \verbinclude HessenbergDecomposition_matrixH.out - * - * \sa matrixQ(), packedMatrix() - */ - MatrixHReturnType matrixH() const - { - eigen_assert(m_isInitialized && "HessenbergDecomposition is not initialized."); - return MatrixHReturnType(*this); - } - - private: - - typedef Matrix VectorType; - typedef typename NumTraits::Real RealScalar; - static void _compute(MatrixType& matA, CoeffVectorType& hCoeffs, VectorType& temp); - - protected: - MatrixType m_matrix; - CoeffVectorType m_hCoeffs; - VectorType m_temp; - bool m_isInitialized; -}; - -/** \internal - * Performs a tridiagonal decomposition of \a matA in place. - * - * \param matA the input selfadjoint matrix - * \param hCoeffs returned Householder coefficients - * - * The result is written in the lower triangular part of \a matA. - * - * Implemented from Golub's "%Matrix Computations", algorithm 8.3.1. - * - * \sa packedMatrix() - */ -template -void HessenbergDecomposition::_compute(MatrixType& matA, CoeffVectorType& hCoeffs, VectorType& temp) -{ - eigen_assert(matA.rows()==matA.cols()); - Index n = matA.rows(); - temp.resize(n); - for (Index i = 0; i struct HessenbergDecompositionMatrixHReturnType -: public ReturnByValue > -{ - typedef typename MatrixType::Index Index; - public: - /** \brief Constructor. - * - * \param[in] hess Hessenberg decomposition - */ - HessenbergDecompositionMatrixHReturnType(const HessenbergDecomposition& hess) : m_hess(hess) { } - - /** \brief Hessenberg matrix in decomposition. - * - * \param[out] result Hessenberg matrix in decomposition \p hess which - * was passed to the constructor - */ - template - inline void evalTo(ResultType& result) const - { - result = m_hess.packedMatrix(); - Index n = result.rows(); - if (n>2) - result.bottomLeftCorner(n-2, n-2).template triangularView().setZero(); - } - - Index rows() const { return m_hess.packedMatrix().rows(); } - Index cols() const { return m_hess.packedMatrix().cols(); } - - protected: - const HessenbergDecomposition& m_hess; -}; - -} // end namespace internal - -} // end namespace Eigen - -#endif // EIGEN_HESSENBERGDECOMPOSITION_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h b/thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h deleted file mode 100644 index 4fec8af0..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h +++ /dev/null @@ -1,160 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud -// Copyright (C) 2010 Jitse Niesen -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_MATRIXBASEEIGENVALUES_H -#define EIGEN_MATRIXBASEEIGENVALUES_H - -namespace Eigen { - -namespace internal { - -template -struct eigenvalues_selector -{ - // this is the implementation for the case IsComplex = true - static inline typename MatrixBase::EigenvaluesReturnType const - run(const MatrixBase& m) - { - typedef typename Derived::PlainObject PlainObject; - PlainObject m_eval(m); - return ComplexEigenSolver(m_eval, false).eigenvalues(); - } -}; - -template -struct eigenvalues_selector -{ - static inline typename MatrixBase::EigenvaluesReturnType const - run(const MatrixBase& m) - { - typedef typename Derived::PlainObject PlainObject; - PlainObject m_eval(m); - return EigenSolver(m_eval, false).eigenvalues(); - } -}; - -} // end namespace internal - -/** \brief Computes the eigenvalues of a matrix - * \returns Column vector containing the eigenvalues. - * - * \eigenvalues_module - * This function computes the eigenvalues with the help of the EigenSolver - * class (for real matrices) or the ComplexEigenSolver class (for complex - * matrices). - * - * The eigenvalues are repeated according to their algebraic multiplicity, - * so there are as many eigenvalues as rows in the matrix. - * - * The SelfAdjointView class provides a better algorithm for selfadjoint - * matrices. - * - * Example: \include MatrixBase_eigenvalues.cpp - * Output: \verbinclude MatrixBase_eigenvalues.out - * - * \sa EigenSolver::eigenvalues(), ComplexEigenSolver::eigenvalues(), - * SelfAdjointView::eigenvalues() - */ -template -inline typename MatrixBase::EigenvaluesReturnType -MatrixBase::eigenvalues() const -{ - typedef typename internal::traits::Scalar Scalar; - return internal::eigenvalues_selector::IsComplex>::run(derived()); -} - -/** \brief Computes the eigenvalues of a matrix - * \returns Column vector containing the eigenvalues. - * - * \eigenvalues_module - * This function computes the eigenvalues with the help of the - * SelfAdjointEigenSolver class. The eigenvalues are repeated according to - * their algebraic multiplicity, so there are as many eigenvalues as rows in - * the matrix. - * - * Example: \include SelfAdjointView_eigenvalues.cpp - * Output: \verbinclude SelfAdjointView_eigenvalues.out - * - * \sa SelfAdjointEigenSolver::eigenvalues(), MatrixBase::eigenvalues() - */ -template -inline typename SelfAdjointView::EigenvaluesReturnType -SelfAdjointView::eigenvalues() const -{ - typedef typename SelfAdjointView::PlainObject PlainObject; - PlainObject thisAsMatrix(*this); - return SelfAdjointEigenSolver(thisAsMatrix, false).eigenvalues(); -} - - - -/** \brief Computes the L2 operator norm - * \returns Operator norm of the matrix. - * - * \eigenvalues_module - * This function computes the L2 operator norm of a matrix, which is also - * known as the spectral norm. The norm of a matrix \f$ A \f$ is defined to be - * \f[ \|A\|_2 = \max_x \frac{\|Ax\|_2}{\|x\|_2} \f] - * where the maximum is over all vectors and the norm on the right is the - * Euclidean vector norm. The norm equals the largest singular value, which is - * the square root of the largest eigenvalue of the positive semi-definite - * matrix \f$ A^*A \f$. - * - * The current implementation uses the eigenvalues of \f$ A^*A \f$, as computed - * by SelfAdjointView::eigenvalues(), to compute the operator norm of a - * matrix. The SelfAdjointView class provides a better algorithm for - * selfadjoint matrices. - * - * Example: \include MatrixBase_operatorNorm.cpp - * Output: \verbinclude MatrixBase_operatorNorm.out - * - * \sa SelfAdjointView::eigenvalues(), SelfAdjointView::operatorNorm() - */ -template -inline typename MatrixBase::RealScalar -MatrixBase::operatorNorm() const -{ - using std::sqrt; - typename Derived::PlainObject m_eval(derived()); - // FIXME if it is really guaranteed that the eigenvalues are already sorted, - // then we don't need to compute a maxCoeff() here, comparing the 1st and last ones is enough. - return sqrt((m_eval*m_eval.adjoint()) - .eval() - .template selfadjointView() - .eigenvalues() - .maxCoeff() - ); -} - -/** \brief Computes the L2 operator norm - * \returns Operator norm of the matrix. - * - * \eigenvalues_module - * This function computes the L2 operator norm of a self-adjoint matrix. For a - * self-adjoint matrix, the operator norm is the largest eigenvalue. - * - * The current implementation uses the eigenvalues of the matrix, as computed - * by eigenvalues(), to compute the operator norm of the matrix. - * - * Example: \include SelfAdjointView_operatorNorm.cpp - * Output: \verbinclude SelfAdjointView_operatorNorm.out - * - * \sa eigenvalues(), MatrixBase::operatorNorm() - */ -template -inline typename SelfAdjointView::RealScalar -SelfAdjointView::operatorNorm() const -{ - return eigenvalues().cwiseAbs().maxCoeff(); -} - -} // end namespace Eigen - -#endif diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/RealQZ.h b/thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/RealQZ.h deleted file mode 100644 index aa3833eb..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/RealQZ.h +++ /dev/null @@ -1,624 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2012 Alexey Korepanov -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_REAL_QZ_H -#define EIGEN_REAL_QZ_H - -namespace Eigen { - - /** \eigenvalues_module \ingroup Eigenvalues_Module - * - * - * \class RealQZ - * - * \brief Performs a real QZ decomposition of a pair of square matrices - * - * \tparam _MatrixType the type of the matrix of which we are computing the - * real QZ decomposition; this is expected to be an instantiation of the - * Matrix class template. - * - * Given a real square matrices A and B, this class computes the real QZ - * decomposition: \f$ A = Q S Z \f$, \f$ B = Q T Z \f$ where Q and Z are - * real orthogonal matrixes, T is upper-triangular matrix, and S is upper - * quasi-triangular matrix. An orthogonal matrix is a matrix whose - * inverse is equal to its transpose, \f$ U^{-1} = U^T \f$. A quasi-triangular - * matrix is a block-triangular matrix whose diagonal consists of 1-by-1 - * blocks and 2-by-2 blocks where further reduction is impossible due to - * complex eigenvalues. - * - * The eigenvalues of the pencil \f$ A - z B \f$ can be obtained from - * 1x1 and 2x2 blocks on the diagonals of S and T. - * - * Call the function compute() to compute the real QZ decomposition of a - * given pair of matrices. Alternatively, you can use the - * RealQZ(const MatrixType& B, const MatrixType& B, bool computeQZ) - * constructor which computes the real QZ decomposition at construction - * time. Once the decomposition is computed, you can use the matrixS(), - * matrixT(), matrixQ() and matrixZ() functions to retrieve the matrices - * S, T, Q and Z in the decomposition. If computeQZ==false, some time - * is saved by not computing matrices Q and Z. - * - * Example: \include RealQZ_compute.cpp - * Output: \include RealQZ_compute.out - * - * \note The implementation is based on the algorithm in "Matrix Computations" - * by Gene H. Golub and Charles F. Van Loan, and a paper "An algorithm for - * generalized eigenvalue problems" by C.B.Moler and G.W.Stewart. - * - * \sa class RealSchur, class ComplexSchur, class EigenSolver, class ComplexEigenSolver - */ - - template class RealQZ - { - public: - typedef _MatrixType MatrixType; - enum { - RowsAtCompileTime = MatrixType::RowsAtCompileTime, - ColsAtCompileTime = MatrixType::ColsAtCompileTime, - Options = MatrixType::Options, - MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime, - MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime - }; - typedef typename MatrixType::Scalar Scalar; - typedef std::complex::Real> ComplexScalar; - typedef typename MatrixType::Index Index; - - typedef Matrix EigenvalueType; - typedef Matrix ColumnVectorType; - - /** \brief Default constructor. - * - * \param [in] size Positive integer, size of the matrix whose QZ decomposition will be computed. - * - * The default constructor is useful in cases in which the user intends to - * perform decompositions via compute(). The \p size parameter is only - * used as a hint. It is not an error to give a wrong \p size, but it may - * impair performance. - * - * \sa compute() for an example. - */ - RealQZ(Index size = RowsAtCompileTime==Dynamic ? 1 : RowsAtCompileTime) : - m_S(size, size), - m_T(size, size), - m_Q(size, size), - m_Z(size, size), - m_workspace(size*2), - m_maxIters(400), - m_isInitialized(false) - { } - - /** \brief Constructor; computes real QZ decomposition of given matrices - * - * \param[in] A Matrix A. - * \param[in] B Matrix B. - * \param[in] computeQZ If false, A and Z are not computed. - * - * This constructor calls compute() to compute the QZ decomposition. - */ - RealQZ(const MatrixType& A, const MatrixType& B, bool computeQZ = true) : - m_S(A.rows(),A.cols()), - m_T(A.rows(),A.cols()), - m_Q(A.rows(),A.cols()), - m_Z(A.rows(),A.cols()), - m_workspace(A.rows()*2), - m_maxIters(400), - m_isInitialized(false) { - compute(A, B, computeQZ); - } - - /** \brief Returns matrix Q in the QZ decomposition. - * - * \returns A const reference to the matrix Q. - */ - const MatrixType& matrixQ() const { - eigen_assert(m_isInitialized && "RealQZ is not initialized."); - eigen_assert(m_computeQZ && "The matrices Q and Z have not been computed during the QZ decomposition."); - return m_Q; - } - - /** \brief Returns matrix Z in the QZ decomposition. - * - * \returns A const reference to the matrix Z. - */ - const MatrixType& matrixZ() const { - eigen_assert(m_isInitialized && "RealQZ is not initialized."); - eigen_assert(m_computeQZ && "The matrices Q and Z have not been computed during the QZ decomposition."); - return m_Z; - } - - /** \brief Returns matrix S in the QZ decomposition. - * - * \returns A const reference to the matrix S. - */ - const MatrixType& matrixS() const { - eigen_assert(m_isInitialized && "RealQZ is not initialized."); - return m_S; - } - - /** \brief Returns matrix S in the QZ decomposition. - * - * \returns A const reference to the matrix S. - */ - const MatrixType& matrixT() const { - eigen_assert(m_isInitialized && "RealQZ is not initialized."); - return m_T; - } - - /** \brief Computes QZ decomposition of given matrix. - * - * \param[in] A Matrix A. - * \param[in] B Matrix B. - * \param[in] computeQZ If false, A and Z are not computed. - * \returns Reference to \c *this - */ - RealQZ& compute(const MatrixType& A, const MatrixType& B, bool computeQZ = true); - - /** \brief Reports whether previous computation was successful. - * - * \returns \c Success if computation was succesful, \c NoConvergence otherwise. - */ - ComputationInfo info() const - { - eigen_assert(m_isInitialized && "RealQZ is not initialized."); - return m_info; - } - - /** \brief Returns number of performed QR-like iterations. - */ - Index iterations() const - { - eigen_assert(m_isInitialized && "RealQZ is not initialized."); - return m_global_iter; - } - - /** Sets the maximal number of iterations allowed to converge to one eigenvalue - * or decouple the problem. - */ - RealQZ& setMaxIterations(Index maxIters) - { - m_maxIters = maxIters; - return *this; - } - - private: - - MatrixType m_S, m_T, m_Q, m_Z; - Matrix m_workspace; - ComputationInfo m_info; - Index m_maxIters; - bool m_isInitialized; - bool m_computeQZ; - Scalar m_normOfT, m_normOfS; - Index m_global_iter; - - typedef Matrix Vector3s; - typedef Matrix Vector2s; - typedef Matrix Matrix2s; - typedef JacobiRotation JRs; - - void hessenbergTriangular(); - void computeNorms(); - Index findSmallSubdiagEntry(Index iu); - Index findSmallDiagEntry(Index f, Index l); - void splitOffTwoRows(Index i); - void pushDownZero(Index z, Index f, Index l); - void step(Index f, Index l, Index iter); - - }; // RealQZ - - /** \internal Reduces S and T to upper Hessenberg - triangular form */ - template - void RealQZ::hessenbergTriangular() - { - - const Index dim = m_S.cols(); - - // perform QR decomposition of T, overwrite T with R, save Q - HouseholderQR qrT(m_T); - m_T = qrT.matrixQR(); - m_T.template triangularView().setZero(); - m_Q = qrT.householderQ(); - // overwrite S with Q* S - m_S.applyOnTheLeft(m_Q.adjoint()); - // init Z as Identity - if (m_computeQZ) - m_Z = MatrixType::Identity(dim,dim); - // reduce S to upper Hessenberg with Givens rotations - for (Index j=0; j<=dim-3; j++) { - for (Index i=dim-1; i>=j+2; i--) { - JRs G; - // kill S(i,j) - if(m_S.coeff(i,j) != 0) - { - G.makeGivens(m_S.coeff(i-1,j), m_S.coeff(i,j), &m_S.coeffRef(i-1, j)); - m_S.coeffRef(i,j) = Scalar(0.0); - m_S.rightCols(dim-j-1).applyOnTheLeft(i-1,i,G.adjoint()); - m_T.rightCols(dim-i+1).applyOnTheLeft(i-1,i,G.adjoint()); - // update Q - if (m_computeQZ) - m_Q.applyOnTheRight(i-1,i,G); - } - // kill T(i,i-1) - if(m_T.coeff(i,i-1)!=Scalar(0)) - { - G.makeGivens(m_T.coeff(i,i), m_T.coeff(i,i-1), &m_T.coeffRef(i,i)); - m_T.coeffRef(i,i-1) = Scalar(0.0); - m_S.applyOnTheRight(i,i-1,G); - m_T.topRows(i).applyOnTheRight(i,i-1,G); - // update Z - if (m_computeQZ) - m_Z.applyOnTheLeft(i,i-1,G.adjoint()); - } - } - } - } - - /** \internal Computes vector L1 norms of S and T when in Hessenberg-Triangular form already */ - template - inline void RealQZ::computeNorms() - { - const Index size = m_S.cols(); - m_normOfS = Scalar(0.0); - m_normOfT = Scalar(0.0); - for (Index j = 0; j < size; ++j) - { - m_normOfS += m_S.col(j).segment(0, (std::min)(size,j+2)).cwiseAbs().sum(); - m_normOfT += m_T.row(j).segment(j, size - j).cwiseAbs().sum(); - } - } - - - /** \internal Look for single small sub-diagonal element S(res, res-1) and return res (or 0) */ - template - inline typename MatrixType::Index RealQZ::findSmallSubdiagEntry(Index iu) - { - using std::abs; - Index res = iu; - while (res > 0) - { - Scalar s = abs(m_S.coeff(res-1,res-1)) + abs(m_S.coeff(res,res)); - if (s == Scalar(0.0)) - s = m_normOfS; - if (abs(m_S.coeff(res,res-1)) < NumTraits::epsilon() * s) - break; - res--; - } - return res; - } - - /** \internal Look for single small diagonal element T(res, res) for res between f and l, and return res (or f-1) */ - template - inline typename MatrixType::Index RealQZ::findSmallDiagEntry(Index f, Index l) - { - using std::abs; - Index res = l; - while (res >= f) { - if (abs(m_T.coeff(res,res)) <= NumTraits::epsilon() * m_normOfT) - break; - res--; - } - return res; - } - - /** \internal decouple 2x2 diagonal block in rows i, i+1 if eigenvalues are real */ - template - inline void RealQZ::splitOffTwoRows(Index i) - { - using std::abs; - using std::sqrt; - const Index dim=m_S.cols(); - if (abs(m_S.coeff(i+1,i))==Scalar(0)) - return; - Index z = findSmallDiagEntry(i,i+1); - if (z==i-1) - { - // block of (S T^{-1}) - Matrix2s STi = m_T.template block<2,2>(i,i).template triangularView(). - template solve(m_S.template block<2,2>(i,i)); - Scalar p = Scalar(0.5)*(STi(0,0)-STi(1,1)); - Scalar q = p*p + STi(1,0)*STi(0,1); - if (q>=0) { - Scalar z = sqrt(q); - // one QR-like iteration for ABi - lambda I - // is enough - when we know exact eigenvalue in advance, - // convergence is immediate - JRs G; - if (p>=0) - G.makeGivens(p + z, STi(1,0)); - else - G.makeGivens(p - z, STi(1,0)); - m_S.rightCols(dim-i).applyOnTheLeft(i,i+1,G.adjoint()); - m_T.rightCols(dim-i).applyOnTheLeft(i,i+1,G.adjoint()); - // update Q - if (m_computeQZ) - m_Q.applyOnTheRight(i,i+1,G); - - G.makeGivens(m_T.coeff(i+1,i+1), m_T.coeff(i+1,i)); - m_S.topRows(i+2).applyOnTheRight(i+1,i,G); - m_T.topRows(i+2).applyOnTheRight(i+1,i,G); - // update Z - if (m_computeQZ) - m_Z.applyOnTheLeft(i+1,i,G.adjoint()); - - m_S.coeffRef(i+1,i) = Scalar(0.0); - m_T.coeffRef(i+1,i) = Scalar(0.0); - } - } - else - { - pushDownZero(z,i,i+1); - } - } - - /** \internal use zero in T(z,z) to zero S(l,l-1), working in block f..l */ - template - inline void RealQZ::pushDownZero(Index z, Index f, Index l) - { - JRs G; - const Index dim = m_S.cols(); - for (Index zz=z; zzf ? (zz-1) : zz; - G.makeGivens(m_T.coeff(zz, zz+1), m_T.coeff(zz+1, zz+1)); - m_S.rightCols(dim-firstColS).applyOnTheLeft(zz,zz+1,G.adjoint()); - m_T.rightCols(dim-zz).applyOnTheLeft(zz,zz+1,G.adjoint()); - m_T.coeffRef(zz+1,zz+1) = Scalar(0.0); - // update Q - if (m_computeQZ) - m_Q.applyOnTheRight(zz,zz+1,G); - // kill S(zz+1, zz-1) - if (zz>f) - { - G.makeGivens(m_S.coeff(zz+1, zz), m_S.coeff(zz+1,zz-1)); - m_S.topRows(zz+2).applyOnTheRight(zz, zz-1,G); - m_T.topRows(zz+1).applyOnTheRight(zz, zz-1,G); - m_S.coeffRef(zz+1,zz-1) = Scalar(0.0); - // update Z - if (m_computeQZ) - m_Z.applyOnTheLeft(zz,zz-1,G.adjoint()); - } - } - // finally kill S(l,l-1) - G.makeGivens(m_S.coeff(l,l), m_S.coeff(l,l-1)); - m_S.applyOnTheRight(l,l-1,G); - m_T.applyOnTheRight(l,l-1,G); - m_S.coeffRef(l,l-1)=Scalar(0.0); - // update Z - if (m_computeQZ) - m_Z.applyOnTheLeft(l,l-1,G.adjoint()); - } - - /** \internal QR-like iterative step for block f..l */ - template - inline void RealQZ::step(Index f, Index l, Index iter) - { - using std::abs; - const Index dim = m_S.cols(); - - // x, y, z - Scalar x, y, z; - if (iter==10) - { - // Wilkinson ad hoc shift - const Scalar - a11=m_S.coeff(f+0,f+0), a12=m_S.coeff(f+0,f+1), - a21=m_S.coeff(f+1,f+0), a22=m_S.coeff(f+1,f+1), a32=m_S.coeff(f+2,f+1), - b12=m_T.coeff(f+0,f+1), - b11i=Scalar(1.0)/m_T.coeff(f+0,f+0), - b22i=Scalar(1.0)/m_T.coeff(f+1,f+1), - a87=m_S.coeff(l-1,l-2), - a98=m_S.coeff(l-0,l-1), - b77i=Scalar(1.0)/m_T.coeff(l-2,l-2), - b88i=Scalar(1.0)/m_T.coeff(l-1,l-1); - Scalar ss = abs(a87*b77i) + abs(a98*b88i), - lpl = Scalar(1.5)*ss, - ll = ss*ss; - x = ll + a11*a11*b11i*b11i - lpl*a11*b11i + a12*a21*b11i*b22i - - a11*a21*b12*b11i*b11i*b22i; - y = a11*a21*b11i*b11i - lpl*a21*b11i + a21*a22*b11i*b22i - - a21*a21*b12*b11i*b11i*b22i; - z = a21*a32*b11i*b22i; - } - else if (iter==16) - { - // another exceptional shift - x = m_S.coeff(f,f)/m_T.coeff(f,f)-m_S.coeff(l,l)/m_T.coeff(l,l) + m_S.coeff(l,l-1)*m_T.coeff(l-1,l) / - (m_T.coeff(l-1,l-1)*m_T.coeff(l,l)); - y = m_S.coeff(f+1,f)/m_T.coeff(f,f); - z = 0; - } - else if (iter>23 && !(iter%8)) - { - // extremely exceptional shift - x = internal::random(-1.0,1.0); - y = internal::random(-1.0,1.0); - z = internal::random(-1.0,1.0); - } - else - { - // Compute the shifts: (x,y,z,0...) = (AB^-1 - l1 I) (AB^-1 - l2 I) e1 - // where l1 and l2 are the eigenvalues of the 2x2 matrix C = U V^-1 where - // U and V are 2x2 bottom right sub matrices of A and B. Thus: - // = AB^-1AB^-1 + l1 l2 I - (l1+l2)(AB^-1) - // = AB^-1AB^-1 + det(M) - tr(M)(AB^-1) - // Since we are only interested in having x, y, z with a correct ratio, we have: - const Scalar - a11 = m_S.coeff(f,f), a12 = m_S.coeff(f,f+1), - a21 = m_S.coeff(f+1,f), a22 = m_S.coeff(f+1,f+1), - a32 = m_S.coeff(f+2,f+1), - - a88 = m_S.coeff(l-1,l-1), a89 = m_S.coeff(l-1,l), - a98 = m_S.coeff(l,l-1), a99 = m_S.coeff(l,l), - - b11 = m_T.coeff(f,f), b12 = m_T.coeff(f,f+1), - b22 = m_T.coeff(f+1,f+1), - - b88 = m_T.coeff(l-1,l-1), b89 = m_T.coeff(l-1,l), - b99 = m_T.coeff(l,l); - - x = ( (a88/b88 - a11/b11)*(a99/b99 - a11/b11) - (a89/b99)*(a98/b88) + (a98/b88)*(b89/b99)*(a11/b11) ) * (b11/a21) - + a12/b22 - (a11/b11)*(b12/b22); - y = (a22/b22-a11/b11) - (a21/b11)*(b12/b22) - (a88/b88-a11/b11) - (a99/b99-a11/b11) + (a98/b88)*(b89/b99); - z = a32/b22; - } - - JRs G; - - for (Index k=f; k<=l-2; k++) - { - // variables for Householder reflections - Vector2s essential2; - Scalar tau, beta; - - Vector3s hr(x,y,z); - - // Q_k to annihilate S(k+1,k-1) and S(k+2,k-1) - hr.makeHouseholderInPlace(tau, beta); - essential2 = hr.template bottomRows<2>(); - Index fc=(std::max)(k-1,Index(0)); // first col to update - m_S.template middleRows<3>(k).rightCols(dim-fc).applyHouseholderOnTheLeft(essential2, tau, m_workspace.data()); - m_T.template middleRows<3>(k).rightCols(dim-fc).applyHouseholderOnTheLeft(essential2, tau, m_workspace.data()); - if (m_computeQZ) - m_Q.template middleCols<3>(k).applyHouseholderOnTheRight(essential2, tau, m_workspace.data()); - if (k>f) - m_S.coeffRef(k+2,k-1) = m_S.coeffRef(k+1,k-1) = Scalar(0.0); - - // Z_{k1} to annihilate T(k+2,k+1) and T(k+2,k) - hr << m_T.coeff(k+2,k+2),m_T.coeff(k+2,k),m_T.coeff(k+2,k+1); - hr.makeHouseholderInPlace(tau, beta); - essential2 = hr.template bottomRows<2>(); - { - Index lr = (std::min)(k+4,dim); // last row to update - Map > tmp(m_workspace.data(),lr); - // S - tmp = m_S.template middleCols<2>(k).topRows(lr) * essential2; - tmp += m_S.col(k+2).head(lr); - m_S.col(k+2).head(lr) -= tau*tmp; - m_S.template middleCols<2>(k).topRows(lr) -= (tau*tmp) * essential2.adjoint(); - // T - tmp = m_T.template middleCols<2>(k).topRows(lr) * essential2; - tmp += m_T.col(k+2).head(lr); - m_T.col(k+2).head(lr) -= tau*tmp; - m_T.template middleCols<2>(k).topRows(lr) -= (tau*tmp) * essential2.adjoint(); - } - if (m_computeQZ) - { - // Z - Map > tmp(m_workspace.data(),dim); - tmp = essential2.adjoint()*(m_Z.template middleRows<2>(k)); - tmp += m_Z.row(k+2); - m_Z.row(k+2) -= tau*tmp; - m_Z.template middleRows<2>(k) -= essential2 * (tau*tmp); - } - m_T.coeffRef(k+2,k) = m_T.coeffRef(k+2,k+1) = Scalar(0.0); - - // Z_{k2} to annihilate T(k+1,k) - G.makeGivens(m_T.coeff(k+1,k+1), m_T.coeff(k+1,k)); - m_S.applyOnTheRight(k+1,k,G); - m_T.applyOnTheRight(k+1,k,G); - // update Z - if (m_computeQZ) - m_Z.applyOnTheLeft(k+1,k,G.adjoint()); - m_T.coeffRef(k+1,k) = Scalar(0.0); - - // update x,y,z - x = m_S.coeff(k+1,k); - y = m_S.coeff(k+2,k); - if (k < l-2) - z = m_S.coeff(k+3,k); - } // loop over k - - // Q_{n-1} to annihilate y = S(l,l-2) - G.makeGivens(x,y); - m_S.applyOnTheLeft(l-1,l,G.adjoint()); - m_T.applyOnTheLeft(l-1,l,G.adjoint()); - if (m_computeQZ) - m_Q.applyOnTheRight(l-1,l,G); - m_S.coeffRef(l,l-2) = Scalar(0.0); - - // Z_{n-1} to annihilate T(l,l-1) - G.makeGivens(m_T.coeff(l,l),m_T.coeff(l,l-1)); - m_S.applyOnTheRight(l,l-1,G); - m_T.applyOnTheRight(l,l-1,G); - if (m_computeQZ) - m_Z.applyOnTheLeft(l,l-1,G.adjoint()); - m_T.coeffRef(l,l-1) = Scalar(0.0); - } - - - template - RealQZ& RealQZ::compute(const MatrixType& A_in, const MatrixType& B_in, bool computeQZ) - { - - const Index dim = A_in.cols(); - - eigen_assert (A_in.rows()==dim && A_in.cols()==dim - && B_in.rows()==dim && B_in.cols()==dim - && "Need square matrices of the same dimension"); - - m_isInitialized = true; - m_computeQZ = computeQZ; - m_S = A_in; m_T = B_in; - m_workspace.resize(dim*2); - m_global_iter = 0; - - // entrance point: hessenberg triangular decomposition - hessenbergTriangular(); - // compute L1 vector norms of T, S into m_normOfS, m_normOfT - computeNorms(); - - Index l = dim-1, - f, - local_iter = 0; - - while (l>0 && local_iter0) m_S.coeffRef(f,f-1) = Scalar(0.0); - if (f == l) // One root found - { - l--; - local_iter = 0; - } - else if (f == l-1) // Two roots found - { - splitOffTwoRows(f); - l -= 2; - local_iter = 0; - } - else // No convergence yet - { - // if there's zero on diagonal of T, we can isolate an eigenvalue with Givens rotations - Index z = findSmallDiagEntry(f,l); - if (z>=f) - { - // zero found - pushDownZero(z,f,l); - } - else - { - // We are sure now that S.block(f,f, l-f+1,l-f+1) is underuced upper-Hessenberg - // and T.block(f,f, l-f+1,l-f+1) is invertible uper-triangular, which allows to - // apply a QR-like iteration to rows and columns f..l. - step(f,l, local_iter); - local_iter++; - m_global_iter++; - } - } - } - // check if we converged before reaching iterations limit - m_info = (local_iter -// Copyright (C) 2010,2012 Jitse Niesen -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_REAL_SCHUR_H -#define EIGEN_REAL_SCHUR_H - -#include "./HessenbergDecomposition.h" - -namespace Eigen { - -/** \eigenvalues_module \ingroup Eigenvalues_Module - * - * - * \class RealSchur - * - * \brief Performs a real Schur decomposition of a square matrix - * - * \tparam _MatrixType the type of the matrix of which we are computing the - * real Schur decomposition; this is expected to be an instantiation of the - * Matrix class template. - * - * Given a real square matrix A, this class computes the real Schur - * decomposition: \f$ A = U T U^T \f$ where U is a real orthogonal matrix and - * T is a real quasi-triangular matrix. An orthogonal matrix is a matrix whose - * inverse is equal to its transpose, \f$ U^{-1} = U^T \f$. A quasi-triangular - * matrix is a block-triangular matrix whose diagonal consists of 1-by-1 - * blocks and 2-by-2 blocks with complex eigenvalues. The eigenvalues of the - * blocks on the diagonal of T are the same as the eigenvalues of the matrix - * A, and thus the real Schur decomposition is used in EigenSolver to compute - * the eigendecomposition of a matrix. - * - * Call the function compute() to compute the real Schur decomposition of a - * given matrix. Alternatively, you can use the RealSchur(const MatrixType&, bool) - * constructor which computes the real Schur decomposition at construction - * time. Once the decomposition is computed, you can use the matrixU() and - * matrixT() functions to retrieve the matrices U and T in the decomposition. - * - * The documentation of RealSchur(const MatrixType&, bool) contains an example - * of the typical use of this class. - * - * \note The implementation is adapted from - * JAMA (public domain). - * Their code is based on EISPACK. - * - * \sa class ComplexSchur, class EigenSolver, class ComplexEigenSolver - */ -template class RealSchur -{ - public: - typedef _MatrixType MatrixType; - enum { - RowsAtCompileTime = MatrixType::RowsAtCompileTime, - ColsAtCompileTime = MatrixType::ColsAtCompileTime, - Options = MatrixType::Options, - MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime, - MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime - }; - typedef typename MatrixType::Scalar Scalar; - typedef std::complex::Real> ComplexScalar; - typedef typename MatrixType::Index Index; - - typedef Matrix EigenvalueType; - typedef Matrix ColumnVectorType; - - /** \brief Default constructor. - * - * \param [in] size Positive integer, size of the matrix whose Schur decomposition will be computed. - * - * The default constructor is useful in cases in which the user intends to - * perform decompositions via compute(). The \p size parameter is only - * used as a hint. It is not an error to give a wrong \p size, but it may - * impair performance. - * - * \sa compute() for an example. - */ - RealSchur(Index size = RowsAtCompileTime==Dynamic ? 1 : RowsAtCompileTime) - : m_matT(size, size), - m_matU(size, size), - m_workspaceVector(size), - m_hess(size), - m_isInitialized(false), - m_matUisUptodate(false), - m_maxIters(-1) - { } - - /** \brief Constructor; computes real Schur decomposition of given matrix. - * - * \param[in] matrix Square matrix whose Schur decomposition is to be computed. - * \param[in] computeU If true, both T and U are computed; if false, only T is computed. - * - * This constructor calls compute() to compute the Schur decomposition. - * - * Example: \include RealSchur_RealSchur_MatrixType.cpp - * Output: \verbinclude RealSchur_RealSchur_MatrixType.out - */ - RealSchur(const MatrixType& matrix, bool computeU = true) - : m_matT(matrix.rows(),matrix.cols()), - m_matU(matrix.rows(),matrix.cols()), - m_workspaceVector(matrix.rows()), - m_hess(matrix.rows()), - m_isInitialized(false), - m_matUisUptodate(false), - m_maxIters(-1) - { - compute(matrix, computeU); - } - - /** \brief Returns the orthogonal matrix in the Schur decomposition. - * - * \returns A const reference to the matrix U. - * - * \pre Either the constructor RealSchur(const MatrixType&, bool) or the - * member function compute(const MatrixType&, bool) has been called before - * to compute the Schur decomposition of a matrix, and \p computeU was set - * to true (the default value). - * - * \sa RealSchur(const MatrixType&, bool) for an example - */ - const MatrixType& matrixU() const - { - eigen_assert(m_isInitialized && "RealSchur is not initialized."); - eigen_assert(m_matUisUptodate && "The matrix U has not been computed during the RealSchur decomposition."); - return m_matU; - } - - /** \brief Returns the quasi-triangular matrix in the Schur decomposition. - * - * \returns A const reference to the matrix T. - * - * \pre Either the constructor RealSchur(const MatrixType&, bool) or the - * member function compute(const MatrixType&, bool) has been called before - * to compute the Schur decomposition of a matrix. - * - * \sa RealSchur(const MatrixType&, bool) for an example - */ - const MatrixType& matrixT() const - { - eigen_assert(m_isInitialized && "RealSchur is not initialized."); - return m_matT; - } - - /** \brief Computes Schur decomposition of given matrix. - * - * \param[in] matrix Square matrix whose Schur decomposition is to be computed. - * \param[in] computeU If true, both T and U are computed; if false, only T is computed. - * \returns Reference to \c *this - * - * The Schur decomposition is computed by first reducing the matrix to - * Hessenberg form using the class HessenbergDecomposition. The Hessenberg - * matrix is then reduced to triangular form by performing Francis QR - * iterations with implicit double shift. The cost of computing the Schur - * decomposition depends on the number of iterations; as a rough guide, it - * may be taken to be \f$25n^3\f$ flops if \a computeU is true and - * \f$10n^3\f$ flops if \a computeU is false. - * - * Example: \include RealSchur_compute.cpp - * Output: \verbinclude RealSchur_compute.out - * - * \sa compute(const MatrixType&, bool, Index) - */ - RealSchur& compute(const MatrixType& matrix, bool computeU = true); - - /** \brief Computes Schur decomposition of a Hessenberg matrix H = Z T Z^T - * \param[in] matrixH Matrix in Hessenberg form H - * \param[in] matrixQ orthogonal matrix Q that transform a matrix A to H : A = Q H Q^T - * \param computeU Computes the matriX U of the Schur vectors - * \return Reference to \c *this - * - * This routine assumes that the matrix is already reduced in Hessenberg form matrixH - * using either the class HessenbergDecomposition or another mean. - * It computes the upper quasi-triangular matrix T of the Schur decomposition of H - * When computeU is true, this routine computes the matrix U such that - * A = U T U^T = (QZ) T (QZ)^T = Q H Q^T where A is the initial matrix - * - * NOTE Q is referenced if computeU is true; so, if the initial orthogonal matrix - * is not available, the user should give an identity matrix (Q.setIdentity()) - * - * \sa compute(const MatrixType&, bool) - */ - template - RealSchur& computeFromHessenberg(const HessMatrixType& matrixH, const OrthMatrixType& matrixQ, bool computeU); - /** \brief Reports whether previous computation was successful. - * - * \returns \c Success if computation was succesful, \c NoConvergence otherwise. - */ - ComputationInfo info() const - { - eigen_assert(m_isInitialized && "RealSchur is not initialized."); - return m_info; - } - - /** \brief Sets the maximum number of iterations allowed. - * - * If not specified by the user, the maximum number of iterations is m_maxIterationsPerRow times the size - * of the matrix. - */ - RealSchur& setMaxIterations(Index maxIters) - { - m_maxIters = maxIters; - return *this; - } - - /** \brief Returns the maximum number of iterations. */ - Index getMaxIterations() - { - return m_maxIters; - } - - /** \brief Maximum number of iterations per row. - * - * If not otherwise specified, the maximum number of iterations is this number times the size of the - * matrix. It is currently set to 40. - */ - static const int m_maxIterationsPerRow = 40; - - private: - - MatrixType m_matT; - MatrixType m_matU; - ColumnVectorType m_workspaceVector; - HessenbergDecomposition m_hess; - ComputationInfo m_info; - bool m_isInitialized; - bool m_matUisUptodate; - Index m_maxIters; - - typedef Matrix Vector3s; - - Scalar computeNormOfT(); - Index findSmallSubdiagEntry(Index iu); - void splitOffTwoRows(Index iu, bool computeU, const Scalar& exshift); - void computeShift(Index iu, Index iter, Scalar& exshift, Vector3s& shiftInfo); - void initFrancisQRStep(Index il, Index iu, const Vector3s& shiftInfo, Index& im, Vector3s& firstHouseholderVector); - void performFrancisQRStep(Index il, Index im, Index iu, bool computeU, const Vector3s& firstHouseholderVector, Scalar* workspace); -}; - - -template -RealSchur& RealSchur::compute(const MatrixType& matrix, bool computeU) -{ - eigen_assert(matrix.cols() == matrix.rows()); - Index maxIters = m_maxIters; - if (maxIters == -1) - maxIters = m_maxIterationsPerRow * matrix.rows(); - - // Step 1. Reduce to Hessenberg form - m_hess.compute(matrix); - - // Step 2. Reduce to real Schur form - computeFromHessenberg(m_hess.matrixH(), m_hess.matrixQ(), computeU); - - return *this; -} -template -template -RealSchur& RealSchur::computeFromHessenberg(const HessMatrixType& matrixH, const OrthMatrixType& matrixQ, bool computeU) -{ - m_matT = matrixH; - if(computeU) - m_matU = matrixQ; - - Index maxIters = m_maxIters; - if (maxIters == -1) - maxIters = m_maxIterationsPerRow * matrixH.rows(); - m_workspaceVector.resize(m_matT.cols()); - Scalar* workspace = &m_workspaceVector.coeffRef(0); - - // The matrix m_matT is divided in three parts. - // Rows 0,...,il-1 are decoupled from the rest because m_matT(il,il-1) is zero. - // Rows il,...,iu is the part we are working on (the active window). - // Rows iu+1,...,end are already brought in triangular form. - Index iu = m_matT.cols() - 1; - Index iter = 0; // iteration count for current eigenvalue - Index totalIter = 0; // iteration count for whole matrix - Scalar exshift(0); // sum of exceptional shifts - Scalar norm = computeNormOfT(); - - if(norm!=0) - { - while (iu >= 0) - { - Index il = findSmallSubdiagEntry(iu); - - // Check for convergence - if (il == iu) // One root found - { - m_matT.coeffRef(iu,iu) = m_matT.coeff(iu,iu) + exshift; - if (iu > 0) - m_matT.coeffRef(iu, iu-1) = Scalar(0); - iu--; - iter = 0; - } - else if (il == iu-1) // Two roots found - { - splitOffTwoRows(iu, computeU, exshift); - iu -= 2; - iter = 0; - } - else // No convergence yet - { - // The firstHouseholderVector vector has to be initialized to something to get rid of a silly GCC warning (-O1 -Wall -DNDEBUG ) - Vector3s firstHouseholderVector(0,0,0), shiftInfo; - computeShift(iu, iter, exshift, shiftInfo); - iter = iter + 1; - totalIter = totalIter + 1; - if (totalIter > maxIters) break; - Index im; - initFrancisQRStep(il, iu, shiftInfo, im, firstHouseholderVector); - performFrancisQRStep(il, im, iu, computeU, firstHouseholderVector, workspace); - } - } - } - if(totalIter <= maxIters) - m_info = Success; - else - m_info = NoConvergence; - - m_isInitialized = true; - m_matUisUptodate = computeU; - return *this; -} - -/** \internal Computes and returns vector L1 norm of T */ -template -inline typename MatrixType::Scalar RealSchur::computeNormOfT() -{ - const Index size = m_matT.cols(); - // FIXME to be efficient the following would requires a triangular reduxion code - // Scalar norm = m_matT.upper().cwiseAbs().sum() - // + m_matT.bottomLeftCorner(size-1,size-1).diagonal().cwiseAbs().sum(); - Scalar norm(0); - for (Index j = 0; j < size; ++j) - norm += m_matT.col(j).segment(0, (std::min)(size,j+2)).cwiseAbs().sum(); - return norm; -} - -/** \internal Look for single small sub-diagonal element and returns its index */ -template -inline typename MatrixType::Index RealSchur::findSmallSubdiagEntry(Index iu) -{ - using std::abs; - Index res = iu; - while (res > 0) - { - Scalar s = abs(m_matT.coeff(res-1,res-1)) + abs(m_matT.coeff(res,res)); - if (abs(m_matT.coeff(res,res-1)) <= NumTraits::epsilon() * s) - break; - res--; - } - return res; -} - -/** \internal Update T given that rows iu-1 and iu decouple from the rest. */ -template -inline void RealSchur::splitOffTwoRows(Index iu, bool computeU, const Scalar& exshift) -{ - using std::sqrt; - using std::abs; - const Index size = m_matT.cols(); - - // The eigenvalues of the 2x2 matrix [a b; c d] are - // trace +/- sqrt(discr/4) where discr = tr^2 - 4*det, tr = a + d, det = ad - bc - Scalar p = Scalar(0.5) * (m_matT.coeff(iu-1,iu-1) - m_matT.coeff(iu,iu)); - Scalar q = p * p + m_matT.coeff(iu,iu-1) * m_matT.coeff(iu-1,iu); // q = tr^2 / 4 - det = discr/4 - m_matT.coeffRef(iu,iu) += exshift; - m_matT.coeffRef(iu-1,iu-1) += exshift; - - if (q >= Scalar(0)) // Two real eigenvalues - { - Scalar z = sqrt(abs(q)); - JacobiRotation rot; - if (p >= Scalar(0)) - rot.makeGivens(p + z, m_matT.coeff(iu, iu-1)); - else - rot.makeGivens(p - z, m_matT.coeff(iu, iu-1)); - - m_matT.rightCols(size-iu+1).applyOnTheLeft(iu-1, iu, rot.adjoint()); - m_matT.topRows(iu+1).applyOnTheRight(iu-1, iu, rot); - m_matT.coeffRef(iu, iu-1) = Scalar(0); - if (computeU) - m_matU.applyOnTheRight(iu-1, iu, rot); - } - - if (iu > 1) - m_matT.coeffRef(iu-1, iu-2) = Scalar(0); -} - -/** \internal Form shift in shiftInfo, and update exshift if an exceptional shift is performed. */ -template -inline void RealSchur::computeShift(Index iu, Index iter, Scalar& exshift, Vector3s& shiftInfo) -{ - using std::sqrt; - using std::abs; - shiftInfo.coeffRef(0) = m_matT.coeff(iu,iu); - shiftInfo.coeffRef(1) = m_matT.coeff(iu-1,iu-1); - shiftInfo.coeffRef(2) = m_matT.coeff(iu,iu-1) * m_matT.coeff(iu-1,iu); - - // Wilkinson's original ad hoc shift - if (iter == 10) - { - exshift += shiftInfo.coeff(0); - for (Index i = 0; i <= iu; ++i) - m_matT.coeffRef(i,i) -= shiftInfo.coeff(0); - Scalar s = abs(m_matT.coeff(iu,iu-1)) + abs(m_matT.coeff(iu-1,iu-2)); - shiftInfo.coeffRef(0) = Scalar(0.75) * s; - shiftInfo.coeffRef(1) = Scalar(0.75) * s; - shiftInfo.coeffRef(2) = Scalar(-0.4375) * s * s; - } - - // MATLAB's new ad hoc shift - if (iter == 30) - { - Scalar s = (shiftInfo.coeff(1) - shiftInfo.coeff(0)) / Scalar(2.0); - s = s * s + shiftInfo.coeff(2); - if (s > Scalar(0)) - { - s = sqrt(s); - if (shiftInfo.coeff(1) < shiftInfo.coeff(0)) - s = -s; - s = s + (shiftInfo.coeff(1) - shiftInfo.coeff(0)) / Scalar(2.0); - s = shiftInfo.coeff(0) - shiftInfo.coeff(2) / s; - exshift += s; - for (Index i = 0; i <= iu; ++i) - m_matT.coeffRef(i,i) -= s; - shiftInfo.setConstant(Scalar(0.964)); - } - } -} - -/** \internal Compute index im at which Francis QR step starts and the first Householder vector. */ -template -inline void RealSchur::initFrancisQRStep(Index il, Index iu, const Vector3s& shiftInfo, Index& im, Vector3s& firstHouseholderVector) -{ - using std::abs; - Vector3s& v = firstHouseholderVector; // alias to save typing - - for (im = iu-2; im >= il; --im) - { - const Scalar Tmm = m_matT.coeff(im,im); - const Scalar r = shiftInfo.coeff(0) - Tmm; - const Scalar s = shiftInfo.coeff(1) - Tmm; - v.coeffRef(0) = (r * s - shiftInfo.coeff(2)) / m_matT.coeff(im+1,im) + m_matT.coeff(im,im+1); - v.coeffRef(1) = m_matT.coeff(im+1,im+1) - Tmm - r - s; - v.coeffRef(2) = m_matT.coeff(im+2,im+1); - if (im == il) { - break; - } - const Scalar lhs = m_matT.coeff(im,im-1) * (abs(v.coeff(1)) + abs(v.coeff(2))); - const Scalar rhs = v.coeff(0) * (abs(m_matT.coeff(im-1,im-1)) + abs(Tmm) + abs(m_matT.coeff(im+1,im+1))); - if (abs(lhs) < NumTraits::epsilon() * rhs) - break; - } -} - -/** \internal Perform a Francis QR step involving rows il:iu and columns im:iu. */ -template -inline void RealSchur::performFrancisQRStep(Index il, Index im, Index iu, bool computeU, const Vector3s& firstHouseholderVector, Scalar* workspace) -{ - eigen_assert(im >= il); - eigen_assert(im <= iu-2); - - const Index size = m_matT.cols(); - - for (Index k = im; k <= iu-2; ++k) - { - bool firstIteration = (k == im); - - Vector3s v; - if (firstIteration) - v = firstHouseholderVector; - else - v = m_matT.template block<3,1>(k,k-1); - - Scalar tau, beta; - Matrix ess; - v.makeHouseholder(ess, tau, beta); - - if (beta != Scalar(0)) // if v is not zero - { - if (firstIteration && k > il) - m_matT.coeffRef(k,k-1) = -m_matT.coeff(k,k-1); - else if (!firstIteration) - m_matT.coeffRef(k,k-1) = beta; - - // These Householder transformations form the O(n^3) part of the algorithm - m_matT.block(k, k, 3, size-k).applyHouseholderOnTheLeft(ess, tau, workspace); - m_matT.block(0, k, (std::min)(iu,k+3) + 1, 3).applyHouseholderOnTheRight(ess, tau, workspace); - if (computeU) - m_matU.block(0, k, size, 3).applyHouseholderOnTheRight(ess, tau, workspace); - } - } - - Matrix v = m_matT.template block<2,1>(iu-1, iu-2); - Scalar tau, beta; - Matrix ess; - v.makeHouseholder(ess, tau, beta); - - if (beta != Scalar(0)) // if v is not zero - { - m_matT.coeffRef(iu-1, iu-2) = beta; - m_matT.block(iu-1, iu-1, 2, size-iu+1).applyHouseholderOnTheLeft(ess, tau, workspace); - m_matT.block(0, iu-1, iu+1, 2).applyHouseholderOnTheRight(ess, tau, workspace); - if (computeU) - m_matU.block(0, iu-1, size, 2).applyHouseholderOnTheRight(ess, tau, workspace); - } - - // clean up pollution due to round-off errors - for (Index i = im+2; i <= iu; ++i) - { - m_matT.coeffRef(i,i-2) = Scalar(0); - if (i > im+2) - m_matT.coeffRef(i,i-3) = Scalar(0); - } -} - -} // end namespace Eigen - -#endif // EIGEN_REAL_SCHUR_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/RealSchur_MKL.h b/thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/RealSchur_MKL.h deleted file mode 100644 index ad973646..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/RealSchur_MKL.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - Copyright (c) 2011, Intel Corporation. All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of Intel Corporation nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - ******************************************************************************** - * Content : Eigen bindings to Intel(R) MKL - * Real Schur needed to real unsymmetrical eigenvalues/eigenvectors. - ******************************************************************************** -*/ - -#ifndef EIGEN_REAL_SCHUR_MKL_H -#define EIGEN_REAL_SCHUR_MKL_H - -#include "Eigen/src/Core/util/MKL_support.h" - -namespace Eigen { - -/** \internal Specialization for the data types supported by MKL */ - -#define EIGEN_MKL_SCHUR_REAL(EIGTYPE, MKLTYPE, MKLPREFIX, MKLPREFIX_U, EIGCOLROW, MKLCOLROW) \ -template<> inline \ -RealSchur >& \ -RealSchur >::compute(const Matrix& matrix, bool computeU) \ -{ \ - typedef Matrix MatrixType; \ - typedef MatrixType::Scalar Scalar; \ - typedef MatrixType::RealScalar RealScalar; \ -\ - eigen_assert(matrix.cols() == matrix.rows()); \ -\ - lapack_int n = matrix.cols(), sdim, info; \ - lapack_int lda = matrix.outerStride(); \ - lapack_int matrix_order = MKLCOLROW; \ - char jobvs, sort='N'; \ - LAPACK_##MKLPREFIX_U##_SELECT2 select = 0; \ - jobvs = (computeU) ? 'V' : 'N'; \ - m_matU.resize(n, n); \ - lapack_int ldvs = m_matU.outerStride(); \ - m_matT = matrix; \ - Matrix wr, wi; \ - wr.resize(n, 1); wi.resize(n, 1); \ - info = LAPACKE_##MKLPREFIX##gees( matrix_order, jobvs, sort, select, n, (MKLTYPE*)m_matT.data(), lda, &sdim, (MKLTYPE*)wr.data(), (MKLTYPE*)wi.data(), (MKLTYPE*)m_matU.data(), ldvs ); \ - if(info == 0) \ - m_info = Success; \ - else \ - m_info = NoConvergence; \ -\ - m_isInitialized = true; \ - m_matUisUptodate = computeU; \ - return *this; \ -\ -} - -EIGEN_MKL_SCHUR_REAL(double, double, d, D, ColMajor, LAPACK_COL_MAJOR) -EIGEN_MKL_SCHUR_REAL(float, float, s, S, ColMajor, LAPACK_COL_MAJOR) -EIGEN_MKL_SCHUR_REAL(double, double, d, D, RowMajor, LAPACK_ROW_MAJOR) -EIGEN_MKL_SCHUR_REAL(float, float, s, S, RowMajor, LAPACK_ROW_MAJOR) - -} // end namespace Eigen - -#endif // EIGEN_REAL_SCHUR_MKL_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h b/thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h deleted file mode 100644 index 1131c8af..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h +++ /dev/null @@ -1,801 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2010 Gael Guennebaud -// Copyright (C) 2010 Jitse Niesen -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_SELFADJOINTEIGENSOLVER_H -#define EIGEN_SELFADJOINTEIGENSOLVER_H - -#include "./Tridiagonalization.h" - -namespace Eigen { - -template -class GeneralizedSelfAdjointEigenSolver; - -namespace internal { -template struct direct_selfadjoint_eigenvalues; -} - -/** \eigenvalues_module \ingroup Eigenvalues_Module - * - * - * \class SelfAdjointEigenSolver - * - * \brief Computes eigenvalues and eigenvectors of selfadjoint matrices - * - * \tparam _MatrixType the type of the matrix of which we are computing the - * eigendecomposition; this is expected to be an instantiation of the Matrix - * class template. - * - * A matrix \f$ A \f$ is selfadjoint if it equals its adjoint. For real - * matrices, this means that the matrix is symmetric: it equals its - * transpose. This class computes the eigenvalues and eigenvectors of a - * selfadjoint matrix. These are the scalars \f$ \lambda \f$ and vectors - * \f$ v \f$ such that \f$ Av = \lambda v \f$. The eigenvalues of a - * selfadjoint matrix are always real. If \f$ D \f$ is a diagonal matrix with - * the eigenvalues on the diagonal, and \f$ V \f$ is a matrix with the - * eigenvectors as its columns, then \f$ A = V D V^{-1} \f$ (for selfadjoint - * matrices, the matrix \f$ V \f$ is always invertible). This is called the - * eigendecomposition. - * - * The algorithm exploits the fact that the matrix is selfadjoint, making it - * faster and more accurate than the general purpose eigenvalue algorithms - * implemented in EigenSolver and ComplexEigenSolver. - * - * Only the \b lower \b triangular \b part of the input matrix is referenced. - * - * Call the function compute() to compute the eigenvalues and eigenvectors of - * a given matrix. Alternatively, you can use the - * SelfAdjointEigenSolver(const MatrixType&, int) constructor which computes - * the eigenvalues and eigenvectors at construction time. Once the eigenvalue - * and eigenvectors are computed, they can be retrieved with the eigenvalues() - * and eigenvectors() functions. - * - * The documentation for SelfAdjointEigenSolver(const MatrixType&, int) - * contains an example of the typical use of this class. - * - * To solve the \em generalized eigenvalue problem \f$ Av = \lambda Bv \f$ and - * the likes, see the class GeneralizedSelfAdjointEigenSolver. - * - * \sa MatrixBase::eigenvalues(), class EigenSolver, class ComplexEigenSolver - */ -template class SelfAdjointEigenSolver -{ - public: - - typedef _MatrixType MatrixType; - enum { - Size = MatrixType::RowsAtCompileTime, - ColsAtCompileTime = MatrixType::ColsAtCompileTime, - Options = MatrixType::Options, - MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime - }; - - /** \brief Scalar type for matrices of type \p _MatrixType. */ - typedef typename MatrixType::Scalar Scalar; - typedef typename MatrixType::Index Index; - - typedef Matrix EigenvectorsType; - - /** \brief Real scalar type for \p _MatrixType. - * - * This is just \c Scalar if #Scalar is real (e.g., \c float or - * \c double), and the type of the real part of \c Scalar if #Scalar is - * complex. - */ - typedef typename NumTraits::Real RealScalar; - - friend struct internal::direct_selfadjoint_eigenvalues::IsComplex>; - - /** \brief Type for vector of eigenvalues as returned by eigenvalues(). - * - * This is a column vector with entries of type #RealScalar. - * The length of the vector is the size of \p _MatrixType. - */ - typedef typename internal::plain_col_type::type RealVectorType; - typedef Tridiagonalization TridiagonalizationType; - - /** \brief Default constructor for fixed-size matrices. - * - * The default constructor is useful in cases in which the user intends to - * perform decompositions via compute(). This constructor - * can only be used if \p _MatrixType is a fixed-size matrix; use - * SelfAdjointEigenSolver(Index) for dynamic-size matrices. - * - * Example: \include SelfAdjointEigenSolver_SelfAdjointEigenSolver.cpp - * Output: \verbinclude SelfAdjointEigenSolver_SelfAdjointEigenSolver.out - */ - SelfAdjointEigenSolver() - : m_eivec(), - m_eivalues(), - m_subdiag(), - m_isInitialized(false) - { } - - /** \brief Constructor, pre-allocates memory for dynamic-size matrices. - * - * \param [in] size Positive integer, size of the matrix whose - * eigenvalues and eigenvectors will be computed. - * - * This constructor is useful for dynamic-size matrices, when the user - * intends to perform decompositions via compute(). The \p size - * parameter is only used as a hint. It is not an error to give a wrong - * \p size, but it may impair performance. - * - * \sa compute() for an example - */ - SelfAdjointEigenSolver(Index size) - : m_eivec(size, size), - m_eivalues(size), - m_subdiag(size > 1 ? size - 1 : 1), - m_isInitialized(false) - {} - - /** \brief Constructor; computes eigendecomposition of given matrix. - * - * \param[in] matrix Selfadjoint matrix whose eigendecomposition is to - * be computed. Only the lower triangular part of the matrix is referenced. - * \param[in] options Can be #ComputeEigenvectors (default) or #EigenvaluesOnly. - * - * This constructor calls compute(const MatrixType&, int) to compute the - * eigenvalues of the matrix \p matrix. The eigenvectors are computed if - * \p options equals #ComputeEigenvectors. - * - * Example: \include SelfAdjointEigenSolver_SelfAdjointEigenSolver_MatrixType.cpp - * Output: \verbinclude SelfAdjointEigenSolver_SelfAdjointEigenSolver_MatrixType.out - * - * \sa compute(const MatrixType&, int) - */ - SelfAdjointEigenSolver(const MatrixType& matrix, int options = ComputeEigenvectors) - : m_eivec(matrix.rows(), matrix.cols()), - m_eivalues(matrix.cols()), - m_subdiag(matrix.rows() > 1 ? matrix.rows() - 1 : 1), - m_isInitialized(false) - { - compute(matrix, options); - } - - /** \brief Computes eigendecomposition of given matrix. - * - * \param[in] matrix Selfadjoint matrix whose eigendecomposition is to - * be computed. Only the lower triangular part of the matrix is referenced. - * \param[in] options Can be #ComputeEigenvectors (default) or #EigenvaluesOnly. - * \returns Reference to \c *this - * - * This function computes the eigenvalues of \p matrix. The eigenvalues() - * function can be used to retrieve them. If \p options equals #ComputeEigenvectors, - * then the eigenvectors are also computed and can be retrieved by - * calling eigenvectors(). - * - * This implementation uses a symmetric QR algorithm. The matrix is first - * reduced to tridiagonal form using the Tridiagonalization class. The - * tridiagonal matrix is then brought to diagonal form with implicit - * symmetric QR steps with Wilkinson shift. Details can be found in - * Section 8.3 of Golub \& Van Loan, %Matrix Computations. - * - * The cost of the computation is about \f$ 9n^3 \f$ if the eigenvectors - * are required and \f$ 4n^3/3 \f$ if they are not required. - * - * This method reuses the memory in the SelfAdjointEigenSolver object that - * was allocated when the object was constructed, if the size of the - * matrix does not change. - * - * Example: \include SelfAdjointEigenSolver_compute_MatrixType.cpp - * Output: \verbinclude SelfAdjointEigenSolver_compute_MatrixType.out - * - * \sa SelfAdjointEigenSolver(const MatrixType&, int) - */ - SelfAdjointEigenSolver& compute(const MatrixType& matrix, int options = ComputeEigenvectors); - - /** \brief Computes eigendecomposition of given matrix using a direct algorithm - * - * This is a variant of compute(const MatrixType&, int options) which - * directly solves the underlying polynomial equation. - * - * Currently only 3x3 matrices for which the sizes are known at compile time are supported (e.g., Matrix3d). - * - * This method is usually significantly faster than the QR algorithm - * but it might also be less accurate. It is also worth noting that - * for 3x3 matrices it involves trigonometric operations which are - * not necessarily available for all scalar types. - * - * \sa compute(const MatrixType&, int options) - */ - SelfAdjointEigenSolver& computeDirect(const MatrixType& matrix, int options = ComputeEigenvectors); - - /** \brief Returns the eigenvectors of given matrix. - * - * \returns A const reference to the matrix whose columns are the eigenvectors. - * - * \pre The eigenvectors have been computed before. - * - * Column \f$ k \f$ of the returned matrix is an eigenvector corresponding - * to eigenvalue number \f$ k \f$ as returned by eigenvalues(). The - * eigenvectors are normalized to have (Euclidean) norm equal to one. If - * this object was used to solve the eigenproblem for the selfadjoint - * matrix \f$ A \f$, then the matrix returned by this function is the - * matrix \f$ V \f$ in the eigendecomposition \f$ A = V D V^{-1} \f$. - * - * Example: \include SelfAdjointEigenSolver_eigenvectors.cpp - * Output: \verbinclude SelfAdjointEigenSolver_eigenvectors.out - * - * \sa eigenvalues() - */ - const EigenvectorsType& eigenvectors() const - { - eigen_assert(m_isInitialized && "SelfAdjointEigenSolver is not initialized."); - eigen_assert(m_eigenvectorsOk && "The eigenvectors have not been computed together with the eigenvalues."); - return m_eivec; - } - - /** \brief Returns the eigenvalues of given matrix. - * - * \returns A const reference to the column vector containing the eigenvalues. - * - * \pre The eigenvalues have been computed before. - * - * The eigenvalues are repeated according to their algebraic multiplicity, - * so there are as many eigenvalues as rows in the matrix. The eigenvalues - * are sorted in increasing order. - * - * Example: \include SelfAdjointEigenSolver_eigenvalues.cpp - * Output: \verbinclude SelfAdjointEigenSolver_eigenvalues.out - * - * \sa eigenvectors(), MatrixBase::eigenvalues() - */ - const RealVectorType& eigenvalues() const - { - eigen_assert(m_isInitialized && "SelfAdjointEigenSolver is not initialized."); - return m_eivalues; - } - - /** \brief Computes the positive-definite square root of the matrix. - * - * \returns the positive-definite square root of the matrix - * - * \pre The eigenvalues and eigenvectors of a positive-definite matrix - * have been computed before. - * - * The square root of a positive-definite matrix \f$ A \f$ is the - * positive-definite matrix whose square equals \f$ A \f$. This function - * uses the eigendecomposition \f$ A = V D V^{-1} \f$ to compute the - * square root as \f$ A^{1/2} = V D^{1/2} V^{-1} \f$. - * - * Example: \include SelfAdjointEigenSolver_operatorSqrt.cpp - * Output: \verbinclude SelfAdjointEigenSolver_operatorSqrt.out - * - * \sa operatorInverseSqrt(), - * \ref MatrixFunctions_Module "MatrixFunctions Module" - */ - MatrixType operatorSqrt() const - { - eigen_assert(m_isInitialized && "SelfAdjointEigenSolver is not initialized."); - eigen_assert(m_eigenvectorsOk && "The eigenvectors have not been computed together with the eigenvalues."); - return m_eivec * m_eivalues.cwiseSqrt().asDiagonal() * m_eivec.adjoint(); - } - - /** \brief Computes the inverse square root of the matrix. - * - * \returns the inverse positive-definite square root of the matrix - * - * \pre The eigenvalues and eigenvectors of a positive-definite matrix - * have been computed before. - * - * This function uses the eigendecomposition \f$ A = V D V^{-1} \f$ to - * compute the inverse square root as \f$ V D^{-1/2} V^{-1} \f$. This is - * cheaper than first computing the square root with operatorSqrt() and - * then its inverse with MatrixBase::inverse(). - * - * Example: \include SelfAdjointEigenSolver_operatorInverseSqrt.cpp - * Output: \verbinclude SelfAdjointEigenSolver_operatorInverseSqrt.out - * - * \sa operatorSqrt(), MatrixBase::inverse(), - * \ref MatrixFunctions_Module "MatrixFunctions Module" - */ - MatrixType operatorInverseSqrt() const - { - eigen_assert(m_isInitialized && "SelfAdjointEigenSolver is not initialized."); - eigen_assert(m_eigenvectorsOk && "The eigenvectors have not been computed together with the eigenvalues."); - return m_eivec * m_eivalues.cwiseInverse().cwiseSqrt().asDiagonal() * m_eivec.adjoint(); - } - - /** \brief Reports whether previous computation was successful. - * - * \returns \c Success if computation was succesful, \c NoConvergence otherwise. - */ - ComputationInfo info() const - { - eigen_assert(m_isInitialized && "SelfAdjointEigenSolver is not initialized."); - return m_info; - } - - /** \brief Maximum number of iterations. - * - * The algorithm terminates if it does not converge within m_maxIterations * n iterations, where n - * denotes the size of the matrix. This value is currently set to 30 (copied from LAPACK). - */ - static const int m_maxIterations = 30; - - #ifdef EIGEN2_SUPPORT - SelfAdjointEigenSolver(const MatrixType& matrix, bool computeEigenvectors) - : m_eivec(matrix.rows(), matrix.cols()), - m_eivalues(matrix.cols()), - m_subdiag(matrix.rows() > 1 ? matrix.rows() - 1 : 1), - m_isInitialized(false) - { - compute(matrix, computeEigenvectors); - } - - SelfAdjointEigenSolver(const MatrixType& matA, const MatrixType& matB, bool computeEigenvectors = true) - : m_eivec(matA.cols(), matA.cols()), - m_eivalues(matA.cols()), - m_subdiag(matA.cols() > 1 ? matA.cols() - 1 : 1), - m_isInitialized(false) - { - static_cast*>(this)->compute(matA, matB, computeEigenvectors ? ComputeEigenvectors : EigenvaluesOnly); - } - - void compute(const MatrixType& matrix, bool computeEigenvectors) - { - compute(matrix, computeEigenvectors ? ComputeEigenvectors : EigenvaluesOnly); - } - - void compute(const MatrixType& matA, const MatrixType& matB, bool computeEigenvectors = true) - { - compute(matA, matB, computeEigenvectors ? ComputeEigenvectors : EigenvaluesOnly); - } - #endif // EIGEN2_SUPPORT - - protected: - static void check_template_parameters() - { - EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar); - } - - EigenvectorsType m_eivec; - RealVectorType m_eivalues; - typename TridiagonalizationType::SubDiagonalType m_subdiag; - ComputationInfo m_info; - bool m_isInitialized; - bool m_eigenvectorsOk; -}; - -/** \internal - * - * \eigenvalues_module \ingroup Eigenvalues_Module - * - * Performs a QR step on a tridiagonal symmetric matrix represented as a - * pair of two vectors \a diag and \a subdiag. - * - * \param matA the input selfadjoint matrix - * \param hCoeffs returned Householder coefficients - * - * For compilation efficiency reasons, this procedure does not use eigen expression - * for its arguments. - * - * Implemented from Golub's "Matrix Computations", algorithm 8.3.2: - * "implicit symmetric QR step with Wilkinson shift" - */ -namespace internal { -template -static void tridiagonal_qr_step(RealScalar* diag, RealScalar* subdiag, Index start, Index end, Scalar* matrixQ, Index n); -} - -template -SelfAdjointEigenSolver& SelfAdjointEigenSolver -::compute(const MatrixType& matrix, int options) -{ - check_template_parameters(); - - using std::abs; - eigen_assert(matrix.cols() == matrix.rows()); - eigen_assert((options&~(EigVecMask|GenEigMask))==0 - && (options&EigVecMask)!=EigVecMask - && "invalid option parameter"); - bool computeEigenvectors = (options&ComputeEigenvectors)==ComputeEigenvectors; - Index n = matrix.cols(); - m_eivalues.resize(n,1); - - if(n==1) - { - m_eivalues.coeffRef(0,0) = numext::real(matrix.coeff(0,0)); - if(computeEigenvectors) - m_eivec.setOnes(n,n); - m_info = Success; - m_isInitialized = true; - m_eigenvectorsOk = computeEigenvectors; - return *this; - } - - // declare some aliases - RealVectorType& diag = m_eivalues; - EigenvectorsType& mat = m_eivec; - - // map the matrix coefficients to [-1:1] to avoid over- and underflow. - mat = matrix.template triangularView(); - RealScalar scale = mat.cwiseAbs().maxCoeff(); - if(scale==RealScalar(0)) scale = RealScalar(1); - mat.template triangularView() /= scale; - m_subdiag.resize(n-1); - internal::tridiagonalization_inplace(mat, diag, m_subdiag, computeEigenvectors); - - Index end = n-1; - Index start = 0; - Index iter = 0; // total number of iterations - - while (end>0) - { - for (Index i = start; i0 && m_subdiag[end-1]==0) - { - end--; - } - if (end<=0) - break; - - // if we spent too many iterations, we give up - iter++; - if(iter > m_maxIterations * n) break; - - start = end - 1; - while (start>0 && m_subdiag[start-1]!=0) - start--; - - internal::tridiagonal_qr_step(diag.data(), m_subdiag.data(), start, end, computeEigenvectors ? m_eivec.data() : (Scalar*)0, n); - } - - if (iter <= m_maxIterations * n) - m_info = Success; - else - m_info = NoConvergence; - - // Sort eigenvalues and corresponding vectors. - // TODO make the sort optional ? - // TODO use a better sort algorithm !! - if (m_info == Success) - { - for (Index i = 0; i < n-1; ++i) - { - Index k; - m_eivalues.segment(i,n-i).minCoeff(&k); - if (k > 0) - { - std::swap(m_eivalues[i], m_eivalues[k+i]); - if(computeEigenvectors) - m_eivec.col(i).swap(m_eivec.col(k+i)); - } - } - } - - // scale back the eigen values - m_eivalues *= scale; - - m_isInitialized = true; - m_eigenvectorsOk = computeEigenvectors; - return *this; -} - - -namespace internal { - -template struct direct_selfadjoint_eigenvalues -{ - static inline void run(SolverType& eig, const typename SolverType::MatrixType& A, int options) - { eig.compute(A,options); } -}; - -template struct direct_selfadjoint_eigenvalues -{ - typedef typename SolverType::MatrixType MatrixType; - typedef typename SolverType::RealVectorType VectorType; - typedef typename SolverType::Scalar Scalar; - typedef typename MatrixType::Index Index; - typedef typename SolverType::EigenvectorsType EigenvectorsType; - - /** \internal - * Computes the roots of the characteristic polynomial of \a m. - * For numerical stability m.trace() should be near zero and to avoid over- or underflow m should be normalized. - */ - static inline void computeRoots(const MatrixType& m, VectorType& roots) - { - using std::sqrt; - using std::atan2; - using std::cos; - using std::sin; - const Scalar s_inv3 = Scalar(1.0)/Scalar(3.0); - const Scalar s_sqrt3 = sqrt(Scalar(3.0)); - - // The characteristic equation is x^3 - c2*x^2 + c1*x - c0 = 0. The - // eigenvalues are the roots to this equation, all guaranteed to be - // real-valued, because the matrix is symmetric. - Scalar c0 = m(0,0)*m(1,1)*m(2,2) + Scalar(2)*m(1,0)*m(2,0)*m(2,1) - m(0,0)*m(2,1)*m(2,1) - m(1,1)*m(2,0)*m(2,0) - m(2,2)*m(1,0)*m(1,0); - Scalar c1 = m(0,0)*m(1,1) - m(1,0)*m(1,0) + m(0,0)*m(2,2) - m(2,0)*m(2,0) + m(1,1)*m(2,2) - m(2,1)*m(2,1); - Scalar c2 = m(0,0) + m(1,1) + m(2,2); - - // Construct the parameters used in classifying the roots of the equation - // and in solving the equation for the roots in closed form. - Scalar c2_over_3 = c2*s_inv3; - Scalar a_over_3 = (c2*c2_over_3 - c1)*s_inv3; - if(a_over_3 0, atan2 is in [0, pi] and theta is in [0, pi/3] - Scalar cos_theta = cos(theta); - Scalar sin_theta = sin(theta); - // roots are already sorted, since cos is monotonically decreasing on [0, pi] - roots(0) = c2_over_3 - rho*(cos_theta + s_sqrt3*sin_theta); // == 2*rho*cos(theta+2pi/3) - roots(1) = c2_over_3 - rho*(cos_theta - s_sqrt3*sin_theta); // == 2*rho*cos(theta+ pi/3) - roots(2) = c2_over_3 + Scalar(2)*rho*cos_theta; - } - - static inline bool extract_kernel(MatrixType& mat, Ref res, Ref representative) - { - using std::abs; - Index i0; - // Find non-zero column i0 (by construction, there must exist a non zero coefficient on the diagonal): - mat.diagonal().cwiseAbs().maxCoeff(&i0); - // mat.col(i0) is a good candidate for an orthogonal vector to the current eigenvector, - // so let's save it: - representative = mat.col(i0); - Scalar n0, n1; - VectorType c0, c1; - n0 = (c0 = representative.cross(mat.col((i0+1)%3))).squaredNorm(); - n1 = (c1 = representative.cross(mat.col((i0+2)%3))).squaredNorm(); - if(n0>n1) res = c0/std::sqrt(n0); - else res = c1/std::sqrt(n1); - - return true; - } - - static inline void run(SolverType& solver, const MatrixType& mat, int options) - { - eigen_assert(mat.cols() == 3 && mat.cols() == mat.rows()); - eigen_assert((options&~(EigVecMask|GenEigMask))==0 - && (options&EigVecMask)!=EigVecMask - && "invalid option parameter"); - bool computeEigenvectors = (options&ComputeEigenvectors)==ComputeEigenvectors; - - EigenvectorsType& eivecs = solver.m_eivec; - VectorType& eivals = solver.m_eivalues; - - // Shift the matrix to the mean eigenvalue and map the matrix coefficients to [-1:1] to avoid over- and underflow. - Scalar shift = mat.trace() / Scalar(3); - // TODO Avoid this copy. Currently it is necessary to suppress bogus values when determining maxCoeff and for computing the eigenvectors later - MatrixType scaledMat = mat.template selfadjointView(); - scaledMat.diagonal().array() -= shift; - Scalar scale = scaledMat.cwiseAbs().maxCoeff(); - if(scale > 0) scaledMat /= scale; // TODO for scale==0 we could save the remaining operations - - // compute the eigenvalues - computeRoots(scaledMat,eivals); - - // compute the eigenvectors - if(computeEigenvectors) - { - if((eivals(2)-eivals(0))<=Eigen::NumTraits::epsilon()) - { - // All three eigenvalues are numerically the same - eivecs.setIdentity(); - } - else - { - MatrixType tmp; - tmp = scaledMat; - - // Compute the eigenvector of the most distinct eigenvalue - Scalar d0 = eivals(2) - eivals(1); - Scalar d1 = eivals(1) - eivals(0); - Index k(0), l(2); - if(d0 > d1) - { - std::swap(k,l); - d0 = d1; - } - - // Compute the eigenvector of index k - { - tmp.diagonal().array () -= eivals(k); - // By construction, 'tmp' is of rank 2, and its kernel corresponds to the respective eigenvector. - extract_kernel(tmp, eivecs.col(k), eivecs.col(l)); - } - - // Compute eigenvector of index l - if(d0<=2*Eigen::NumTraits::epsilon()*d1) - { - // If d0 is too small, then the two other eigenvalues are numerically the same, - // and thus we only have to ortho-normalize the near orthogonal vector we saved above. - eivecs.col(l) -= eivecs.col(k).dot(eivecs.col(l))*eivecs.col(l); - eivecs.col(l).normalize(); - } - else - { - tmp = scaledMat; - tmp.diagonal().array () -= eivals(l); - - VectorType dummy; - extract_kernel(tmp, eivecs.col(l), dummy); - } - - // Compute last eigenvector from the other two - eivecs.col(1) = eivecs.col(2).cross(eivecs.col(0)).normalized(); - } - } - - // Rescale back to the original size. - eivals *= scale; - eivals.array() += shift; - - solver.m_info = Success; - solver.m_isInitialized = true; - solver.m_eigenvectorsOk = computeEigenvectors; - } -}; - -// 2x2 direct eigenvalues decomposition, code from Hauke Heibel -template struct direct_selfadjoint_eigenvalues -{ - typedef typename SolverType::MatrixType MatrixType; - typedef typename SolverType::RealVectorType VectorType; - typedef typename SolverType::Scalar Scalar; - typedef typename SolverType::EigenvectorsType EigenvectorsType; - - static inline void computeRoots(const MatrixType& m, VectorType& roots) - { - using std::sqrt; - const Scalar t0 = Scalar(0.5) * sqrt( numext::abs2(m(0,0)-m(1,1)) + Scalar(4)*numext::abs2(m(1,0))); - const Scalar t1 = Scalar(0.5) * (m(0,0) + m(1,1)); - roots(0) = t1 - t0; - roots(1) = t1 + t0; - } - - static inline void run(SolverType& solver, const MatrixType& mat, int options) - { - using std::sqrt; - using std::abs; - - eigen_assert(mat.cols() == 2 && mat.cols() == mat.rows()); - eigen_assert((options&~(EigVecMask|GenEigMask))==0 - && (options&EigVecMask)!=EigVecMask - && "invalid option parameter"); - bool computeEigenvectors = (options&ComputeEigenvectors)==ComputeEigenvectors; - - EigenvectorsType& eivecs = solver.m_eivec; - VectorType& eivals = solver.m_eivalues; - - // map the matrix coefficients to [-1:1] to avoid over- and underflow. - Scalar scale = mat.cwiseAbs().maxCoeff(); - scale = (std::max)(scale,Scalar(1)); - MatrixType scaledMat = mat / scale; - - // Compute the eigenvalues - computeRoots(scaledMat,eivals); - - // compute the eigen vectors - if(computeEigenvectors) - { - if((eivals(1)-eivals(0))<=abs(eivals(1))*Eigen::NumTraits::epsilon()) - { - eivecs.setIdentity(); - } - else - { - scaledMat.diagonal().array () -= eivals(1); - Scalar a2 = numext::abs2(scaledMat(0,0)); - Scalar c2 = numext::abs2(scaledMat(1,1)); - Scalar b2 = numext::abs2(scaledMat(1,0)); - if(a2>c2) - { - eivecs.col(1) << -scaledMat(1,0), scaledMat(0,0); - eivecs.col(1) /= sqrt(a2+b2); - } - else - { - eivecs.col(1) << -scaledMat(1,1), scaledMat(1,0); - eivecs.col(1) /= sqrt(c2+b2); - } - - eivecs.col(0) << eivecs.col(1).unitOrthogonal(); - } - } - - // Rescale back to the original size. - eivals *= scale; - - solver.m_info = Success; - solver.m_isInitialized = true; - solver.m_eigenvectorsOk = computeEigenvectors; - } -}; - -} - -template -SelfAdjointEigenSolver& SelfAdjointEigenSolver -::computeDirect(const MatrixType& matrix, int options) -{ - internal::direct_selfadjoint_eigenvalues::IsComplex>::run(*this,matrix,options); - return *this; -} - -namespace internal { -template -static void tridiagonal_qr_step(RealScalar* diag, RealScalar* subdiag, Index start, Index end, Scalar* matrixQ, Index n) -{ - using std::abs; - RealScalar td = (diag[end-1] - diag[end])*RealScalar(0.5); - RealScalar e = subdiag[end-1]; - // Note that thanks to scaling, e^2 or td^2 cannot overflow, however they can still - // underflow thus leading to inf/NaN values when using the following commented code: -// RealScalar e2 = numext::abs2(subdiag[end-1]); -// RealScalar mu = diag[end] - e2 / (td + (td>0 ? 1 : -1) * sqrt(td*td + e2)); - // This explain the following, somewhat more complicated, version: - RealScalar mu = diag[end]; - if(td==0) - mu -= abs(e); - else - { - RealScalar e2 = numext::abs2(subdiag[end-1]); - RealScalar h = numext::hypot(td,e); - if(e2==0) mu -= (e / (td + (td>0 ? 1 : -1))) * (e / h); - else mu -= e2 / (td + (td>0 ? h : -h)); - } - - RealScalar x = diag[start] - mu; - RealScalar z = subdiag[start]; - for (Index k = start; k < end; ++k) - { - JacobiRotation rot; - rot.makeGivens(x, z); - - // do T = G' T G - RealScalar sdk = rot.s() * diag[k] + rot.c() * subdiag[k]; - RealScalar dkp1 = rot.s() * subdiag[k] + rot.c() * diag[k+1]; - - diag[k] = rot.c() * (rot.c() * diag[k] - rot.s() * subdiag[k]) - rot.s() * (rot.c() * subdiag[k] - rot.s() * diag[k+1]); - diag[k+1] = rot.s() * sdk + rot.c() * dkp1; - subdiag[k] = rot.c() * sdk - rot.s() * dkp1; - - - if (k > start) - subdiag[k - 1] = rot.c() * subdiag[k-1] - rot.s() * z; - - x = subdiag[k]; - - if (k < end - 1) - { - z = -rot.s() * subdiag[k+1]; - subdiag[k + 1] = rot.c() * subdiag[k+1]; - } - - // apply the givens rotation to the unit matrix Q = Q * G - if (matrixQ) - { - Map > q(matrixQ,n,n); - q.applyOnTheRight(k,k+1,rot); - } - } -} - -} // end namespace internal - -} // end namespace Eigen - -#endif // EIGEN_SELFADJOINTEIGENSOLVER_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_MKL.h b/thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_MKL.h deleted file mode 100644 index 17c0dadd..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_MKL.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - Copyright (c) 2011, Intel Corporation. All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of Intel Corporation nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - ******************************************************************************** - * Content : Eigen bindings to Intel(R) MKL - * Self-adjoint eigenvalues/eigenvectors. - ******************************************************************************** -*/ - -#ifndef EIGEN_SAEIGENSOLVER_MKL_H -#define EIGEN_SAEIGENSOLVER_MKL_H - -#include "Eigen/src/Core/util/MKL_support.h" - -namespace Eigen { - -/** \internal Specialization for the data types supported by MKL */ - -#define EIGEN_MKL_EIG_SELFADJ(EIGTYPE, MKLTYPE, MKLRTYPE, MKLNAME, EIGCOLROW, MKLCOLROW ) \ -template<> inline \ -SelfAdjointEigenSolver >& \ -SelfAdjointEigenSolver >::compute(const Matrix& matrix, int options) \ -{ \ - eigen_assert(matrix.cols() == matrix.rows()); \ - eigen_assert((options&~(EigVecMask|GenEigMask))==0 \ - && (options&EigVecMask)!=EigVecMask \ - && "invalid option parameter"); \ - bool computeEigenvectors = (options&ComputeEigenvectors)==ComputeEigenvectors; \ - lapack_int n = matrix.cols(), lda, matrix_order, info; \ - m_eivalues.resize(n,1); \ - m_subdiag.resize(n-1); \ - m_eivec = matrix; \ -\ - if(n==1) \ - { \ - m_eivalues.coeffRef(0,0) = numext::real(matrix.coeff(0,0)); \ - if(computeEigenvectors) m_eivec.setOnes(n,n); \ - m_info = Success; \ - m_isInitialized = true; \ - m_eigenvectorsOk = computeEigenvectors; \ - return *this; \ - } \ -\ - lda = matrix.outerStride(); \ - matrix_order=MKLCOLROW; \ - char jobz, uplo='L'/*, range='A'*/; \ - jobz = computeEigenvectors ? 'V' : 'N'; \ -\ - info = LAPACKE_##MKLNAME( matrix_order, jobz, uplo, n, (MKLTYPE*)m_eivec.data(), lda, (MKLRTYPE*)m_eivalues.data() ); \ - m_info = (info==0) ? Success : NoConvergence; \ - m_isInitialized = true; \ - m_eigenvectorsOk = computeEigenvectors; \ - return *this; \ -} - - -EIGEN_MKL_EIG_SELFADJ(double, double, double, dsyev, ColMajor, LAPACK_COL_MAJOR) -EIGEN_MKL_EIG_SELFADJ(float, float, float, ssyev, ColMajor, LAPACK_COL_MAJOR) -EIGEN_MKL_EIG_SELFADJ(dcomplex, MKL_Complex16, double, zheev, ColMajor, LAPACK_COL_MAJOR) -EIGEN_MKL_EIG_SELFADJ(scomplex, MKL_Complex8, float, cheev, ColMajor, LAPACK_COL_MAJOR) - -EIGEN_MKL_EIG_SELFADJ(double, double, double, dsyev, RowMajor, LAPACK_ROW_MAJOR) -EIGEN_MKL_EIG_SELFADJ(float, float, float, ssyev, RowMajor, LAPACK_ROW_MAJOR) -EIGEN_MKL_EIG_SELFADJ(dcomplex, MKL_Complex16, double, zheev, RowMajor, LAPACK_ROW_MAJOR) -EIGEN_MKL_EIG_SELFADJ(scomplex, MKL_Complex8, float, cheev, RowMajor, LAPACK_ROW_MAJOR) - -} // end namespace Eigen - -#endif // EIGEN_SAEIGENSOLVER_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/Tridiagonalization.h b/thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/Tridiagonalization.h deleted file mode 100644 index 192278d6..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/Tridiagonalization.h +++ /dev/null @@ -1,557 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud -// Copyright (C) 2010 Jitse Niesen -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_TRIDIAGONALIZATION_H -#define EIGEN_TRIDIAGONALIZATION_H - -namespace Eigen { - -namespace internal { - -template struct TridiagonalizationMatrixTReturnType; -template -struct traits > -{ - typedef typename MatrixType::PlainObject ReturnType; -}; - -template -void tridiagonalization_inplace(MatrixType& matA, CoeffVectorType& hCoeffs); -} - -/** \eigenvalues_module \ingroup Eigenvalues_Module - * - * - * \class Tridiagonalization - * - * \brief Tridiagonal decomposition of a selfadjoint matrix - * - * \tparam _MatrixType the type of the matrix of which we are computing the - * tridiagonal decomposition; this is expected to be an instantiation of the - * Matrix class template. - * - * This class performs a tridiagonal decomposition of a selfadjoint matrix \f$ A \f$ such that: - * \f$ A = Q T Q^* \f$ where \f$ Q \f$ is unitary and \f$ T \f$ a real symmetric tridiagonal matrix. - * - * A tridiagonal matrix is a matrix which has nonzero elements only on the - * main diagonal and the first diagonal below and above it. The Hessenberg - * decomposition of a selfadjoint matrix is in fact a tridiagonal - * decomposition. This class is used in SelfAdjointEigenSolver to compute the - * eigenvalues and eigenvectors of a selfadjoint matrix. - * - * Call the function compute() to compute the tridiagonal decomposition of a - * given matrix. Alternatively, you can use the Tridiagonalization(const MatrixType&) - * constructor which computes the tridiagonal Schur decomposition at - * construction time. Once the decomposition is computed, you can use the - * matrixQ() and matrixT() functions to retrieve the matrices Q and T in the - * decomposition. - * - * The documentation of Tridiagonalization(const MatrixType&) contains an - * example of the typical use of this class. - * - * \sa class HessenbergDecomposition, class SelfAdjointEigenSolver - */ -template class Tridiagonalization -{ - public: - - /** \brief Synonym for the template parameter \p _MatrixType. */ - typedef _MatrixType MatrixType; - - typedef typename MatrixType::Scalar Scalar; - typedef typename NumTraits::Real RealScalar; - typedef typename MatrixType::Index Index; - - enum { - Size = MatrixType::RowsAtCompileTime, - SizeMinusOne = Size == Dynamic ? Dynamic : (Size > 1 ? Size - 1 : 1), - Options = MatrixType::Options, - MaxSize = MatrixType::MaxRowsAtCompileTime, - MaxSizeMinusOne = MaxSize == Dynamic ? Dynamic : (MaxSize > 1 ? MaxSize - 1 : 1) - }; - - typedef Matrix CoeffVectorType; - typedef typename internal::plain_col_type::type DiagonalType; - typedef Matrix SubDiagonalType; - typedef typename internal::remove_all::type MatrixTypeRealView; - typedef internal::TridiagonalizationMatrixTReturnType MatrixTReturnType; - - typedef typename internal::conditional::IsComplex, - typename internal::add_const_on_value_type::RealReturnType>::type, - const Diagonal - >::type DiagonalReturnType; - - typedef typename internal::conditional::IsComplex, - typename internal::add_const_on_value_type >::RealReturnType>::type, - const Diagonal< - Block > - >::type SubDiagonalReturnType; - - /** \brief Return type of matrixQ() */ - typedef HouseholderSequence::type> HouseholderSequenceType; - - /** \brief Default constructor. - * - * \param [in] size Positive integer, size of the matrix whose tridiagonal - * decomposition will be computed. - * - * The default constructor is useful in cases in which the user intends to - * perform decompositions via compute(). The \p size parameter is only - * used as a hint. It is not an error to give a wrong \p size, but it may - * impair performance. - * - * \sa compute() for an example. - */ - Tridiagonalization(Index size = Size==Dynamic ? 2 : Size) - : m_matrix(size,size), - m_hCoeffs(size > 1 ? size-1 : 1), - m_isInitialized(false) - {} - - /** \brief Constructor; computes tridiagonal decomposition of given matrix. - * - * \param[in] matrix Selfadjoint matrix whose tridiagonal decomposition - * is to be computed. - * - * This constructor calls compute() to compute the tridiagonal decomposition. - * - * Example: \include Tridiagonalization_Tridiagonalization_MatrixType.cpp - * Output: \verbinclude Tridiagonalization_Tridiagonalization_MatrixType.out - */ - Tridiagonalization(const MatrixType& matrix) - : m_matrix(matrix), - m_hCoeffs(matrix.cols() > 1 ? matrix.cols()-1 : 1), - m_isInitialized(false) - { - internal::tridiagonalization_inplace(m_matrix, m_hCoeffs); - m_isInitialized = true; - } - - /** \brief Computes tridiagonal decomposition of given matrix. - * - * \param[in] matrix Selfadjoint matrix whose tridiagonal decomposition - * is to be computed. - * \returns Reference to \c *this - * - * The tridiagonal decomposition is computed by bringing the columns of - * the matrix successively in the required form using Householder - * reflections. The cost is \f$ 4n^3/3 \f$ flops, where \f$ n \f$ denotes - * the size of the given matrix. - * - * This method reuses of the allocated data in the Tridiagonalization - * object, if the size of the matrix does not change. - * - * Example: \include Tridiagonalization_compute.cpp - * Output: \verbinclude Tridiagonalization_compute.out - */ - Tridiagonalization& compute(const MatrixType& matrix) - { - m_matrix = matrix; - m_hCoeffs.resize(matrix.rows()-1, 1); - internal::tridiagonalization_inplace(m_matrix, m_hCoeffs); - m_isInitialized = true; - return *this; - } - - /** \brief Returns the Householder coefficients. - * - * \returns a const reference to the vector of Householder coefficients - * - * \pre Either the constructor Tridiagonalization(const MatrixType&) or - * the member function compute(const MatrixType&) has been called before - * to compute the tridiagonal decomposition of a matrix. - * - * The Householder coefficients allow the reconstruction of the matrix - * \f$ Q \f$ in the tridiagonal decomposition from the packed data. - * - * Example: \include Tridiagonalization_householderCoefficients.cpp - * Output: \verbinclude Tridiagonalization_householderCoefficients.out - * - * \sa packedMatrix(), \ref Householder_Module "Householder module" - */ - inline CoeffVectorType householderCoefficients() const - { - eigen_assert(m_isInitialized && "Tridiagonalization is not initialized."); - return m_hCoeffs; - } - - /** \brief Returns the internal representation of the decomposition - * - * \returns a const reference to a matrix with the internal representation - * of the decomposition. - * - * \pre Either the constructor Tridiagonalization(const MatrixType&) or - * the member function compute(const MatrixType&) has been called before - * to compute the tridiagonal decomposition of a matrix. - * - * The returned matrix contains the following information: - * - the strict upper triangular part is equal to the input matrix A. - * - the diagonal and lower sub-diagonal represent the real tridiagonal - * symmetric matrix T. - * - the rest of the lower part contains the Householder vectors that, - * combined with Householder coefficients returned by - * householderCoefficients(), allows to reconstruct the matrix Q as - * \f$ Q = H_{N-1} \ldots H_1 H_0 \f$. - * Here, the matrices \f$ H_i \f$ are the Householder transformations - * \f$ H_i = (I - h_i v_i v_i^T) \f$ - * where \f$ h_i \f$ is the \f$ i \f$th Householder coefficient and - * \f$ v_i \f$ is the Householder vector defined by - * \f$ v_i = [ 0, \ldots, 0, 1, M(i+2,i), \ldots, M(N-1,i) ]^T \f$ - * with M the matrix returned by this function. - * - * See LAPACK for further details on this packed storage. - * - * Example: \include Tridiagonalization_packedMatrix.cpp - * Output: \verbinclude Tridiagonalization_packedMatrix.out - * - * \sa householderCoefficients() - */ - inline const MatrixType& packedMatrix() const - { - eigen_assert(m_isInitialized && "Tridiagonalization is not initialized."); - return m_matrix; - } - - /** \brief Returns the unitary matrix Q in the decomposition - * - * \returns object representing the matrix Q - * - * \pre Either the constructor Tridiagonalization(const MatrixType&) or - * the member function compute(const MatrixType&) has been called before - * to compute the tridiagonal decomposition of a matrix. - * - * This function returns a light-weight object of template class - * HouseholderSequence. You can either apply it directly to a matrix or - * you can convert it to a matrix of type #MatrixType. - * - * \sa Tridiagonalization(const MatrixType&) for an example, - * matrixT(), class HouseholderSequence - */ - HouseholderSequenceType matrixQ() const - { - eigen_assert(m_isInitialized && "Tridiagonalization is not initialized."); - return HouseholderSequenceType(m_matrix, m_hCoeffs.conjugate()) - .setLength(m_matrix.rows() - 1) - .setShift(1); - } - - /** \brief Returns an expression of the tridiagonal matrix T in the decomposition - * - * \returns expression object representing the matrix T - * - * \pre Either the constructor Tridiagonalization(const MatrixType&) or - * the member function compute(const MatrixType&) has been called before - * to compute the tridiagonal decomposition of a matrix. - * - * Currently, this function can be used to extract the matrix T from internal - * data and copy it to a dense matrix object. In most cases, it may be - * sufficient to directly use the packed matrix or the vector expressions - * returned by diagonal() and subDiagonal() instead of creating a new - * dense copy matrix with this function. - * - * \sa Tridiagonalization(const MatrixType&) for an example, - * matrixQ(), packedMatrix(), diagonal(), subDiagonal() - */ - MatrixTReturnType matrixT() const - { - eigen_assert(m_isInitialized && "Tridiagonalization is not initialized."); - return MatrixTReturnType(m_matrix.real()); - } - - /** \brief Returns the diagonal of the tridiagonal matrix T in the decomposition. - * - * \returns expression representing the diagonal of T - * - * \pre Either the constructor Tridiagonalization(const MatrixType&) or - * the member function compute(const MatrixType&) has been called before - * to compute the tridiagonal decomposition of a matrix. - * - * Example: \include Tridiagonalization_diagonal.cpp - * Output: \verbinclude Tridiagonalization_diagonal.out - * - * \sa matrixT(), subDiagonal() - */ - DiagonalReturnType diagonal() const; - - /** \brief Returns the subdiagonal of the tridiagonal matrix T in the decomposition. - * - * \returns expression representing the subdiagonal of T - * - * \pre Either the constructor Tridiagonalization(const MatrixType&) or - * the member function compute(const MatrixType&) has been called before - * to compute the tridiagonal decomposition of a matrix. - * - * \sa diagonal() for an example, matrixT() - */ - SubDiagonalReturnType subDiagonal() const; - - protected: - - MatrixType m_matrix; - CoeffVectorType m_hCoeffs; - bool m_isInitialized; -}; - -template -typename Tridiagonalization::DiagonalReturnType -Tridiagonalization::diagonal() const -{ - eigen_assert(m_isInitialized && "Tridiagonalization is not initialized."); - return m_matrix.diagonal(); -} - -template -typename Tridiagonalization::SubDiagonalReturnType -Tridiagonalization::subDiagonal() const -{ - eigen_assert(m_isInitialized && "Tridiagonalization is not initialized."); - Index n = m_matrix.rows(); - return Block(m_matrix, 1, 0, n-1,n-1).diagonal(); -} - -namespace internal { - -/** \internal - * Performs a tridiagonal decomposition of the selfadjoint matrix \a matA in-place. - * - * \param[in,out] matA On input the selfadjoint matrix. Only the \b lower triangular part is referenced. - * On output, the strict upper part is left unchanged, and the lower triangular part - * represents the T and Q matrices in packed format has detailed below. - * \param[out] hCoeffs returned Householder coefficients (see below) - * - * On output, the tridiagonal selfadjoint matrix T is stored in the diagonal - * and lower sub-diagonal of the matrix \a matA. - * The unitary matrix Q is represented in a compact way as a product of - * Householder reflectors \f$ H_i \f$ such that: - * \f$ Q = H_{N-1} \ldots H_1 H_0 \f$. - * The Householder reflectors are defined as - * \f$ H_i = (I - h_i v_i v_i^T) \f$ - * where \f$ h_i = hCoeffs[i]\f$ is the \f$ i \f$th Householder coefficient and - * \f$ v_i \f$ is the Householder vector defined by - * \f$ v_i = [ 0, \ldots, 0, 1, matA(i+2,i), \ldots, matA(N-1,i) ]^T \f$. - * - * Implemented from Golub's "Matrix Computations", algorithm 8.3.1. - * - * \sa Tridiagonalization::packedMatrix() - */ -template -void tridiagonalization_inplace(MatrixType& matA, CoeffVectorType& hCoeffs) -{ - using numext::conj; - typedef typename MatrixType::Index Index; - typedef typename MatrixType::Scalar Scalar; - typedef typename MatrixType::RealScalar RealScalar; - Index n = matA.rows(); - eigen_assert(n==matA.cols()); - eigen_assert(n==hCoeffs.size()+1 || n==1); - - for (Index i = 0; i() - * (conj(h) * matA.col(i).tail(remainingSize))); - - hCoeffs.tail(n-i-1) += (conj(h)*Scalar(-0.5)*(hCoeffs.tail(remainingSize).dot(matA.col(i).tail(remainingSize)))) * matA.col(i).tail(n-i-1); - - matA.bottomRightCorner(remainingSize, remainingSize).template selfadjointView() - .rankUpdate(matA.col(i).tail(remainingSize), hCoeffs.tail(remainingSize), -1); - - matA.col(i).coeffRef(i+1) = beta; - hCoeffs.coeffRef(i) = h; - } -} - -// forward declaration, implementation at the end of this file -template::IsComplex> -struct tridiagonalization_inplace_selector; - -/** \brief Performs a full tridiagonalization in place - * - * \param[in,out] mat On input, the selfadjoint matrix whose tridiagonal - * decomposition is to be computed. Only the lower triangular part referenced. - * The rest is left unchanged. On output, the orthogonal matrix Q - * in the decomposition if \p extractQ is true. - * \param[out] diag The diagonal of the tridiagonal matrix T in the - * decomposition. - * \param[out] subdiag The subdiagonal of the tridiagonal matrix T in - * the decomposition. - * \param[in] extractQ If true, the orthogonal matrix Q in the - * decomposition is computed and stored in \p mat. - * - * Computes the tridiagonal decomposition of the selfadjoint matrix \p mat in place - * such that \f$ mat = Q T Q^* \f$ where \f$ Q \f$ is unitary and \f$ T \f$ a real - * symmetric tridiagonal matrix. - * - * The tridiagonal matrix T is passed to the output parameters \p diag and \p subdiag. If - * \p extractQ is true, then the orthogonal matrix Q is passed to \p mat. Otherwise the lower - * part of the matrix \p mat is destroyed. - * - * The vectors \p diag and \p subdiag are not resized. The function - * assumes that they are already of the correct size. The length of the - * vector \p diag should equal the number of rows in \p mat, and the - * length of the vector \p subdiag should be one left. - * - * This implementation contains an optimized path for 3-by-3 matrices - * which is especially useful for plane fitting. - * - * \note Currently, it requires two temporary vectors to hold the intermediate - * Householder coefficients, and to reconstruct the matrix Q from the Householder - * reflectors. - * - * Example (this uses the same matrix as the example in - * Tridiagonalization::Tridiagonalization(const MatrixType&)): - * \include Tridiagonalization_decomposeInPlace.cpp - * Output: \verbinclude Tridiagonalization_decomposeInPlace.out - * - * \sa class Tridiagonalization - */ -template -void tridiagonalization_inplace(MatrixType& mat, DiagonalType& diag, SubDiagonalType& subdiag, bool extractQ) -{ - eigen_assert(mat.cols()==mat.rows() && diag.size()==mat.rows() && subdiag.size()==mat.rows()-1); - tridiagonalization_inplace_selector::run(mat, diag, subdiag, extractQ); -} - -/** \internal - * General full tridiagonalization - */ -template -struct tridiagonalization_inplace_selector -{ - typedef typename Tridiagonalization::CoeffVectorType CoeffVectorType; - typedef typename Tridiagonalization::HouseholderSequenceType HouseholderSequenceType; - typedef typename MatrixType::Index Index; - template - static void run(MatrixType& mat, DiagonalType& diag, SubDiagonalType& subdiag, bool extractQ) - { - CoeffVectorType hCoeffs(mat.cols()-1); - tridiagonalization_inplace(mat,hCoeffs); - diag = mat.diagonal().real(); - subdiag = mat.template diagonal<-1>().real(); - if(extractQ) - mat = HouseholderSequenceType(mat, hCoeffs.conjugate()) - .setLength(mat.rows() - 1) - .setShift(1); - } -}; - -/** \internal - * Specialization for 3x3 real matrices. - * Especially useful for plane fitting. - */ -template -struct tridiagonalization_inplace_selector -{ - typedef typename MatrixType::Scalar Scalar; - typedef typename MatrixType::RealScalar RealScalar; - - template - static void run(MatrixType& mat, DiagonalType& diag, SubDiagonalType& subdiag, bool extractQ) - { - using std::sqrt; - diag[0] = mat(0,0); - RealScalar v1norm2 = numext::abs2(mat(2,0)); - if(v1norm2 == RealScalar(0)) - { - diag[1] = mat(1,1); - diag[2] = mat(2,2); - subdiag[0] = mat(1,0); - subdiag[1] = mat(2,1); - if (extractQ) - mat.setIdentity(); - } - else - { - RealScalar beta = sqrt(numext::abs2(mat(1,0)) + v1norm2); - RealScalar invBeta = RealScalar(1)/beta; - Scalar m01 = mat(1,0) * invBeta; - Scalar m02 = mat(2,0) * invBeta; - Scalar q = RealScalar(2)*m01*mat(2,1) + m02*(mat(2,2) - mat(1,1)); - diag[1] = mat(1,1) + m02*q; - diag[2] = mat(2,2) - m02*q; - subdiag[0] = beta; - subdiag[1] = mat(2,1) - m01 * q; - if (extractQ) - { - mat << 1, 0, 0, - 0, m01, m02, - 0, m02, -m01; - } - } - } -}; - -/** \internal - * Trivial specialization for 1x1 matrices - */ -template -struct tridiagonalization_inplace_selector -{ - typedef typename MatrixType::Scalar Scalar; - - template - static void run(MatrixType& mat, DiagonalType& diag, SubDiagonalType&, bool extractQ) - { - diag(0,0) = numext::real(mat(0,0)); - if(extractQ) - mat(0,0) = Scalar(1); - } -}; - -/** \internal - * \eigenvalues_module \ingroup Eigenvalues_Module - * - * \brief Expression type for return value of Tridiagonalization::matrixT() - * - * \tparam MatrixType type of underlying dense matrix - */ -template struct TridiagonalizationMatrixTReturnType -: public ReturnByValue > -{ - typedef typename MatrixType::Index Index; - public: - /** \brief Constructor. - * - * \param[in] mat The underlying dense matrix - */ - TridiagonalizationMatrixTReturnType(const MatrixType& mat) : m_matrix(mat) { } - - template - inline void evalTo(ResultType& result) const - { - result.setZero(); - result.template diagonal<1>() = m_matrix.template diagonal<-1>().conjugate(); - result.diagonal() = m_matrix.diagonal(); - result.template diagonal<-1>() = m_matrix.template diagonal<-1>(); - } - - Index rows() const { return m_matrix.rows(); } - Index cols() const { return m_matrix.cols(); } - - protected: - typename MatrixType::Nested m_matrix; -}; - -} // end namespace internal - -} // end namespace Eigen - -#endif // EIGEN_TRIDIAGONALIZATION_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Geometry/AlignedBox.h b/thirdparty/eigen-3.2.7/Eigen/src/Geometry/AlignedBox.h deleted file mode 100644 index 7e1cd9eb..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Geometry/AlignedBox.h +++ /dev/null @@ -1,392 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_ALIGNEDBOX_H -#define EIGEN_ALIGNEDBOX_H - -namespace Eigen { - -/** \geometry_module \ingroup Geometry_Module - * - * - * \class AlignedBox - * - * \brief An axis aligned box - * - * \tparam _Scalar the type of the scalar coefficients - * \tparam _AmbientDim the dimension of the ambient space, can be a compile time value or Dynamic. - * - * This class represents an axis aligned box as a pair of the minimal and maximal corners. - * \warning The result of most methods is undefined when applied to an empty box. You can check for empty boxes using isEmpty(). - * \sa alignedboxtypedefs - */ -template -class AlignedBox -{ -public: -EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim) - enum { AmbientDimAtCompileTime = _AmbientDim }; - typedef _Scalar Scalar; - typedef NumTraits ScalarTraits; - typedef DenseIndex Index; - typedef typename ScalarTraits::Real RealScalar; - typedef typename ScalarTraits::NonInteger NonInteger; - typedef Matrix VectorType; - - /** Define constants to name the corners of a 1D, 2D or 3D axis aligned bounding box */ - enum CornerType - { - /** 1D names @{ */ - Min=0, Max=1, - /** @} */ - - /** Identifier for 2D corner @{ */ - BottomLeft=0, BottomRight=1, - TopLeft=2, TopRight=3, - /** @} */ - - /** Identifier for 3D corner @{ */ - BottomLeftFloor=0, BottomRightFloor=1, - TopLeftFloor=2, TopRightFloor=3, - BottomLeftCeil=4, BottomRightCeil=5, - TopLeftCeil=6, TopRightCeil=7 - /** @} */ - }; - - - /** Default constructor initializing a null box. */ - inline AlignedBox() - { if (AmbientDimAtCompileTime!=Dynamic) setEmpty(); } - - /** Constructs a null box with \a _dim the dimension of the ambient space. */ - inline explicit AlignedBox(Index _dim) : m_min(_dim), m_max(_dim) - { setEmpty(); } - - /** Constructs a box with extremities \a _min and \a _max. - * \warning If either component of \a _min is larger than the same component of \a _max, the constructed box is empty. */ - template - inline AlignedBox(const OtherVectorType1& _min, const OtherVectorType2& _max) : m_min(_min), m_max(_max) {} - - /** Constructs a box containing a single point \a p. */ - template - inline explicit AlignedBox(const MatrixBase& p) : m_min(p), m_max(m_min) - { } - - ~AlignedBox() {} - - /** \returns the dimension in which the box holds */ - inline Index dim() const { return AmbientDimAtCompileTime==Dynamic ? m_min.size() : Index(AmbientDimAtCompileTime); } - - /** \deprecated use isEmpty() */ - inline bool isNull() const { return isEmpty(); } - - /** \deprecated use setEmpty() */ - inline void setNull() { setEmpty(); } - - /** \returns true if the box is empty. - * \sa setEmpty */ - inline bool isEmpty() const { return (m_min.array() > m_max.array()).any(); } - - /** Makes \c *this an empty box. - * \sa isEmpty */ - inline void setEmpty() - { - m_min.setConstant( ScalarTraits::highest() ); - m_max.setConstant( ScalarTraits::lowest() ); - } - - /** \returns the minimal corner */ - inline const VectorType& (min)() const { return m_min; } - /** \returns a non const reference to the minimal corner */ - inline VectorType& (min)() { return m_min; } - /** \returns the maximal corner */ - inline const VectorType& (max)() const { return m_max; } - /** \returns a non const reference to the maximal corner */ - inline VectorType& (max)() { return m_max; } - - /** \returns the center of the box */ - inline const CwiseUnaryOp, - const CwiseBinaryOp, const VectorType, const VectorType> > - center() const - { return (m_min+m_max)/2; } - - /** \returns the lengths of the sides of the bounding box. - * Note that this function does not get the same - * result for integral or floating scalar types: see - */ - inline const CwiseBinaryOp< internal::scalar_difference_op, const VectorType, const VectorType> sizes() const - { return m_max - m_min; } - - /** \returns the volume of the bounding box */ - inline Scalar volume() const - { return sizes().prod(); } - - /** \returns an expression for the bounding box diagonal vector - * if the length of the diagonal is needed: diagonal().norm() - * will provide it. - */ - inline CwiseBinaryOp< internal::scalar_difference_op, const VectorType, const VectorType> diagonal() const - { return sizes(); } - - /** \returns the vertex of the bounding box at the corner defined by - * the corner-id corner. It works only for a 1D, 2D or 3D bounding box. - * For 1D bounding boxes corners are named by 2 enum constants: - * BottomLeft and BottomRight. - * For 2D bounding boxes, corners are named by 4 enum constants: - * BottomLeft, BottomRight, TopLeft, TopRight. - * For 3D bounding boxes, the following names are added: - * BottomLeftCeil, BottomRightCeil, TopLeftCeil, TopRightCeil. - */ - inline VectorType corner(CornerType corner) const - { - EIGEN_STATIC_ASSERT(_AmbientDim <= 3, THIS_METHOD_IS_ONLY_FOR_VECTORS_OF_A_SPECIFIC_SIZE); - - VectorType res; - - Index mult = 1; - for(Index d=0; d(Scalar(0), Scalar(1)); - } - else - r[d] = internal::random(m_min[d], m_max[d]); - } - return r; - } - - /** \returns true if the point \a p is inside the box \c *this. */ - template - inline bool contains(const MatrixBase& p) const - { - typename internal::nested::type p_n(p.derived()); - return (m_min.array()<=p_n.array()).all() && (p_n.array()<=m_max.array()).all(); - } - - /** \returns true if the box \a b is entirely inside the box \c *this. */ - inline bool contains(const AlignedBox& b) const - { return (m_min.array()<=(b.min)().array()).all() && ((b.max)().array()<=m_max.array()).all(); } - - /** \returns true if the box \a b is intersecting the box \c *this. - * \sa intersection, clamp */ - inline bool intersects(const AlignedBox& b) const - { return (m_min.array()<=(b.max)().array()).all() && ((b.min)().array()<=m_max.array()).all(); } - - /** Extends \c *this such that it contains the point \a p and returns a reference to \c *this. - * \sa extend(const AlignedBox&) */ - template - inline AlignedBox& extend(const MatrixBase& p) - { - typename internal::nested::type p_n(p.derived()); - m_min = m_min.cwiseMin(p_n); - m_max = m_max.cwiseMax(p_n); - return *this; - } - - /** Extends \c *this such that it contains the box \a b and returns a reference to \c *this. - * \sa merged, extend(const MatrixBase&) */ - inline AlignedBox& extend(const AlignedBox& b) - { - m_min = m_min.cwiseMin(b.m_min); - m_max = m_max.cwiseMax(b.m_max); - return *this; - } - - /** Clamps \c *this by the box \a b and returns a reference to \c *this. - * \note If the boxes don't intersect, the resulting box is empty. - * \sa intersection(), intersects() */ - inline AlignedBox& clamp(const AlignedBox& b) - { - m_min = m_min.cwiseMax(b.m_min); - m_max = m_max.cwiseMin(b.m_max); - return *this; - } - - /** Returns an AlignedBox that is the intersection of \a b and \c *this - * \note If the boxes don't intersect, the resulting box is empty. - * \sa intersects(), clamp, contains() */ - inline AlignedBox intersection(const AlignedBox& b) const - {return AlignedBox(m_min.cwiseMax(b.m_min), m_max.cwiseMin(b.m_max)); } - - /** Returns an AlignedBox that is the union of \a b and \c *this. - * \note Merging with an empty box may result in a box bigger than \c *this. - * \sa extend(const AlignedBox&) */ - inline AlignedBox merged(const AlignedBox& b) const - { return AlignedBox(m_min.cwiseMin(b.m_min), m_max.cwiseMax(b.m_max)); } - - /** Translate \c *this by the vector \a t and returns a reference to \c *this. */ - template - inline AlignedBox& translate(const MatrixBase& a_t) - { - const typename internal::nested::type t(a_t.derived()); - m_min += t; - m_max += t; - return *this; - } - - /** \returns the squared distance between the point \a p and the box \c *this, - * and zero if \a p is inside the box. - * \sa exteriorDistance(const MatrixBase&), squaredExteriorDistance(const AlignedBox&) - */ - template - inline Scalar squaredExteriorDistance(const MatrixBase& p) const; - - /** \returns the squared distance between the boxes \a b and \c *this, - * and zero if the boxes intersect. - * \sa exteriorDistance(const AlignedBox&), squaredExteriorDistance(const MatrixBase&) - */ - inline Scalar squaredExteriorDistance(const AlignedBox& b) const; - - /** \returns the distance between the point \a p and the box \c *this, - * and zero if \a p is inside the box. - * \sa squaredExteriorDistance(const MatrixBase&), exteriorDistance(const AlignedBox&) - */ - template - inline NonInteger exteriorDistance(const MatrixBase& p) const - { using std::sqrt; return sqrt(NonInteger(squaredExteriorDistance(p))); } - - /** \returns the distance between the boxes \a b and \c *this, - * and zero if the boxes intersect. - * \sa squaredExteriorDistance(const AlignedBox&), exteriorDistance(const MatrixBase&) - */ - inline NonInteger exteriorDistance(const AlignedBox& b) const - { using std::sqrt; return sqrt(NonInteger(squaredExteriorDistance(b))); } - - /** \returns \c *this with scalar type casted to \a NewScalarType - * - * Note that if \a NewScalarType is equal to the current scalar type of \c *this - * then this function smartly returns a const reference to \c *this. - */ - template - inline typename internal::cast_return_type >::type cast() const - { - return typename internal::cast_return_type >::type(*this); - } - - /** Copy constructor with scalar type conversion */ - template - inline explicit AlignedBox(const AlignedBox& other) - { - m_min = (other.min)().template cast(); - m_max = (other.max)().template cast(); - } - - /** \returns \c true if \c *this is approximately equal to \a other, within the precision - * determined by \a prec. - * - * \sa MatrixBase::isApprox() */ - bool isApprox(const AlignedBox& other, const RealScalar& prec = ScalarTraits::dummy_precision()) const - { return m_min.isApprox(other.m_min, prec) && m_max.isApprox(other.m_max, prec); } - -protected: - - VectorType m_min, m_max; -}; - - - -template -template -inline Scalar AlignedBox::squaredExteriorDistance(const MatrixBase& a_p) const -{ - typename internal::nested::type p(a_p.derived()); - Scalar dist2(0); - Scalar aux; - for (Index k=0; k p[k] ) - { - aux = m_min[k] - p[k]; - dist2 += aux*aux; - } - else if( p[k] > m_max[k] ) - { - aux = p[k] - m_max[k]; - dist2 += aux*aux; - } - } - return dist2; -} - -template -inline Scalar AlignedBox::squaredExteriorDistance(const AlignedBox& b) const -{ - Scalar dist2(0); - Scalar aux; - for (Index k=0; k b.m_max[k] ) - { - aux = m_min[k] - b.m_max[k]; - dist2 += aux*aux; - } - else if( b.m_min[k] > m_max[k] ) - { - aux = b.m_min[k] - m_max[k]; - dist2 += aux*aux; - } - } - return dist2; -} - -/** \defgroup alignedboxtypedefs Global aligned box typedefs - * - * \ingroup Geometry_Module - * - * Eigen defines several typedef shortcuts for most common aligned box types. - * - * The general patterns are the following: - * - * \c AlignedBoxSizeType where \c Size can be \c 1, \c 2,\c 3,\c 4 for fixed size boxes or \c X for dynamic size, - * and where \c Type can be \c i for integer, \c f for float, \c d for double. - * - * For example, \c AlignedBox3d is a fixed-size 3x3 aligned box type of doubles, and \c AlignedBoxXf is a dynamic-size aligned box of floats. - * - * \sa class AlignedBox - */ - -#define EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, Size, SizeSuffix) \ -/** \ingroup alignedboxtypedefs */ \ -typedef AlignedBox AlignedBox##SizeSuffix##TypeSuffix; - -#define EIGEN_MAKE_TYPEDEFS_ALL_SIZES(Type, TypeSuffix) \ -EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, 1, 1) \ -EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, 2, 2) \ -EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, 3, 3) \ -EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, 4, 4) \ -EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, Dynamic, X) - -EIGEN_MAKE_TYPEDEFS_ALL_SIZES(int, i) -EIGEN_MAKE_TYPEDEFS_ALL_SIZES(float, f) -EIGEN_MAKE_TYPEDEFS_ALL_SIZES(double, d) - -#undef EIGEN_MAKE_TYPEDEFS_ALL_SIZES -#undef EIGEN_MAKE_TYPEDEFS - -} // end namespace Eigen - -#endif // EIGEN_ALIGNEDBOX_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Geometry/AngleAxis.h b/thirdparty/eigen-3.2.7/Eigen/src/Geometry/AngleAxis.h deleted file mode 100644 index bbf6a7ed..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Geometry/AngleAxis.h +++ /dev/null @@ -1,233 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_ANGLEAXIS_H -#define EIGEN_ANGLEAXIS_H - -namespace Eigen { - -/** \geometry_module \ingroup Geometry_Module - * - * \class AngleAxis - * - * \brief Represents a 3D rotation as a rotation angle around an arbitrary 3D axis - * - * \param _Scalar the scalar type, i.e., the type of the coefficients. - * - * \warning When setting up an AngleAxis object, the axis vector \b must \b be \b normalized. - * - * The following two typedefs are provided for convenience: - * \li \c AngleAxisf for \c float - * \li \c AngleAxisd for \c double - * - * Combined with MatrixBase::Unit{X,Y,Z}, AngleAxis can be used to easily - * mimic Euler-angles. Here is an example: - * \include AngleAxis_mimic_euler.cpp - * Output: \verbinclude AngleAxis_mimic_euler.out - * - * \note This class is not aimed to be used to store a rotation transformation, - * but rather to make easier the creation of other rotation (Quaternion, rotation Matrix) - * and transformation objects. - * - * \sa class Quaternion, class Transform, MatrixBase::UnitX() - */ - -namespace internal { -template struct traits > -{ - typedef _Scalar Scalar; -}; -} - -template -class AngleAxis : public RotationBase,3> -{ - typedef RotationBase,3> Base; - -public: - - using Base::operator*; - - enum { Dim = 3 }; - /** the scalar type of the coefficients */ - typedef _Scalar Scalar; - typedef Matrix Matrix3; - typedef Matrix Vector3; - typedef Quaternion QuaternionType; - -protected: - - Vector3 m_axis; - Scalar m_angle; - -public: - - /** Default constructor without initialization. */ - AngleAxis() {} - /** Constructs and initialize the angle-axis rotation from an \a angle in radian - * and an \a axis which \b must \b be \b normalized. - * - * \warning If the \a axis vector is not normalized, then the angle-axis object - * represents an invalid rotation. */ - template - inline AngleAxis(const Scalar& angle, const MatrixBase& axis) : m_axis(axis), m_angle(angle) {} - /** Constructs and initialize the angle-axis rotation from a quaternion \a q. */ - template inline explicit AngleAxis(const QuaternionBase& q) { *this = q; } - /** Constructs and initialize the angle-axis rotation from a 3x3 rotation matrix. */ - template - inline explicit AngleAxis(const MatrixBase& m) { *this = m; } - - Scalar angle() const { return m_angle; } - Scalar& angle() { return m_angle; } - - const Vector3& axis() const { return m_axis; } - Vector3& axis() { return m_axis; } - - /** Concatenates two rotations */ - inline QuaternionType operator* (const AngleAxis& other) const - { return QuaternionType(*this) * QuaternionType(other); } - - /** Concatenates two rotations */ - inline QuaternionType operator* (const QuaternionType& other) const - { return QuaternionType(*this) * other; } - - /** Concatenates two rotations */ - friend inline QuaternionType operator* (const QuaternionType& a, const AngleAxis& b) - { return a * QuaternionType(b); } - - /** \returns the inverse rotation, i.e., an angle-axis with opposite rotation angle */ - AngleAxis inverse() const - { return AngleAxis(-m_angle, m_axis); } - - template - AngleAxis& operator=(const QuaternionBase& q); - template - AngleAxis& operator=(const MatrixBase& m); - - template - AngleAxis& fromRotationMatrix(const MatrixBase& m); - Matrix3 toRotationMatrix(void) const; - - /** \returns \c *this with scalar type casted to \a NewScalarType - * - * Note that if \a NewScalarType is equal to the current scalar type of \c *this - * then this function smartly returns a const reference to \c *this. - */ - template - inline typename internal::cast_return_type >::type cast() const - { return typename internal::cast_return_type >::type(*this); } - - /** Copy constructor with scalar type conversion */ - template - inline explicit AngleAxis(const AngleAxis& other) - { - m_axis = other.axis().template cast(); - m_angle = Scalar(other.angle()); - } - - static inline const AngleAxis Identity() { return AngleAxis(Scalar(0), Vector3::UnitX()); } - - /** \returns \c true if \c *this is approximately equal to \a other, within the precision - * determined by \a prec. - * - * \sa MatrixBase::isApprox() */ - bool isApprox(const AngleAxis& other, const typename NumTraits::Real& prec = NumTraits::dummy_precision()) const - { return m_axis.isApprox(other.m_axis, prec) && internal::isApprox(m_angle,other.m_angle, prec); } -}; - -/** \ingroup Geometry_Module - * single precision angle-axis type */ -typedef AngleAxis AngleAxisf; -/** \ingroup Geometry_Module - * double precision angle-axis type */ -typedef AngleAxis AngleAxisd; - -/** Set \c *this from a \b unit quaternion. - * The axis is normalized. - * - * \warning As any other method dealing with quaternion, if the input quaternion - * is not normalized then the result is undefined. - */ -template -template -AngleAxis& AngleAxis::operator=(const QuaternionBase& q) -{ - using std::acos; - using std::min; - using std::max; - using std::sqrt; - Scalar n2 = q.vec().squaredNorm(); - if (n2 < NumTraits::dummy_precision()*NumTraits::dummy_precision()) - { - m_angle = Scalar(0); - m_axis << Scalar(1), Scalar(0), Scalar(0); - } - else - { - m_angle = Scalar(2)*acos((min)((max)(Scalar(-1),q.w()),Scalar(1))); - m_axis = q.vec() / sqrt(n2); - } - return *this; -} - -/** Set \c *this from a 3x3 rotation matrix \a mat. - */ -template -template -AngleAxis& AngleAxis::operator=(const MatrixBase& mat) -{ - // Since a direct conversion would not be really faster, - // let's use the robust Quaternion implementation: - return *this = QuaternionType(mat); -} - -/** -* \brief Sets \c *this from a 3x3 rotation matrix. -**/ -template -template -AngleAxis& AngleAxis::fromRotationMatrix(const MatrixBase& mat) -{ - return *this = QuaternionType(mat); -} - -/** Constructs and \returns an equivalent 3x3 rotation matrix. - */ -template -typename AngleAxis::Matrix3 -AngleAxis::toRotationMatrix(void) const -{ - using std::sin; - using std::cos; - Matrix3 res; - Vector3 sin_axis = sin(m_angle) * m_axis; - Scalar c = cos(m_angle); - Vector3 cos1_axis = (Scalar(1)-c) * m_axis; - - Scalar tmp; - tmp = cos1_axis.x() * m_axis.y(); - res.coeffRef(0,1) = tmp - sin_axis.z(); - res.coeffRef(1,0) = tmp + sin_axis.z(); - - tmp = cos1_axis.x() * m_axis.z(); - res.coeffRef(0,2) = tmp + sin_axis.y(); - res.coeffRef(2,0) = tmp - sin_axis.y(); - - tmp = cos1_axis.y() * m_axis.z(); - res.coeffRef(1,2) = tmp - sin_axis.x(); - res.coeffRef(2,1) = tmp + sin_axis.x(); - - res.diagonal() = (cos1_axis.cwiseProduct(m_axis)).array() + c; - - return res; -} - -} // end namespace Eigen - -#endif // EIGEN_ANGLEAXIS_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Geometry/EulerAngles.h b/thirdparty/eigen-3.2.7/Eigen/src/Geometry/EulerAngles.h deleted file mode 100644 index 82802fb4..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Geometry/EulerAngles.h +++ /dev/null @@ -1,104 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_EULERANGLES_H -#define EIGEN_EULERANGLES_H - -namespace Eigen { - -/** \geometry_module \ingroup Geometry_Module - * - * - * \returns the Euler-angles of the rotation matrix \c *this using the convention defined by the triplet (\a a0,\a a1,\a a2) - * - * Each of the three parameters \a a0,\a a1,\a a2 represents the respective rotation axis as an integer in {0,1,2}. - * For instance, in: - * \code Vector3f ea = mat.eulerAngles(2, 0, 2); \endcode - * "2" represents the z axis and "0" the x axis, etc. The returned angles are such that - * we have the following equality: - * \code - * mat == AngleAxisf(ea[0], Vector3f::UnitZ()) - * * AngleAxisf(ea[1], Vector3f::UnitX()) - * * AngleAxisf(ea[2], Vector3f::UnitZ()); \endcode - * This corresponds to the right-multiply conventions (with right hand side frames). - * - * The returned angles are in the ranges [0:pi]x[-pi:pi]x[-pi:pi]. - * - * \sa class AngleAxis - */ -template -inline Matrix::Scalar,3,1> -MatrixBase::eulerAngles(Index a0, Index a1, Index a2) const -{ - using std::atan2; - using std::sin; - using std::cos; - /* Implemented from Graphics Gems IV */ - EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived,3,3) - - Matrix res; - typedef Matrix Vector2; - - const Index odd = ((a0+1)%3 == a1) ? 0 : 1; - const Index i = a0; - const Index j = (a0 + 1 + odd)%3; - const Index k = (a0 + 2 - odd)%3; - - if (a0==a2) - { - res[0] = atan2(coeff(j,i), coeff(k,i)); - if((odd && res[0]Scalar(0))) - { - res[0] = (res[0] > Scalar(0)) ? res[0] - Scalar(M_PI) : res[0] + Scalar(M_PI); - Scalar s2 = Vector2(coeff(j,i), coeff(k,i)).norm(); - res[1] = -atan2(s2, coeff(i,i)); - } - else - { - Scalar s2 = Vector2(coeff(j,i), coeff(k,i)).norm(); - res[1] = atan2(s2, coeff(i,i)); - } - - // With a=(0,1,0), we have i=0; j=1; k=2, and after computing the first two angles, - // we can compute their respective rotation, and apply its inverse to M. Since the result must - // be a rotation around x, we have: - // - // c2 s1.s2 c1.s2 1 0 0 - // 0 c1 -s1 * M = 0 c3 s3 - // -s2 s1.c2 c1.c2 0 -s3 c3 - // - // Thus: m11.c1 - m21.s1 = c3 & m12.c1 - m22.s1 = s3 - - Scalar s1 = sin(res[0]); - Scalar c1 = cos(res[0]); - res[2] = atan2(c1*coeff(j,k)-s1*coeff(k,k), c1*coeff(j,j) - s1 * coeff(k,j)); - } - else - { - res[0] = atan2(coeff(j,k), coeff(k,k)); - Scalar c2 = Vector2(coeff(i,i), coeff(i,j)).norm(); - if((odd && res[0]Scalar(0))) { - res[0] = (res[0] > Scalar(0)) ? res[0] - Scalar(M_PI) : res[0] + Scalar(M_PI); - res[1] = atan2(-coeff(i,k), -c2); - } - else - res[1] = atan2(-coeff(i,k), c2); - Scalar s1 = sin(res[0]); - Scalar c1 = cos(res[0]); - res[2] = atan2(s1*coeff(k,i)-c1*coeff(j,i), c1*coeff(j,j) - s1 * coeff(k,j)); - } - if (!odd) - res = -res; - - return res; -} - -} // end namespace Eigen - -#endif // EIGEN_EULERANGLES_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Geometry/Homogeneous.h b/thirdparty/eigen-3.2.7/Eigen/src/Geometry/Homogeneous.h deleted file mode 100644 index 372e422b..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Geometry/Homogeneous.h +++ /dev/null @@ -1,307 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2009-2010 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_HOMOGENEOUS_H -#define EIGEN_HOMOGENEOUS_H - -namespace Eigen { - -/** \geometry_module \ingroup Geometry_Module - * - * \class Homogeneous - * - * \brief Expression of one (or a set of) homogeneous vector(s) - * - * \param MatrixType the type of the object in which we are making homogeneous - * - * This class represents an expression of one (or a set of) homogeneous vector(s). - * It is the return type of MatrixBase::homogeneous() and most of the time - * this is the only way it is used. - * - * \sa MatrixBase::homogeneous() - */ - -namespace internal { - -template -struct traits > - : traits -{ - typedef typename traits::StorageKind StorageKind; - typedef typename nested::type MatrixTypeNested; - typedef typename remove_reference::type _MatrixTypeNested; - enum { - RowsPlusOne = (MatrixType::RowsAtCompileTime != Dynamic) ? - int(MatrixType::RowsAtCompileTime) + 1 : Dynamic, - ColsPlusOne = (MatrixType::ColsAtCompileTime != Dynamic) ? - int(MatrixType::ColsAtCompileTime) + 1 : Dynamic, - RowsAtCompileTime = Direction==Vertical ? RowsPlusOne : MatrixType::RowsAtCompileTime, - ColsAtCompileTime = Direction==Horizontal ? ColsPlusOne : MatrixType::ColsAtCompileTime, - MaxRowsAtCompileTime = RowsAtCompileTime, - MaxColsAtCompileTime = ColsAtCompileTime, - TmpFlags = _MatrixTypeNested::Flags & HereditaryBits, - Flags = ColsAtCompileTime==1 ? (TmpFlags & ~RowMajorBit) - : RowsAtCompileTime==1 ? (TmpFlags | RowMajorBit) - : TmpFlags, - CoeffReadCost = _MatrixTypeNested::CoeffReadCost - }; -}; - -template struct homogeneous_left_product_impl; -template struct homogeneous_right_product_impl; - -} // end namespace internal - -template class Homogeneous - : internal::no_assignment_operator, public MatrixBase > -{ - public: - - enum { Direction = _Direction }; - - typedef MatrixBase Base; - EIGEN_DENSE_PUBLIC_INTERFACE(Homogeneous) - - inline Homogeneous(const MatrixType& matrix) - : m_matrix(matrix) - {} - - inline Index rows() const { return m_matrix.rows() + (int(Direction)==Vertical ? 1 : 0); } - inline Index cols() const { return m_matrix.cols() + (int(Direction)==Horizontal ? 1 : 0); } - - inline Scalar coeff(Index row, Index col) const - { - if( (int(Direction)==Vertical && row==m_matrix.rows()) - || (int(Direction)==Horizontal && col==m_matrix.cols())) - return Scalar(1); - return m_matrix.coeff(row, col); - } - - template - inline const internal::homogeneous_right_product_impl - operator* (const MatrixBase& rhs) const - { - eigen_assert(int(Direction)==Horizontal); - return internal::homogeneous_right_product_impl(m_matrix,rhs.derived()); - } - - template friend - inline const internal::homogeneous_left_product_impl - operator* (const MatrixBase& lhs, const Homogeneous& rhs) - { - eigen_assert(int(Direction)==Vertical); - return internal::homogeneous_left_product_impl(lhs.derived(),rhs.m_matrix); - } - - template friend - inline const internal::homogeneous_left_product_impl > - operator* (const Transform& lhs, const Homogeneous& rhs) - { - eigen_assert(int(Direction)==Vertical); - return internal::homogeneous_left_product_impl >(lhs,rhs.m_matrix); - } - - protected: - typename MatrixType::Nested m_matrix; -}; - -/** \geometry_module - * - * \return an expression of the equivalent homogeneous vector - * - * \only_for_vectors - * - * Example: \include MatrixBase_homogeneous.cpp - * Output: \verbinclude MatrixBase_homogeneous.out - * - * \sa class Homogeneous - */ -template -inline typename MatrixBase::HomogeneousReturnType -MatrixBase::homogeneous() const -{ - EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived); - return derived(); -} - -/** \geometry_module - * - * \returns a matrix expression of homogeneous column (or row) vectors - * - * Example: \include VectorwiseOp_homogeneous.cpp - * Output: \verbinclude VectorwiseOp_homogeneous.out - * - * \sa MatrixBase::homogeneous() */ -template -inline Homogeneous -VectorwiseOp::homogeneous() const -{ - return _expression(); -} - -/** \geometry_module - * - * \returns an expression of the homogeneous normalized vector of \c *this - * - * Example: \include MatrixBase_hnormalized.cpp - * Output: \verbinclude MatrixBase_hnormalized.out - * - * \sa VectorwiseOp::hnormalized() */ -template -inline const typename MatrixBase::HNormalizedReturnType -MatrixBase::hnormalized() const -{ - EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived); - return ConstStartMinusOne(derived(),0,0, - ColsAtCompileTime==1?size()-1:1, - ColsAtCompileTime==1?1:size()-1) / coeff(size()-1); -} - -/** \geometry_module - * - * \returns an expression of the homogeneous normalized vector of \c *this - * - * Example: \include DirectionWise_hnormalized.cpp - * Output: \verbinclude DirectionWise_hnormalized.out - * - * \sa MatrixBase::hnormalized() */ -template -inline const typename VectorwiseOp::HNormalizedReturnType -VectorwiseOp::hnormalized() const -{ - return HNormalized_Block(_expression(),0,0, - Direction==Vertical ? _expression().rows()-1 : _expression().rows(), - Direction==Horizontal ? _expression().cols()-1 : _expression().cols()).cwiseQuotient( - Replicate - (HNormalized_Factors(_expression(), - Direction==Vertical ? _expression().rows()-1:0, - Direction==Horizontal ? _expression().cols()-1:0, - Direction==Vertical ? 1 : _expression().rows(), - Direction==Horizontal ? 1 : _expression().cols()), - Direction==Vertical ? _expression().rows()-1 : 1, - Direction==Horizontal ? _expression().cols()-1 : 1)); -} - -namespace internal { - -template -struct take_matrix_for_product -{ - typedef MatrixOrTransformType type; - static const type& run(const type &x) { return x; } -}; - -template -struct take_matrix_for_product > -{ - typedef Transform TransformType; - typedef typename internal::add_const::type type; - static type run (const TransformType& x) { return x.affine(); } -}; - -template -struct take_matrix_for_product > -{ - typedef Transform TransformType; - typedef typename TransformType::MatrixType type; - static const type& run (const TransformType& x) { return x.matrix(); } -}; - -template -struct traits,Lhs> > -{ - typedef typename take_matrix_for_product::type LhsMatrixType; - typedef typename remove_all::type MatrixTypeCleaned; - typedef typename remove_all::type LhsMatrixTypeCleaned; - typedef typename make_proper_matrix_type< - typename traits::Scalar, - LhsMatrixTypeCleaned::RowsAtCompileTime, - MatrixTypeCleaned::ColsAtCompileTime, - MatrixTypeCleaned::PlainObject::Options, - LhsMatrixTypeCleaned::MaxRowsAtCompileTime, - MatrixTypeCleaned::MaxColsAtCompileTime>::type ReturnType; -}; - -template -struct homogeneous_left_product_impl,Lhs> - : public ReturnByValue,Lhs> > -{ - typedef typename traits::LhsMatrixType LhsMatrixType; - typedef typename remove_all::type LhsMatrixTypeCleaned; - typedef typename remove_all::type LhsMatrixTypeNested; - typedef typename MatrixType::Index Index; - homogeneous_left_product_impl(const Lhs& lhs, const MatrixType& rhs) - : m_lhs(take_matrix_for_product::run(lhs)), - m_rhs(rhs) - {} - - inline Index rows() const { return m_lhs.rows(); } - inline Index cols() const { return m_rhs.cols(); } - - template void evalTo(Dest& dst) const - { - // FIXME investigate how to allow lazy evaluation of this product when possible - dst = Block - (m_lhs,0,0,m_lhs.rows(),m_lhs.cols()-1) * m_rhs; - dst += m_lhs.col(m_lhs.cols()-1).rowwise() - .template replicate(m_rhs.cols()); - } - - typename LhsMatrixTypeCleaned::Nested m_lhs; - typename MatrixType::Nested m_rhs; -}; - -template -struct traits,Rhs> > -{ - typedef typename make_proper_matrix_type::Scalar, - MatrixType::RowsAtCompileTime, - Rhs::ColsAtCompileTime, - MatrixType::PlainObject::Options, - MatrixType::MaxRowsAtCompileTime, - Rhs::MaxColsAtCompileTime>::type ReturnType; -}; - -template -struct homogeneous_right_product_impl,Rhs> - : public ReturnByValue,Rhs> > -{ - typedef typename remove_all::type RhsNested; - typedef typename MatrixType::Index Index; - homogeneous_right_product_impl(const MatrixType& lhs, const Rhs& rhs) - : m_lhs(lhs), m_rhs(rhs) - {} - - inline Index rows() const { return m_lhs.rows(); } - inline Index cols() const { return m_rhs.cols(); } - - template void evalTo(Dest& dst) const - { - // FIXME investigate how to allow lazy evaluation of this product when possible - dst = m_lhs * Block - (m_rhs,0,0,m_rhs.rows()-1,m_rhs.cols()); - dst += m_rhs.row(m_rhs.rows()-1).colwise() - .template replicate(m_lhs.rows()); - } - - typename MatrixType::Nested m_lhs; - typename Rhs::Nested m_rhs; -}; - -} // end namespace internal - -} // end namespace Eigen - -#endif // EIGEN_HOMOGENEOUS_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Geometry/Hyperplane.h b/thirdparty/eigen-3.2.7/Eigen/src/Geometry/Hyperplane.h deleted file mode 100644 index 00b7c430..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Geometry/Hyperplane.h +++ /dev/null @@ -1,280 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud -// Copyright (C) 2008 Benoit Jacob -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_HYPERPLANE_H -#define EIGEN_HYPERPLANE_H - -namespace Eigen { - -/** \geometry_module \ingroup Geometry_Module - * - * \class Hyperplane - * - * \brief A hyperplane - * - * A hyperplane is an affine subspace of dimension n-1 in a space of dimension n. - * For example, a hyperplane in a plane is a line; a hyperplane in 3-space is a plane. - * - * \param _Scalar the scalar type, i.e., the type of the coefficients - * \param _AmbientDim the dimension of the ambient space, can be a compile time value or Dynamic. - * Notice that the dimension of the hyperplane is _AmbientDim-1. - * - * This class represents an hyperplane as the zero set of the implicit equation - * \f$ n \cdot x + d = 0 \f$ where \f$ n \f$ is a unit normal vector of the plane (linear part) - * and \f$ d \f$ is the distance (offset) to the origin. - */ -template -class Hyperplane -{ -public: - EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim==Dynamic ? Dynamic : _AmbientDim+1) - enum { - AmbientDimAtCompileTime = _AmbientDim, - Options = _Options - }; - typedef _Scalar Scalar; - typedef typename NumTraits::Real RealScalar; - typedef DenseIndex Index; - typedef Matrix VectorType; - typedef Matrix Coefficients; - typedef Block NormalReturnType; - typedef const Block ConstNormalReturnType; - - /** Default constructor without initialization */ - inline Hyperplane() {} - - template - Hyperplane(const Hyperplane& other) - : m_coeffs(other.coeffs()) - {} - - /** Constructs a dynamic-size hyperplane with \a _dim the dimension - * of the ambient space */ - inline explicit Hyperplane(Index _dim) : m_coeffs(_dim+1) {} - - /** Construct a plane from its normal \a n and a point \a e onto the plane. - * \warning the vector normal is assumed to be normalized. - */ - inline Hyperplane(const VectorType& n, const VectorType& e) - : m_coeffs(n.size()+1) - { - normal() = n; - offset() = -n.dot(e); - } - - /** Constructs a plane from its normal \a n and distance to the origin \a d - * such that the algebraic equation of the plane is \f$ n \cdot x + d = 0 \f$. - * \warning the vector normal is assumed to be normalized. - */ - inline Hyperplane(const VectorType& n, const Scalar& d) - : m_coeffs(n.size()+1) - { - normal() = n; - offset() = d; - } - - /** Constructs a hyperplane passing through the two points. If the dimension of the ambient space - * is greater than 2, then there isn't uniqueness, so an arbitrary choice is made. - */ - static inline Hyperplane Through(const VectorType& p0, const VectorType& p1) - { - Hyperplane result(p0.size()); - result.normal() = (p1 - p0).unitOrthogonal(); - result.offset() = -p0.dot(result.normal()); - return result; - } - - /** Constructs a hyperplane passing through the three points. The dimension of the ambient space - * is required to be exactly 3. - */ - static inline Hyperplane Through(const VectorType& p0, const VectorType& p1, const VectorType& p2) - { - EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(VectorType, 3) - Hyperplane result(p0.size()); - VectorType v0(p2 - p0), v1(p1 - p0); - result.normal() = v0.cross(v1); - RealScalar norm = result.normal().norm(); - if(norm <= v0.norm() * v1.norm() * NumTraits::epsilon()) - { - Matrix m; m << v0.transpose(), v1.transpose(); - JacobiSVD > svd(m, ComputeFullV); - result.normal() = svd.matrixV().col(2); - } - else - result.normal() /= norm; - result.offset() = -p0.dot(result.normal()); - return result; - } - - /** Constructs a hyperplane passing through the parametrized line \a parametrized. - * If the dimension of the ambient space is greater than 2, then there isn't uniqueness, - * so an arbitrary choice is made. - */ - // FIXME to be consitent with the rest this could be implemented as a static Through function ?? - explicit Hyperplane(const ParametrizedLine& parametrized) - { - normal() = parametrized.direction().unitOrthogonal(); - offset() = -parametrized.origin().dot(normal()); - } - - ~Hyperplane() {} - - /** \returns the dimension in which the plane holds */ - inline Index dim() const { return AmbientDimAtCompileTime==Dynamic ? m_coeffs.size()-1 : Index(AmbientDimAtCompileTime); } - - /** normalizes \c *this */ - void normalize(void) - { - m_coeffs /= normal().norm(); - } - - /** \returns the signed distance between the plane \c *this and a point \a p. - * \sa absDistance() - */ - inline Scalar signedDistance(const VectorType& p) const { return normal().dot(p) + offset(); } - - /** \returns the absolute distance between the plane \c *this and a point \a p. - * \sa signedDistance() - */ - inline Scalar absDistance(const VectorType& p) const { using std::abs; return abs(signedDistance(p)); } - - /** \returns the projection of a point \a p onto the plane \c *this. - */ - inline VectorType projection(const VectorType& p) const { return p - signedDistance(p) * normal(); } - - /** \returns a constant reference to the unit normal vector of the plane, which corresponds - * to the linear part of the implicit equation. - */ - inline ConstNormalReturnType normal() const { return ConstNormalReturnType(m_coeffs,0,0,dim(),1); } - - /** \returns a non-constant reference to the unit normal vector of the plane, which corresponds - * to the linear part of the implicit equation. - */ - inline NormalReturnType normal() { return NormalReturnType(m_coeffs,0,0,dim(),1); } - - /** \returns the distance to the origin, which is also the "constant term" of the implicit equation - * \warning the vector normal is assumed to be normalized. - */ - inline const Scalar& offset() const { return m_coeffs.coeff(dim()); } - - /** \returns a non-constant reference to the distance to the origin, which is also the constant part - * of the implicit equation */ - inline Scalar& offset() { return m_coeffs(dim()); } - - /** \returns a constant reference to the coefficients c_i of the plane equation: - * \f$ c_0*x_0 + ... + c_{d-1}*x_{d-1} + c_d = 0 \f$ - */ - inline const Coefficients& coeffs() const { return m_coeffs; } - - /** \returns a non-constant reference to the coefficients c_i of the plane equation: - * \f$ c_0*x_0 + ... + c_{d-1}*x_{d-1} + c_d = 0 \f$ - */ - inline Coefficients& coeffs() { return m_coeffs; } - - /** \returns the intersection of *this with \a other. - * - * \warning The ambient space must be a plane, i.e. have dimension 2, so that \c *this and \a other are lines. - * - * \note If \a other is approximately parallel to *this, this method will return any point on *this. - */ - VectorType intersection(const Hyperplane& other) const - { - using std::abs; - EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(VectorType, 2) - Scalar det = coeffs().coeff(0) * other.coeffs().coeff(1) - coeffs().coeff(1) * other.coeffs().coeff(0); - // since the line equations ax+by=c are normalized with a^2+b^2=1, the following tests - // whether the two lines are approximately parallel. - if(internal::isMuchSmallerThan(det, Scalar(1))) - { // special case where the two lines are approximately parallel. Pick any point on the first line. - if(abs(coeffs().coeff(1))>abs(coeffs().coeff(0))) - return VectorType(coeffs().coeff(1), -coeffs().coeff(2)/coeffs().coeff(1)-coeffs().coeff(0)); - else - return VectorType(-coeffs().coeff(2)/coeffs().coeff(0)-coeffs().coeff(1), coeffs().coeff(0)); - } - else - { // general case - Scalar invdet = Scalar(1) / det; - return VectorType(invdet*(coeffs().coeff(1)*other.coeffs().coeff(2)-other.coeffs().coeff(1)*coeffs().coeff(2)), - invdet*(other.coeffs().coeff(0)*coeffs().coeff(2)-coeffs().coeff(0)*other.coeffs().coeff(2))); - } - } - - /** Applies the transformation matrix \a mat to \c *this and returns a reference to \c *this. - * - * \param mat the Dim x Dim transformation matrix - * \param traits specifies whether the matrix \a mat represents an #Isometry - * or a more generic #Affine transformation. The default is #Affine. - */ - template - inline Hyperplane& transform(const MatrixBase& mat, TransformTraits traits = Affine) - { - if (traits==Affine) - normal() = mat.inverse().transpose() * normal(); - else if (traits==Isometry) - normal() = mat * normal(); - else - { - eigen_assert(0 && "invalid traits value in Hyperplane::transform()"); - } - return *this; - } - - /** Applies the transformation \a t to \c *this and returns a reference to \c *this. - * - * \param t the transformation of dimension Dim - * \param traits specifies whether the transformation \a t represents an #Isometry - * or a more generic #Affine transformation. The default is #Affine. - * Other kind of transformations are not supported. - */ - template - inline Hyperplane& transform(const Transform& t, - TransformTraits traits = Affine) - { - transform(t.linear(), traits); - offset() -= normal().dot(t.translation()); - return *this; - } - - /** \returns \c *this with scalar type casted to \a NewScalarType - * - * Note that if \a NewScalarType is equal to the current scalar type of \c *this - * then this function smartly returns a const reference to \c *this. - */ - template - inline typename internal::cast_return_type >::type cast() const - { - return typename internal::cast_return_type >::type(*this); - } - - /** Copy constructor with scalar type conversion */ - template - inline explicit Hyperplane(const Hyperplane& other) - { m_coeffs = other.coeffs().template cast(); } - - /** \returns \c true if \c *this is approximately equal to \a other, within the precision - * determined by \a prec. - * - * \sa MatrixBase::isApprox() */ - template - bool isApprox(const Hyperplane& other, const typename NumTraits::Real& prec = NumTraits::dummy_precision()) const - { return m_coeffs.isApprox(other.m_coeffs, prec); } - -protected: - - Coefficients m_coeffs; -}; - -} // end namespace Eigen - -#endif // EIGEN_HYPERPLANE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Geometry/OrthoMethods.h b/thirdparty/eigen-3.2.7/Eigen/src/Geometry/OrthoMethods.h deleted file mode 100644 index 556bc816..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Geometry/OrthoMethods.h +++ /dev/null @@ -1,218 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2009 Gael Guennebaud -// Copyright (C) 2006-2008 Benoit Jacob -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_ORTHOMETHODS_H -#define EIGEN_ORTHOMETHODS_H - -namespace Eigen { - -/** \geometry_module - * - * \returns the cross product of \c *this and \a other - * - * Here is a very good explanation of cross-product: http://xkcd.com/199/ - * \sa MatrixBase::cross3() - */ -template -template -inline typename MatrixBase::template cross_product_return_type::type -MatrixBase::cross(const MatrixBase& other) const -{ - EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Derived,3) - EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,3) - - // Note that there is no need for an expression here since the compiler - // optimize such a small temporary very well (even within a complex expression) - typename internal::nested::type lhs(derived()); - typename internal::nested::type rhs(other.derived()); - return typename cross_product_return_type::type( - numext::conj(lhs.coeff(1) * rhs.coeff(2) - lhs.coeff(2) * rhs.coeff(1)), - numext::conj(lhs.coeff(2) * rhs.coeff(0) - lhs.coeff(0) * rhs.coeff(2)), - numext::conj(lhs.coeff(0) * rhs.coeff(1) - lhs.coeff(1) * rhs.coeff(0)) - ); -} - -namespace internal { - -template< int Arch,typename VectorLhs,typename VectorRhs, - typename Scalar = typename VectorLhs::Scalar, - bool Vectorizable = bool((VectorLhs::Flags&VectorRhs::Flags)&PacketAccessBit)> -struct cross3_impl { - static inline typename internal::plain_matrix_type::type - run(const VectorLhs& lhs, const VectorRhs& rhs) - { - return typename internal::plain_matrix_type::type( - numext::conj(lhs.coeff(1) * rhs.coeff(2) - lhs.coeff(2) * rhs.coeff(1)), - numext::conj(lhs.coeff(2) * rhs.coeff(0) - lhs.coeff(0) * rhs.coeff(2)), - numext::conj(lhs.coeff(0) * rhs.coeff(1) - lhs.coeff(1) * rhs.coeff(0)), - 0 - ); - } -}; - -} - -/** \geometry_module - * - * \returns the cross product of \c *this and \a other using only the x, y, and z coefficients - * - * The size of \c *this and \a other must be four. This function is especially useful - * when using 4D vectors instead of 3D ones to get advantage of SSE/AltiVec vectorization. - * - * \sa MatrixBase::cross() - */ -template -template -inline typename MatrixBase::PlainObject -MatrixBase::cross3(const MatrixBase& other) const -{ - EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Derived,4) - EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,4) - - typedef typename internal::nested::type DerivedNested; - typedef typename internal::nested::type OtherDerivedNested; - DerivedNested lhs(derived()); - OtherDerivedNested rhs(other.derived()); - - return internal::cross3_impl::type, - typename internal::remove_all::type>::run(lhs,rhs); -} - -/** \returns a matrix expression of the cross product of each column or row - * of the referenced expression with the \a other vector. - * - * The referenced matrix must have one dimension equal to 3. - * The result matrix has the same dimensions than the referenced one. - * - * \geometry_module - * - * \sa MatrixBase::cross() */ -template -template -const typename VectorwiseOp::CrossReturnType -VectorwiseOp::cross(const MatrixBase& other) const -{ - EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,3) - EIGEN_STATIC_ASSERT((internal::is_same::value), - YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) - - CrossReturnType res(_expression().rows(),_expression().cols()); - if(Direction==Vertical) - { - eigen_assert(CrossReturnType::RowsAtCompileTime==3 && "the matrix must have exactly 3 rows"); - res.row(0) = (_expression().row(1) * other.coeff(2) - _expression().row(2) * other.coeff(1)).conjugate(); - res.row(1) = (_expression().row(2) * other.coeff(0) - _expression().row(0) * other.coeff(2)).conjugate(); - res.row(2) = (_expression().row(0) * other.coeff(1) - _expression().row(1) * other.coeff(0)).conjugate(); - } - else - { - eigen_assert(CrossReturnType::ColsAtCompileTime==3 && "the matrix must have exactly 3 columns"); - res.col(0) = (_expression().col(1) * other.coeff(2) - _expression().col(2) * other.coeff(1)).conjugate(); - res.col(1) = (_expression().col(2) * other.coeff(0) - _expression().col(0) * other.coeff(2)).conjugate(); - res.col(2) = (_expression().col(0) * other.coeff(1) - _expression().col(1) * other.coeff(0)).conjugate(); - } - return res; -} - -namespace internal { - -template -struct unitOrthogonal_selector -{ - typedef typename plain_matrix_type::type VectorType; - typedef typename traits::Scalar Scalar; - typedef typename NumTraits::Real RealScalar; - typedef typename Derived::Index Index; - typedef Matrix Vector2; - static inline VectorType run(const Derived& src) - { - VectorType perp = VectorType::Zero(src.size()); - Index maxi = 0; - Index sndi = 0; - src.cwiseAbs().maxCoeff(&maxi); - if (maxi==0) - sndi = 1; - RealScalar invnm = RealScalar(1)/(Vector2() << src.coeff(sndi),src.coeff(maxi)).finished().norm(); - perp.coeffRef(maxi) = -numext::conj(src.coeff(sndi)) * invnm; - perp.coeffRef(sndi) = numext::conj(src.coeff(maxi)) * invnm; - - return perp; - } -}; - -template -struct unitOrthogonal_selector -{ - typedef typename plain_matrix_type::type VectorType; - typedef typename traits::Scalar Scalar; - typedef typename NumTraits::Real RealScalar; - static inline VectorType run(const Derived& src) - { - VectorType perp; - /* Let us compute the crossed product of *this with a vector - * that is not too close to being colinear to *this. - */ - - /* unless the x and y coords are both close to zero, we can - * simply take ( -y, x, 0 ) and normalize it. - */ - if((!isMuchSmallerThan(src.x(), src.z())) - || (!isMuchSmallerThan(src.y(), src.z()))) - { - RealScalar invnm = RealScalar(1)/src.template head<2>().norm(); - perp.coeffRef(0) = -numext::conj(src.y())*invnm; - perp.coeffRef(1) = numext::conj(src.x())*invnm; - perp.coeffRef(2) = 0; - } - /* if both x and y are close to zero, then the vector is close - * to the z-axis, so it's far from colinear to the x-axis for instance. - * So we take the crossed product with (1,0,0) and normalize it. - */ - else - { - RealScalar invnm = RealScalar(1)/src.template tail<2>().norm(); - perp.coeffRef(0) = 0; - perp.coeffRef(1) = -numext::conj(src.z())*invnm; - perp.coeffRef(2) = numext::conj(src.y())*invnm; - } - - return perp; - } -}; - -template -struct unitOrthogonal_selector -{ - typedef typename plain_matrix_type::type VectorType; - static inline VectorType run(const Derived& src) - { return VectorType(-numext::conj(src.y()), numext::conj(src.x())).normalized(); } -}; - -} // end namespace internal - -/** \returns a unit vector which is orthogonal to \c *this - * - * The size of \c *this must be at least 2. If the size is exactly 2, - * then the returned vector is a counter clock wise rotation of \c *this, i.e., (-y,x).normalized(). - * - * \sa cross() - */ -template -typename MatrixBase::PlainObject -MatrixBase::unitOrthogonal() const -{ - EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) - return internal::unitOrthogonal_selector::run(derived()); -} - -} // end namespace Eigen - -#endif // EIGEN_ORTHOMETHODS_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Geometry/ParametrizedLine.h b/thirdparty/eigen-3.2.7/Eigen/src/Geometry/ParametrizedLine.h deleted file mode 100644 index 77fa228e..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Geometry/ParametrizedLine.h +++ /dev/null @@ -1,195 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud -// Copyright (C) 2008 Benoit Jacob -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_PARAMETRIZEDLINE_H -#define EIGEN_PARAMETRIZEDLINE_H - -namespace Eigen { - -/** \geometry_module \ingroup Geometry_Module - * - * \class ParametrizedLine - * - * \brief A parametrized line - * - * A parametrized line is defined by an origin point \f$ \mathbf{o} \f$ and a unit - * direction vector \f$ \mathbf{d} \f$ such that the line corresponds to - * the set \f$ l(t) = \mathbf{o} + t \mathbf{d} \f$, \f$ t \in \mathbf{R} \f$. - * - * \param _Scalar the scalar type, i.e., the type of the coefficients - * \param _AmbientDim the dimension of the ambient space, can be a compile time value or Dynamic. - */ -template -class ParametrizedLine -{ -public: - EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim) - enum { - AmbientDimAtCompileTime = _AmbientDim, - Options = _Options - }; - typedef _Scalar Scalar; - typedef typename NumTraits::Real RealScalar; - typedef DenseIndex Index; - typedef Matrix VectorType; - - /** Default constructor without initialization */ - inline ParametrizedLine() {} - - template - ParametrizedLine(const ParametrizedLine& other) - : m_origin(other.origin()), m_direction(other.direction()) - {} - - /** Constructs a dynamic-size line with \a _dim the dimension - * of the ambient space */ - inline explicit ParametrizedLine(Index _dim) : m_origin(_dim), m_direction(_dim) {} - - /** Initializes a parametrized line of direction \a direction and origin \a origin. - * \warning the vector direction is assumed to be normalized. - */ - ParametrizedLine(const VectorType& origin, const VectorType& direction) - : m_origin(origin), m_direction(direction) {} - - template - explicit ParametrizedLine(const Hyperplane<_Scalar, _AmbientDim, OtherOptions>& hyperplane); - - /** Constructs a parametrized line going from \a p0 to \a p1. */ - static inline ParametrizedLine Through(const VectorType& p0, const VectorType& p1) - { return ParametrizedLine(p0, (p1-p0).normalized()); } - - ~ParametrizedLine() {} - - /** \returns the dimension in which the line holds */ - inline Index dim() const { return m_direction.size(); } - - const VectorType& origin() const { return m_origin; } - VectorType& origin() { return m_origin; } - - const VectorType& direction() const { return m_direction; } - VectorType& direction() { return m_direction; } - - /** \returns the squared distance of a point \a p to its projection onto the line \c *this. - * \sa distance() - */ - RealScalar squaredDistance(const VectorType& p) const - { - VectorType diff = p - origin(); - return (diff - direction().dot(diff) * direction()).squaredNorm(); - } - /** \returns the distance of a point \a p to its projection onto the line \c *this. - * \sa squaredDistance() - */ - RealScalar distance(const VectorType& p) const { using std::sqrt; return sqrt(squaredDistance(p)); } - - /** \returns the projection of a point \a p onto the line \c *this. */ - VectorType projection(const VectorType& p) const - { return origin() + direction().dot(p-origin()) * direction(); } - - VectorType pointAt(const Scalar& t) const; - - template - Scalar intersectionParameter(const Hyperplane<_Scalar, _AmbientDim, OtherOptions>& hyperplane) const; - - template - Scalar intersection(const Hyperplane<_Scalar, _AmbientDim, OtherOptions>& hyperplane) const; - - template - VectorType intersectionPoint(const Hyperplane<_Scalar, _AmbientDim, OtherOptions>& hyperplane) const; - - /** \returns \c *this with scalar type casted to \a NewScalarType - * - * Note that if \a NewScalarType is equal to the current scalar type of \c *this - * then this function smartly returns a const reference to \c *this. - */ - template - inline typename internal::cast_return_type >::type cast() const - { - return typename internal::cast_return_type >::type(*this); - } - - /** Copy constructor with scalar type conversion */ - template - inline explicit ParametrizedLine(const ParametrizedLine& other) - { - m_origin = other.origin().template cast(); - m_direction = other.direction().template cast(); - } - - /** \returns \c true if \c *this is approximately equal to \a other, within the precision - * determined by \a prec. - * - * \sa MatrixBase::isApprox() */ - bool isApprox(const ParametrizedLine& other, typename NumTraits::Real prec = NumTraits::dummy_precision()) const - { return m_origin.isApprox(other.m_origin, prec) && m_direction.isApprox(other.m_direction, prec); } - -protected: - - VectorType m_origin, m_direction; -}; - -/** Constructs a parametrized line from a 2D hyperplane - * - * \warning the ambient space must have dimension 2 such that the hyperplane actually describes a line - */ -template -template -inline ParametrizedLine<_Scalar, _AmbientDim,_Options>::ParametrizedLine(const Hyperplane<_Scalar, _AmbientDim,OtherOptions>& hyperplane) -{ - EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(VectorType, 2) - direction() = hyperplane.normal().unitOrthogonal(); - origin() = -hyperplane.normal()*hyperplane.offset(); -} - -/** \returns the point at \a t along this line - */ -template -inline typename ParametrizedLine<_Scalar, _AmbientDim,_Options>::VectorType -ParametrizedLine<_Scalar, _AmbientDim,_Options>::pointAt(const _Scalar& t) const -{ - return origin() + (direction()*t); -} - -/** \returns the parameter value of the intersection between \c *this and the given \a hyperplane - */ -template -template -inline _Scalar ParametrizedLine<_Scalar, _AmbientDim,_Options>::intersectionParameter(const Hyperplane<_Scalar, _AmbientDim, OtherOptions>& hyperplane) const -{ - return -(hyperplane.offset()+hyperplane.normal().dot(origin())) - / hyperplane.normal().dot(direction()); -} - - -/** \deprecated use intersectionParameter() - * \returns the parameter value of the intersection between \c *this and the given \a hyperplane - */ -template -template -inline _Scalar ParametrizedLine<_Scalar, _AmbientDim,_Options>::intersection(const Hyperplane<_Scalar, _AmbientDim, OtherOptions>& hyperplane) const -{ - return intersectionParameter(hyperplane); -} - -/** \returns the point of the intersection between \c *this and the given hyperplane - */ -template -template -inline typename ParametrizedLine<_Scalar, _AmbientDim,_Options>::VectorType -ParametrizedLine<_Scalar, _AmbientDim,_Options>::intersectionPoint(const Hyperplane<_Scalar, _AmbientDim, OtherOptions>& hyperplane) const -{ - return pointAt(intersectionParameter(hyperplane)); -} - -} // end namespace Eigen - -#endif // EIGEN_PARAMETRIZEDLINE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Geometry/Quaternion.h b/thirdparty/eigen-3.2.7/Eigen/src/Geometry/Quaternion.h deleted file mode 100644 index 25ed17bb..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Geometry/Quaternion.h +++ /dev/null @@ -1,776 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2010 Gael Guennebaud -// Copyright (C) 2009 Mathieu Gautier -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_QUATERNION_H -#define EIGEN_QUATERNION_H -namespace Eigen { - - -/*************************************************************************** -* Definition of QuaternionBase -* The implementation is at the end of the file -***************************************************************************/ - -namespace internal { -template -struct quaternionbase_assign_impl; -} - -/** \geometry_module \ingroup Geometry_Module - * \class QuaternionBase - * \brief Base class for quaternion expressions - * \tparam Derived derived type (CRTP) - * \sa class Quaternion - */ -template -class QuaternionBase : public RotationBase -{ - typedef RotationBase Base; -public: - using Base::operator*; - using Base::derived; - - typedef typename internal::traits::Scalar Scalar; - typedef typename NumTraits::Real RealScalar; - typedef typename internal::traits::Coefficients Coefficients; - enum { - Flags = Eigen::internal::traits::Flags - }; - - // typedef typename Matrix Coefficients; - /** the type of a 3D vector */ - typedef Matrix Vector3; - /** the equivalent rotation matrix type */ - typedef Matrix Matrix3; - /** the equivalent angle-axis type */ - typedef AngleAxis AngleAxisType; - - - - /** \returns the \c x coefficient */ - inline Scalar x() const { return this->derived().coeffs().coeff(0); } - /** \returns the \c y coefficient */ - inline Scalar y() const { return this->derived().coeffs().coeff(1); } - /** \returns the \c z coefficient */ - inline Scalar z() const { return this->derived().coeffs().coeff(2); } - /** \returns the \c w coefficient */ - inline Scalar w() const { return this->derived().coeffs().coeff(3); } - - /** \returns a reference to the \c x coefficient */ - inline Scalar& x() { return this->derived().coeffs().coeffRef(0); } - /** \returns a reference to the \c y coefficient */ - inline Scalar& y() { return this->derived().coeffs().coeffRef(1); } - /** \returns a reference to the \c z coefficient */ - inline Scalar& z() { return this->derived().coeffs().coeffRef(2); } - /** \returns a reference to the \c w coefficient */ - inline Scalar& w() { return this->derived().coeffs().coeffRef(3); } - - /** \returns a read-only vector expression of the imaginary part (x,y,z) */ - inline const VectorBlock vec() const { return coeffs().template head<3>(); } - - /** \returns a vector expression of the imaginary part (x,y,z) */ - inline VectorBlock vec() { return coeffs().template head<3>(); } - - /** \returns a read-only vector expression of the coefficients (x,y,z,w) */ - inline const typename internal::traits::Coefficients& coeffs() const { return derived().coeffs(); } - - /** \returns a vector expression of the coefficients (x,y,z,w) */ - inline typename internal::traits::Coefficients& coeffs() { return derived().coeffs(); } - - EIGEN_STRONG_INLINE QuaternionBase& operator=(const QuaternionBase& other); - template EIGEN_STRONG_INLINE Derived& operator=(const QuaternionBase& other); - -// disabled this copy operator as it is giving very strange compilation errors when compiling -// test_stdvector with GCC 4.4.2. This looks like a GCC bug though, so feel free to re-enable it if it's -// useful; however notice that we already have the templated operator= above and e.g. in MatrixBase -// we didn't have to add, in addition to templated operator=, such a non-templated copy operator. -// Derived& operator=(const QuaternionBase& other) -// { return operator=(other); } - - Derived& operator=(const AngleAxisType& aa); - template Derived& operator=(const MatrixBase& m); - - /** \returns a quaternion representing an identity rotation - * \sa MatrixBase::Identity() - */ - static inline Quaternion Identity() { return Quaternion(Scalar(1), Scalar(0), Scalar(0), Scalar(0)); } - - /** \sa QuaternionBase::Identity(), MatrixBase::setIdentity() - */ - inline QuaternionBase& setIdentity() { coeffs() << Scalar(0), Scalar(0), Scalar(0), Scalar(1); return *this; } - - /** \returns the squared norm of the quaternion's coefficients - * \sa QuaternionBase::norm(), MatrixBase::squaredNorm() - */ - inline Scalar squaredNorm() const { return coeffs().squaredNorm(); } - - /** \returns the norm of the quaternion's coefficients - * \sa QuaternionBase::squaredNorm(), MatrixBase::norm() - */ - inline Scalar norm() const { return coeffs().norm(); } - - /** Normalizes the quaternion \c *this - * \sa normalized(), MatrixBase::normalize() */ - inline void normalize() { coeffs().normalize(); } - /** \returns a normalized copy of \c *this - * \sa normalize(), MatrixBase::normalized() */ - inline Quaternion normalized() const { return Quaternion(coeffs().normalized()); } - - /** \returns the dot product of \c *this and \a other - * Geometrically speaking, the dot product of two unit quaternions - * corresponds to the cosine of half the angle between the two rotations. - * \sa angularDistance() - */ - template inline Scalar dot(const QuaternionBase& other) const { return coeffs().dot(other.coeffs()); } - - template Scalar angularDistance(const QuaternionBase& other) const; - - /** \returns an equivalent 3x3 rotation matrix */ - Matrix3 toRotationMatrix() const; - - /** \returns the quaternion which transform \a a into \a b through a rotation */ - template - Derived& setFromTwoVectors(const MatrixBase& a, const MatrixBase& b); - - template EIGEN_STRONG_INLINE Quaternion operator* (const QuaternionBase& q) const; - template EIGEN_STRONG_INLINE Derived& operator*= (const QuaternionBase& q); - - /** \returns the quaternion describing the inverse rotation */ - Quaternion inverse() const; - - /** \returns the conjugated quaternion */ - Quaternion conjugate() const; - - template Quaternion slerp(const Scalar& t, const QuaternionBase& other) const; - - /** \returns \c true if \c *this is approximately equal to \a other, within the precision - * determined by \a prec. - * - * \sa MatrixBase::isApprox() */ - template - bool isApprox(const QuaternionBase& other, const RealScalar& prec = NumTraits::dummy_precision()) const - { return coeffs().isApprox(other.coeffs(), prec); } - - /** return the result vector of \a v through the rotation*/ - EIGEN_STRONG_INLINE Vector3 _transformVector(const Vector3& v) const; - - /** \returns \c *this with scalar type casted to \a NewScalarType - * - * Note that if \a NewScalarType is equal to the current scalar type of \c *this - * then this function smartly returns a const reference to \c *this. - */ - template - inline typename internal::cast_return_type >::type cast() const - { - return typename internal::cast_return_type >::type(derived()); - } - -#ifdef EIGEN_QUATERNIONBASE_PLUGIN -# include EIGEN_QUATERNIONBASE_PLUGIN -#endif -}; - -/*************************************************************************** -* Definition/implementation of Quaternion -***************************************************************************/ - -/** \geometry_module \ingroup Geometry_Module - * - * \class Quaternion - * - * \brief The quaternion class used to represent 3D orientations and rotations - * - * \tparam _Scalar the scalar type, i.e., the type of the coefficients - * \tparam _Options controls the memory alignment of the coefficients. Can be \# AutoAlign or \# DontAlign. Default is AutoAlign. - * - * This class represents a quaternion \f$ w+xi+yj+zk \f$ that is a convenient representation of - * orientations and rotations of objects in three dimensions. Compared to other representations - * like Euler angles or 3x3 matrices, quaternions offer the following advantages: - * \li \b compact storage (4 scalars) - * \li \b efficient to compose (28 flops), - * \li \b stable spherical interpolation - * - * The following two typedefs are provided for convenience: - * \li \c Quaternionf for \c float - * \li \c Quaterniond for \c double - * - * \warning Operations interpreting the quaternion as rotation have undefined behavior if the quaternion is not normalized. - * - * \sa class AngleAxis, class Transform - */ - -namespace internal { -template -struct traits > -{ - typedef Quaternion<_Scalar,_Options> PlainObject; - typedef _Scalar Scalar; - typedef Matrix<_Scalar,4,1,_Options> Coefficients; - enum{ - IsAligned = internal::traits::Flags & AlignedBit, - Flags = IsAligned ? (AlignedBit | LvalueBit) : LvalueBit - }; -}; -} - -template -class Quaternion : public QuaternionBase > -{ - typedef QuaternionBase > Base; - enum { IsAligned = internal::traits::IsAligned }; - -public: - typedef _Scalar Scalar; - - EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Quaternion) - using Base::operator*=; - - typedef typename internal::traits::Coefficients Coefficients; - typedef typename Base::AngleAxisType AngleAxisType; - - /** Default constructor leaving the quaternion uninitialized. */ - inline Quaternion() {} - - /** Constructs and initializes the quaternion \f$ w+xi+yj+zk \f$ from - * its four coefficients \a w, \a x, \a y and \a z. - * - * \warning Note the order of the arguments: the real \a w coefficient first, - * while internally the coefficients are stored in the following order: - * [\c x, \c y, \c z, \c w] - */ - inline Quaternion(const Scalar& w, const Scalar& x, const Scalar& y, const Scalar& z) : m_coeffs(x, y, z, w){} - - /** Constructs and initialize a quaternion from the array data */ - inline Quaternion(const Scalar* data) : m_coeffs(data) {} - - /** Copy constructor */ - template EIGEN_STRONG_INLINE Quaternion(const QuaternionBase& other) { this->Base::operator=(other); } - - /** Constructs and initializes a quaternion from the angle-axis \a aa */ - explicit inline Quaternion(const AngleAxisType& aa) { *this = aa; } - - /** Constructs and initializes a quaternion from either: - * - a rotation matrix expression, - * - a 4D vector expression representing quaternion coefficients. - */ - template - explicit inline Quaternion(const MatrixBase& other) { *this = other; } - - /** Explicit copy constructor with scalar conversion */ - template - explicit inline Quaternion(const Quaternion& other) - { m_coeffs = other.coeffs().template cast(); } - - template - static Quaternion FromTwoVectors(const MatrixBase& a, const MatrixBase& b); - - inline Coefficients& coeffs() { return m_coeffs;} - inline const Coefficients& coeffs() const { return m_coeffs;} - - EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(IsAligned) - -protected: - Coefficients m_coeffs; - -#ifndef EIGEN_PARSED_BY_DOXYGEN - static EIGEN_STRONG_INLINE void _check_template_params() - { - EIGEN_STATIC_ASSERT( (_Options & DontAlign) == _Options, - INVALID_MATRIX_TEMPLATE_PARAMETERS) - } -#endif -}; - -/** \ingroup Geometry_Module - * single precision quaternion type */ -typedef Quaternion Quaternionf; -/** \ingroup Geometry_Module - * double precision quaternion type */ -typedef Quaternion Quaterniond; - -/*************************************************************************** -* Specialization of Map> -***************************************************************************/ - -namespace internal { - template - struct traits, _Options> > : traits > - { - typedef Map, _Options> Coefficients; - }; -} - -namespace internal { - template - struct traits, _Options> > : traits > - { - typedef Map, _Options> Coefficients; - typedef traits > TraitsBase; - enum { - Flags = TraitsBase::Flags & ~LvalueBit - }; - }; -} - -/** \ingroup Geometry_Module - * \brief Quaternion expression mapping a constant memory buffer - * - * \tparam _Scalar the type of the Quaternion coefficients - * \tparam _Options see class Map - * - * This is a specialization of class Map for Quaternion. This class allows to view - * a 4 scalar memory buffer as an Eigen's Quaternion object. - * - * \sa class Map, class Quaternion, class QuaternionBase - */ -template -class Map, _Options > - : public QuaternionBase, _Options> > -{ - typedef QuaternionBase, _Options> > Base; - - public: - typedef _Scalar Scalar; - typedef typename internal::traits::Coefficients Coefficients; - EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Map) - using Base::operator*=; - - /** Constructs a Mapped Quaternion object from the pointer \a coeffs - * - * The pointer \a coeffs must reference the four coefficients of Quaternion in the following order: - * \code *coeffs == {x, y, z, w} \endcode - * - * If the template parameter _Options is set to #Aligned, then the pointer coeffs must be aligned. */ - EIGEN_STRONG_INLINE Map(const Scalar* coeffs) : m_coeffs(coeffs) {} - - inline const Coefficients& coeffs() const { return m_coeffs;} - - protected: - const Coefficients m_coeffs; -}; - -/** \ingroup Geometry_Module - * \brief Expression of a quaternion from a memory buffer - * - * \tparam _Scalar the type of the Quaternion coefficients - * \tparam _Options see class Map - * - * This is a specialization of class Map for Quaternion. This class allows to view - * a 4 scalar memory buffer as an Eigen's Quaternion object. - * - * \sa class Map, class Quaternion, class QuaternionBase - */ -template -class Map, _Options > - : public QuaternionBase, _Options> > -{ - typedef QuaternionBase, _Options> > Base; - - public: - typedef _Scalar Scalar; - typedef typename internal::traits::Coefficients Coefficients; - EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Map) - using Base::operator*=; - - /** Constructs a Mapped Quaternion object from the pointer \a coeffs - * - * The pointer \a coeffs must reference the four coefficients of Quaternion in the following order: - * \code *coeffs == {x, y, z, w} \endcode - * - * If the template parameter _Options is set to #Aligned, then the pointer coeffs must be aligned. */ - EIGEN_STRONG_INLINE Map(Scalar* coeffs) : m_coeffs(coeffs) {} - - inline Coefficients& coeffs() { return m_coeffs; } - inline const Coefficients& coeffs() const { return m_coeffs; } - - protected: - Coefficients m_coeffs; -}; - -/** \ingroup Geometry_Module - * Map an unaligned array of single precision scalars as a quaternion */ -typedef Map, 0> QuaternionMapf; -/** \ingroup Geometry_Module - * Map an unaligned array of double precision scalars as a quaternion */ -typedef Map, 0> QuaternionMapd; -/** \ingroup Geometry_Module - * Map a 16-byte aligned array of single precision scalars as a quaternion */ -typedef Map, Aligned> QuaternionMapAlignedf; -/** \ingroup Geometry_Module - * Map a 16-byte aligned array of double precision scalars as a quaternion */ -typedef Map, Aligned> QuaternionMapAlignedd; - -/*************************************************************************** -* Implementation of QuaternionBase methods -***************************************************************************/ - -// Generic Quaternion * Quaternion product -// This product can be specialized for a given architecture via the Arch template argument. -namespace internal { -template struct quat_product -{ - static EIGEN_STRONG_INLINE Quaternion run(const QuaternionBase& a, const QuaternionBase& b){ - return Quaternion - ( - a.w() * b.w() - a.x() * b.x() - a.y() * b.y() - a.z() * b.z(), - a.w() * b.x() + a.x() * b.w() + a.y() * b.z() - a.z() * b.y(), - a.w() * b.y() + a.y() * b.w() + a.z() * b.x() - a.x() * b.z(), - a.w() * b.z() + a.z() * b.w() + a.x() * b.y() - a.y() * b.x() - ); - } -}; -} - -/** \returns the concatenation of two rotations as a quaternion-quaternion product */ -template -template -EIGEN_STRONG_INLINE Quaternion::Scalar> -QuaternionBase::operator* (const QuaternionBase& other) const -{ - EIGEN_STATIC_ASSERT((internal::is_same::value), - YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) - return internal::quat_product::Scalar, - internal::traits::IsAligned && internal::traits::IsAligned>::run(*this, other); -} - -/** \sa operator*(Quaternion) */ -template -template -EIGEN_STRONG_INLINE Derived& QuaternionBase::operator*= (const QuaternionBase& other) -{ - derived() = derived() * other.derived(); - return derived(); -} - -/** Rotation of a vector by a quaternion. - * \remarks If the quaternion is used to rotate several points (>1) - * then it is much more efficient to first convert it to a 3x3 Matrix. - * Comparison of the operation cost for n transformations: - * - Quaternion2: 30n - * - Via a Matrix3: 24 + 15n - */ -template -EIGEN_STRONG_INLINE typename QuaternionBase::Vector3 -QuaternionBase::_transformVector(const Vector3& v) const -{ - // Note that this algorithm comes from the optimization by hand - // of the conversion to a Matrix followed by a Matrix/Vector product. - // It appears to be much faster than the common algorithm found - // in the literature (30 versus 39 flops). It also requires two - // Vector3 as temporaries. - Vector3 uv = this->vec().cross(v); - uv += uv; - return v + this->w() * uv + this->vec().cross(uv); -} - -template -EIGEN_STRONG_INLINE QuaternionBase& QuaternionBase::operator=(const QuaternionBase& other) -{ - coeffs() = other.coeffs(); - return derived(); -} - -template -template -EIGEN_STRONG_INLINE Derived& QuaternionBase::operator=(const QuaternionBase& other) -{ - coeffs() = other.coeffs(); - return derived(); -} - -/** Set \c *this from an angle-axis \a aa and returns a reference to \c *this - */ -template -EIGEN_STRONG_INLINE Derived& QuaternionBase::operator=(const AngleAxisType& aa) -{ - using std::cos; - using std::sin; - Scalar ha = Scalar(0.5)*aa.angle(); // Scalar(0.5) to suppress precision loss warnings - this->w() = cos(ha); - this->vec() = sin(ha) * aa.axis(); - return derived(); -} - -/** Set \c *this from the expression \a xpr: - * - if \a xpr is a 4x1 vector, then \a xpr is assumed to be a quaternion - * - if \a xpr is a 3x3 matrix, then \a xpr is assumed to be rotation matrix - * and \a xpr is converted to a quaternion - */ - -template -template -inline Derived& QuaternionBase::operator=(const MatrixBase& xpr) -{ - EIGEN_STATIC_ASSERT((internal::is_same::value), - YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) - internal::quaternionbase_assign_impl::run(*this, xpr.derived()); - return derived(); -} - -/** Convert the quaternion to a 3x3 rotation matrix. The quaternion is required to - * be normalized, otherwise the result is undefined. - */ -template -inline typename QuaternionBase::Matrix3 -QuaternionBase::toRotationMatrix(void) const -{ - // NOTE if inlined, then gcc 4.2 and 4.4 get rid of the temporary (not gcc 4.3 !!) - // if not inlined then the cost of the return by value is huge ~ +35%, - // however, not inlining this function is an order of magnitude slower, so - // it has to be inlined, and so the return by value is not an issue - Matrix3 res; - - const Scalar tx = Scalar(2)*this->x(); - const Scalar ty = Scalar(2)*this->y(); - const Scalar tz = Scalar(2)*this->z(); - const Scalar twx = tx*this->w(); - const Scalar twy = ty*this->w(); - const Scalar twz = tz*this->w(); - const Scalar txx = tx*this->x(); - const Scalar txy = ty*this->x(); - const Scalar txz = tz*this->x(); - const Scalar tyy = ty*this->y(); - const Scalar tyz = tz*this->y(); - const Scalar tzz = tz*this->z(); - - res.coeffRef(0,0) = Scalar(1)-(tyy+tzz); - res.coeffRef(0,1) = txy-twz; - res.coeffRef(0,2) = txz+twy; - res.coeffRef(1,0) = txy+twz; - res.coeffRef(1,1) = Scalar(1)-(txx+tzz); - res.coeffRef(1,2) = tyz-twx; - res.coeffRef(2,0) = txz-twy; - res.coeffRef(2,1) = tyz+twx; - res.coeffRef(2,2) = Scalar(1)-(txx+tyy); - - return res; -} - -/** Sets \c *this to be a quaternion representing a rotation between - * the two arbitrary vectors \a a and \a b. In other words, the built - * rotation represent a rotation sending the line of direction \a a - * to the line of direction \a b, both lines passing through the origin. - * - * \returns a reference to \c *this. - * - * Note that the two input vectors do \b not have to be normalized, and - * do not need to have the same norm. - */ -template -template -inline Derived& QuaternionBase::setFromTwoVectors(const MatrixBase& a, const MatrixBase& b) -{ - using std::max; - using std::sqrt; - Vector3 v0 = a.normalized(); - Vector3 v1 = b.normalized(); - Scalar c = v1.dot(v0); - - // if dot == -1, vectors are nearly opposites - // => accurately compute the rotation axis by computing the - // intersection of the two planes. This is done by solving: - // x^T v0 = 0 - // x^T v1 = 0 - // under the constraint: - // ||x|| = 1 - // which yields a singular value problem - if (c < Scalar(-1)+NumTraits::dummy_precision()) - { - c = (max)(c,Scalar(-1)); - Matrix m; m << v0.transpose(), v1.transpose(); - JacobiSVD > svd(m, ComputeFullV); - Vector3 axis = svd.matrixV().col(2); - - Scalar w2 = (Scalar(1)+c)*Scalar(0.5); - this->w() = sqrt(w2); - this->vec() = axis * sqrt(Scalar(1) - w2); - return derived(); - } - Vector3 axis = v0.cross(v1); - Scalar s = sqrt((Scalar(1)+c)*Scalar(2)); - Scalar invs = Scalar(1)/s; - this->vec() = axis * invs; - this->w() = s * Scalar(0.5); - - return derived(); -} - - -/** Returns a quaternion representing a rotation between - * the two arbitrary vectors \a a and \a b. In other words, the built - * rotation represent a rotation sending the line of direction \a a - * to the line of direction \a b, both lines passing through the origin. - * - * \returns resulting quaternion - * - * Note that the two input vectors do \b not have to be normalized, and - * do not need to have the same norm. - */ -template -template -Quaternion Quaternion::FromTwoVectors(const MatrixBase& a, const MatrixBase& b) -{ - Quaternion quat; - quat.setFromTwoVectors(a, b); - return quat; -} - - -/** \returns the multiplicative inverse of \c *this - * Note that in most cases, i.e., if you simply want the opposite rotation, - * and/or the quaternion is normalized, then it is enough to use the conjugate. - * - * \sa QuaternionBase::conjugate() - */ -template -inline Quaternion::Scalar> QuaternionBase::inverse() const -{ - // FIXME should this function be called multiplicativeInverse and conjugate() be called inverse() or opposite() ?? - Scalar n2 = this->squaredNorm(); - if (n2 > Scalar(0)) - return Quaternion(conjugate().coeffs() / n2); - else - { - // return an invalid result to flag the error - return Quaternion(Coefficients::Zero()); - } -} - -/** \returns the conjugate of the \c *this which is equal to the multiplicative inverse - * if the quaternion is normalized. - * The conjugate of a quaternion represents the opposite rotation. - * - * \sa Quaternion2::inverse() - */ -template -inline Quaternion::Scalar> -QuaternionBase::conjugate() const -{ - return Quaternion(this->w(),-this->x(),-this->y(),-this->z()); -} - -/** \returns the angle (in radian) between two rotations - * \sa dot() - */ -template -template -inline typename internal::traits::Scalar -QuaternionBase::angularDistance(const QuaternionBase& other) const -{ - using std::atan2; - using std::abs; - Quaternion d = (*this) * other.conjugate(); - return Scalar(2) * atan2( d.vec().norm(), abs(d.w()) ); -} - - - -/** \returns the spherical linear interpolation between the two quaternions - * \c *this and \a other at the parameter \a t in [0;1]. - * - * This represents an interpolation for a constant motion between \c *this and \a other, - * see also http://en.wikipedia.org/wiki/Slerp. - */ -template -template -Quaternion::Scalar> -QuaternionBase::slerp(const Scalar& t, const QuaternionBase& other) const -{ - using std::acos; - using std::sin; - using std::abs; - static const Scalar one = Scalar(1) - NumTraits::epsilon(); - Scalar d = this->dot(other); - Scalar absD = abs(d); - - Scalar scale0; - Scalar scale1; - - if(absD>=one) - { - scale0 = Scalar(1) - t; - scale1 = t; - } - else - { - // theta is the angle between the 2 quaternions - Scalar theta = acos(absD); - Scalar sinTheta = sin(theta); - - scale0 = sin( ( Scalar(1) - t ) * theta) / sinTheta; - scale1 = sin( ( t * theta) ) / sinTheta; - } - if(d(scale0 * coeffs() + scale1 * other.coeffs()); -} - -namespace internal { - -// set from a rotation matrix -template -struct quaternionbase_assign_impl -{ - typedef typename Other::Scalar Scalar; - typedef DenseIndex Index; - template static inline void run(QuaternionBase& q, const Other& mat) - { - using std::sqrt; - // This algorithm comes from "Quaternion Calculus and Fast Animation", - // Ken Shoemake, 1987 SIGGRAPH course notes - Scalar t = mat.trace(); - if (t > Scalar(0)) - { - t = sqrt(t + Scalar(1.0)); - q.w() = Scalar(0.5)*t; - t = Scalar(0.5)/t; - q.x() = (mat.coeff(2,1) - mat.coeff(1,2)) * t; - q.y() = (mat.coeff(0,2) - mat.coeff(2,0)) * t; - q.z() = (mat.coeff(1,0) - mat.coeff(0,1)) * t; - } - else - { - DenseIndex i = 0; - if (mat.coeff(1,1) > mat.coeff(0,0)) - i = 1; - if (mat.coeff(2,2) > mat.coeff(i,i)) - i = 2; - DenseIndex j = (i+1)%3; - DenseIndex k = (j+1)%3; - - t = sqrt(mat.coeff(i,i)-mat.coeff(j,j)-mat.coeff(k,k) + Scalar(1.0)); - q.coeffs().coeffRef(i) = Scalar(0.5) * t; - t = Scalar(0.5)/t; - q.w() = (mat.coeff(k,j)-mat.coeff(j,k))*t; - q.coeffs().coeffRef(j) = (mat.coeff(j,i)+mat.coeff(i,j))*t; - q.coeffs().coeffRef(k) = (mat.coeff(k,i)+mat.coeff(i,k))*t; - } - } -}; - -// set from a vector of coefficients assumed to be a quaternion -template -struct quaternionbase_assign_impl -{ - typedef typename Other::Scalar Scalar; - template static inline void run(QuaternionBase& q, const Other& vec) - { - q.coeffs() = vec; - } -}; - -} // end namespace internal - -} // end namespace Eigen - -#endif // EIGEN_QUATERNION_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Geometry/Rotation2D.h b/thirdparty/eigen-3.2.7/Eigen/src/Geometry/Rotation2D.h deleted file mode 100644 index a2d59fce..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Geometry/Rotation2D.h +++ /dev/null @@ -1,160 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_ROTATION2D_H -#define EIGEN_ROTATION2D_H - -namespace Eigen { - -/** \geometry_module \ingroup Geometry_Module - * - * \class Rotation2D - * - * \brief Represents a rotation/orientation in a 2 dimensional space. - * - * \param _Scalar the scalar type, i.e., the type of the coefficients - * - * This class is equivalent to a single scalar representing a counter clock wise rotation - * as a single angle in radian. It provides some additional features such as the automatic - * conversion from/to a 2x2 rotation matrix. Moreover this class aims to provide a similar - * interface to Quaternion in order to facilitate the writing of generic algorithms - * dealing with rotations. - * - * \sa class Quaternion, class Transform - */ - -namespace internal { - -template struct traits > -{ - typedef _Scalar Scalar; -}; -} // end namespace internal - -template -class Rotation2D : public RotationBase,2> -{ - typedef RotationBase,2> Base; - -public: - - using Base::operator*; - - enum { Dim = 2 }; - /** the scalar type of the coefficients */ - typedef _Scalar Scalar; - typedef Matrix Vector2; - typedef Matrix Matrix2; - -protected: - - Scalar m_angle; - -public: - - /** Construct a 2D counter clock wise rotation from the angle \a a in radian. */ - inline Rotation2D(const Scalar& a) : m_angle(a) {} - - /** Default constructor wihtout initialization. The represented rotation is undefined. */ - Rotation2D() {} - - /** \returns the rotation angle */ - inline Scalar angle() const { return m_angle; } - - /** \returns a read-write reference to the rotation angle */ - inline Scalar& angle() { return m_angle; } - - /** \returns the inverse rotation */ - inline Rotation2D inverse() const { return -m_angle; } - - /** Concatenates two rotations */ - inline Rotation2D operator*(const Rotation2D& other) const - { return m_angle + other.m_angle; } - - /** Concatenates two rotations */ - inline Rotation2D& operator*=(const Rotation2D& other) - { m_angle += other.m_angle; return *this; } - - /** Applies the rotation to a 2D vector */ - Vector2 operator* (const Vector2& vec) const - { return toRotationMatrix() * vec; } - - template - Rotation2D& fromRotationMatrix(const MatrixBase& m); - Matrix2 toRotationMatrix() const; - - /** \returns the spherical interpolation between \c *this and \a other using - * parameter \a t. It is in fact equivalent to a linear interpolation. - */ - inline Rotation2D slerp(const Scalar& t, const Rotation2D& other) const - { return m_angle * (1-t) + other.angle() * t; } - - /** \returns \c *this with scalar type casted to \a NewScalarType - * - * Note that if \a NewScalarType is equal to the current scalar type of \c *this - * then this function smartly returns a const reference to \c *this. - */ - template - inline typename internal::cast_return_type >::type cast() const - { return typename internal::cast_return_type >::type(*this); } - - /** Copy constructor with scalar type conversion */ - template - inline explicit Rotation2D(const Rotation2D& other) - { - m_angle = Scalar(other.angle()); - } - - static inline Rotation2D Identity() { return Rotation2D(0); } - - /** \returns \c true if \c *this is approximately equal to \a other, within the precision - * determined by \a prec. - * - * \sa MatrixBase::isApprox() */ - bool isApprox(const Rotation2D& other, const typename NumTraits::Real& prec = NumTraits::dummy_precision()) const - { return internal::isApprox(m_angle,other.m_angle, prec); } -}; - -/** \ingroup Geometry_Module - * single precision 2D rotation type */ -typedef Rotation2D Rotation2Df; -/** \ingroup Geometry_Module - * double precision 2D rotation type */ -typedef Rotation2D Rotation2Dd; - -/** Set \c *this from a 2x2 rotation matrix \a mat. - * In other words, this function extract the rotation angle - * from the rotation matrix. - */ -template -template -Rotation2D& Rotation2D::fromRotationMatrix(const MatrixBase& mat) -{ - using std::atan2; - EIGEN_STATIC_ASSERT(Derived::RowsAtCompileTime==2 && Derived::ColsAtCompileTime==2,YOU_MADE_A_PROGRAMMING_MISTAKE) - m_angle = atan2(mat.coeff(1,0), mat.coeff(0,0)); - return *this; -} - -/** Constructs and \returns an equivalent 2x2 rotation matrix. - */ -template -typename Rotation2D::Matrix2 -Rotation2D::toRotationMatrix(void) const -{ - using std::sin; - using std::cos; - Scalar sinA = sin(m_angle); - Scalar cosA = cos(m_angle); - return (Matrix2() << cosA, -sinA, sinA, cosA).finished(); -} - -} // end namespace Eigen - -#endif // EIGEN_ROTATION2D_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Geometry/RotationBase.h b/thirdparty/eigen-3.2.7/Eigen/src/Geometry/RotationBase.h deleted file mode 100644 index b88661de..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Geometry/RotationBase.h +++ /dev/null @@ -1,206 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_ROTATIONBASE_H -#define EIGEN_ROTATIONBASE_H - -namespace Eigen { - -// forward declaration -namespace internal { -template -struct rotation_base_generic_product_selector; -} - -/** \class RotationBase - * - * \brief Common base class for compact rotation representations - * - * \param Derived is the derived type, i.e., a rotation type - * \param _Dim the dimension of the space - */ -template -class RotationBase -{ - public: - enum { Dim = _Dim }; - /** the scalar type of the coefficients */ - typedef typename internal::traits::Scalar Scalar; - - /** corresponding linear transformation matrix type */ - typedef Matrix RotationMatrixType; - typedef Matrix VectorType; - - public: - inline const Derived& derived() const { return *static_cast(this); } - inline Derived& derived() { return *static_cast(this); } - - /** \returns an equivalent rotation matrix */ - inline RotationMatrixType toRotationMatrix() const { return derived().toRotationMatrix(); } - - /** \returns an equivalent rotation matrix - * This function is added to be conform with the Transform class' naming scheme. - */ - inline RotationMatrixType matrix() const { return derived().toRotationMatrix(); } - - /** \returns the inverse rotation */ - inline Derived inverse() const { return derived().inverse(); } - - /** \returns the concatenation of the rotation \c *this with a translation \a t */ - inline Transform operator*(const Translation& t) const - { return Transform(*this) * t; } - - /** \returns the concatenation of the rotation \c *this with a uniform scaling \a s */ - inline RotationMatrixType operator*(const UniformScaling& s) const - { return toRotationMatrix() * s.factor(); } - - /** \returns the concatenation of the rotation \c *this with a generic expression \a e - * \a e can be: - * - a DimxDim linear transformation matrix - * - a DimxDim diagonal matrix (axis aligned scaling) - * - a vector of size Dim - */ - template - EIGEN_STRONG_INLINE typename internal::rotation_base_generic_product_selector::ReturnType - operator*(const EigenBase& e) const - { return internal::rotation_base_generic_product_selector::run(derived(), e.derived()); } - - /** \returns the concatenation of a linear transformation \a l with the rotation \a r */ - template friend - inline RotationMatrixType operator*(const EigenBase& l, const Derived& r) - { return l.derived() * r.toRotationMatrix(); } - - /** \returns the concatenation of a scaling \a l with the rotation \a r */ - friend inline Transform operator*(const DiagonalMatrix& l, const Derived& r) - { - Transform res(r); - res.linear().applyOnTheLeft(l); - return res; - } - - /** \returns the concatenation of the rotation \c *this with a transformation \a t */ - template - inline Transform operator*(const Transform& t) const - { return toRotationMatrix() * t; } - - template - inline VectorType _transformVector(const OtherVectorType& v) const - { return toRotationMatrix() * v; } -}; - -namespace internal { - -// implementation of the generic product rotation * matrix -template -struct rotation_base_generic_product_selector -{ - enum { Dim = RotationDerived::Dim }; - typedef Matrix ReturnType; - static inline ReturnType run(const RotationDerived& r, const MatrixType& m) - { return r.toRotationMatrix() * m; } -}; - -template -struct rotation_base_generic_product_selector< RotationDerived, DiagonalMatrix, false > -{ - typedef Transform ReturnType; - static inline ReturnType run(const RotationDerived& r, const DiagonalMatrix& m) - { - ReturnType res(r); - res.linear() *= m; - return res; - } -}; - -template -struct rotation_base_generic_product_selector -{ - enum { Dim = RotationDerived::Dim }; - typedef Matrix ReturnType; - static EIGEN_STRONG_INLINE ReturnType run(const RotationDerived& r, const OtherVectorType& v) - { - return r._transformVector(v); - } -}; - -} // end namespace internal - -/** \geometry_module - * - * \brief Constructs a Dim x Dim rotation matrix from the rotation \a r - */ -template -template -Matrix<_Scalar, _Rows, _Cols, _Storage, _MaxRows, _MaxCols> -::Matrix(const RotationBase& r) -{ - EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Matrix,int(OtherDerived::Dim),int(OtherDerived::Dim)) - *this = r.toRotationMatrix(); -} - -/** \geometry_module - * - * \brief Set a Dim x Dim rotation matrix from the rotation \a r - */ -template -template -Matrix<_Scalar, _Rows, _Cols, _Storage, _MaxRows, _MaxCols>& -Matrix<_Scalar, _Rows, _Cols, _Storage, _MaxRows, _MaxCols> -::operator=(const RotationBase& r) -{ - EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Matrix,int(OtherDerived::Dim),int(OtherDerived::Dim)) - return *this = r.toRotationMatrix(); -} - -namespace internal { - -/** \internal - * - * Helper function to return an arbitrary rotation object to a rotation matrix. - * - * \param Scalar the numeric type of the matrix coefficients - * \param Dim the dimension of the current space - * - * It returns a Dim x Dim fixed size matrix. - * - * Default specializations are provided for: - * - any scalar type (2D), - * - any matrix expression, - * - any type based on RotationBase (e.g., Quaternion, AngleAxis, Rotation2D) - * - * Currently toRotationMatrix is only used by Transform. - * - * \sa class Transform, class Rotation2D, class Quaternion, class AngleAxis - */ -template -static inline Matrix toRotationMatrix(const Scalar& s) -{ - EIGEN_STATIC_ASSERT(Dim==2,YOU_MADE_A_PROGRAMMING_MISTAKE) - return Rotation2D(s).toRotationMatrix(); -} - -template -static inline Matrix toRotationMatrix(const RotationBase& r) -{ - return r.toRotationMatrix(); -} - -template -static inline const MatrixBase& toRotationMatrix(const MatrixBase& mat) -{ - EIGEN_STATIC_ASSERT(OtherDerived::RowsAtCompileTime==Dim && OtherDerived::ColsAtCompileTime==Dim, - YOU_MADE_A_PROGRAMMING_MISTAKE) - return mat; -} - -} // end namespace internal - -} // end namespace Eigen - -#endif // EIGEN_ROTATIONBASE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Geometry/Scaling.h b/thirdparty/eigen-3.2.7/Eigen/src/Geometry/Scaling.h deleted file mode 100644 index 1c25f36f..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Geometry/Scaling.h +++ /dev/null @@ -1,166 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_SCALING_H -#define EIGEN_SCALING_H - -namespace Eigen { - -/** \geometry_module \ingroup Geometry_Module - * - * \class Scaling - * - * \brief Represents a generic uniform scaling transformation - * - * \param _Scalar the scalar type, i.e., the type of the coefficients. - * - * This class represent a uniform scaling transformation. It is the return - * type of Scaling(Scalar), and most of the time this is the only way it - * is used. In particular, this class is not aimed to be used to store a scaling transformation, - * but rather to make easier the constructions and updates of Transform objects. - * - * To represent an axis aligned scaling, use the DiagonalMatrix class. - * - * \sa Scaling(), class DiagonalMatrix, MatrixBase::asDiagonal(), class Translation, class Transform - */ -template -class UniformScaling -{ -public: - /** the scalar type of the coefficients */ - typedef _Scalar Scalar; - -protected: - - Scalar m_factor; - -public: - - /** Default constructor without initialization. */ - UniformScaling() {} - /** Constructs and initialize a uniform scaling transformation */ - explicit inline UniformScaling(const Scalar& s) : m_factor(s) {} - - inline const Scalar& factor() const { return m_factor; } - inline Scalar& factor() { return m_factor; } - - /** Concatenates two uniform scaling */ - inline UniformScaling operator* (const UniformScaling& other) const - { return UniformScaling(m_factor * other.factor()); } - - /** Concatenates a uniform scaling and a translation */ - template - inline Transform operator* (const Translation& t) const; - - /** Concatenates a uniform scaling and an affine transformation */ - template - inline Transform operator* (const Transform& t) const - { - Transform res = t; - res.prescale(factor()); - return res; -} - - /** Concatenates a uniform scaling and a linear transformation matrix */ - // TODO returns an expression - template - inline typename internal::plain_matrix_type::type operator* (const MatrixBase& other) const - { return other * m_factor; } - - template - inline Matrix operator*(const RotationBase& r) const - { return r.toRotationMatrix() * m_factor; } - - /** \returns the inverse scaling */ - inline UniformScaling inverse() const - { return UniformScaling(Scalar(1)/m_factor); } - - /** \returns \c *this with scalar type casted to \a NewScalarType - * - * Note that if \a NewScalarType is equal to the current scalar type of \c *this - * then this function smartly returns a const reference to \c *this. - */ - template - inline UniformScaling cast() const - { return UniformScaling(NewScalarType(m_factor)); } - - /** Copy constructor with scalar type conversion */ - template - inline explicit UniformScaling(const UniformScaling& other) - { m_factor = Scalar(other.factor()); } - - /** \returns \c true if \c *this is approximately equal to \a other, within the precision - * determined by \a prec. - * - * \sa MatrixBase::isApprox() */ - bool isApprox(const UniformScaling& other, const typename NumTraits::Real& prec = NumTraits::dummy_precision()) const - { return internal::isApprox(m_factor, other.factor(), prec); } - -}; - -/** Concatenates a linear transformation matrix and a uniform scaling */ -// NOTE this operator is defiend in MatrixBase and not as a friend function -// of UniformScaling to fix an internal crash of Intel's ICC -template typename MatrixBase::ScalarMultipleReturnType -MatrixBase::operator*(const UniformScaling& s) const -{ return derived() * s.factor(); } - -/** Constructs a uniform scaling from scale factor \a s */ -static inline UniformScaling Scaling(float s) { return UniformScaling(s); } -/** Constructs a uniform scaling from scale factor \a s */ -static inline UniformScaling Scaling(double s) { return UniformScaling(s); } -/** Constructs a uniform scaling from scale factor \a s */ -template -static inline UniformScaling > Scaling(const std::complex& s) -{ return UniformScaling >(s); } - -/** Constructs a 2D axis aligned scaling */ -template -static inline DiagonalMatrix Scaling(const Scalar& sx, const Scalar& sy) -{ return DiagonalMatrix(sx, sy); } -/** Constructs a 3D axis aligned scaling */ -template -static inline DiagonalMatrix Scaling(const Scalar& sx, const Scalar& sy, const Scalar& sz) -{ return DiagonalMatrix(sx, sy, sz); } - -/** Constructs an axis aligned scaling expression from vector expression \a coeffs - * This is an alias for coeffs.asDiagonal() - */ -template -static inline const DiagonalWrapper Scaling(const MatrixBase& coeffs) -{ return coeffs.asDiagonal(); } - -/** \addtogroup Geometry_Module */ -//@{ -/** \deprecated */ -typedef DiagonalMatrix AlignedScaling2f; -/** \deprecated */ -typedef DiagonalMatrix AlignedScaling2d; -/** \deprecated */ -typedef DiagonalMatrix AlignedScaling3f; -/** \deprecated */ -typedef DiagonalMatrix AlignedScaling3d; -//@} - -template -template -inline Transform -UniformScaling::operator* (const Translation& t) const -{ - Transform res; - res.matrix().setZero(); - res.linear().diagonal().fill(factor()); - res.translation() = factor() * t.vector(); - res(Dim,Dim) = Scalar(1); - return res; -} - -} // end namespace Eigen - -#endif // EIGEN_SCALING_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Geometry/Transform.h b/thirdparty/eigen-3.2.7/Eigen/src/Geometry/Transform.h deleted file mode 100644 index e786e535..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Geometry/Transform.h +++ /dev/null @@ -1,1455 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud -// Copyright (C) 2009 Benoit Jacob -// Copyright (C) 2010 Hauke Heibel -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_TRANSFORM_H -#define EIGEN_TRANSFORM_H - -namespace Eigen { - -namespace internal { - -template -struct transform_traits -{ - enum - { - Dim = Transform::Dim, - HDim = Transform::HDim, - Mode = Transform::Mode, - IsProjective = (int(Mode)==int(Projective)) - }; -}; - -template< typename TransformType, - typename MatrixType, - int Case = transform_traits::IsProjective ? 0 - : int(MatrixType::RowsAtCompileTime) == int(transform_traits::HDim) ? 1 - : 2> -struct transform_right_product_impl; - -template< typename Other, - int Mode, - int Options, - int Dim, - int HDim, - int OtherRows=Other::RowsAtCompileTime, - int OtherCols=Other::ColsAtCompileTime> -struct transform_left_product_impl; - -template< typename Lhs, - typename Rhs, - bool AnyProjective = - transform_traits::IsProjective || - transform_traits::IsProjective> -struct transform_transform_product_impl; - -template< typename Other, - int Mode, - int Options, - int Dim, - int HDim, - int OtherRows=Other::RowsAtCompileTime, - int OtherCols=Other::ColsAtCompileTime> -struct transform_construct_from_matrix; - -template struct transform_take_affine_part; - -template struct transform_make_affine; - -} // end namespace internal - -/** \geometry_module \ingroup Geometry_Module - * - * \class Transform - * - * \brief Represents an homogeneous transformation in a N dimensional space - * - * \tparam _Scalar the scalar type, i.e., the type of the coefficients - * \tparam _Dim the dimension of the space - * \tparam _Mode the type of the transformation. Can be: - * - #Affine: the transformation is stored as a (Dim+1)^2 matrix, - * where the last row is assumed to be [0 ... 0 1]. - * - #AffineCompact: the transformation is stored as a (Dim)x(Dim+1) matrix. - * - #Projective: the transformation is stored as a (Dim+1)^2 matrix - * without any assumption. - * \tparam _Options has the same meaning as in class Matrix. It allows to specify DontAlign and/or RowMajor. - * These Options are passed directly to the underlying matrix type. - * - * The homography is internally represented and stored by a matrix which - * is available through the matrix() method. To understand the behavior of - * this class you have to think a Transform object as its internal - * matrix representation. The chosen convention is right multiply: - * - * \code v' = T * v \endcode - * - * Therefore, an affine transformation matrix M is shaped like this: - * - * \f$ \left( \begin{array}{cc} - * linear & translation\\ - * 0 ... 0 & 1 - * \end{array} \right) \f$ - * - * Note that for a projective transformation the last row can be anything, - * and then the interpretation of different parts might be sightly different. - * - * However, unlike a plain matrix, the Transform class provides many features - * simplifying both its assembly and usage. In particular, it can be composed - * with any other transformations (Transform,Translation,RotationBase,Matrix) - * and can be directly used to transform implicit homogeneous vectors. All these - * operations are handled via the operator*. For the composition of transformations, - * its principle consists to first convert the right/left hand sides of the product - * to a compatible (Dim+1)^2 matrix and then perform a pure matrix product. - * Of course, internally, operator* tries to perform the minimal number of operations - * according to the nature of each terms. Likewise, when applying the transform - * to non homogeneous vectors, the latters are automatically promoted to homogeneous - * one before doing the matrix product. The convertions to homogeneous representations - * are performed as follow: - * - * \b Translation t (Dim)x(1): - * \f$ \left( \begin{array}{cc} - * I & t \\ - * 0\,...\,0 & 1 - * \end{array} \right) \f$ - * - * \b Rotation R (Dim)x(Dim): - * \f$ \left( \begin{array}{cc} - * R & 0\\ - * 0\,...\,0 & 1 - * \end{array} \right) \f$ - * - * \b Linear \b Matrix L (Dim)x(Dim): - * \f$ \left( \begin{array}{cc} - * L & 0\\ - * 0\,...\,0 & 1 - * \end{array} \right) \f$ - * - * \b Affine \b Matrix A (Dim)x(Dim+1): - * \f$ \left( \begin{array}{c} - * A\\ - * 0\,...\,0\,1 - * \end{array} \right) \f$ - * - * \b Column \b vector v (Dim)x(1): - * \f$ \left( \begin{array}{c} - * v\\ - * 1 - * \end{array} \right) \f$ - * - * \b Set \b of \b column \b vectors V1...Vn (Dim)x(n): - * \f$ \left( \begin{array}{ccc} - * v_1 & ... & v_n\\ - * 1 & ... & 1 - * \end{array} \right) \f$ - * - * The concatenation of a Transform object with any kind of other transformation - * always returns a Transform object. - * - * A little exception to the "as pure matrix product" rule is the case of the - * transformation of non homogeneous vectors by an affine transformation. In - * that case the last matrix row can be ignored, and the product returns non - * homogeneous vectors. - * - * Since, for instance, a Dim x Dim matrix is interpreted as a linear transformation, - * it is not possible to directly transform Dim vectors stored in a Dim x Dim matrix. - * The solution is either to use a Dim x Dynamic matrix or explicitly request a - * vector transformation by making the vector homogeneous: - * \code - * m' = T * m.colwise().homogeneous(); - * \endcode - * Note that there is zero overhead. - * - * Conversion methods from/to Qt's QMatrix and QTransform are available if the - * preprocessor token EIGEN_QT_SUPPORT is defined. - * - * This class can be extended with the help of the plugin mechanism described on the page - * \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_TRANSFORM_PLUGIN. - * - * \sa class Matrix, class Quaternion - */ -template -class Transform -{ -public: - EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_Dim==Dynamic ? Dynamic : (_Dim+1)*(_Dim+1)) - enum { - Mode = _Mode, - Options = _Options, - Dim = _Dim, ///< space dimension in which the transformation holds - HDim = _Dim+1, ///< size of a respective homogeneous vector - Rows = int(Mode)==(AffineCompact) ? Dim : HDim - }; - /** the scalar type of the coefficients */ - typedef _Scalar Scalar; - typedef DenseIndex Index; - /** type of the matrix used to represent the transformation */ - typedef typename internal::make_proper_matrix_type::type MatrixType; - /** constified MatrixType */ - typedef const MatrixType ConstMatrixType; - /** type of the matrix used to represent the linear part of the transformation */ - typedef Matrix LinearMatrixType; - /** type of read/write reference to the linear part of the transformation */ - typedef Block LinearPart; - /** type of read reference to the linear part of the transformation */ - typedef const Block ConstLinearPart; - /** type of read/write reference to the affine part of the transformation */ - typedef typename internal::conditional >::type AffinePart; - /** type of read reference to the affine part of the transformation */ - typedef typename internal::conditional >::type ConstAffinePart; - /** type of a vector */ - typedef Matrix VectorType; - /** type of a read/write reference to the translation part of the rotation */ - typedef Block TranslationPart; - /** type of a read reference to the translation part of the rotation */ - typedef const Block ConstTranslationPart; - /** corresponding translation type */ - typedef Translation TranslationType; - - // this intermediate enum is needed to avoid an ICE with gcc 3.4 and 4.0 - enum { TransformTimeDiagonalMode = ((Mode==int(Isometry))?Affine:int(Mode)) }; - /** The return type of the product between a diagonal matrix and a transform */ - typedef Transform TransformTimeDiagonalReturnType; - -protected: - - MatrixType m_matrix; - -public: - - /** Default constructor without initialization of the meaningful coefficients. - * If Mode==Affine, then the last row is set to [0 ... 0 1] */ - inline Transform() - { - check_template_params(); - internal::transform_make_affine<(int(Mode)==Affine) ? Affine : AffineCompact>::run(m_matrix); - } - - inline Transform(const Transform& other) - { - check_template_params(); - m_matrix = other.m_matrix; - } - - inline explicit Transform(const TranslationType& t) - { - check_template_params(); - *this = t; - } - inline explicit Transform(const UniformScaling& s) - { - check_template_params(); - *this = s; - } - template - inline explicit Transform(const RotationBase& r) - { - check_template_params(); - *this = r; - } - - inline Transform& operator=(const Transform& other) - { m_matrix = other.m_matrix; return *this; } - - typedef internal::transform_take_affine_part take_affine_part; - - /** Constructs and initializes a transformation from a Dim^2 or a (Dim+1)^2 matrix. */ - template - inline explicit Transform(const EigenBase& other) - { - EIGEN_STATIC_ASSERT((internal::is_same::value), - YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY); - - check_template_params(); - internal::transform_construct_from_matrix::run(this, other.derived()); - } - - /** Set \c *this from a Dim^2 or (Dim+1)^2 matrix. */ - template - inline Transform& operator=(const EigenBase& other) - { - EIGEN_STATIC_ASSERT((internal::is_same::value), - YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY); - - internal::transform_construct_from_matrix::run(this, other.derived()); - return *this; - } - - template - inline Transform(const Transform& other) - { - check_template_params(); - // only the options change, we can directly copy the matrices - m_matrix = other.matrix(); - } - - template - inline Transform(const Transform& other) - { - check_template_params(); - // prevent conversions as: - // Affine | AffineCompact | Isometry = Projective - EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(OtherMode==int(Projective), Mode==int(Projective)), - YOU_PERFORMED_AN_INVALID_TRANSFORMATION_CONVERSION) - - // prevent conversions as: - // Isometry = Affine | AffineCompact - EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(OtherMode==int(Affine)||OtherMode==int(AffineCompact), Mode!=int(Isometry)), - YOU_PERFORMED_AN_INVALID_TRANSFORMATION_CONVERSION) - - enum { ModeIsAffineCompact = Mode == int(AffineCompact), - OtherModeIsAffineCompact = OtherMode == int(AffineCompact) - }; - - if(ModeIsAffineCompact == OtherModeIsAffineCompact) - { - // We need the block expression because the code is compiled for all - // combinations of transformations and will trigger a compile time error - // if one tries to assign the matrices directly - m_matrix.template block(0,0) = other.matrix().template block(0,0); - makeAffine(); - } - else if(OtherModeIsAffineCompact) - { - typedef typename Transform::MatrixType OtherMatrixType; - internal::transform_construct_from_matrix::run(this, other.matrix()); - } - else - { - // here we know that Mode == AffineCompact and OtherMode != AffineCompact. - // if OtherMode were Projective, the static assert above would already have caught it. - // So the only possibility is that OtherMode == Affine - linear() = other.linear(); - translation() = other.translation(); - } - } - - template - Transform(const ReturnByValue& other) - { - check_template_params(); - other.evalTo(*this); - } - - template - Transform& operator=(const ReturnByValue& other) - { - other.evalTo(*this); - return *this; - } - - #ifdef EIGEN_QT_SUPPORT - inline Transform(const QMatrix& other); - inline Transform& operator=(const QMatrix& other); - inline QMatrix toQMatrix(void) const; - inline Transform(const QTransform& other); - inline Transform& operator=(const QTransform& other); - inline QTransform toQTransform(void) const; - #endif - - /** shortcut for m_matrix(row,col); - * \sa MatrixBase::operator(Index,Index) const */ - inline Scalar operator() (Index row, Index col) const { return m_matrix(row,col); } - /** shortcut for m_matrix(row,col); - * \sa MatrixBase::operator(Index,Index) */ - inline Scalar& operator() (Index row, Index col) { return m_matrix(row,col); } - - /** \returns a read-only expression of the transformation matrix */ - inline const MatrixType& matrix() const { return m_matrix; } - /** \returns a writable expression of the transformation matrix */ - inline MatrixType& matrix() { return m_matrix; } - - /** \returns a read-only expression of the linear part of the transformation */ - inline ConstLinearPart linear() const { return ConstLinearPart(m_matrix,0,0); } - /** \returns a writable expression of the linear part of the transformation */ - inline LinearPart linear() { return LinearPart(m_matrix,0,0); } - - /** \returns a read-only expression of the Dim x HDim affine part of the transformation */ - inline ConstAffinePart affine() const { return take_affine_part::run(m_matrix); } - /** \returns a writable expression of the Dim x HDim affine part of the transformation */ - inline AffinePart affine() { return take_affine_part::run(m_matrix); } - - /** \returns a read-only expression of the translation vector of the transformation */ - inline ConstTranslationPart translation() const { return ConstTranslationPart(m_matrix,0,Dim); } - /** \returns a writable expression of the translation vector of the transformation */ - inline TranslationPart translation() { return TranslationPart(m_matrix,0,Dim); } - - /** \returns an expression of the product between the transform \c *this and a matrix expression \a other - * - * The right hand side \a other might be either: - * \li a vector of size Dim, - * \li an homogeneous vector of size Dim+1, - * \li a set of vectors of size Dim x Dynamic, - * \li a set of homogeneous vectors of size Dim+1 x Dynamic, - * \li a linear transformation matrix of size Dim x Dim, - * \li an affine transformation matrix of size Dim x Dim+1, - * \li a transformation matrix of size Dim+1 x Dim+1. - */ - // note: this function is defined here because some compilers cannot find the respective declaration - template - EIGEN_STRONG_INLINE const typename internal::transform_right_product_impl::ResultType - operator * (const EigenBase &other) const - { return internal::transform_right_product_impl::run(*this,other.derived()); } - - /** \returns the product expression of a transformation matrix \a a times a transform \a b - * - * The left hand side \a other might be either: - * \li a linear transformation matrix of size Dim x Dim, - * \li an affine transformation matrix of size Dim x Dim+1, - * \li a general transformation matrix of size Dim+1 x Dim+1. - */ - template friend - inline const typename internal::transform_left_product_impl::ResultType - operator * (const EigenBase &a, const Transform &b) - { return internal::transform_left_product_impl::run(a.derived(),b); } - - /** \returns The product expression of a transform \a a times a diagonal matrix \a b - * - * The rhs diagonal matrix is interpreted as an affine scaling transformation. The - * product results in a Transform of the same type (mode) as the lhs only if the lhs - * mode is no isometry. In that case, the returned transform is an affinity. - */ - template - inline const TransformTimeDiagonalReturnType - operator * (const DiagonalBase &b) const - { - TransformTimeDiagonalReturnType res(*this); - res.linear() *= b; - return res; - } - - /** \returns The product expression of a diagonal matrix \a a times a transform \a b - * - * The lhs diagonal matrix is interpreted as an affine scaling transformation. The - * product results in a Transform of the same type (mode) as the lhs only if the lhs - * mode is no isometry. In that case, the returned transform is an affinity. - */ - template - friend inline TransformTimeDiagonalReturnType - operator * (const DiagonalBase &a, const Transform &b) - { - TransformTimeDiagonalReturnType res; - res.linear().noalias() = a*b.linear(); - res.translation().noalias() = a*b.translation(); - if (Mode!=int(AffineCompact)) - res.matrix().row(Dim) = b.matrix().row(Dim); - return res; - } - - template - inline Transform& operator*=(const EigenBase& other) { return *this = *this * other; } - - /** Concatenates two transformations */ - inline const Transform operator * (const Transform& other) const - { - return internal::transform_transform_product_impl::run(*this,other); - } - - #ifdef __INTEL_COMPILER -private: - // this intermediate structure permits to workaround a bug in ICC 11: - // error: template instantiation resulted in unexpected function type of "Eigen::Transform - // (const Eigen::Transform &) const" - // (the meaning of a name may have changed since the template declaration -- the type of the template is: - // "Eigen::internal::transform_transform_product_impl, - // Eigen::Transform, >::ResultType (const Eigen::Transform &) const") - // - template struct icc_11_workaround - { - typedef internal::transform_transform_product_impl > ProductType; - typedef typename ProductType::ResultType ResultType; - }; - -public: - /** Concatenates two different transformations */ - template - inline typename icc_11_workaround::ResultType - operator * (const Transform& other) const - { - typedef typename icc_11_workaround::ProductType ProductType; - return ProductType::run(*this,other); - } - #else - /** Concatenates two different transformations */ - template - inline typename internal::transform_transform_product_impl >::ResultType - operator * (const Transform& other) const - { - return internal::transform_transform_product_impl >::run(*this,other); - } - #endif - - /** \sa MatrixBase::setIdentity() */ - void setIdentity() { m_matrix.setIdentity(); } - - /** - * \brief Returns an identity transformation. - * \todo In the future this function should be returning a Transform expression. - */ - static const Transform Identity() - { - return Transform(MatrixType::Identity()); - } - - template - inline Transform& scale(const MatrixBase &other); - - template - inline Transform& prescale(const MatrixBase &other); - - inline Transform& scale(const Scalar& s); - inline Transform& prescale(const Scalar& s); - - template - inline Transform& translate(const MatrixBase &other); - - template - inline Transform& pretranslate(const MatrixBase &other); - - template - inline Transform& rotate(const RotationType& rotation); - - template - inline Transform& prerotate(const RotationType& rotation); - - Transform& shear(const Scalar& sx, const Scalar& sy); - Transform& preshear(const Scalar& sx, const Scalar& sy); - - inline Transform& operator=(const TranslationType& t); - inline Transform& operator*=(const TranslationType& t) { return translate(t.vector()); } - inline Transform operator*(const TranslationType& t) const; - - inline Transform& operator=(const UniformScaling& t); - inline Transform& operator*=(const UniformScaling& s) { return scale(s.factor()); } - inline Transform operator*(const UniformScaling& s) const - { - Transform res = *this; - res.scale(s.factor()); - return res; - } - - inline Transform& operator*=(const DiagonalMatrix& s) { linear() *= s; return *this; } - - template - inline Transform& operator=(const RotationBase& r); - template - inline Transform& operator*=(const RotationBase& r) { return rotate(r.toRotationMatrix()); } - template - inline Transform operator*(const RotationBase& r) const; - - const LinearMatrixType rotation() const; - template - void computeRotationScaling(RotationMatrixType *rotation, ScalingMatrixType *scaling) const; - template - void computeScalingRotation(ScalingMatrixType *scaling, RotationMatrixType *rotation) const; - - template - Transform& fromPositionOrientationScale(const MatrixBase &position, - const OrientationType& orientation, const MatrixBase &scale); - - inline Transform inverse(TransformTraits traits = (TransformTraits)Mode) const; - - /** \returns a const pointer to the column major internal matrix */ - const Scalar* data() const { return m_matrix.data(); } - /** \returns a non-const pointer to the column major internal matrix */ - Scalar* data() { return m_matrix.data(); } - - /** \returns \c *this with scalar type casted to \a NewScalarType - * - * Note that if \a NewScalarType is equal to the current scalar type of \c *this - * then this function smartly returns a const reference to \c *this. - */ - template - inline typename internal::cast_return_type >::type cast() const - { return typename internal::cast_return_type >::type(*this); } - - /** Copy constructor with scalar type conversion */ - template - inline explicit Transform(const Transform& other) - { - check_template_params(); - m_matrix = other.matrix().template cast(); - } - - /** \returns \c true if \c *this is approximately equal to \a other, within the precision - * determined by \a prec. - * - * \sa MatrixBase::isApprox() */ - bool isApprox(const Transform& other, const typename NumTraits::Real& prec = NumTraits::dummy_precision()) const - { return m_matrix.isApprox(other.m_matrix, prec); } - - /** Sets the last row to [0 ... 0 1] - */ - void makeAffine() - { - internal::transform_make_affine::run(m_matrix); - } - - /** \internal - * \returns the Dim x Dim linear part if the transformation is affine, - * and the HDim x Dim part for projective transformations. - */ - inline Block linearExt() - { return m_matrix.template block(0,0); } - /** \internal - * \returns the Dim x Dim linear part if the transformation is affine, - * and the HDim x Dim part for projective transformations. - */ - inline const Block linearExt() const - { return m_matrix.template block(0,0); } - - /** \internal - * \returns the translation part if the transformation is affine, - * and the last column for projective transformations. - */ - inline Block translationExt() - { return m_matrix.template block(0,Dim); } - /** \internal - * \returns the translation part if the transformation is affine, - * and the last column for projective transformations. - */ - inline const Block translationExt() const - { return m_matrix.template block(0,Dim); } - - - #ifdef EIGEN_TRANSFORM_PLUGIN - #include EIGEN_TRANSFORM_PLUGIN - #endif - -protected: - #ifndef EIGEN_PARSED_BY_DOXYGEN - static EIGEN_STRONG_INLINE void check_template_params() - { - EIGEN_STATIC_ASSERT((Options & (DontAlign|RowMajor)) == Options, INVALID_MATRIX_TEMPLATE_PARAMETERS) - } - #endif - -}; - -/** \ingroup Geometry_Module */ -typedef Transform Isometry2f; -/** \ingroup Geometry_Module */ -typedef Transform Isometry3f; -/** \ingroup Geometry_Module */ -typedef Transform Isometry2d; -/** \ingroup Geometry_Module */ -typedef Transform Isometry3d; - -/** \ingroup Geometry_Module */ -typedef Transform Affine2f; -/** \ingroup Geometry_Module */ -typedef Transform Affine3f; -/** \ingroup Geometry_Module */ -typedef Transform Affine2d; -/** \ingroup Geometry_Module */ -typedef Transform Affine3d; - -/** \ingroup Geometry_Module */ -typedef Transform AffineCompact2f; -/** \ingroup Geometry_Module */ -typedef Transform AffineCompact3f; -/** \ingroup Geometry_Module */ -typedef Transform AffineCompact2d; -/** \ingroup Geometry_Module */ -typedef Transform AffineCompact3d; - -/** \ingroup Geometry_Module */ -typedef Transform Projective2f; -/** \ingroup Geometry_Module */ -typedef Transform Projective3f; -/** \ingroup Geometry_Module */ -typedef Transform Projective2d; -/** \ingroup Geometry_Module */ -typedef Transform Projective3d; - -/************************** -*** Optional QT support *** -**************************/ - -#ifdef EIGEN_QT_SUPPORT -/** Initializes \c *this from a QMatrix assuming the dimension is 2. - * - * This function is available only if the token EIGEN_QT_SUPPORT is defined. - */ -template -Transform::Transform(const QMatrix& other) -{ - check_template_params(); - *this = other; -} - -/** Set \c *this from a QMatrix assuming the dimension is 2. - * - * This function is available only if the token EIGEN_QT_SUPPORT is defined. - */ -template -Transform& Transform::operator=(const QMatrix& other) -{ - EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE) - m_matrix << other.m11(), other.m21(), other.dx(), - other.m12(), other.m22(), other.dy(), - 0, 0, 1; - return *this; -} - -/** \returns a QMatrix from \c *this assuming the dimension is 2. - * - * \warning this conversion might loss data if \c *this is not affine - * - * This function is available only if the token EIGEN_QT_SUPPORT is defined. - */ -template -QMatrix Transform::toQMatrix(void) const -{ - check_template_params(); - EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE) - return QMatrix(m_matrix.coeff(0,0), m_matrix.coeff(1,0), - m_matrix.coeff(0,1), m_matrix.coeff(1,1), - m_matrix.coeff(0,2), m_matrix.coeff(1,2)); -} - -/** Initializes \c *this from a QTransform assuming the dimension is 2. - * - * This function is available only if the token EIGEN_QT_SUPPORT is defined. - */ -template -Transform::Transform(const QTransform& other) -{ - check_template_params(); - *this = other; -} - -/** Set \c *this from a QTransform assuming the dimension is 2. - * - * This function is available only if the token EIGEN_QT_SUPPORT is defined. - */ -template -Transform& Transform::operator=(const QTransform& other) -{ - check_template_params(); - EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE) - if (Mode == int(AffineCompact)) - m_matrix << other.m11(), other.m21(), other.dx(), - other.m12(), other.m22(), other.dy(); - else - m_matrix << other.m11(), other.m21(), other.dx(), - other.m12(), other.m22(), other.dy(), - other.m13(), other.m23(), other.m33(); - return *this; -} - -/** \returns a QTransform from \c *this assuming the dimension is 2. - * - * This function is available only if the token EIGEN_QT_SUPPORT is defined. - */ -template -QTransform Transform::toQTransform(void) const -{ - EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE) - if (Mode == int(AffineCompact)) - return QTransform(m_matrix.coeff(0,0), m_matrix.coeff(1,0), - m_matrix.coeff(0,1), m_matrix.coeff(1,1), - m_matrix.coeff(0,2), m_matrix.coeff(1,2)); - else - return QTransform(m_matrix.coeff(0,0), m_matrix.coeff(1,0), m_matrix.coeff(2,0), - m_matrix.coeff(0,1), m_matrix.coeff(1,1), m_matrix.coeff(2,1), - m_matrix.coeff(0,2), m_matrix.coeff(1,2), m_matrix.coeff(2,2)); -} -#endif - -/********************* -*** Procedural API *** -*********************/ - -/** Applies on the right the non uniform scale transformation represented - * by the vector \a other to \c *this and returns a reference to \c *this. - * \sa prescale() - */ -template -template -Transform& -Transform::scale(const MatrixBase &other) -{ - EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim)) - EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS) - linearExt().noalias() = (linearExt() * other.asDiagonal()); - return *this; -} - -/** Applies on the right a uniform scale of a factor \a c to \c *this - * and returns a reference to \c *this. - * \sa prescale(Scalar) - */ -template -inline Transform& Transform::scale(const Scalar& s) -{ - EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS) - linearExt() *= s; - return *this; -} - -/** Applies on the left the non uniform scale transformation represented - * by the vector \a other to \c *this and returns a reference to \c *this. - * \sa scale() - */ -template -template -Transform& -Transform::prescale(const MatrixBase &other) -{ - EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim)) - EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS) - m_matrix.template block(0,0).noalias() = (other.asDiagonal() * m_matrix.template block(0,0)); - return *this; -} - -/** Applies on the left a uniform scale of a factor \a c to \c *this - * and returns a reference to \c *this. - * \sa scale(Scalar) - */ -template -inline Transform& Transform::prescale(const Scalar& s) -{ - EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS) - m_matrix.template topRows() *= s; - return *this; -} - -/** Applies on the right the translation matrix represented by the vector \a other - * to \c *this and returns a reference to \c *this. - * \sa pretranslate() - */ -template -template -Transform& -Transform::translate(const MatrixBase &other) -{ - EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim)) - translationExt() += linearExt() * other; - return *this; -} - -/** Applies on the left the translation matrix represented by the vector \a other - * to \c *this and returns a reference to \c *this. - * \sa translate() - */ -template -template -Transform& -Transform::pretranslate(const MatrixBase &other) -{ - EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim)) - if(int(Mode)==int(Projective)) - affine() += other * m_matrix.row(Dim); - else - translation() += other; - return *this; -} - -/** Applies on the right the rotation represented by the rotation \a rotation - * to \c *this and returns a reference to \c *this. - * - * The template parameter \a RotationType is the type of the rotation which - * must be known by internal::toRotationMatrix<>. - * - * Natively supported types includes: - * - any scalar (2D), - * - a Dim x Dim matrix expression, - * - a Quaternion (3D), - * - a AngleAxis (3D) - * - * This mechanism is easily extendable to support user types such as Euler angles, - * or a pair of Quaternion for 4D rotations. - * - * \sa rotate(Scalar), class Quaternion, class AngleAxis, prerotate(RotationType) - */ -template -template -Transform& -Transform::rotate(const RotationType& rotation) -{ - linearExt() *= internal::toRotationMatrix(rotation); - return *this; -} - -/** Applies on the left the rotation represented by the rotation \a rotation - * to \c *this and returns a reference to \c *this. - * - * See rotate() for further details. - * - * \sa rotate() - */ -template -template -Transform& -Transform::prerotate(const RotationType& rotation) -{ - m_matrix.template block(0,0) = internal::toRotationMatrix(rotation) - * m_matrix.template block(0,0); - return *this; -} - -/** Applies on the right the shear transformation represented - * by the vector \a other to \c *this and returns a reference to \c *this. - * \warning 2D only. - * \sa preshear() - */ -template -Transform& -Transform::shear(const Scalar& sx, const Scalar& sy) -{ - EIGEN_STATIC_ASSERT(int(Dim)==2, YOU_MADE_A_PROGRAMMING_MISTAKE) - EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS) - VectorType tmp = linear().col(0)*sy + linear().col(1); - linear() << linear().col(0) + linear().col(1)*sx, tmp; - return *this; -} - -/** Applies on the left the shear transformation represented - * by the vector \a other to \c *this and returns a reference to \c *this. - * \warning 2D only. - * \sa shear() - */ -template -Transform& -Transform::preshear(const Scalar& sx, const Scalar& sy) -{ - EIGEN_STATIC_ASSERT(int(Dim)==2, YOU_MADE_A_PROGRAMMING_MISTAKE) - EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS) - m_matrix.template block(0,0) = LinearMatrixType(1, sx, sy, 1) * m_matrix.template block(0,0); - return *this; -} - -/****************************************************** -*** Scaling, Translation and Rotation compatibility *** -******************************************************/ - -template -inline Transform& Transform::operator=(const TranslationType& t) -{ - linear().setIdentity(); - translation() = t.vector(); - makeAffine(); - return *this; -} - -template -inline Transform Transform::operator*(const TranslationType& t) const -{ - Transform res = *this; - res.translate(t.vector()); - return res; -} - -template -inline Transform& Transform::operator=(const UniformScaling& s) -{ - m_matrix.setZero(); - linear().diagonal().fill(s.factor()); - makeAffine(); - return *this; -} - -template -template -inline Transform& Transform::operator=(const RotationBase& r) -{ - linear() = internal::toRotationMatrix(r); - translation().setZero(); - makeAffine(); - return *this; -} - -template -template -inline Transform Transform::operator*(const RotationBase& r) const -{ - Transform res = *this; - res.rotate(r.derived()); - return res; -} - -/************************ -*** Special functions *** -************************/ - -/** \returns the rotation part of the transformation - * - * - * \svd_module - * - * \sa computeRotationScaling(), computeScalingRotation(), class SVD - */ -template -const typename Transform::LinearMatrixType -Transform::rotation() const -{ - LinearMatrixType result; - computeRotationScaling(&result, (LinearMatrixType*)0); - return result; -} - - -/** decomposes the linear part of the transformation as a product rotation x scaling, the scaling being - * not necessarily positive. - * - * If either pointer is zero, the corresponding computation is skipped. - * - * - * - * \svd_module - * - * \sa computeScalingRotation(), rotation(), class SVD - */ -template -template -void Transform::computeRotationScaling(RotationMatrixType *rotation, ScalingMatrixType *scaling) const -{ - JacobiSVD svd(linear(), ComputeFullU | ComputeFullV); - - Scalar x = (svd.matrixU() * svd.matrixV().adjoint()).determinant(); // so x has absolute value 1 - VectorType sv(svd.singularValues()); - sv.coeffRef(0) *= x; - if(scaling) scaling->lazyAssign(svd.matrixV() * sv.asDiagonal() * svd.matrixV().adjoint()); - if(rotation) - { - LinearMatrixType m(svd.matrixU()); - m.col(0) /= x; - rotation->lazyAssign(m * svd.matrixV().adjoint()); - } -} - -/** decomposes the linear part of the transformation as a product rotation x scaling, the scaling being - * not necessarily positive. - * - * If either pointer is zero, the corresponding computation is skipped. - * - * - * - * \svd_module - * - * \sa computeRotationScaling(), rotation(), class SVD - */ -template -template -void Transform::computeScalingRotation(ScalingMatrixType *scaling, RotationMatrixType *rotation) const -{ - JacobiSVD svd(linear(), ComputeFullU | ComputeFullV); - - Scalar x = (svd.matrixU() * svd.matrixV().adjoint()).determinant(); // so x has absolute value 1 - VectorType sv(svd.singularValues()); - sv.coeffRef(0) *= x; - if(scaling) scaling->lazyAssign(svd.matrixU() * sv.asDiagonal() * svd.matrixU().adjoint()); - if(rotation) - { - LinearMatrixType m(svd.matrixU()); - m.col(0) /= x; - rotation->lazyAssign(m * svd.matrixV().adjoint()); - } -} - -/** Convenient method to set \c *this from a position, orientation and scale - * of a 3D object. - */ -template -template -Transform& -Transform::fromPositionOrientationScale(const MatrixBase &position, - const OrientationType& orientation, const MatrixBase &scale) -{ - linear() = internal::toRotationMatrix(orientation); - linear() *= scale.asDiagonal(); - translation() = position; - makeAffine(); - return *this; -} - -namespace internal { - -template -struct transform_make_affine -{ - template - static void run(MatrixType &mat) - { - static const int Dim = MatrixType::ColsAtCompileTime-1; - mat.template block<1,Dim>(Dim,0).setZero(); - mat.coeffRef(Dim,Dim) = typename MatrixType::Scalar(1); - } -}; - -template<> -struct transform_make_affine -{ - template static void run(MatrixType &) { } -}; - -// selector needed to avoid taking the inverse of a 3x4 matrix -template -struct projective_transform_inverse -{ - static inline void run(const TransformType&, TransformType&) - {} -}; - -template -struct projective_transform_inverse -{ - static inline void run(const TransformType& m, TransformType& res) - { - res.matrix() = m.matrix().inverse(); - } -}; - -} // end namespace internal - - -/** - * - * \returns the inverse transformation according to some given knowledge - * on \c *this. - * - * \param hint allows to optimize the inversion process when the transformation - * is known to be not a general transformation (optional). The possible values are: - * - #Projective if the transformation is not necessarily affine, i.e., if the - * last row is not guaranteed to be [0 ... 0 1] - * - #Affine if the last row can be assumed to be [0 ... 0 1] - * - #Isometry if the transformation is only a concatenations of translations - * and rotations. - * The default is the template class parameter \c Mode. - * - * \warning unless \a traits is always set to NoShear or NoScaling, this function - * requires the generic inverse method of MatrixBase defined in the LU module. If - * you forget to include this module, then you will get hard to debug linking errors. - * - * \sa MatrixBase::inverse() - */ -template -Transform -Transform::inverse(TransformTraits hint) const -{ - Transform res; - if (hint == Projective) - { - internal::projective_transform_inverse::run(*this, res); - } - else - { - if (hint == Isometry) - { - res.matrix().template topLeftCorner() = linear().transpose(); - } - else if(hint&Affine) - { - res.matrix().template topLeftCorner() = linear().inverse(); - } - else - { - eigen_assert(false && "Invalid transform traits in Transform::Inverse"); - } - // translation and remaining parts - res.matrix().template topRightCorner() - = - res.matrix().template topLeftCorner() * translation(); - res.makeAffine(); // we do need this, because in the beginning res is uninitialized - } - return res; -} - -namespace internal { - -/***************************************************** -*** Specializations of take affine part *** -*****************************************************/ - -template struct transform_take_affine_part { - typedef typename TransformType::MatrixType MatrixType; - typedef typename TransformType::AffinePart AffinePart; - typedef typename TransformType::ConstAffinePart ConstAffinePart; - static inline AffinePart run(MatrixType& m) - { return m.template block(0,0); } - static inline ConstAffinePart run(const MatrixType& m) - { return m.template block(0,0); } -}; - -template -struct transform_take_affine_part > { - typedef typename Transform::MatrixType MatrixType; - static inline MatrixType& run(MatrixType& m) { return m; } - static inline const MatrixType& run(const MatrixType& m) { return m; } -}; - -/***************************************************** -*** Specializations of construct from matrix *** -*****************************************************/ - -template -struct transform_construct_from_matrix -{ - static inline void run(Transform *transform, const Other& other) - { - transform->linear() = other; - transform->translation().setZero(); - transform->makeAffine(); - } -}; - -template -struct transform_construct_from_matrix -{ - static inline void run(Transform *transform, const Other& other) - { - transform->affine() = other; - transform->makeAffine(); - } -}; - -template -struct transform_construct_from_matrix -{ - static inline void run(Transform *transform, const Other& other) - { transform->matrix() = other; } -}; - -template -struct transform_construct_from_matrix -{ - static inline void run(Transform *transform, const Other& other) - { transform->matrix() = other.template block(0,0); } -}; - -/********************************************************** -*** Specializations of operator* with rhs EigenBase *** -**********************************************************/ - -template -struct transform_product_result -{ - enum - { - Mode = - (LhsMode == (int)Projective || RhsMode == (int)Projective ) ? Projective : - (LhsMode == (int)Affine || RhsMode == (int)Affine ) ? Affine : - (LhsMode == (int)AffineCompact || RhsMode == (int)AffineCompact ) ? AffineCompact : - (LhsMode == (int)Isometry || RhsMode == (int)Isometry ) ? Isometry : Projective - }; -}; - -template< typename TransformType, typename MatrixType > -struct transform_right_product_impl< TransformType, MatrixType, 0 > -{ - typedef typename MatrixType::PlainObject ResultType; - - static EIGEN_STRONG_INLINE ResultType run(const TransformType& T, const MatrixType& other) - { - return T.matrix() * other; - } -}; - -template< typename TransformType, typename MatrixType > -struct transform_right_product_impl< TransformType, MatrixType, 1 > -{ - enum { - Dim = TransformType::Dim, - HDim = TransformType::HDim, - OtherRows = MatrixType::RowsAtCompileTime, - OtherCols = MatrixType::ColsAtCompileTime - }; - - typedef typename MatrixType::PlainObject ResultType; - - static EIGEN_STRONG_INLINE ResultType run(const TransformType& T, const MatrixType& other) - { - EIGEN_STATIC_ASSERT(OtherRows==HDim, YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES); - - typedef Block TopLeftLhs; - - ResultType res(other.rows(),other.cols()); - TopLeftLhs(res, 0, 0, Dim, other.cols()).noalias() = T.affine() * other; - res.row(OtherRows-1) = other.row(OtherRows-1); - - return res; - } -}; - -template< typename TransformType, typename MatrixType > -struct transform_right_product_impl< TransformType, MatrixType, 2 > -{ - enum { - Dim = TransformType::Dim, - HDim = TransformType::HDim, - OtherRows = MatrixType::RowsAtCompileTime, - OtherCols = MatrixType::ColsAtCompileTime - }; - - typedef typename MatrixType::PlainObject ResultType; - - static EIGEN_STRONG_INLINE ResultType run(const TransformType& T, const MatrixType& other) - { - EIGEN_STATIC_ASSERT(OtherRows==Dim, YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES); - - typedef Block TopLeftLhs; - ResultType res(Replicate(T.translation(),1,other.cols())); - TopLeftLhs(res, 0, 0, Dim, other.cols()).noalias() += T.linear() * other; - - return res; - } -}; - -/********************************************************** -*** Specializations of operator* with lhs EigenBase *** -**********************************************************/ - -// generic HDim x HDim matrix * T => Projective -template -struct transform_left_product_impl -{ - typedef Transform TransformType; - typedef typename TransformType::MatrixType MatrixType; - typedef Transform ResultType; - static ResultType run(const Other& other,const TransformType& tr) - { return ResultType(other * tr.matrix()); } -}; - -// generic HDim x HDim matrix * AffineCompact => Projective -template -struct transform_left_product_impl -{ - typedef Transform TransformType; - typedef typename TransformType::MatrixType MatrixType; - typedef Transform ResultType; - static ResultType run(const Other& other,const TransformType& tr) - { - ResultType res; - res.matrix().noalias() = other.template block(0,0) * tr.matrix(); - res.matrix().col(Dim) += other.col(Dim); - return res; - } -}; - -// affine matrix * T -template -struct transform_left_product_impl -{ - typedef Transform TransformType; - typedef typename TransformType::MatrixType MatrixType; - typedef TransformType ResultType; - static ResultType run(const Other& other,const TransformType& tr) - { - ResultType res; - res.affine().noalias() = other * tr.matrix(); - res.matrix().row(Dim) = tr.matrix().row(Dim); - return res; - } -}; - -// affine matrix * AffineCompact -template -struct transform_left_product_impl -{ - typedef Transform TransformType; - typedef typename TransformType::MatrixType MatrixType; - typedef TransformType ResultType; - static ResultType run(const Other& other,const TransformType& tr) - { - ResultType res; - res.matrix().noalias() = other.template block(0,0) * tr.matrix(); - res.translation() += other.col(Dim); - return res; - } -}; - -// linear matrix * T -template -struct transform_left_product_impl -{ - typedef Transform TransformType; - typedef typename TransformType::MatrixType MatrixType; - typedef TransformType ResultType; - static ResultType run(const Other& other, const TransformType& tr) - { - TransformType res; - if(Mode!=int(AffineCompact)) - res.matrix().row(Dim) = tr.matrix().row(Dim); - res.matrix().template topRows().noalias() - = other * tr.matrix().template topRows(); - return res; - } -}; - -/********************************************************** -*** Specializations of operator* with another Transform *** -**********************************************************/ - -template -struct transform_transform_product_impl,Transform,false > -{ - enum { ResultMode = transform_product_result::Mode }; - typedef Transform Lhs; - typedef Transform Rhs; - typedef Transform ResultType; - static ResultType run(const Lhs& lhs, const Rhs& rhs) - { - ResultType res; - res.linear() = lhs.linear() * rhs.linear(); - res.translation() = lhs.linear() * rhs.translation() + lhs.translation(); - res.makeAffine(); - return res; - } -}; - -template -struct transform_transform_product_impl,Transform,true > -{ - typedef Transform Lhs; - typedef Transform Rhs; - typedef Transform ResultType; - static ResultType run(const Lhs& lhs, const Rhs& rhs) - { - return ResultType( lhs.matrix() * rhs.matrix() ); - } -}; - -template -struct transform_transform_product_impl,Transform,true > -{ - typedef Transform Lhs; - typedef Transform Rhs; - typedef Transform ResultType; - static ResultType run(const Lhs& lhs, const Rhs& rhs) - { - ResultType res; - res.matrix().template topRows() = lhs.matrix() * rhs.matrix(); - res.matrix().row(Dim) = rhs.matrix().row(Dim); - return res; - } -}; - -template -struct transform_transform_product_impl,Transform,true > -{ - typedef Transform Lhs; - typedef Transform Rhs; - typedef Transform ResultType; - static ResultType run(const Lhs& lhs, const Rhs& rhs) - { - ResultType res(lhs.matrix().template leftCols() * rhs.matrix()); - res.matrix().col(Dim) += lhs.matrix().col(Dim); - return res; - } -}; - -} // end namespace internal - -} // end namespace Eigen - -#endif // EIGEN_TRANSFORM_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Geometry/Translation.h b/thirdparty/eigen-3.2.7/Eigen/src/Geometry/Translation.h deleted file mode 100644 index 7fda179c..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Geometry/Translation.h +++ /dev/null @@ -1,206 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_TRANSLATION_H -#define EIGEN_TRANSLATION_H - -namespace Eigen { - -/** \geometry_module \ingroup Geometry_Module - * - * \class Translation - * - * \brief Represents a translation transformation - * - * \param _Scalar the scalar type, i.e., the type of the coefficients. - * \param _Dim the dimension of the space, can be a compile time value or Dynamic - * - * \note This class is not aimed to be used to store a translation transformation, - * but rather to make easier the constructions and updates of Transform objects. - * - * \sa class Scaling, class Transform - */ -template -class Translation -{ -public: - EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_Dim) - /** dimension of the space */ - enum { Dim = _Dim }; - /** the scalar type of the coefficients */ - typedef _Scalar Scalar; - /** corresponding vector type */ - typedef Matrix VectorType; - /** corresponding linear transformation matrix type */ - typedef Matrix LinearMatrixType; - /** corresponding affine transformation type */ - typedef Transform AffineTransformType; - /** corresponding isometric transformation type */ - typedef Transform IsometryTransformType; - -protected: - - VectorType m_coeffs; - -public: - - /** Default constructor without initialization. */ - Translation() {} - /** */ - inline Translation(const Scalar& sx, const Scalar& sy) - { - eigen_assert(Dim==2); - m_coeffs.x() = sx; - m_coeffs.y() = sy; - } - /** */ - inline Translation(const Scalar& sx, const Scalar& sy, const Scalar& sz) - { - eigen_assert(Dim==3); - m_coeffs.x() = sx; - m_coeffs.y() = sy; - m_coeffs.z() = sz; - } - /** Constructs and initialize the translation transformation from a vector of translation coefficients */ - explicit inline Translation(const VectorType& vector) : m_coeffs(vector) {} - - /** \brief Retruns the x-translation by value. **/ - inline Scalar x() const { return m_coeffs.x(); } - /** \brief Retruns the y-translation by value. **/ - inline Scalar y() const { return m_coeffs.y(); } - /** \brief Retruns the z-translation by value. **/ - inline Scalar z() const { return m_coeffs.z(); } - - /** \brief Retruns the x-translation as a reference. **/ - inline Scalar& x() { return m_coeffs.x(); } - /** \brief Retruns the y-translation as a reference. **/ - inline Scalar& y() { return m_coeffs.y(); } - /** \brief Retruns the z-translation as a reference. **/ - inline Scalar& z() { return m_coeffs.z(); } - - const VectorType& vector() const { return m_coeffs; } - VectorType& vector() { return m_coeffs; } - - const VectorType& translation() const { return m_coeffs; } - VectorType& translation() { return m_coeffs; } - - /** Concatenates two translation */ - inline Translation operator* (const Translation& other) const - { return Translation(m_coeffs + other.m_coeffs); } - - /** Concatenates a translation and a uniform scaling */ - inline AffineTransformType operator* (const UniformScaling& other) const; - - /** Concatenates a translation and a linear transformation */ - template - inline AffineTransformType operator* (const EigenBase& linear) const; - - /** Concatenates a translation and a rotation */ - template - inline IsometryTransformType operator*(const RotationBase& r) const - { return *this * IsometryTransformType(r); } - - /** \returns the concatenation of a linear transformation \a l with the translation \a t */ - // its a nightmare to define a templated friend function outside its declaration - template friend - inline AffineTransformType operator*(const EigenBase& linear, const Translation& t) - { - AffineTransformType res; - res.matrix().setZero(); - res.linear() = linear.derived(); - res.translation() = linear.derived() * t.m_coeffs; - res.matrix().row(Dim).setZero(); - res(Dim,Dim) = Scalar(1); - return res; - } - - /** Concatenates a translation and a transformation */ - template - inline Transform operator* (const Transform& t) const - { - Transform res = t; - res.pretranslate(m_coeffs); - return res; - } - - /** Applies translation to vector */ - inline VectorType operator* (const VectorType& other) const - { return m_coeffs + other; } - - /** \returns the inverse translation (opposite) */ - Translation inverse() const { return Translation(-m_coeffs); } - - Translation& operator=(const Translation& other) - { - m_coeffs = other.m_coeffs; - return *this; - } - - static const Translation Identity() { return Translation(VectorType::Zero()); } - - /** \returns \c *this with scalar type casted to \a NewScalarType - * - * Note that if \a NewScalarType is equal to the current scalar type of \c *this - * then this function smartly returns a const reference to \c *this. - */ - template - inline typename internal::cast_return_type >::type cast() const - { return typename internal::cast_return_type >::type(*this); } - - /** Copy constructor with scalar type conversion */ - template - inline explicit Translation(const Translation& other) - { m_coeffs = other.vector().template cast(); } - - /** \returns \c true if \c *this is approximately equal to \a other, within the precision - * determined by \a prec. - * - * \sa MatrixBase::isApprox() */ - bool isApprox(const Translation& other, typename NumTraits::Real prec = NumTraits::dummy_precision()) const - { return m_coeffs.isApprox(other.m_coeffs, prec); } - -}; - -/** \addtogroup Geometry_Module */ -//@{ -typedef Translation Translation2f; -typedef Translation Translation2d; -typedef Translation Translation3f; -typedef Translation Translation3d; -//@} - -template -inline typename Translation::AffineTransformType -Translation::operator* (const UniformScaling& other) const -{ - AffineTransformType res; - res.matrix().setZero(); - res.linear().diagonal().fill(other.factor()); - res.translation() = m_coeffs; - res(Dim,Dim) = Scalar(1); - return res; -} - -template -template -inline typename Translation::AffineTransformType -Translation::operator* (const EigenBase& linear) const -{ - AffineTransformType res; - res.matrix().setZero(); - res.linear() = linear.derived(); - res.translation() = m_coeffs; - res.matrix().row(Dim).setZero(); - res(Dim,Dim) = Scalar(1); - return res; -} - -} // end namespace Eigen - -#endif // EIGEN_TRANSLATION_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Geometry/Umeyama.h b/thirdparty/eigen-3.2.7/Eigen/src/Geometry/Umeyama.h deleted file mode 100644 index 5e20662f..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Geometry/Umeyama.h +++ /dev/null @@ -1,177 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2009 Hauke Heibel -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_UMEYAMA_H -#define EIGEN_UMEYAMA_H - -// This file requires the user to include -// * Eigen/Core -// * Eigen/LU -// * Eigen/SVD -// * Eigen/Array - -namespace Eigen { - -#ifndef EIGEN_PARSED_BY_DOXYGEN - -// These helpers are required since it allows to use mixed types as parameters -// for the Umeyama. The problem with mixed parameters is that the return type -// cannot trivially be deduced when float and double types are mixed. -namespace internal { - -// Compile time return type deduction for different MatrixBase types. -// Different means here different alignment and parameters but the same underlying -// real scalar type. -template -struct umeyama_transform_matrix_type -{ - enum { - MinRowsAtCompileTime = EIGEN_SIZE_MIN_PREFER_DYNAMIC(MatrixType::RowsAtCompileTime, OtherMatrixType::RowsAtCompileTime), - - // When possible we want to choose some small fixed size value since the result - // is likely to fit on the stack. So here, EIGEN_SIZE_MIN_PREFER_DYNAMIC is not what we want. - HomogeneousDimension = int(MinRowsAtCompileTime) == Dynamic ? Dynamic : int(MinRowsAtCompileTime)+1 - }; - - typedef Matrix::Scalar, - HomogeneousDimension, - HomogeneousDimension, - AutoAlign | (traits::Flags & RowMajorBit ? RowMajor : ColMajor), - HomogeneousDimension, - HomogeneousDimension - > type; -}; - -} - -#endif - -/** -* \geometry_module \ingroup Geometry_Module -* -* \brief Returns the transformation between two point sets. -* -* The algorithm is based on: -* "Least-squares estimation of transformation parameters between two point patterns", -* Shinji Umeyama, PAMI 1991, DOI: 10.1109/34.88573 -* -* It estimates parameters \f$ c, \mathbf{R}, \f$ and \f$ \mathbf{t} \f$ such that -* \f{align*} -* \frac{1}{n} \sum_{i=1}^n \vert\vert y_i - (c\mathbf{R}x_i + \mathbf{t}) \vert\vert_2^2 -* \f} -* is minimized. -* -* The algorithm is based on the analysis of the covariance matrix -* \f$ \Sigma_{\mathbf{x}\mathbf{y}} \in \mathbb{R}^{d \times d} \f$ -* of the input point sets \f$ \mathbf{x} \f$ and \f$ \mathbf{y} \f$ where -* \f$d\f$ is corresponding to the dimension (which is typically small). -* The analysis is involving the SVD having a complexity of \f$O(d^3)\f$ -* though the actual computational effort lies in the covariance -* matrix computation which has an asymptotic lower bound of \f$O(dm)\f$ when -* the input point sets have dimension \f$d \times m\f$. -* -* Currently the method is working only for floating point matrices. -* -* \todo Should the return type of umeyama() become a Transform? -* -* \param src Source points \f$ \mathbf{x} = \left( x_1, \hdots, x_n \right) \f$. -* \param dst Destination points \f$ \mathbf{y} = \left( y_1, \hdots, y_n \right) \f$. -* \param with_scaling Sets \f$ c=1 \f$ when false is passed. -* \return The homogeneous transformation -* \f{align*} -* T = \begin{bmatrix} c\mathbf{R} & \mathbf{t} \\ \mathbf{0} & 1 \end{bmatrix} -* \f} -* minimizing the resudiual above. This transformation is always returned as an -* Eigen::Matrix. -*/ -template -typename internal::umeyama_transform_matrix_type::type -umeyama(const MatrixBase& src, const MatrixBase& dst, bool with_scaling = true) -{ - typedef typename internal::umeyama_transform_matrix_type::type TransformationMatrixType; - typedef typename internal::traits::Scalar Scalar; - typedef typename NumTraits::Real RealScalar; - typedef typename Derived::Index Index; - - EIGEN_STATIC_ASSERT(!NumTraits::IsComplex, NUMERIC_TYPE_MUST_BE_REAL) - EIGEN_STATIC_ASSERT((internal::is_same::Scalar>::value), - YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) - - enum { Dimension = EIGEN_SIZE_MIN_PREFER_DYNAMIC(Derived::RowsAtCompileTime, OtherDerived::RowsAtCompileTime) }; - - typedef Matrix VectorType; - typedef Matrix MatrixType; - typedef typename internal::plain_matrix_type_row_major::type RowMajorMatrixType; - - const Index m = src.rows(); // dimension - const Index n = src.cols(); // number of measurements - - // required for demeaning ... - const RealScalar one_over_n = RealScalar(1) / static_cast(n); - - // computation of mean - const VectorType src_mean = src.rowwise().sum() * one_over_n; - const VectorType dst_mean = dst.rowwise().sum() * one_over_n; - - // demeaning of src and dst points - const RowMajorMatrixType src_demean = src.colwise() - src_mean; - const RowMajorMatrixType dst_demean = dst.colwise() - dst_mean; - - // Eq. (36)-(37) - const Scalar src_var = src_demean.rowwise().squaredNorm().sum() * one_over_n; - - // Eq. (38) - const MatrixType sigma = one_over_n * dst_demean * src_demean.transpose(); - - JacobiSVD svd(sigma, ComputeFullU | ComputeFullV); - - // Initialize the resulting transformation with an identity matrix... - TransformationMatrixType Rt = TransformationMatrixType::Identity(m+1,m+1); - - // Eq. (39) - VectorType S = VectorType::Ones(m); - if (sigma.determinant() Scalar(0) ) { - Rt.block(0,0,m,m).noalias() = svd.matrixU()*svd.matrixV().transpose(); - } else { - const Scalar s = S(m-1); S(m-1) = Scalar(-1); - Rt.block(0,0,m,m).noalias() = svd.matrixU() * S.asDiagonal() * svd.matrixV().transpose(); - S(m-1) = s; - } - } else { - Rt.block(0,0,m,m).noalias() = svd.matrixU() * S.asDiagonal() * svd.matrixV().transpose(); - } - - if (with_scaling) - { - // Eq. (42) - const Scalar c = Scalar(1)/src_var * svd.singularValues().dot(S); - - // Eq. (41) - Rt.col(m).head(m) = dst_mean; - Rt.col(m).head(m).noalias() -= c*Rt.topLeftCorner(m,m)*src_mean; - Rt.block(0,0,m,m) *= c; - } - else - { - Rt.col(m).head(m) = dst_mean; - Rt.col(m).head(m).noalias() -= Rt.topLeftCorner(m,m)*src_mean; - } - - return Rt; -} - -} // end namespace Eigen - -#endif // EIGEN_UMEYAMA_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Geometry/arch/Geometry_SSE.h b/thirdparty/eigen-3.2.7/Eigen/src/Geometry/arch/Geometry_SSE.h deleted file mode 100644 index 3d8284f2..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Geometry/arch/Geometry_SSE.h +++ /dev/null @@ -1,115 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2009 Rohit Garg -// Copyright (C) 2009-2010 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_GEOMETRY_SSE_H -#define EIGEN_GEOMETRY_SSE_H - -namespace Eigen { - -namespace internal { - -template -struct quat_product -{ - static inline Quaternion run(const QuaternionBase& _a, const QuaternionBase& _b) - { - const __m128 mask = _mm_castsi128_ps(_mm_setr_epi32(0,0,0,0x80000000)); - Quaternion res; - __m128 a = _a.coeffs().template packet(0); - __m128 b = _b.coeffs().template packet(0); - __m128 flip1 = _mm_xor_ps(_mm_mul_ps(vec4f_swizzle1(a,1,2,0,2), - vec4f_swizzle1(b,2,0,1,2)),mask); - __m128 flip2 = _mm_xor_ps(_mm_mul_ps(vec4f_swizzle1(a,3,3,3,1), - vec4f_swizzle1(b,0,1,2,1)),mask); - pstore(&res.x(), - _mm_add_ps(_mm_sub_ps(_mm_mul_ps(a,vec4f_swizzle1(b,3,3,3,3)), - _mm_mul_ps(vec4f_swizzle1(a,2,0,1,0), - vec4f_swizzle1(b,1,2,0,0))), - _mm_add_ps(flip1,flip2))); - return res; - } -}; - -template -struct cross3_impl -{ - static inline typename plain_matrix_type::type - run(const VectorLhs& lhs, const VectorRhs& rhs) - { - __m128 a = lhs.template packet(0); - __m128 b = rhs.template packet(0); - __m128 mul1=_mm_mul_ps(vec4f_swizzle1(a,1,2,0,3),vec4f_swizzle1(b,2,0,1,3)); - __m128 mul2=_mm_mul_ps(vec4f_swizzle1(a,2,0,1,3),vec4f_swizzle1(b,1,2,0,3)); - typename plain_matrix_type::type res; - pstore(&res.x(),_mm_sub_ps(mul1,mul2)); - return res; - } -}; - - - - -template -struct quat_product -{ - static inline Quaternion run(const QuaternionBase& _a, const QuaternionBase& _b) - { - const Packet2d mask = _mm_castsi128_pd(_mm_set_epi32(0x0,0x0,0x80000000,0x0)); - - Quaternion res; - - const double* a = _a.coeffs().data(); - Packet2d b_xy = _b.coeffs().template packet(0); - Packet2d b_zw = _b.coeffs().template packet(2); - Packet2d a_xx = pset1(a[0]); - Packet2d a_yy = pset1(a[1]); - Packet2d a_zz = pset1(a[2]); - Packet2d a_ww = pset1(a[3]); - - // two temporaries: - Packet2d t1, t2; - - /* - * t1 = ww*xy + yy*zw - * t2 = zz*xy - xx*zw - * res.xy = t1 +/- swap(t2) - */ - t1 = padd(pmul(a_ww, b_xy), pmul(a_yy, b_zw)); - t2 = psub(pmul(a_zz, b_xy), pmul(a_xx, b_zw)); -#ifdef EIGEN_VECTORIZE_SSE3 - EIGEN_UNUSED_VARIABLE(mask) - pstore(&res.x(), _mm_addsub_pd(t1, preverse(t2))); -#else - pstore(&res.x(), padd(t1, pxor(mask,preverse(t2)))); -#endif - - /* - * t1 = ww*zw - yy*xy - * t2 = zz*zw + xx*xy - * res.zw = t1 -/+ swap(t2) = swap( swap(t1) +/- t2) - */ - t1 = psub(pmul(a_ww, b_zw), pmul(a_yy, b_xy)); - t2 = padd(pmul(a_zz, b_zw), pmul(a_xx, b_xy)); -#ifdef EIGEN_VECTORIZE_SSE3 - EIGEN_UNUSED_VARIABLE(mask) - pstore(&res.z(), preverse(_mm_addsub_pd(preverse(t1), t2))); -#else - pstore(&res.z(), psub(t1, pxor(mask,preverse(t2)))); -#endif - - return res; -} -}; - -} // end namespace internal - -} // end namespace Eigen - -#endif // EIGEN_GEOMETRY_SSE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Householder/BlockHouseholder.h b/thirdparty/eigen-3.2.7/Eigen/src/Householder/BlockHouseholder.h deleted file mode 100644 index 60dbea5f..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Householder/BlockHouseholder.h +++ /dev/null @@ -1,68 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2010 Vincent Lejeune -// Copyright (C) 2010 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_BLOCK_HOUSEHOLDER_H -#define EIGEN_BLOCK_HOUSEHOLDER_H - -// This file contains some helper function to deal with block householder reflectors - -namespace Eigen { - -namespace internal { - -/** \internal */ -template -void make_block_householder_triangular_factor(TriangularFactorType& triFactor, const VectorsType& vectors, const CoeffsType& hCoeffs) -{ - typedef typename TriangularFactorType::Index Index; - typedef typename VectorsType::Scalar Scalar; - const Index nbVecs = vectors.cols(); - eigen_assert(triFactor.rows() == nbVecs && triFactor.cols() == nbVecs && vectors.rows()>=nbVecs); - - for(Index i = 0; i < nbVecs; i++) - { - Index rs = vectors.rows() - i; - Scalar Vii = vectors(i,i); - vectors.const_cast_derived().coeffRef(i,i) = Scalar(1); - triFactor.col(i).head(i).noalias() = -hCoeffs(i) * vectors.block(i, 0, rs, i).adjoint() - * vectors.col(i).tail(rs); - vectors.const_cast_derived().coeffRef(i, i) = Vii; - // FIXME add .noalias() once the triangular product can work inplace - triFactor.col(i).head(i) = triFactor.block(0,0,i,i).template triangularView() - * triFactor.col(i).head(i); - triFactor(i,i) = hCoeffs(i); - } -} - -/** \internal */ -template -void apply_block_householder_on_the_left(MatrixType& mat, const VectorsType& vectors, const CoeffsType& hCoeffs) -{ - typedef typename MatrixType::Index Index; - enum { TFactorSize = MatrixType::ColsAtCompileTime }; - Index nbVecs = vectors.cols(); - Matrix T(nbVecs,nbVecs); - make_block_householder_triangular_factor(T, vectors, hCoeffs); - - const TriangularView& V(vectors); - - // A -= V T V^* A - Matrix tmp = V.adjoint() * mat; - // FIXME add .noalias() once the triangular product can work inplace - tmp = T.template triangularView().adjoint() * tmp; - mat.noalias() -= V * tmp; -} - -} // end namespace internal - -} // end namespace Eigen - -#endif // EIGEN_BLOCK_HOUSEHOLDER_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Householder/Householder.h b/thirdparty/eigen-3.2.7/Eigen/src/Householder/Householder.h deleted file mode 100644 index 32112af9..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Householder/Householder.h +++ /dev/null @@ -1,171 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2010 Benoit Jacob -// Copyright (C) 2009 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_HOUSEHOLDER_H -#define EIGEN_HOUSEHOLDER_H - -namespace Eigen { - -namespace internal { -template struct decrement_size -{ - enum { - ret = n==Dynamic ? n : n-1 - }; -}; -} - -/** Computes the elementary reflector H such that: - * \f$ H *this = [ beta 0 ... 0]^T \f$ - * where the transformation H is: - * \f$ H = I - tau v v^*\f$ - * and the vector v is: - * \f$ v^T = [1 essential^T] \f$ - * - * The essential part of the vector \c v is stored in *this. - * - * On output: - * \param tau the scaling factor of the Householder transformation - * \param beta the result of H * \c *this - * - * \sa MatrixBase::makeHouseholder(), MatrixBase::applyHouseholderOnTheLeft(), - * MatrixBase::applyHouseholderOnTheRight() - */ -template -void MatrixBase::makeHouseholderInPlace(Scalar& tau, RealScalar& beta) -{ - VectorBlock::ret> essentialPart(derived(), 1, size()-1); - makeHouseholder(essentialPart, tau, beta); -} - -/** Computes the elementary reflector H such that: - * \f$ H *this = [ beta 0 ... 0]^T \f$ - * where the transformation H is: - * \f$ H = I - tau v v^*\f$ - * and the vector v is: - * \f$ v^T = [1 essential^T] \f$ - * - * On output: - * \param essential the essential part of the vector \c v - * \param tau the scaling factor of the Householder transformation - * \param beta the result of H * \c *this - * - * \sa MatrixBase::makeHouseholderInPlace(), MatrixBase::applyHouseholderOnTheLeft(), - * MatrixBase::applyHouseholderOnTheRight() - */ -template -template -void MatrixBase::makeHouseholder( - EssentialPart& essential, - Scalar& tau, - RealScalar& beta) const -{ - using std::sqrt; - using numext::conj; - - EIGEN_STATIC_ASSERT_VECTOR_ONLY(EssentialPart) - VectorBlock tail(derived(), 1, size()-1); - - RealScalar tailSqNorm = size()==1 ? RealScalar(0) : tail.squaredNorm(); - Scalar c0 = coeff(0); - - if(tailSqNorm == RealScalar(0) && numext::imag(c0)==RealScalar(0)) - { - tau = RealScalar(0); - beta = numext::real(c0); - essential.setZero(); - } - else - { - beta = sqrt(numext::abs2(c0) + tailSqNorm); - if (numext::real(c0)>=RealScalar(0)) - beta = -beta; - essential = tail / (c0 - beta); - tau = conj((beta - c0) / beta); - } -} - -/** Apply the elementary reflector H given by - * \f$ H = I - tau v v^*\f$ - * with - * \f$ v^T = [1 essential^T] \f$ - * from the left to a vector or matrix. - * - * On input: - * \param essential the essential part of the vector \c v - * \param tau the scaling factor of the Householder transformation - * \param workspace a pointer to working space with at least - * this->cols() * essential.size() entries - * - * \sa MatrixBase::makeHouseholder(), MatrixBase::makeHouseholderInPlace(), - * MatrixBase::applyHouseholderOnTheRight() - */ -template -template -void MatrixBase::applyHouseholderOnTheLeft( - const EssentialPart& essential, - const Scalar& tau, - Scalar* workspace) -{ - if(rows() == 1) - { - *this *= Scalar(1)-tau; - } - else - { - Map::type> tmp(workspace,cols()); - Block bottom(derived(), 1, 0, rows()-1, cols()); - tmp.noalias() = essential.adjoint() * bottom; - tmp += this->row(0); - this->row(0) -= tau * tmp; - bottom.noalias() -= tau * essential * tmp; - } -} - -/** Apply the elementary reflector H given by - * \f$ H = I - tau v v^*\f$ - * with - * \f$ v^T = [1 essential^T] \f$ - * from the right to a vector or matrix. - * - * On input: - * \param essential the essential part of the vector \c v - * \param tau the scaling factor of the Householder transformation - * \param workspace a pointer to working space with at least - * this->cols() * essential.size() entries - * - * \sa MatrixBase::makeHouseholder(), MatrixBase::makeHouseholderInPlace(), - * MatrixBase::applyHouseholderOnTheLeft() - */ -template -template -void MatrixBase::applyHouseholderOnTheRight( - const EssentialPart& essential, - const Scalar& tau, - Scalar* workspace) -{ - if(cols() == 1) - { - *this *= Scalar(1)-tau; - } - else - { - Map::type> tmp(workspace,rows()); - Block right(derived(), 0, 1, rows(), cols()-1); - tmp.noalias() = right * essential.conjugate(); - tmp += this->col(0); - this->col(0) -= tau * tmp; - right.noalias() -= tau * tmp * essential.transpose(); - } -} - -} // end namespace Eigen - -#endif // EIGEN_HOUSEHOLDER_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Householder/HouseholderSequence.h b/thirdparty/eigen-3.2.7/Eigen/src/Householder/HouseholderSequence.h deleted file mode 100644 index d800ca1f..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Householder/HouseholderSequence.h +++ /dev/null @@ -1,441 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2009 Gael Guennebaud -// Copyright (C) 2010 Benoit Jacob -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_HOUSEHOLDER_SEQUENCE_H -#define EIGEN_HOUSEHOLDER_SEQUENCE_H - -namespace Eigen { - -/** \ingroup Householder_Module - * \householder_module - * \class HouseholderSequence - * \brief Sequence of Householder reflections acting on subspaces with decreasing size - * \tparam VectorsType type of matrix containing the Householder vectors - * \tparam CoeffsType type of vector containing the Householder coefficients - * \tparam Side either OnTheLeft (the default) or OnTheRight - * - * This class represents a product sequence of Householder reflections where the first Householder reflection - * acts on the whole space, the second Householder reflection leaves the one-dimensional subspace spanned by - * the first unit vector invariant, the third Householder reflection leaves the two-dimensional subspace - * spanned by the first two unit vectors invariant, and so on up to the last reflection which leaves all but - * one dimensions invariant and acts only on the last dimension. Such sequences of Householder reflections - * are used in several algorithms to zero out certain parts of a matrix. Indeed, the methods - * HessenbergDecomposition::matrixQ(), Tridiagonalization::matrixQ(), HouseholderQR::householderQ(), - * and ColPivHouseholderQR::householderQ() all return a %HouseholderSequence. - * - * More precisely, the class %HouseholderSequence represents an \f$ n \times n \f$ matrix \f$ H \f$ of the - * form \f$ H = \prod_{i=0}^{n-1} H_i \f$ where the i-th Householder reflection is \f$ H_i = I - h_i v_i - * v_i^* \f$. The i-th Householder coefficient \f$ h_i \f$ is a scalar and the i-th Householder vector \f$ - * v_i \f$ is a vector of the form - * \f[ - * v_i = [\underbrace{0, \ldots, 0}_{i-1\mbox{ zeros}}, 1, \underbrace{*, \ldots,*}_{n-i\mbox{ arbitrary entries}} ]. - * \f] - * The last \f$ n-i \f$ entries of \f$ v_i \f$ are called the essential part of the Householder vector. - * - * Typical usages are listed below, where H is a HouseholderSequence: - * \code - * A.applyOnTheRight(H); // A = A * H - * A.applyOnTheLeft(H); // A = H * A - * A.applyOnTheRight(H.adjoint()); // A = A * H^* - * A.applyOnTheLeft(H.adjoint()); // A = H^* * A - * MatrixXd Q = H; // conversion to a dense matrix - * \endcode - * In addition to the adjoint, you can also apply the inverse (=adjoint), the transpose, and the conjugate operators. - * - * See the documentation for HouseholderSequence(const VectorsType&, const CoeffsType&) for an example. - * - * \sa MatrixBase::applyOnTheLeft(), MatrixBase::applyOnTheRight() - */ - -namespace internal { - -template -struct traits > -{ - typedef typename VectorsType::Scalar Scalar; - typedef typename VectorsType::Index Index; - typedef typename VectorsType::StorageKind StorageKind; - enum { - RowsAtCompileTime = Side==OnTheLeft ? traits::RowsAtCompileTime - : traits::ColsAtCompileTime, - ColsAtCompileTime = RowsAtCompileTime, - MaxRowsAtCompileTime = Side==OnTheLeft ? traits::MaxRowsAtCompileTime - : traits::MaxColsAtCompileTime, - MaxColsAtCompileTime = MaxRowsAtCompileTime, - Flags = 0 - }; -}; - -template -struct hseq_side_dependent_impl -{ - typedef Block EssentialVectorType; - typedef HouseholderSequence HouseholderSequenceType; - typedef typename VectorsType::Index Index; - static inline const EssentialVectorType essentialVector(const HouseholderSequenceType& h, Index k) - { - Index start = k+1+h.m_shift; - return Block(h.m_vectors, start, k, h.rows()-start, 1); - } -}; - -template -struct hseq_side_dependent_impl -{ - typedef Transpose > EssentialVectorType; - typedef HouseholderSequence HouseholderSequenceType; - typedef typename VectorsType::Index Index; - static inline const EssentialVectorType essentialVector(const HouseholderSequenceType& h, Index k) - { - Index start = k+1+h.m_shift; - return Block(h.m_vectors, k, start, 1, h.rows()-start).transpose(); - } -}; - -template struct matrix_type_times_scalar_type -{ - typedef typename scalar_product_traits::ReturnType - ResultScalar; - typedef Matrix Type; -}; - -} // end namespace internal - -template class HouseholderSequence - : public EigenBase > -{ - typedef typename internal::hseq_side_dependent_impl::EssentialVectorType EssentialVectorType; - - public: - enum { - RowsAtCompileTime = internal::traits::RowsAtCompileTime, - ColsAtCompileTime = internal::traits::ColsAtCompileTime, - MaxRowsAtCompileTime = internal::traits::MaxRowsAtCompileTime, - MaxColsAtCompileTime = internal::traits::MaxColsAtCompileTime - }; - typedef typename internal::traits::Scalar Scalar; - typedef typename VectorsType::Index Index; - - typedef HouseholderSequence< - typename internal::conditional::IsComplex, - typename internal::remove_all::type, - VectorsType>::type, - typename internal::conditional::IsComplex, - typename internal::remove_all::type, - CoeffsType>::type, - Side - > ConjugateReturnType; - - /** \brief Constructor. - * \param[in] v %Matrix containing the essential parts of the Householder vectors - * \param[in] h Vector containing the Householder coefficients - * - * Constructs the Householder sequence with coefficients given by \p h and vectors given by \p v. The - * i-th Householder coefficient \f$ h_i \f$ is given by \p h(i) and the essential part of the i-th - * Householder vector \f$ v_i \f$ is given by \p v(k,i) with \p k > \p i (the subdiagonal part of the - * i-th column). If \p v has fewer columns than rows, then the Householder sequence contains as many - * Householder reflections as there are columns. - * - * \note The %HouseholderSequence object stores \p v and \p h by reference. - * - * Example: \include HouseholderSequence_HouseholderSequence.cpp - * Output: \verbinclude HouseholderSequence_HouseholderSequence.out - * - * \sa setLength(), setShift() - */ - HouseholderSequence(const VectorsType& v, const CoeffsType& h) - : m_vectors(v), m_coeffs(h), m_trans(false), m_length(v.diagonalSize()), - m_shift(0) - { - } - - /** \brief Copy constructor. */ - HouseholderSequence(const HouseholderSequence& other) - : m_vectors(other.m_vectors), - m_coeffs(other.m_coeffs), - m_trans(other.m_trans), - m_length(other.m_length), - m_shift(other.m_shift) - { - } - - /** \brief Number of rows of transformation viewed as a matrix. - * \returns Number of rows - * \details This equals the dimension of the space that the transformation acts on. - */ - Index rows() const { return Side==OnTheLeft ? m_vectors.rows() : m_vectors.cols(); } - - /** \brief Number of columns of transformation viewed as a matrix. - * \returns Number of columns - * \details This equals the dimension of the space that the transformation acts on. - */ - Index cols() const { return rows(); } - - /** \brief Essential part of a Householder vector. - * \param[in] k Index of Householder reflection - * \returns Vector containing non-trivial entries of k-th Householder vector - * - * This function returns the essential part of the Householder vector \f$ v_i \f$. This is a vector of - * length \f$ n-i \f$ containing the last \f$ n-i \f$ entries of the vector - * \f[ - * v_i = [\underbrace{0, \ldots, 0}_{i-1\mbox{ zeros}}, 1, \underbrace{*, \ldots,*}_{n-i\mbox{ arbitrary entries}} ]. - * \f] - * The index \f$ i \f$ equals \p k + shift(), corresponding to the k-th column of the matrix \p v - * passed to the constructor. - * - * \sa setShift(), shift() - */ - const EssentialVectorType essentialVector(Index k) const - { - eigen_assert(k >= 0 && k < m_length); - return internal::hseq_side_dependent_impl::essentialVector(*this, k); - } - - /** \brief %Transpose of the Householder sequence. */ - HouseholderSequence transpose() const - { - return HouseholderSequence(*this).setTrans(!m_trans); - } - - /** \brief Complex conjugate of the Householder sequence. */ - ConjugateReturnType conjugate() const - { - return ConjugateReturnType(m_vectors.conjugate(), m_coeffs.conjugate()) - .setTrans(m_trans) - .setLength(m_length) - .setShift(m_shift); - } - - /** \brief Adjoint (conjugate transpose) of the Householder sequence. */ - ConjugateReturnType adjoint() const - { - return conjugate().setTrans(!m_trans); - } - - /** \brief Inverse of the Householder sequence (equals the adjoint). */ - ConjugateReturnType inverse() const { return adjoint(); } - - /** \internal */ - template inline void evalTo(DestType& dst) const - { - Matrix workspace(rows()); - evalTo(dst, workspace); - } - - /** \internal */ - template - void evalTo(Dest& dst, Workspace& workspace) const - { - workspace.resize(rows()); - Index vecs = m_length; - if( internal::is_same::type,Dest>::value - && internal::extract_data(dst) == internal::extract_data(m_vectors)) - { - // in-place - dst.diagonal().setOnes(); - dst.template triangularView().setZero(); - for(Index k = vecs-1; k >= 0; --k) - { - Index cornerSize = rows() - k - m_shift; - if(m_trans) - dst.bottomRightCorner(cornerSize, cornerSize) - .applyHouseholderOnTheRight(essentialVector(k), m_coeffs.coeff(k), workspace.data()); - else - dst.bottomRightCorner(cornerSize, cornerSize) - .applyHouseholderOnTheLeft(essentialVector(k), m_coeffs.coeff(k), workspace.data()); - - // clear the off diagonal vector - dst.col(k).tail(rows()-k-1).setZero(); - } - // clear the remaining columns if needed - for(Index k = 0; k= 0; --k) - { - Index cornerSize = rows() - k - m_shift; - if(m_trans) - dst.bottomRightCorner(cornerSize, cornerSize) - .applyHouseholderOnTheRight(essentialVector(k), m_coeffs.coeff(k), &workspace.coeffRef(0)); - else - dst.bottomRightCorner(cornerSize, cornerSize) - .applyHouseholderOnTheLeft(essentialVector(k), m_coeffs.coeff(k), &workspace.coeffRef(0)); - } - } - } - - /** \internal */ - template inline void applyThisOnTheRight(Dest& dst) const - { - Matrix workspace(dst.rows()); - applyThisOnTheRight(dst, workspace); - } - - /** \internal */ - template - inline void applyThisOnTheRight(Dest& dst, Workspace& workspace) const - { - workspace.resize(dst.rows()); - for(Index k = 0; k < m_length; ++k) - { - Index actual_k = m_trans ? m_length-k-1 : k; - dst.rightCols(rows()-m_shift-actual_k) - .applyHouseholderOnTheRight(essentialVector(actual_k), m_coeffs.coeff(actual_k), workspace.data()); - } - } - - /** \internal */ - template inline void applyThisOnTheLeft(Dest& dst) const - { - Matrix workspace(dst.cols()); - applyThisOnTheLeft(dst, workspace); - } - - /** \internal */ - template - inline void applyThisOnTheLeft(Dest& dst, Workspace& workspace) const - { - workspace.resize(dst.cols()); - for(Index k = 0; k < m_length; ++k) - { - Index actual_k = m_trans ? k : m_length-k-1; - dst.bottomRows(rows()-m_shift-actual_k) - .applyHouseholderOnTheLeft(essentialVector(actual_k), m_coeffs.coeff(actual_k), workspace.data()); - } - } - - /** \brief Computes the product of a Householder sequence with a matrix. - * \param[in] other %Matrix being multiplied. - * \returns Expression object representing the product. - * - * This function computes \f$ HM \f$ where \f$ H \f$ is the Householder sequence represented by \p *this - * and \f$ M \f$ is the matrix \p other. - */ - template - typename internal::matrix_type_times_scalar_type::Type operator*(const MatrixBase& other) const - { - typename internal::matrix_type_times_scalar_type::Type - res(other.template cast::ResultScalar>()); - applyThisOnTheLeft(res); - return res; - } - - template friend struct internal::hseq_side_dependent_impl; - - /** \brief Sets the length of the Householder sequence. - * \param [in] length New value for the length. - * - * By default, the length \f$ n \f$ of the Householder sequence \f$ H = H_0 H_1 \ldots H_{n-1} \f$ is set - * to the number of columns of the matrix \p v passed to the constructor, or the number of rows if that - * is smaller. After this function is called, the length equals \p length. - * - * \sa length() - */ - HouseholderSequence& setLength(Index length) - { - m_length = length; - return *this; - } - - /** \brief Sets the shift of the Householder sequence. - * \param [in] shift New value for the shift. - * - * By default, a %HouseholderSequence object represents \f$ H = H_0 H_1 \ldots H_{n-1} \f$ and the i-th - * column of the matrix \p v passed to the constructor corresponds to the i-th Householder - * reflection. After this function is called, the object represents \f$ H = H_{\mathrm{shift}} - * H_{\mathrm{shift}+1} \ldots H_{n-1} \f$ and the i-th column of \p v corresponds to the (shift+i)-th - * Householder reflection. - * - * \sa shift() - */ - HouseholderSequence& setShift(Index shift) - { - m_shift = shift; - return *this; - } - - Index length() const { return m_length; } /**< \brief Returns the length of the Householder sequence. */ - Index shift() const { return m_shift; } /**< \brief Returns the shift of the Householder sequence. */ - - /* Necessary for .adjoint() and .conjugate() */ - template friend class HouseholderSequence; - - protected: - - /** \brief Sets the transpose flag. - * \param [in] trans New value of the transpose flag. - * - * By default, the transpose flag is not set. If the transpose flag is set, then this object represents - * \f$ H^T = H_{n-1}^T \ldots H_1^T H_0^T \f$ instead of \f$ H = H_0 H_1 \ldots H_{n-1} \f$. - * - * \sa trans() - */ - HouseholderSequence& setTrans(bool trans) - { - m_trans = trans; - return *this; - } - - bool trans() const { return m_trans; } /**< \brief Returns the transpose flag. */ - - typename VectorsType::Nested m_vectors; - typename CoeffsType::Nested m_coeffs; - bool m_trans; - Index m_length; - Index m_shift; -}; - -/** \brief Computes the product of a matrix with a Householder sequence. - * \param[in] other %Matrix being multiplied. - * \param[in] h %HouseholderSequence being multiplied. - * \returns Expression object representing the product. - * - * This function computes \f$ MH \f$ where \f$ M \f$ is the matrix \p other and \f$ H \f$ is the - * Householder sequence represented by \p h. - */ -template -typename internal::matrix_type_times_scalar_type::Type operator*(const MatrixBase& other, const HouseholderSequence& h) -{ - typename internal::matrix_type_times_scalar_type::Type - res(other.template cast::ResultScalar>()); - h.applyThisOnTheRight(res); - return res; -} - -/** \ingroup Householder_Module \householder_module - * \brief Convenience function for constructing a Householder sequence. - * \returns A HouseholderSequence constructed from the specified arguments. - */ -template -HouseholderSequence householderSequence(const VectorsType& v, const CoeffsType& h) -{ - return HouseholderSequence(v, h); -} - -/** \ingroup Householder_Module \householder_module - * \brief Convenience function for constructing a Householder sequence. - * \returns A HouseholderSequence constructed from the specified arguments. - * \details This function differs from householderSequence() in that the template argument \p OnTheSide of - * the constructed HouseholderSequence is set to OnTheRight, instead of the default OnTheLeft. - */ -template -HouseholderSequence rightHouseholderSequence(const VectorsType& v, const CoeffsType& h) -{ - return HouseholderSequence(v, h); -} - -} // end namespace Eigen - -#endif // EIGEN_HOUSEHOLDER_SEQUENCE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h b/thirdparty/eigen-3.2.7/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h deleted file mode 100644 index 1f3c060d..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h +++ /dev/null @@ -1,149 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2011 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_BASIC_PRECONDITIONERS_H -#define EIGEN_BASIC_PRECONDITIONERS_H - -namespace Eigen { - -/** \ingroup IterativeLinearSolvers_Module - * \brief A preconditioner based on the digonal entries - * - * This class allows to approximately solve for A.x = b problems assuming A is a diagonal matrix. - * In other words, this preconditioner neglects all off diagonal entries and, in Eigen's language, solves for: - * \code - * A.diagonal().asDiagonal() . x = b - * \endcode - * - * \tparam _Scalar the type of the scalar. - * - * This preconditioner is suitable for both selfadjoint and general problems. - * The diagonal entries are pre-inverted and stored into a dense vector. - * - * \note A variant that has yet to be implemented would attempt to preserve the norm of each column. - * - */ -template -class DiagonalPreconditioner -{ - typedef _Scalar Scalar; - typedef Matrix Vector; - typedef typename Vector::Index Index; - - public: - // this typedef is only to export the scalar type and compile-time dimensions to solve_retval - typedef Matrix MatrixType; - - DiagonalPreconditioner() : m_isInitialized(false) {} - - template - DiagonalPreconditioner(const MatType& mat) : m_invdiag(mat.cols()) - { - compute(mat); - } - - Index rows() const { return m_invdiag.size(); } - Index cols() const { return m_invdiag.size(); } - - template - DiagonalPreconditioner& analyzePattern(const MatType& ) - { - return *this; - } - - template - DiagonalPreconditioner& factorize(const MatType& mat) - { - m_invdiag.resize(mat.cols()); - for(int j=0; j - DiagonalPreconditioner& compute(const MatType& mat) - { - return factorize(mat); - } - - template - void _solve(const Rhs& b, Dest& x) const - { - x = m_invdiag.array() * b.array() ; - } - - template inline const internal::solve_retval - solve(const MatrixBase& b) const - { - eigen_assert(m_isInitialized && "DiagonalPreconditioner is not initialized."); - eigen_assert(m_invdiag.size()==b.rows() - && "DiagonalPreconditioner::solve(): invalid number of rows of the right hand side matrix b"); - return internal::solve_retval(*this, b.derived()); - } - - protected: - Vector m_invdiag; - bool m_isInitialized; -}; - -namespace internal { - -template -struct solve_retval, Rhs> - : solve_retval_base, Rhs> -{ - typedef DiagonalPreconditioner<_MatrixType> Dec; - EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs) - - template void evalTo(Dest& dst) const - { - dec()._solve(rhs(),dst); - } -}; - -} - -/** \ingroup IterativeLinearSolvers_Module - * \brief A naive preconditioner which approximates any matrix as the identity matrix - * - * \sa class DiagonalPreconditioner - */ -class IdentityPreconditioner -{ - public: - - IdentityPreconditioner() {} - - template - IdentityPreconditioner(const MatrixType& ) {} - - template - IdentityPreconditioner& analyzePattern(const MatrixType& ) { return *this; } - - template - IdentityPreconditioner& factorize(const MatrixType& ) { return *this; } - - template - IdentityPreconditioner& compute(const MatrixType& ) { return *this; } - - template - inline const Rhs& solve(const Rhs& b) const { return b; } -}; - -} // end namespace Eigen - -#endif // EIGEN_BASIC_PRECONDITIONERS_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h b/thirdparty/eigen-3.2.7/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h deleted file mode 100644 index 55122190..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h +++ /dev/null @@ -1,263 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2011 Gael Guennebaud -// Copyright (C) 2012 Désiré Nuentsa-Wakam -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_BICGSTAB_H -#define EIGEN_BICGSTAB_H - -namespace Eigen { - -namespace internal { - -/** \internal Low-level bi conjugate gradient stabilized algorithm - * \param mat The matrix A - * \param rhs The right hand side vector b - * \param x On input and initial solution, on output the computed solution. - * \param precond A preconditioner being able to efficiently solve for an - * approximation of Ax=b (regardless of b) - * \param iters On input the max number of iteration, on output the number of performed iterations. - * \param tol_error On input the tolerance error, on output an estimation of the relative error. - * \return false in the case of numerical issue, for example a break down of BiCGSTAB. - */ -template -bool bicgstab(const MatrixType& mat, const Rhs& rhs, Dest& x, - const Preconditioner& precond, int& iters, - typename Dest::RealScalar& tol_error) -{ - using std::sqrt; - using std::abs; - typedef typename Dest::RealScalar RealScalar; - typedef typename Dest::Scalar Scalar; - typedef Matrix VectorType; - RealScalar tol = tol_error; - int maxIters = iters; - - int n = mat.cols(); - VectorType r = rhs - mat * x; - VectorType r0 = r; - - RealScalar r0_sqnorm = r0.squaredNorm(); - RealScalar rhs_sqnorm = rhs.squaredNorm(); - if(rhs_sqnorm == 0) - { - x.setZero(); - return true; - } - Scalar rho = 1; - Scalar alpha = 1; - Scalar w = 1; - - VectorType v = VectorType::Zero(n), p = VectorType::Zero(n); - VectorType y(n), z(n); - VectorType kt(n), ks(n); - - VectorType s(n), t(n); - - RealScalar tol2 = tol*tol; - RealScalar eps2 = NumTraits::epsilon()*NumTraits::epsilon(); - int i = 0; - int restarts = 0; - - while ( r.squaredNorm()/rhs_sqnorm > tol2 && iRealScalar(0)) - w = t.dot(s) / tmp; - else - w = Scalar(0); - x += alpha * y + w * z; - r = s - w * t; - ++i; - } - tol_error = sqrt(r.squaredNorm()/rhs_sqnorm); - iters = i; - return true; -} - -} - -template< typename _MatrixType, - typename _Preconditioner = DiagonalPreconditioner > -class BiCGSTAB; - -namespace internal { - -template< typename _MatrixType, typename _Preconditioner> -struct traits > -{ - typedef _MatrixType MatrixType; - typedef _Preconditioner Preconditioner; -}; - -} - -/** \ingroup IterativeLinearSolvers_Module - * \brief A bi conjugate gradient stabilized solver for sparse square problems - * - * This class allows to solve for A.x = b sparse linear problems using a bi conjugate gradient - * stabilized algorithm. The vectors x and b can be either dense or sparse. - * - * \tparam _MatrixType the type of the sparse matrix A, can be a dense or a sparse matrix. - * \tparam _Preconditioner the type of the preconditioner. Default is DiagonalPreconditioner - * - * The maximal number of iterations and tolerance value can be controlled via the setMaxIterations() - * and setTolerance() methods. The defaults are the size of the problem for the maximal number of iterations - * and NumTraits::epsilon() for the tolerance. - * - * This class can be used as the direct solver classes. Here is a typical usage example: - * \code - * int n = 10000; - * VectorXd x(n), b(n); - * SparseMatrix A(n,n); - * // fill A and b - * BiCGSTAB > solver; - * solver.compute(A); - * x = solver.solve(b); - * std::cout << "#iterations: " << solver.iterations() << std::endl; - * std::cout << "estimated error: " << solver.error() << std::endl; - * // update b, and solve again - * x = solver.solve(b); - * \endcode - * - * By default the iterations start with x=0 as an initial guess of the solution. - * One can control the start using the solveWithGuess() method. - * - * \sa class SimplicialCholesky, DiagonalPreconditioner, IdentityPreconditioner - */ -template< typename _MatrixType, typename _Preconditioner> -class BiCGSTAB : public IterativeSolverBase > -{ - typedef IterativeSolverBase Base; - using Base::mp_matrix; - using Base::m_error; - using Base::m_iterations; - using Base::m_info; - using Base::m_isInitialized; -public: - typedef _MatrixType MatrixType; - typedef typename MatrixType::Scalar Scalar; - typedef typename MatrixType::Index Index; - typedef typename MatrixType::RealScalar RealScalar; - typedef _Preconditioner Preconditioner; - -public: - - /** Default constructor. */ - BiCGSTAB() : Base() {} - - /** Initialize the solver with matrix \a A for further \c Ax=b solving. - * - * This constructor is a shortcut for the default constructor followed - * by a call to compute(). - * - * \warning this class stores a reference to the matrix A as well as some - * precomputed values that depend on it. Therefore, if \a A is changed - * this class becomes invalid. Call compute() to update it with the new - * matrix A, or modify a copy of A. - */ - template - explicit BiCGSTAB(const EigenBase& A) : Base(A.derived()) {} - - ~BiCGSTAB() {} - - /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A - * \a x0 as an initial solution. - * - * \sa compute() - */ - template - inline const internal::solve_retval_with_guess - solveWithGuess(const MatrixBase& b, const Guess& x0) const - { - eigen_assert(m_isInitialized && "BiCGSTAB is not initialized."); - eigen_assert(Base::rows()==b.rows() - && "BiCGSTAB::solve(): invalid number of rows of the right hand side matrix b"); - return internal::solve_retval_with_guess - (*this, b.derived(), x0); - } - - /** \internal */ - template - void _solveWithGuess(const Rhs& b, Dest& x) const - { - bool failed = false; - for(int j=0; j - void _solve(const Rhs& b, Dest& x) const - { -// x.setZero(); - x = b; - _solveWithGuess(b,x); - } - -protected: - -}; - - -namespace internal { - - template -struct solve_retval, Rhs> - : solve_retval_base, Rhs> -{ - typedef BiCGSTAB<_MatrixType, _Preconditioner> Dec; - EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs) - - template void evalTo(Dest& dst) const - { - dec()._solve(rhs(),dst); - } -}; - -} // end namespace internal - -} // end namespace Eigen - -#endif // EIGEN_BICGSTAB_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h b/thirdparty/eigen-3.2.7/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h deleted file mode 100644 index 1a7e569c..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h +++ /dev/null @@ -1,256 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2011 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_CONJUGATE_GRADIENT_H -#define EIGEN_CONJUGATE_GRADIENT_H - -namespace Eigen { - -namespace internal { - -/** \internal Low-level conjugate gradient algorithm - * \param mat The matrix A - * \param rhs The right hand side vector b - * \param x On input and initial solution, on output the computed solution. - * \param precond A preconditioner being able to efficiently solve for an - * approximation of Ax=b (regardless of b) - * \param iters On input the max number of iteration, on output the number of performed iterations. - * \param tol_error On input the tolerance error, on output an estimation of the relative error. - */ -template -EIGEN_DONT_INLINE -void conjugate_gradient(const MatrixType& mat, const Rhs& rhs, Dest& x, - const Preconditioner& precond, int& iters, - typename Dest::RealScalar& tol_error) -{ - using std::sqrt; - using std::abs; - typedef typename Dest::RealScalar RealScalar; - typedef typename Dest::Scalar Scalar; - typedef Matrix VectorType; - - RealScalar tol = tol_error; - int maxIters = iters; - - int n = mat.cols(); - - VectorType residual = rhs - mat * x; //initial residual - - RealScalar rhsNorm2 = rhs.squaredNorm(); - if(rhsNorm2 == 0) - { - x.setZero(); - iters = 0; - tol_error = 0; - return; - } - RealScalar threshold = tol*tol*rhsNorm2; - RealScalar residualNorm2 = residual.squaredNorm(); - if (residualNorm2 < threshold) - { - iters = 0; - tol_error = sqrt(residualNorm2 / rhsNorm2); - return; - } - - VectorType p(n); - p = precond.solve(residual); //initial search direction - - VectorType z(n), tmp(n); - RealScalar absNew = numext::real(residual.dot(p)); // the square of the absolute value of r scaled by invM - int i = 0; - while(i < maxIters) - { - tmp.noalias() = mat * p; // the bottleneck of the algorithm - - Scalar alpha = absNew / p.dot(tmp); // the amount we travel on dir - x += alpha * p; // update solution - residual -= alpha * tmp; // update residue - - residualNorm2 = residual.squaredNorm(); - if(residualNorm2 < threshold) - break; - - z = precond.solve(residual); // approximately solve for "A z = residual" - - RealScalar absOld = absNew; - absNew = numext::real(residual.dot(z)); // update the absolute value of r - RealScalar beta = absNew / absOld; // calculate the Gram-Schmidt value used to create the new search direction - p = z + beta * p; // update search direction - i++; - } - tol_error = sqrt(residualNorm2 / rhsNorm2); - iters = i; -} - -} - -template< typename _MatrixType, int _UpLo=Lower, - typename _Preconditioner = DiagonalPreconditioner > -class ConjugateGradient; - -namespace internal { - -template< typename _MatrixType, int _UpLo, typename _Preconditioner> -struct traits > -{ - typedef _MatrixType MatrixType; - typedef _Preconditioner Preconditioner; -}; - -} - -/** \ingroup IterativeLinearSolvers_Module - * \brief A conjugate gradient solver for sparse self-adjoint problems - * - * This class allows to solve for A.x = b sparse linear problems using a conjugate gradient algorithm. - * The sparse matrix A must be selfadjoint. The vectors x and b can be either dense or sparse. - * - * \tparam _MatrixType the type of the matrix A, can be a dense or a sparse matrix. - * \tparam _UpLo the triangular part that will be used for the computations. It can be Lower, - * Upper, or Lower|Upper in which the full matrix entries will be considered. Default is Lower. - * \tparam _Preconditioner the type of the preconditioner. Default is DiagonalPreconditioner - * - * The maximal number of iterations and tolerance value can be controlled via the setMaxIterations() - * and setTolerance() methods. The defaults are the size of the problem for the maximal number of iterations - * and NumTraits::epsilon() for the tolerance. - * - * This class can be used as the direct solver classes. Here is a typical usage example: - * \code - * int n = 10000; - * VectorXd x(n), b(n); - * SparseMatrix A(n,n); - * // fill A and b - * ConjugateGradient > cg; - * cg.compute(A); - * x = cg.solve(b); - * std::cout << "#iterations: " << cg.iterations() << std::endl; - * std::cout << "estimated error: " << cg.error() << std::endl; - * // update b, and solve again - * x = cg.solve(b); - * \endcode - * - * By default the iterations start with x=0 as an initial guess of the solution. - * One can control the start using the solveWithGuess() method. - * - * \sa class SimplicialCholesky, DiagonalPreconditioner, IdentityPreconditioner - */ -template< typename _MatrixType, int _UpLo, typename _Preconditioner> -class ConjugateGradient : public IterativeSolverBase > -{ - typedef IterativeSolverBase Base; - using Base::mp_matrix; - using Base::m_error; - using Base::m_iterations; - using Base::m_info; - using Base::m_isInitialized; -public: - typedef _MatrixType MatrixType; - typedef typename MatrixType::Scalar Scalar; - typedef typename MatrixType::Index Index; - typedef typename MatrixType::RealScalar RealScalar; - typedef _Preconditioner Preconditioner; - - enum { - UpLo = _UpLo - }; - -public: - - /** Default constructor. */ - ConjugateGradient() : Base() {} - - /** Initialize the solver with matrix \a A for further \c Ax=b solving. - * - * This constructor is a shortcut for the default constructor followed - * by a call to compute(). - * - * \warning this class stores a reference to the matrix A as well as some - * precomputed values that depend on it. Therefore, if \a A is changed - * this class becomes invalid. Call compute() to update it with the new - * matrix A, or modify a copy of A. - */ - template - explicit ConjugateGradient(const EigenBase& A) : Base(A.derived()) {} - - ~ConjugateGradient() {} - - /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A - * \a x0 as an initial solution. - * - * \sa compute() - */ - template - inline const internal::solve_retval_with_guess - solveWithGuess(const MatrixBase& b, const Guess& x0) const - { - eigen_assert(m_isInitialized && "ConjugateGradient is not initialized."); - eigen_assert(Base::rows()==b.rows() - && "ConjugateGradient::solve(): invalid number of rows of the right hand side matrix b"); - return internal::solve_retval_with_guess - (*this, b.derived(), x0); - } - - /** \internal */ - template - void _solveWithGuess(const Rhs& b, Dest& x) const - { - typedef typename internal::conditional - >::type MatrixWrapperType; - m_iterations = Base::maxIterations(); - m_error = Base::m_tolerance; - - for(int j=0; j - void _solve(const Rhs& b, Dest& x) const - { - x.setZero(); - _solveWithGuess(b,x); - } - -protected: - -}; - - -namespace internal { - -template -struct solve_retval, Rhs> - : solve_retval_base, Rhs> -{ - typedef ConjugateGradient<_MatrixType,_UpLo,_Preconditioner> Dec; - EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs) - - template void evalTo(Dest& dst) const - { - dec()._solve(rhs(),dst); - } -}; - -} // end namespace internal - -} // end namespace Eigen - -#endif // EIGEN_CONJUGATE_GRADIENT_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h b/thirdparty/eigen-3.2.7/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h deleted file mode 100644 index d3f37fea..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h +++ /dev/null @@ -1,478 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2012 Désiré Nuentsa-Wakam -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_INCOMPLETE_LUT_H -#define EIGEN_INCOMPLETE_LUT_H - - -namespace Eigen { - -namespace internal { - -/** \internal - * Compute a quick-sort split of a vector - * On output, the vector row is permuted such that its elements satisfy - * abs(row(i)) >= abs(row(ncut)) if incut - * \param row The vector of values - * \param ind The array of index for the elements in @p row - * \param ncut The number of largest elements to keep - **/ -template -Index QuickSplit(VectorV &row, VectorI &ind, Index ncut) -{ - typedef typename VectorV::RealScalar RealScalar; - using std::swap; - using std::abs; - Index mid; - Index n = row.size(); /* length of the vector */ - Index first, last ; - - ncut--; /* to fit the zero-based indices */ - first = 0; - last = n-1; - if (ncut < first || ncut > last ) return 0; - - do { - mid = first; - RealScalar abskey = abs(row(mid)); - for (Index j = first + 1; j <= last; j++) { - if ( abs(row(j)) > abskey) { - ++mid; - swap(row(mid), row(j)); - swap(ind(mid), ind(j)); - } - } - /* Interchange for the pivot element */ - swap(row(mid), row(first)); - swap(ind(mid), ind(first)); - - if (mid > ncut) last = mid - 1; - else if (mid < ncut ) first = mid + 1; - } while (mid != ncut ); - - return 0; /* mid is equal to ncut */ -} - -}// end namespace internal - -/** \ingroup IterativeLinearSolvers_Module - * \class IncompleteLUT - * \brief Incomplete LU factorization with dual-threshold strategy - * - * During the numerical factorization, two dropping rules are used : - * 1) any element whose magnitude is less than some tolerance is dropped. - * This tolerance is obtained by multiplying the input tolerance @p droptol - * by the average magnitude of all the original elements in the current row. - * 2) After the elimination of the row, only the @p fill largest elements in - * the L part and the @p fill largest elements in the U part are kept - * (in addition to the diagonal element ). Note that @p fill is computed from - * the input parameter @p fillfactor which is used the ratio to control the fill_in - * relatively to the initial number of nonzero elements. - * - * The two extreme cases are when @p droptol=0 (to keep all the @p fill*2 largest elements) - * and when @p fill=n/2 with @p droptol being different to zero. - * - * References : Yousef Saad, ILUT: A dual threshold incomplete LU factorization, - * Numerical Linear Algebra with Applications, 1(4), pp 387-402, 1994. - * - * NOTE : The following implementation is derived from the ILUT implementation - * in the SPARSKIT package, Copyright (C) 2005, the Regents of the University of Minnesota - * released under the terms of the GNU LGPL: - * http://www-users.cs.umn.edu/~saad/software/SPARSKIT/README - * However, Yousef Saad gave us permission to relicense his ILUT code to MPL2. - * See the Eigen mailing list archive, thread: ILUT, date: July 8, 2012: - * http://listengine.tuxfamily.org/lists.tuxfamily.org/eigen/2012/07/msg00064.html - * alternatively, on GMANE: - * http://comments.gmane.org/gmane.comp.lib.eigen/3302 - */ -template -class IncompleteLUT : internal::noncopyable -{ - typedef _Scalar Scalar; - typedef typename NumTraits::Real RealScalar; - typedef Matrix Vector; - typedef SparseMatrix FactorType; - typedef SparseMatrix PermutType; - typedef typename FactorType::Index Index; - - public: - typedef Matrix MatrixType; - - IncompleteLUT() - : m_droptol(NumTraits::dummy_precision()), m_fillfactor(10), - m_analysisIsOk(false), m_factorizationIsOk(false), m_isInitialized(false) - {} - - template - IncompleteLUT(const MatrixType& mat, const RealScalar& droptol=NumTraits::dummy_precision(), int fillfactor = 10) - : m_droptol(droptol),m_fillfactor(fillfactor), - m_analysisIsOk(false),m_factorizationIsOk(false),m_isInitialized(false) - { - eigen_assert(fillfactor != 0); - compute(mat); - } - - Index rows() const { return m_lu.rows(); } - - Index cols() const { return m_lu.cols(); } - - /** \brief Reports whether previous computation was successful. - * - * \returns \c Success if computation was succesful, - * \c NumericalIssue if the matrix.appears to be negative. - */ - ComputationInfo info() const - { - eigen_assert(m_isInitialized && "IncompleteLUT is not initialized."); - return m_info; - } - - template - void analyzePattern(const MatrixType& amat); - - template - void factorize(const MatrixType& amat); - - /** - * Compute an incomplete LU factorization with dual threshold on the matrix mat - * No pivoting is done in this version - * - **/ - template - IncompleteLUT& compute(const MatrixType& amat) - { - analyzePattern(amat); - factorize(amat); - return *this; - } - - void setDroptol(const RealScalar& droptol); - void setFillfactor(int fillfactor); - - template - void _solve(const Rhs& b, Dest& x) const - { - x = m_Pinv * b; - x = m_lu.template triangularView().solve(x); - x = m_lu.template triangularView().solve(x); - x = m_P * x; - } - - template inline const internal::solve_retval - solve(const MatrixBase& b) const - { - eigen_assert(m_isInitialized && "IncompleteLUT is not initialized."); - eigen_assert(cols()==b.rows() - && "IncompleteLUT::solve(): invalid number of rows of the right hand side matrix b"); - return internal::solve_retval(*this, b.derived()); - } - -protected: - - /** keeps off-diagonal entries; drops diagonal entries */ - struct keep_diag { - inline bool operator() (const Index& row, const Index& col, const Scalar&) const - { - return row!=col; - } - }; - -protected: - - FactorType m_lu; - RealScalar m_droptol; - int m_fillfactor; - bool m_analysisIsOk; - bool m_factorizationIsOk; - bool m_isInitialized; - ComputationInfo m_info; - PermutationMatrix m_P; // Fill-reducing permutation - PermutationMatrix m_Pinv; // Inverse permutation -}; - -/** - * Set control parameter droptol - * \param droptol Drop any element whose magnitude is less than this tolerance - **/ -template -void IncompleteLUT::setDroptol(const RealScalar& droptol) -{ - this->m_droptol = droptol; -} - -/** - * Set control parameter fillfactor - * \param fillfactor This is used to compute the number @p fill_in of largest elements to keep on each row. - **/ -template -void IncompleteLUT::setFillfactor(int fillfactor) -{ - this->m_fillfactor = fillfactor; -} - -template -template -void IncompleteLUT::analyzePattern(const _MatrixType& amat) -{ - // Compute the Fill-reducing permutation - // Since ILUT does not perform any numerical pivoting, - // it is highly preferable to keep the diagonal through symmetric permutations. -#ifndef EIGEN_MPL2_ONLY - // To this end, let's symmetrize the pattern and perform AMD on it. - SparseMatrix mat1 = amat; - SparseMatrix mat2 = amat.transpose(); - // FIXME for a matrix with nearly symmetric pattern, mat2+mat1 is the appropriate choice. - // on the other hand for a really non-symmetric pattern, mat2*mat1 should be prefered... - SparseMatrix AtA = mat2 + mat1; - AMDOrdering ordering; - ordering(AtA,m_P); - m_Pinv = m_P.inverse(); // cache the inverse permutation -#else - // If AMD is not available, (MPL2-only), then let's use the slower COLAMD routine. - SparseMatrix mat1 = amat; - COLAMDOrdering ordering; - ordering(mat1,m_Pinv); - m_P = m_Pinv.inverse(); -#endif - - m_analysisIsOk = true; - m_factorizationIsOk = false; - m_isInitialized = false; -} - -template -template -void IncompleteLUT::factorize(const _MatrixType& amat) -{ - using std::sqrt; - using std::swap; - using std::abs; - - eigen_assert((amat.rows() == amat.cols()) && "The factorization should be done on a square matrix"); - Index n = amat.cols(); // Size of the matrix - m_lu.resize(n,n); - // Declare Working vectors and variables - Vector u(n) ; // real values of the row -- maximum size is n -- - VectorXi ju(n); // column position of the values in u -- maximum size is n - VectorXi jr(n); // Indicate the position of the nonzero elements in the vector u -- A zero location is indicated by -1 - - // Apply the fill-reducing permutation - eigen_assert(m_analysisIsOk && "You must first call analyzePattern()"); - SparseMatrix mat; - mat = amat.twistedBy(m_Pinv); - - // Initialization - jr.fill(-1); - ju.fill(0); - u.fill(0); - - // number of largest elements to keep in each row: - Index fill_in = static_cast (amat.nonZeros()*m_fillfactor)/n+1; - if (fill_in > n) fill_in = n; - - // number of largest nonzero elements to keep in the L and the U part of the current row: - Index nnzL = fill_in/2; - Index nnzU = nnzL; - m_lu.reserve(n * (nnzL + nnzU + 1)); - - // global loop over the rows of the sparse matrix - for (Index ii = 0; ii < n; ii++) - { - // 1 - copy the lower and the upper part of the row i of mat in the working vector u - - Index sizeu = 1; // number of nonzero elements in the upper part of the current row - Index sizel = 0; // number of nonzero elements in the lower part of the current row - ju(ii) = ii; - u(ii) = 0; - jr(ii) = ii; - RealScalar rownorm = 0; - - typename FactorType::InnerIterator j_it(mat, ii); // Iterate through the current row ii - for (; j_it; ++j_it) - { - Index k = j_it.index(); - if (k < ii) - { - // copy the lower part - ju(sizel) = k; - u(sizel) = j_it.value(); - jr(k) = sizel; - ++sizel; - } - else if (k == ii) - { - u(ii) = j_it.value(); - } - else - { - // copy the upper part - Index jpos = ii + sizeu; - ju(jpos) = k; - u(jpos) = j_it.value(); - jr(k) = jpos; - ++sizeu; - } - rownorm += numext::abs2(j_it.value()); - } - - // 2 - detect possible zero row - if(rownorm==0) - { - m_info = NumericalIssue; - return; - } - // Take the 2-norm of the current row as a relative tolerance - rownorm = sqrt(rownorm); - - // 3 - eliminate the previous nonzero rows - Index jj = 0; - Index len = 0; - while (jj < sizel) - { - // In order to eliminate in the correct order, - // we must select first the smallest column index among ju(jj:sizel) - Index k; - Index minrow = ju.segment(jj,sizel-jj).minCoeff(&k); // k is relative to the segment - k += jj; - if (minrow != ju(jj)) - { - // swap the two locations - Index j = ju(jj); - swap(ju(jj), ju(k)); - jr(minrow) = jj; jr(j) = k; - swap(u(jj), u(k)); - } - // Reset this location - jr(minrow) = -1; - - // Start elimination - typename FactorType::InnerIterator ki_it(m_lu, minrow); - while (ki_it && ki_it.index() < minrow) ++ki_it; - eigen_internal_assert(ki_it && ki_it.col()==minrow); - Scalar fact = u(jj) / ki_it.value(); - - // drop too small elements - if(abs(fact) <= m_droptol) - { - jj++; - continue; - } - - // linear combination of the current row ii and the row minrow - ++ki_it; - for (; ki_it; ++ki_it) - { - Scalar prod = fact * ki_it.value(); - Index j = ki_it.index(); - Index jpos = jr(j); - if (jpos == -1) // fill-in element - { - Index newpos; - if (j >= ii) // dealing with the upper part - { - newpos = ii + sizeu; - sizeu++; - eigen_internal_assert(sizeu<=n); - } - else // dealing with the lower part - { - newpos = sizel; - sizel++; - eigen_internal_assert(sizel<=ii); - } - ju(newpos) = j; - u(newpos) = -prod; - jr(j) = newpos; - } - else - u(jpos) -= prod; - } - // store the pivot element - u(len) = fact; - ju(len) = minrow; - ++len; - - jj++; - } // end of the elimination on the row ii - - // reset the upper part of the pointer jr to zero - for(Index k = 0; k m_droptol * rownorm ) - { - ++len; - u(ii + len) = u(ii + k); - ju(ii + len) = ju(ii + k); - } - } - sizeu = len + 1; // +1 to take into account the diagonal element - len = (std::min)(sizeu, nnzU); - typename Vector::SegmentReturnType uu(u.segment(ii+1, sizeu-1)); - typename VectorXi::SegmentReturnType juu(ju.segment(ii+1, sizeu-1)); - internal::QuickSplit(uu, juu, len); - - // store the largest elements of the U part - for(Index k = ii + 1; k < ii + len; k++) - m_lu.insertBackByOuterInnerUnordered(ii,ju(k)) = u(k); - } - - m_lu.finalize(); - m_lu.makeCompressed(); - - m_factorizationIsOk = true; - m_isInitialized = m_factorizationIsOk; - m_info = Success; -} - -namespace internal { - -template -struct solve_retval, Rhs> - : solve_retval_base, Rhs> -{ - typedef IncompleteLUT<_MatrixType> Dec; - EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs) - - template void evalTo(Dest& dst) const - { - dec()._solve(rhs(),dst); - } -}; - -} // end namespace internal - -} // end namespace Eigen - -#endif // EIGEN_INCOMPLETE_LUT_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h b/thirdparty/eigen-3.2.7/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h deleted file mode 100644 index 501ef2f8..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h +++ /dev/null @@ -1,282 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2011 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_ITERATIVE_SOLVER_BASE_H -#define EIGEN_ITERATIVE_SOLVER_BASE_H - -namespace Eigen { - -/** \ingroup IterativeLinearSolvers_Module - * \brief Base class for linear iterative solvers - * - * \sa class SimplicialCholesky, DiagonalPreconditioner, IdentityPreconditioner - */ -template< typename Derived> -class IterativeSolverBase : internal::noncopyable -{ -public: - typedef typename internal::traits::MatrixType MatrixType; - typedef typename internal::traits::Preconditioner Preconditioner; - typedef typename MatrixType::Scalar Scalar; - typedef typename MatrixType::Index Index; - typedef typename MatrixType::RealScalar RealScalar; - -public: - - Derived& derived() { return *static_cast(this); } - const Derived& derived() const { return *static_cast(this); } - - /** Default constructor. */ - IterativeSolverBase() - : mp_matrix(0) - { - init(); - } - - /** Initialize the solver with matrix \a A for further \c Ax=b solving. - * - * This constructor is a shortcut for the default constructor followed - * by a call to compute(). - * - * \warning this class stores a reference to the matrix A as well as some - * precomputed values that depend on it. Therefore, if \a A is changed - * this class becomes invalid. Call compute() to update it with the new - * matrix A, or modify a copy of A. - */ - template - IterativeSolverBase(const EigenBase& A) - { - init(); - compute(A.derived()); - } - - ~IterativeSolverBase() {} - - /** Initializes the iterative solver for the sparcity pattern of the matrix \a A for further solving \c Ax=b problems. - * - * Currently, this function mostly call analyzePattern on the preconditioner. In the future - * we might, for instance, implement column reodering for faster matrix vector products. - */ - template - Derived& analyzePattern(const EigenBase& A) - { - grabInput(A.derived()); - m_preconditioner.analyzePattern(*mp_matrix); - m_isInitialized = true; - m_analysisIsOk = true; - m_info = Success; - return derived(); - } - - /** Initializes the iterative solver with the numerical values of the matrix \a A for further solving \c Ax=b problems. - * - * Currently, this function mostly call factorize on the preconditioner. - * - * \warning this class stores a reference to the matrix A as well as some - * precomputed values that depend on it. Therefore, if \a A is changed - * this class becomes invalid. Call compute() to update it with the new - * matrix A, or modify a copy of A. - */ - template - Derived& factorize(const EigenBase& A) - { - grabInput(A.derived()); - eigen_assert(m_analysisIsOk && "You must first call analyzePattern()"); - m_preconditioner.factorize(*mp_matrix); - m_factorizationIsOk = true; - m_info = Success; - return derived(); - } - - /** Initializes the iterative solver with the matrix \a A for further solving \c Ax=b problems. - * - * Currently, this function mostly initialized/compute the preconditioner. In the future - * we might, for instance, implement column reodering for faster matrix vector products. - * - * \warning this class stores a reference to the matrix A as well as some - * precomputed values that depend on it. Therefore, if \a A is changed - * this class becomes invalid. Call compute() to update it with the new - * matrix A, or modify a copy of A. - */ - template - Derived& compute(const EigenBase& A) - { - grabInput(A.derived()); - m_preconditioner.compute(*mp_matrix); - m_isInitialized = true; - m_analysisIsOk = true; - m_factorizationIsOk = true; - m_info = Success; - return derived(); - } - - /** \internal */ - Index rows() const { return mp_matrix ? mp_matrix->rows() : 0; } - /** \internal */ - Index cols() const { return mp_matrix ? mp_matrix->cols() : 0; } - - /** \returns the tolerance threshold used by the stopping criteria */ - RealScalar tolerance() const { return m_tolerance; } - - /** Sets the tolerance threshold used by the stopping criteria */ - Derived& setTolerance(const RealScalar& tolerance) - { - m_tolerance = tolerance; - return derived(); - } - - /** \returns a read-write reference to the preconditioner for custom configuration. */ - Preconditioner& preconditioner() { return m_preconditioner; } - - /** \returns a read-only reference to the preconditioner. */ - const Preconditioner& preconditioner() const { return m_preconditioner; } - - /** \returns the max number of iterations */ - int maxIterations() const - { - return (mp_matrix && m_maxIterations<0) ? mp_matrix->cols() : m_maxIterations; - } - - /** Sets the max number of iterations */ - Derived& setMaxIterations(int maxIters) - { - m_maxIterations = maxIters; - return derived(); - } - - /** \returns the number of iterations performed during the last solve */ - int iterations() const - { - eigen_assert(m_isInitialized && "ConjugateGradient is not initialized."); - return m_iterations; - } - - /** \returns the tolerance error reached during the last solve */ - RealScalar error() const - { - eigen_assert(m_isInitialized && "ConjugateGradient is not initialized."); - return m_error; - } - - /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. - * - * \sa compute() - */ - template inline const internal::solve_retval - solve(const MatrixBase& b) const - { - eigen_assert(m_isInitialized && "IterativeSolverBase is not initialized."); - eigen_assert(rows()==b.rows() - && "IterativeSolverBase::solve(): invalid number of rows of the right hand side matrix b"); - return internal::solve_retval(derived(), b.derived()); - } - - /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. - * - * \sa compute() - */ - template - inline const internal::sparse_solve_retval - solve(const SparseMatrixBase& b) const - { - eigen_assert(m_isInitialized && "IterativeSolverBase is not initialized."); - eigen_assert(rows()==b.rows() - && "IterativeSolverBase::solve(): invalid number of rows of the right hand side matrix b"); - return internal::sparse_solve_retval(*this, b.derived()); - } - - /** \returns Success if the iterations converged, and NoConvergence otherwise. */ - ComputationInfo info() const - { - eigen_assert(m_isInitialized && "IterativeSolverBase is not initialized."); - return m_info; - } - - /** \internal */ - template - void _solve_sparse(const Rhs& b, SparseMatrix &dest) const - { - eigen_assert(rows()==b.rows()); - - int rhsCols = b.cols(); - int size = b.rows(); - Eigen::Matrix tb(size); - Eigen::Matrix tx(size); - for(int k=0; k - void grabInput(const EigenBase& A) - { - // we const cast to prevent the creation of a MatrixType temporary by the compiler. - grabInput_impl(A.const_cast_derived()); - } - - template - void grabInput_impl(const EigenBase& A) - { - m_copyMatrix = A; - mp_matrix = &m_copyMatrix; - } - - void grabInput_impl(MatrixType& A) - { - if(MatrixType::RowsAtCompileTime==Dynamic && MatrixType::ColsAtCompileTime==Dynamic) - m_copyMatrix.resize(0,0); - mp_matrix = &A; - } - - void init() - { - m_isInitialized = false; - m_analysisIsOk = false; - m_factorizationIsOk = false; - m_maxIterations = -1; - m_tolerance = NumTraits::epsilon(); - } - MatrixType m_copyMatrix; - const MatrixType* mp_matrix; - Preconditioner m_preconditioner; - - int m_maxIterations; - RealScalar m_tolerance; - - mutable RealScalar m_error; - mutable int m_iterations; - mutable ComputationInfo m_info; - mutable bool m_isInitialized, m_analysisIsOk, m_factorizationIsOk; -}; - -namespace internal { - -template -struct sparse_solve_retval, Rhs> - : sparse_solve_retval_base, Rhs> -{ - typedef IterativeSolverBase Dec; - EIGEN_MAKE_SPARSE_SOLVE_HELPERS(Dec,Rhs) - - template void evalTo(Dest& dst) const - { - dec().derived()._solve_sparse(rhs(),dst); - } -}; - -} // end namespace internal - -} // end namespace Eigen - -#endif // EIGEN_ITERATIVE_SOLVER_BASE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Jacobi/Jacobi.h b/thirdparty/eigen-3.2.7/Eigen/src/Jacobi/Jacobi.h deleted file mode 100644 index 956f72d5..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/Jacobi/Jacobi.h +++ /dev/null @@ -1,433 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2009 Benoit Jacob -// Copyright (C) 2009 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_JACOBI_H -#define EIGEN_JACOBI_H - -namespace Eigen { - -/** \ingroup Jacobi_Module - * \jacobi_module - * \class JacobiRotation - * \brief Rotation given by a cosine-sine pair. - * - * This class represents a Jacobi or Givens rotation. - * This is a 2D rotation in the plane \c J of angle \f$ \theta \f$ defined by - * its cosine \c c and sine \c s as follow: - * \f$ J = \left ( \begin{array}{cc} c & \overline s \\ -s & \overline c \end{array} \right ) \f$ - * - * You can apply the respective counter-clockwise rotation to a column vector \c v by - * applying its adjoint on the left: \f$ v = J^* v \f$ that translates to the following Eigen code: - * \code - * v.applyOnTheLeft(J.adjoint()); - * \endcode - * - * \sa MatrixBase::applyOnTheLeft(), MatrixBase::applyOnTheRight() - */ -template class JacobiRotation -{ - public: - typedef typename NumTraits::Real RealScalar; - - /** Default constructor without any initialization. */ - JacobiRotation() {} - - /** Construct a planar rotation from a cosine-sine pair (\a c, \c s). */ - JacobiRotation(const Scalar& c, const Scalar& s) : m_c(c), m_s(s) {} - - Scalar& c() { return m_c; } - Scalar c() const { return m_c; } - Scalar& s() { return m_s; } - Scalar s() const { return m_s; } - - /** Concatenates two planar rotation */ - JacobiRotation operator*(const JacobiRotation& other) - { - using numext::conj; - return JacobiRotation(m_c * other.m_c - conj(m_s) * other.m_s, - conj(m_c * conj(other.m_s) + conj(m_s) * conj(other.m_c))); - } - - /** Returns the transposed transformation */ - JacobiRotation transpose() const { using numext::conj; return JacobiRotation(m_c, -conj(m_s)); } - - /** Returns the adjoint transformation */ - JacobiRotation adjoint() const { using numext::conj; return JacobiRotation(conj(m_c), -m_s); } - - template - bool makeJacobi(const MatrixBase&, typename Derived::Index p, typename Derived::Index q); - bool makeJacobi(const RealScalar& x, const Scalar& y, const RealScalar& z); - - void makeGivens(const Scalar& p, const Scalar& q, Scalar* z=0); - - protected: - void makeGivens(const Scalar& p, const Scalar& q, Scalar* z, internal::true_type); - void makeGivens(const Scalar& p, const Scalar& q, Scalar* z, internal::false_type); - - Scalar m_c, m_s; -}; - -/** Makes \c *this as a Jacobi rotation \a J such that applying \a J on both the right and left sides of the selfadjoint 2x2 matrix - * \f$ B = \left ( \begin{array}{cc} x & y \\ \overline y & z \end{array} \right )\f$ yields a diagonal matrix \f$ A = J^* B J \f$ - * - * \sa MatrixBase::makeJacobi(const MatrixBase&, Index, Index), MatrixBase::applyOnTheLeft(), MatrixBase::applyOnTheRight() - */ -template -bool JacobiRotation::makeJacobi(const RealScalar& x, const Scalar& y, const RealScalar& z) -{ - using std::sqrt; - using std::abs; - typedef typename NumTraits::Real RealScalar; - if(y == Scalar(0)) - { - m_c = Scalar(1); - m_s = Scalar(0); - return false; - } - else - { - RealScalar tau = (x-z)/(RealScalar(2)*abs(y)); - RealScalar w = sqrt(numext::abs2(tau) + RealScalar(1)); - RealScalar t; - if(tau>RealScalar(0)) - { - t = RealScalar(1) / (tau + w); - } - else - { - t = RealScalar(1) / (tau - w); - } - RealScalar sign_t = t > RealScalar(0) ? RealScalar(1) : RealScalar(-1); - RealScalar n = RealScalar(1) / sqrt(numext::abs2(t)+RealScalar(1)); - m_s = - sign_t * (numext::conj(y) / abs(y)) * abs(t) * n; - m_c = n; - return true; - } -} - -/** Makes \c *this as a Jacobi rotation \c J such that applying \a J on both the right and left sides of the 2x2 selfadjoint matrix - * \f$ B = \left ( \begin{array}{cc} \text{this}_{pp} & \text{this}_{pq} \\ (\text{this}_{pq})^* & \text{this}_{qq} \end{array} \right )\f$ yields - * a diagonal matrix \f$ A = J^* B J \f$ - * - * Example: \include Jacobi_makeJacobi.cpp - * Output: \verbinclude Jacobi_makeJacobi.out - * - * \sa JacobiRotation::makeJacobi(RealScalar, Scalar, RealScalar), MatrixBase::applyOnTheLeft(), MatrixBase::applyOnTheRight() - */ -template -template -inline bool JacobiRotation::makeJacobi(const MatrixBase& m, typename Derived::Index p, typename Derived::Index q) -{ - return makeJacobi(numext::real(m.coeff(p,p)), m.coeff(p,q), numext::real(m.coeff(q,q))); -} - -/** Makes \c *this as a Givens rotation \c G such that applying \f$ G^* \f$ to the left of the vector - * \f$ V = \left ( \begin{array}{c} p \\ q \end{array} \right )\f$ yields: - * \f$ G^* V = \left ( \begin{array}{c} r \\ 0 \end{array} \right )\f$. - * - * The value of \a z is returned if \a z is not null (the default is null). - * Also note that G is built such that the cosine is always real. - * - * Example: \include Jacobi_makeGivens.cpp - * Output: \verbinclude Jacobi_makeGivens.out - * - * This function implements the continuous Givens rotation generation algorithm - * found in Anderson (2000), Discontinuous Plane Rotations and the Symmetric Eigenvalue Problem. - * LAPACK Working Note 150, University of Tennessee, UT-CS-00-454, December 4, 2000. - * - * \sa MatrixBase::applyOnTheLeft(), MatrixBase::applyOnTheRight() - */ -template -void JacobiRotation::makeGivens(const Scalar& p, const Scalar& q, Scalar* z) -{ - makeGivens(p, q, z, typename internal::conditional::IsComplex, internal::true_type, internal::false_type>::type()); -} - - -// specialization for complexes -template -void JacobiRotation::makeGivens(const Scalar& p, const Scalar& q, Scalar* r, internal::true_type) -{ - using std::sqrt; - using std::abs; - using numext::conj; - - if(q==Scalar(0)) - { - m_c = numext::real(p)<0 ? Scalar(-1) : Scalar(1); - m_s = 0; - if(r) *r = m_c * p; - } - else if(p==Scalar(0)) - { - m_c = 0; - m_s = -q/abs(q); - if(r) *r = abs(q); - } - else - { - RealScalar p1 = numext::norm1(p); - RealScalar q1 = numext::norm1(q); - if(p1>=q1) - { - Scalar ps = p / p1; - RealScalar p2 = numext::abs2(ps); - Scalar qs = q / p1; - RealScalar q2 = numext::abs2(qs); - - RealScalar u = sqrt(RealScalar(1) + q2/p2); - if(numext::real(p) -void JacobiRotation::makeGivens(const Scalar& p, const Scalar& q, Scalar* r, internal::false_type) -{ - using std::sqrt; - using std::abs; - if(q==Scalar(0)) - { - m_c = p abs(q)) - { - Scalar t = q/p; - Scalar u = sqrt(Scalar(1) + numext::abs2(t)); - if(p -void apply_rotation_in_the_plane(VectorX& _x, VectorY& _y, const JacobiRotation& j); -} - -/** \jacobi_module - * Applies the rotation in the plane \a j to the rows \a p and \a q of \c *this, i.e., it computes B = J * B, - * with \f$ B = \left ( \begin{array}{cc} \text{*this.row}(p) \\ \text{*this.row}(q) \end{array} \right ) \f$. - * - * \sa class JacobiRotation, MatrixBase::applyOnTheRight(), internal::apply_rotation_in_the_plane() - */ -template -template -inline void MatrixBase::applyOnTheLeft(Index p, Index q, const JacobiRotation& j) -{ - RowXpr x(this->row(p)); - RowXpr y(this->row(q)); - internal::apply_rotation_in_the_plane(x, y, j); -} - -/** \ingroup Jacobi_Module - * Applies the rotation in the plane \a j to the columns \a p and \a q of \c *this, i.e., it computes B = B * J - * with \f$ B = \left ( \begin{array}{cc} \text{*this.col}(p) & \text{*this.col}(q) \end{array} \right ) \f$. - * - * \sa class JacobiRotation, MatrixBase::applyOnTheLeft(), internal::apply_rotation_in_the_plane() - */ -template -template -inline void MatrixBase::applyOnTheRight(Index p, Index q, const JacobiRotation& j) -{ - ColXpr x(this->col(p)); - ColXpr y(this->col(q)); - internal::apply_rotation_in_the_plane(x, y, j.transpose()); -} - -namespace internal { -template -void /*EIGEN_DONT_INLINE*/ apply_rotation_in_the_plane(VectorX& _x, VectorY& _y, const JacobiRotation& j) -{ - typedef typename VectorX::Index Index; - typedef typename VectorX::Scalar Scalar; - enum { PacketSize = packet_traits::size }; - typedef typename packet_traits::type Packet; - eigen_assert(_x.size() == _y.size()); - Index size = _x.size(); - Index incrx = _x.innerStride(); - Index incry = _y.innerStride(); - - Scalar* EIGEN_RESTRICT x = &_x.coeffRef(0); - Scalar* EIGEN_RESTRICT y = &_y.coeffRef(0); - - OtherScalar c = j.c(); - OtherScalar s = j.s(); - if (c==OtherScalar(1) && s==OtherScalar(0)) - return; - - /*** dynamic-size vectorized paths ***/ - - if(VectorX::SizeAtCompileTime == Dynamic && - (VectorX::Flags & VectorY::Flags & PacketAccessBit) && - ((incrx==1 && incry==1) || PacketSize == 1)) - { - // both vectors are sequentially stored in memory => vectorization - enum { Peeling = 2 }; - - Index alignedStart = internal::first_aligned(y, size); - Index alignedEnd = alignedStart + ((size-alignedStart)/PacketSize)*PacketSize; - - const Packet pc = pset1(c); - const Packet ps = pset1(s); - conj_helper::IsComplex,false> pcj; - - for(Index i=0; i(px); - Packet yi = pload(py); - pstore(px, padd(pmul(pc,xi),pcj.pmul(ps,yi))); - pstore(py, psub(pcj.pmul(pc,yi),pmul(ps,xi))); - px += PacketSize; - py += PacketSize; - } - } - else - { - Index peelingEnd = alignedStart + ((size-alignedStart)/(Peeling*PacketSize))*(Peeling*PacketSize); - for(Index i=alignedStart; i(px); - Packet xi1 = ploadu(px+PacketSize); - Packet yi = pload (py); - Packet yi1 = pload (py+PacketSize); - pstoreu(px, padd(pmul(pc,xi),pcj.pmul(ps,yi))); - pstoreu(px+PacketSize, padd(pmul(pc,xi1),pcj.pmul(ps,yi1))); - pstore (py, psub(pcj.pmul(pc,yi),pmul(ps,xi))); - pstore (py+PacketSize, psub(pcj.pmul(pc,yi1),pmul(ps,xi1))); - px += Peeling*PacketSize; - py += Peeling*PacketSize; - } - if(alignedEnd!=peelingEnd) - { - Packet xi = ploadu(x+peelingEnd); - Packet yi = pload (y+peelingEnd); - pstoreu(x+peelingEnd, padd(pmul(pc,xi),pcj.pmul(ps,yi))); - pstore (y+peelingEnd, psub(pcj.pmul(pc,yi),pmul(ps,xi))); - } - } - - for(Index i=alignedEnd; i(c); - const Packet ps = pset1(s); - conj_helper::IsComplex,false> pcj; - Scalar* EIGEN_RESTRICT px = x; - Scalar* EIGEN_RESTRICT py = y; - for(Index i=0; i(px); - Packet yi = pload(py); - pstore(px, padd(pmul(pc,xi),pcj.pmul(ps,yi))); - pstore(py, psub(pcj.pmul(pc,yi),pmul(ps,xi))); - px += PacketSize; - py += PacketSize; - } - } - - /*** non-vectorized path ***/ - else - { - for(Index i=0; i -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_DETERMINANT_H -#define EIGEN_DETERMINANT_H - -namespace Eigen { - -namespace internal { - -template -inline const typename Derived::Scalar bruteforce_det3_helper -(const MatrixBase& matrix, int a, int b, int c) -{ - return matrix.coeff(0,a) - * (matrix.coeff(1,b) * matrix.coeff(2,c) - matrix.coeff(1,c) * matrix.coeff(2,b)); -} - -template -const typename Derived::Scalar bruteforce_det4_helper -(const MatrixBase& matrix, int j, int k, int m, int n) -{ - return (matrix.coeff(j,0) * matrix.coeff(k,1) - matrix.coeff(k,0) * matrix.coeff(j,1)) - * (matrix.coeff(m,2) * matrix.coeff(n,3) - matrix.coeff(n,2) * matrix.coeff(m,3)); -} - -template struct determinant_impl -{ - static inline typename traits::Scalar run(const Derived& m) - { - if(Derived::ColsAtCompileTime==Dynamic && m.rows()==0) - return typename traits::Scalar(1); - return m.partialPivLu().determinant(); - } -}; - -template struct determinant_impl -{ - static inline typename traits::Scalar run(const Derived& m) - { - return m.coeff(0,0); - } -}; - -template struct determinant_impl -{ - static inline typename traits::Scalar run(const Derived& m) - { - return m.coeff(0,0) * m.coeff(1,1) - m.coeff(1,0) * m.coeff(0,1); - } -}; - -template struct determinant_impl -{ - static inline typename traits::Scalar run(const Derived& m) - { - return bruteforce_det3_helper(m,0,1,2) - - bruteforce_det3_helper(m,1,0,2) - + bruteforce_det3_helper(m,2,0,1); - } -}; - -template struct determinant_impl -{ - static typename traits::Scalar run(const Derived& m) - { - // trick by Martin Costabel to compute 4x4 det with only 30 muls - return bruteforce_det4_helper(m,0,1,2,3) - - bruteforce_det4_helper(m,0,2,1,3) - + bruteforce_det4_helper(m,0,3,1,2) - + bruteforce_det4_helper(m,1,2,0,3) - - bruteforce_det4_helper(m,1,3,0,2) - + bruteforce_det4_helper(m,2,3,0,1); - } -}; - -} // end namespace internal - -/** \lu_module - * - * \returns the determinant of this matrix - */ -template -inline typename internal::traits::Scalar MatrixBase::determinant() const -{ - eigen_assert(rows() == cols()); - typedef typename internal::nested::type Nested; - return internal::determinant_impl::type>::run(derived()); -} - -} // end namespace Eigen - -#endif // EIGEN_DETERMINANT_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/LU/FullPivLU.h b/thirdparty/eigen-3.2.7/Eigen/src/LU/FullPivLU.h deleted file mode 100644 index 26bc7144..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/LU/FullPivLU.h +++ /dev/null @@ -1,751 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2006-2009 Benoit Jacob -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_LU_H -#define EIGEN_LU_H - -namespace Eigen { - -/** \ingroup LU_Module - * - * \class FullPivLU - * - * \brief LU decomposition of a matrix with complete pivoting, and related features - * - * \param MatrixType the type of the matrix of which we are computing the LU decomposition - * - * This class represents a LU decomposition of any matrix, with complete pivoting: the matrix A is - * decomposed as \f$ A = P^{-1} L U Q^{-1} \f$ where L is unit-lower-triangular, U is - * upper-triangular, and P and Q are permutation matrices. This is a rank-revealing LU - * decomposition. The eigenvalues (diagonal coefficients) of U are sorted in such a way that any - * zeros are at the end. - * - * This decomposition provides the generic approach to solving systems of linear equations, computing - * the rank, invertibility, inverse, kernel, and determinant. - * - * This LU decomposition is very stable and well tested with large matrices. However there are use cases where the SVD - * decomposition is inherently more stable and/or flexible. For example, when computing the kernel of a matrix, - * working with the SVD allows to select the smallest singular values of the matrix, something that - * the LU decomposition doesn't see. - * - * The data of the LU decomposition can be directly accessed through the methods matrixLU(), - * permutationP(), permutationQ(). - * - * As an exemple, here is how the original matrix can be retrieved: - * \include class_FullPivLU.cpp - * Output: \verbinclude class_FullPivLU.out - * - * \sa MatrixBase::fullPivLu(), MatrixBase::determinant(), MatrixBase::inverse() - */ -template class FullPivLU -{ - public: - typedef _MatrixType MatrixType; - enum { - RowsAtCompileTime = MatrixType::RowsAtCompileTime, - ColsAtCompileTime = MatrixType::ColsAtCompileTime, - Options = MatrixType::Options, - MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime, - MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime - }; - typedef typename MatrixType::Scalar Scalar; - typedef typename NumTraits::Real RealScalar; - typedef typename internal::traits::StorageKind StorageKind; - typedef typename MatrixType::Index Index; - typedef typename internal::plain_row_type::type IntRowVectorType; - typedef typename internal::plain_col_type::type IntColVectorType; - typedef PermutationMatrix PermutationQType; - typedef PermutationMatrix PermutationPType; - - /** - * \brief Default Constructor. - * - * The default constructor is useful in cases in which the user intends to - * perform decompositions via LU::compute(const MatrixType&). - */ - FullPivLU(); - - /** \brief Default Constructor with memory preallocation - * - * Like the default constructor but with preallocation of the internal data - * according to the specified problem \a size. - * \sa FullPivLU() - */ - FullPivLU(Index rows, Index cols); - - /** Constructor. - * - * \param matrix the matrix of which to compute the LU decomposition. - * It is required to be nonzero. - */ - FullPivLU(const MatrixType& matrix); - - /** Computes the LU decomposition of the given matrix. - * - * \param matrix the matrix of which to compute the LU decomposition. - * It is required to be nonzero. - * - * \returns a reference to *this - */ - FullPivLU& compute(const MatrixType& matrix); - - /** \returns the LU decomposition matrix: the upper-triangular part is U, the - * unit-lower-triangular part is L (at least for square matrices; in the non-square - * case, special care is needed, see the documentation of class FullPivLU). - * - * \sa matrixL(), matrixU() - */ - inline const MatrixType& matrixLU() const - { - eigen_assert(m_isInitialized && "LU is not initialized."); - return m_lu; - } - - /** \returns the number of nonzero pivots in the LU decomposition. - * Here nonzero is meant in the exact sense, not in a fuzzy sense. - * So that notion isn't really intrinsically interesting, but it is - * still useful when implementing algorithms. - * - * \sa rank() - */ - inline Index nonzeroPivots() const - { - eigen_assert(m_isInitialized && "LU is not initialized."); - return m_nonzero_pivots; - } - - /** \returns the absolute value of the biggest pivot, i.e. the biggest - * diagonal coefficient of U. - */ - RealScalar maxPivot() const { return m_maxpivot; } - - /** \returns the permutation matrix P - * - * \sa permutationQ() - */ - inline const PermutationPType& permutationP() const - { - eigen_assert(m_isInitialized && "LU is not initialized."); - return m_p; - } - - /** \returns the permutation matrix Q - * - * \sa permutationP() - */ - inline const PermutationQType& permutationQ() const - { - eigen_assert(m_isInitialized && "LU is not initialized."); - return m_q; - } - - /** \returns the kernel of the matrix, also called its null-space. The columns of the returned matrix - * will form a basis of the kernel. - * - * \note If the kernel has dimension zero, then the returned matrix is a column-vector filled with zeros. - * - * \note This method has to determine which pivots should be considered nonzero. - * For that, it uses the threshold value that you can control by calling - * setThreshold(const RealScalar&). - * - * Example: \include FullPivLU_kernel.cpp - * Output: \verbinclude FullPivLU_kernel.out - * - * \sa image() - */ - inline const internal::kernel_retval kernel() const - { - eigen_assert(m_isInitialized && "LU is not initialized."); - return internal::kernel_retval(*this); - } - - /** \returns the image of the matrix, also called its column-space. The columns of the returned matrix - * will form a basis of the kernel. - * - * \param originalMatrix the original matrix, of which *this is the LU decomposition. - * The reason why it is needed to pass it here, is that this allows - * a large optimization, as otherwise this method would need to reconstruct it - * from the LU decomposition. - * - * \note If the image has dimension zero, then the returned matrix is a column-vector filled with zeros. - * - * \note This method has to determine which pivots should be considered nonzero. - * For that, it uses the threshold value that you can control by calling - * setThreshold(const RealScalar&). - * - * Example: \include FullPivLU_image.cpp - * Output: \verbinclude FullPivLU_image.out - * - * \sa kernel() - */ - inline const internal::image_retval - image(const MatrixType& originalMatrix) const - { - eigen_assert(m_isInitialized && "LU is not initialized."); - return internal::image_retval(*this, originalMatrix); - } - - /** \return a solution x to the equation Ax=b, where A is the matrix of which - * *this is the LU decomposition. - * - * \param b the right-hand-side of the equation to solve. Can be a vector or a matrix, - * the only requirement in order for the equation to make sense is that - * b.rows()==A.rows(), where A is the matrix of which *this is the LU decomposition. - * - * \returns a solution. - * - * \note_about_checking_solutions - * - * \note_about_arbitrary_choice_of_solution - * \note_about_using_kernel_to_study_multiple_solutions - * - * Example: \include FullPivLU_solve.cpp - * Output: \verbinclude FullPivLU_solve.out - * - * \sa TriangularView::solve(), kernel(), inverse() - */ - template - inline const internal::solve_retval - solve(const MatrixBase& b) const - { - eigen_assert(m_isInitialized && "LU is not initialized."); - return internal::solve_retval(*this, b.derived()); - } - - /** \returns the determinant of the matrix of which - * *this is the LU decomposition. It has only linear complexity - * (that is, O(n) where n is the dimension of the square matrix) - * as the LU decomposition has already been computed. - * - * \note This is only for square matrices. - * - * \note For fixed-size matrices of size up to 4, MatrixBase::determinant() offers - * optimized paths. - * - * \warning a determinant can be very big or small, so for matrices - * of large enough dimension, there is a risk of overflow/underflow. - * - * \sa MatrixBase::determinant() - */ - typename internal::traits::Scalar determinant() const; - - /** Allows to prescribe a threshold to be used by certain methods, such as rank(), - * who need to determine when pivots are to be considered nonzero. This is not used for the - * LU decomposition itself. - * - * When it needs to get the threshold value, Eigen calls threshold(). By default, this - * uses a formula to automatically determine a reasonable threshold. - * Once you have called the present method setThreshold(const RealScalar&), - * your value is used instead. - * - * \param threshold The new value to use as the threshold. - * - * A pivot will be considered nonzero if its absolute value is strictly greater than - * \f$ \vert pivot \vert \leqslant threshold \times \vert maxpivot \vert \f$ - * where maxpivot is the biggest pivot. - * - * If you want to come back to the default behavior, call setThreshold(Default_t) - */ - FullPivLU& setThreshold(const RealScalar& threshold) - { - m_usePrescribedThreshold = true; - m_prescribedThreshold = threshold; - return *this; - } - - /** Allows to come back to the default behavior, letting Eigen use its default formula for - * determining the threshold. - * - * You should pass the special object Eigen::Default as parameter here. - * \code lu.setThreshold(Eigen::Default); \endcode - * - * See the documentation of setThreshold(const RealScalar&). - */ - FullPivLU& setThreshold(Default_t) - { - m_usePrescribedThreshold = false; - return *this; - } - - /** Returns the threshold that will be used by certain methods such as rank(). - * - * See the documentation of setThreshold(const RealScalar&). - */ - RealScalar threshold() const - { - eigen_assert(m_isInitialized || m_usePrescribedThreshold); - return m_usePrescribedThreshold ? m_prescribedThreshold - // this formula comes from experimenting (see "LU precision tuning" thread on the list) - // and turns out to be identical to Higham's formula used already in LDLt. - : NumTraits::epsilon() * m_lu.diagonalSize(); - } - - /** \returns the rank of the matrix of which *this is the LU decomposition. - * - * \note This method has to determine which pivots should be considered nonzero. - * For that, it uses the threshold value that you can control by calling - * setThreshold(const RealScalar&). - */ - inline Index rank() const - { - using std::abs; - eigen_assert(m_isInitialized && "LU is not initialized."); - RealScalar premultiplied_threshold = abs(m_maxpivot) * threshold(); - Index result = 0; - for(Index i = 0; i < m_nonzero_pivots; ++i) - result += (abs(m_lu.coeff(i,i)) > premultiplied_threshold); - return result; - } - - /** \returns the dimension of the kernel of the matrix of which *this is the LU decomposition. - * - * \note This method has to determine which pivots should be considered nonzero. - * For that, it uses the threshold value that you can control by calling - * setThreshold(const RealScalar&). - */ - inline Index dimensionOfKernel() const - { - eigen_assert(m_isInitialized && "LU is not initialized."); - return cols() - rank(); - } - - /** \returns true if the matrix of which *this is the LU decomposition represents an injective - * linear map, i.e. has trivial kernel; false otherwise. - * - * \note This method has to determine which pivots should be considered nonzero. - * For that, it uses the threshold value that you can control by calling - * setThreshold(const RealScalar&). - */ - inline bool isInjective() const - { - eigen_assert(m_isInitialized && "LU is not initialized."); - return rank() == cols(); - } - - /** \returns true if the matrix of which *this is the LU decomposition represents a surjective - * linear map; false otherwise. - * - * \note This method has to determine which pivots should be considered nonzero. - * For that, it uses the threshold value that you can control by calling - * setThreshold(const RealScalar&). - */ - inline bool isSurjective() const - { - eigen_assert(m_isInitialized && "LU is not initialized."); - return rank() == rows(); - } - - /** \returns true if the matrix of which *this is the LU decomposition is invertible. - * - * \note This method has to determine which pivots should be considered nonzero. - * For that, it uses the threshold value that you can control by calling - * setThreshold(const RealScalar&). - */ - inline bool isInvertible() const - { - eigen_assert(m_isInitialized && "LU is not initialized."); - return isInjective() && (m_lu.rows() == m_lu.cols()); - } - - /** \returns the inverse of the matrix of which *this is the LU decomposition. - * - * \note If this matrix is not invertible, the returned matrix has undefined coefficients. - * Use isInvertible() to first determine whether this matrix is invertible. - * - * \sa MatrixBase::inverse() - */ - inline const internal::solve_retval inverse() const - { - eigen_assert(m_isInitialized && "LU is not initialized."); - eigen_assert(m_lu.rows() == m_lu.cols() && "You can't take the inverse of a non-square matrix!"); - return internal::solve_retval - (*this, MatrixType::Identity(m_lu.rows(), m_lu.cols())); - } - - MatrixType reconstructedMatrix() const; - - inline Index rows() const { return m_lu.rows(); } - inline Index cols() const { return m_lu.cols(); } - - protected: - - static void check_template_parameters() - { - EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar); - } - - MatrixType m_lu; - PermutationPType m_p; - PermutationQType m_q; - IntColVectorType m_rowsTranspositions; - IntRowVectorType m_colsTranspositions; - Index m_det_pq, m_nonzero_pivots; - RealScalar m_maxpivot, m_prescribedThreshold; - bool m_isInitialized, m_usePrescribedThreshold; -}; - -template -FullPivLU::FullPivLU() - : m_isInitialized(false), m_usePrescribedThreshold(false) -{ -} - -template -FullPivLU::FullPivLU(Index rows, Index cols) - : m_lu(rows, cols), - m_p(rows), - m_q(cols), - m_rowsTranspositions(rows), - m_colsTranspositions(cols), - m_isInitialized(false), - m_usePrescribedThreshold(false) -{ -} - -template -FullPivLU::FullPivLU(const MatrixType& matrix) - : m_lu(matrix.rows(), matrix.cols()), - m_p(matrix.rows()), - m_q(matrix.cols()), - m_rowsTranspositions(matrix.rows()), - m_colsTranspositions(matrix.cols()), - m_isInitialized(false), - m_usePrescribedThreshold(false) -{ - compute(matrix); -} - -template -FullPivLU& FullPivLU::compute(const MatrixType& matrix) -{ - check_template_parameters(); - - // the permutations are stored as int indices, so just to be sure: - eigen_assert(matrix.rows()<=NumTraits::highest() && matrix.cols()<=NumTraits::highest()); - - m_isInitialized = true; - m_lu = matrix; - - const Index size = matrix.diagonalSize(); - const Index rows = matrix.rows(); - const Index cols = matrix.cols(); - - // will store the transpositions, before we accumulate them at the end. - // can't accumulate on-the-fly because that will be done in reverse order for the rows. - m_rowsTranspositions.resize(matrix.rows()); - m_colsTranspositions.resize(matrix.cols()); - Index number_of_transpositions = 0; // number of NONTRIVIAL transpositions, i.e. m_rowsTranspositions[i]!=i - - m_nonzero_pivots = size; // the generic case is that in which all pivots are nonzero (invertible case) - m_maxpivot = RealScalar(0); - - for(Index k = 0; k < size; ++k) - { - // First, we need to find the pivot. - - // biggest coefficient in the remaining bottom-right corner (starting at row k, col k) - Index row_of_biggest_in_corner, col_of_biggest_in_corner; - RealScalar biggest_in_corner; - biggest_in_corner = m_lu.bottomRightCorner(rows-k, cols-k) - .cwiseAbs() - .maxCoeff(&row_of_biggest_in_corner, &col_of_biggest_in_corner); - row_of_biggest_in_corner += k; // correct the values! since they were computed in the corner, - col_of_biggest_in_corner += k; // need to add k to them. - - if(biggest_in_corner==RealScalar(0)) - { - // before exiting, make sure to initialize the still uninitialized transpositions - // in a sane state without destroying what we already have. - m_nonzero_pivots = k; - for(Index i = k; i < size; ++i) - { - m_rowsTranspositions.coeffRef(i) = i; - m_colsTranspositions.coeffRef(i) = i; - } - break; - } - - if(biggest_in_corner > m_maxpivot) m_maxpivot = biggest_in_corner; - - // Now that we've found the pivot, we need to apply the row/col swaps to - // bring it to the location (k,k). - - m_rowsTranspositions.coeffRef(k) = row_of_biggest_in_corner; - m_colsTranspositions.coeffRef(k) = col_of_biggest_in_corner; - if(k != row_of_biggest_in_corner) { - m_lu.row(k).swap(m_lu.row(row_of_biggest_in_corner)); - ++number_of_transpositions; - } - if(k != col_of_biggest_in_corner) { - m_lu.col(k).swap(m_lu.col(col_of_biggest_in_corner)); - ++number_of_transpositions; - } - - // Now that the pivot is at the right location, we update the remaining - // bottom-right corner by Gaussian elimination. - - if(k= 0; --k) - m_p.applyTranspositionOnTheRight(k, m_rowsTranspositions.coeff(k)); - - m_q.setIdentity(cols); - for(Index k = 0; k < size; ++k) - m_q.applyTranspositionOnTheRight(k, m_colsTranspositions.coeff(k)); - - m_det_pq = (number_of_transpositions%2) ? -1 : 1; - return *this; -} - -template -typename internal::traits::Scalar FullPivLU::determinant() const -{ - eigen_assert(m_isInitialized && "LU is not initialized."); - eigen_assert(m_lu.rows() == m_lu.cols() && "You can't take the determinant of a non-square matrix!"); - return Scalar(m_det_pq) * Scalar(m_lu.diagonal().prod()); -} - -/** \returns the matrix represented by the decomposition, - * i.e., it returns the product: \f$ P^{-1} L U Q^{-1} \f$. - * This function is provided for debug purposes. */ -template -MatrixType FullPivLU::reconstructedMatrix() const -{ - eigen_assert(m_isInitialized && "LU is not initialized."); - const Index smalldim = (std::min)(m_lu.rows(), m_lu.cols()); - // LU - MatrixType res(m_lu.rows(),m_lu.cols()); - // FIXME the .toDenseMatrix() should not be needed... - res = m_lu.leftCols(smalldim) - .template triangularView().toDenseMatrix() - * m_lu.topRows(smalldim) - .template triangularView().toDenseMatrix(); - - // P^{-1}(LU) - res = m_p.inverse() * res; - - // (P^{-1}LU)Q^{-1} - res = res * m_q.inverse(); - - return res; -} - -/********* Implementation of kernel() **************************************************/ - -namespace internal { -template -struct kernel_retval > - : kernel_retval_base > -{ - EIGEN_MAKE_KERNEL_HELPERS(FullPivLU<_MatrixType>) - - enum { MaxSmallDimAtCompileTime = EIGEN_SIZE_MIN_PREFER_FIXED( - MatrixType::MaxColsAtCompileTime, - MatrixType::MaxRowsAtCompileTime) - }; - - template void evalTo(Dest& dst) const - { - using std::abs; - const Index cols = dec().matrixLU().cols(), dimker = cols - rank(); - if(dimker == 0) - { - // The Kernel is just {0}, so it doesn't have a basis properly speaking, but let's - // avoid crashing/asserting as that depends on floating point calculations. Let's - // just return a single column vector filled with zeros. - dst.setZero(); - return; - } - - /* Let us use the following lemma: - * - * Lemma: If the matrix A has the LU decomposition PAQ = LU, - * then Ker A = Q(Ker U). - * - * Proof: trivial: just keep in mind that P, Q, L are invertible. - */ - - /* Thus, all we need to do is to compute Ker U, and then apply Q. - * - * U is upper triangular, with eigenvalues sorted so that any zeros appear at the end. - * Thus, the diagonal of U ends with exactly - * dimKer zero's. Let us use that to construct dimKer linearly - * independent vectors in Ker U. - */ - - Matrix pivots(rank()); - RealScalar premultiplied_threshold = dec().maxPivot() * dec().threshold(); - Index p = 0; - for(Index i = 0; i < dec().nonzeroPivots(); ++i) - if(abs(dec().matrixLU().coeff(i,i)) > premultiplied_threshold) - pivots.coeffRef(p++) = i; - eigen_internal_assert(p == rank()); - - // we construct a temporaty trapezoid matrix m, by taking the U matrix and - // permuting the rows and cols to bring the nonnegligible pivots to the top of - // the main diagonal. We need that to be able to apply our triangular solvers. - // FIXME when we get triangularView-for-rectangular-matrices, this can be simplified - Matrix - m(dec().matrixLU().block(0, 0, rank(), cols)); - for(Index i = 0; i < rank(); ++i) - { - if(i) m.row(i).head(i).setZero(); - m.row(i).tail(cols-i) = dec().matrixLU().row(pivots.coeff(i)).tail(cols-i); - } - m.block(0, 0, rank(), rank()); - m.block(0, 0, rank(), rank()).template triangularView().setZero(); - for(Index i = 0; i < rank(); ++i) - m.col(i).swap(m.col(pivots.coeff(i))); - - // ok, we have our trapezoid matrix, we can apply the triangular solver. - // notice that the math behind this suggests that we should apply this to the - // negative of the RHS, but for performance we just put the negative sign elsewhere, see below. - m.topLeftCorner(rank(), rank()) - .template triangularView().solveInPlace( - m.topRightCorner(rank(), dimker) - ); - - // now we must undo the column permutation that we had applied! - for(Index i = rank()-1; i >= 0; --i) - m.col(i).swap(m.col(pivots.coeff(i))); - - // see the negative sign in the next line, that's what we were talking about above. - for(Index i = 0; i < rank(); ++i) dst.row(dec().permutationQ().indices().coeff(i)) = -m.row(i).tail(dimker); - for(Index i = rank(); i < cols; ++i) dst.row(dec().permutationQ().indices().coeff(i)).setZero(); - for(Index k = 0; k < dimker; ++k) dst.coeffRef(dec().permutationQ().indices().coeff(rank()+k), k) = Scalar(1); - } -}; - -/***** Implementation of image() *****************************************************/ - -template -struct image_retval > - : image_retval_base > -{ - EIGEN_MAKE_IMAGE_HELPERS(FullPivLU<_MatrixType>) - - enum { MaxSmallDimAtCompileTime = EIGEN_SIZE_MIN_PREFER_FIXED( - MatrixType::MaxColsAtCompileTime, - MatrixType::MaxRowsAtCompileTime) - }; - - template void evalTo(Dest& dst) const - { - using std::abs; - if(rank() == 0) - { - // The Image is just {0}, so it doesn't have a basis properly speaking, but let's - // avoid crashing/asserting as that depends on floating point calculations. Let's - // just return a single column vector filled with zeros. - dst.setZero(); - return; - } - - Matrix pivots(rank()); - RealScalar premultiplied_threshold = dec().maxPivot() * dec().threshold(); - Index p = 0; - for(Index i = 0; i < dec().nonzeroPivots(); ++i) - if(abs(dec().matrixLU().coeff(i,i)) > premultiplied_threshold) - pivots.coeffRef(p++) = i; - eigen_internal_assert(p == rank()); - - for(Index i = 0; i < rank(); ++i) - dst.col(i) = originalMatrix().col(dec().permutationQ().indices().coeff(pivots.coeff(i))); - } -}; - -/***** Implementation of solve() *****************************************************/ - -template -struct solve_retval, Rhs> - : solve_retval_base, Rhs> -{ - EIGEN_MAKE_SOLVE_HELPERS(FullPivLU<_MatrixType>,Rhs) - - template void evalTo(Dest& dst) const - { - /* The decomposition PAQ = LU can be rewritten as A = P^{-1} L U Q^{-1}. - * So we proceed as follows: - * Step 1: compute c = P * rhs. - * Step 2: replace c by the solution x to Lx = c. Exists because L is invertible. - * Step 3: replace c by the solution x to Ux = c. May or may not exist. - * Step 4: result = Q * c; - */ - - const Index rows = dec().rows(), cols = dec().cols(), - nonzero_pivots = dec().nonzeroPivots(); - eigen_assert(rhs().rows() == rows); - const Index smalldim = (std::min)(rows, cols); - - if(nonzero_pivots == 0) - { - dst.setZero(); - return; - } - - typename Rhs::PlainObject c(rhs().rows(), rhs().cols()); - - // Step 1 - c = dec().permutationP() * rhs(); - - // Step 2 - dec().matrixLU() - .topLeftCorner(smalldim,smalldim) - .template triangularView() - .solveInPlace(c.topRows(smalldim)); - if(rows>cols) - { - c.bottomRows(rows-cols) - -= dec().matrixLU().bottomRows(rows-cols) - * c.topRows(cols); - } - - // Step 3 - dec().matrixLU() - .topLeftCorner(nonzero_pivots, nonzero_pivots) - .template triangularView() - .solveInPlace(c.topRows(nonzero_pivots)); - - // Step 4 - for(Index i = 0; i < nonzero_pivots; ++i) - dst.row(dec().permutationQ().indices().coeff(i)) = c.row(i); - for(Index i = nonzero_pivots; i < dec().matrixLU().cols(); ++i) - dst.row(dec().permutationQ().indices().coeff(i)).setZero(); - } -}; - -} // end namespace internal - -/******* MatrixBase methods *****************************************************************/ - -/** \lu_module - * - * \return the full-pivoting LU decomposition of \c *this. - * - * \sa class FullPivLU - */ -template -inline const FullPivLU::PlainObject> -MatrixBase::fullPivLu() const -{ - return FullPivLU(eval()); -} - -} // end namespace Eigen - -#endif // EIGEN_LU_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/LU/Inverse.h b/thirdparty/eigen-3.2.7/Eigen/src/LU/Inverse.h deleted file mode 100644 index 3cf88719..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/LU/Inverse.h +++ /dev/null @@ -1,400 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2010 Benoit Jacob -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_INVERSE_H -#define EIGEN_INVERSE_H - -namespace Eigen { - -namespace internal { - -/********************************** -*** General case implementation *** -**********************************/ - -template -struct compute_inverse -{ - static inline void run(const MatrixType& matrix, ResultType& result) - { - result = matrix.partialPivLu().inverse(); - } -}; - -template -struct compute_inverse_and_det_with_check { /* nothing! general case not supported. */ }; - -/**************************** -*** Size 1 implementation *** -****************************/ - -template -struct compute_inverse -{ - static inline void run(const MatrixType& matrix, ResultType& result) - { - typedef typename MatrixType::Scalar Scalar; - result.coeffRef(0,0) = Scalar(1) / matrix.coeff(0,0); - } -}; - -template -struct compute_inverse_and_det_with_check -{ - static inline void run( - const MatrixType& matrix, - const typename MatrixType::RealScalar& absDeterminantThreshold, - ResultType& result, - typename ResultType::Scalar& determinant, - bool& invertible - ) - { - using std::abs; - determinant = matrix.coeff(0,0); - invertible = abs(determinant) > absDeterminantThreshold; - if(invertible) result.coeffRef(0,0) = typename ResultType::Scalar(1) / determinant; - } -}; - -/**************************** -*** Size 2 implementation *** -****************************/ - -template -inline void compute_inverse_size2_helper( - const MatrixType& matrix, const typename ResultType::Scalar& invdet, - ResultType& result) -{ - result.coeffRef(0,0) = matrix.coeff(1,1) * invdet; - result.coeffRef(1,0) = -matrix.coeff(1,0) * invdet; - result.coeffRef(0,1) = -matrix.coeff(0,1) * invdet; - result.coeffRef(1,1) = matrix.coeff(0,0) * invdet; -} - -template -struct compute_inverse -{ - static inline void run(const MatrixType& matrix, ResultType& result) - { - typedef typename ResultType::Scalar Scalar; - const Scalar invdet = typename MatrixType::Scalar(1) / matrix.determinant(); - compute_inverse_size2_helper(matrix, invdet, result); - } -}; - -template -struct compute_inverse_and_det_with_check -{ - static inline void run( - const MatrixType& matrix, - const typename MatrixType::RealScalar& absDeterminantThreshold, - ResultType& inverse, - typename ResultType::Scalar& determinant, - bool& invertible - ) - { - using std::abs; - typedef typename ResultType::Scalar Scalar; - determinant = matrix.determinant(); - invertible = abs(determinant) > absDeterminantThreshold; - if(!invertible) return; - const Scalar invdet = Scalar(1) / determinant; - compute_inverse_size2_helper(matrix, invdet, inverse); - } -}; - -/**************************** -*** Size 3 implementation *** -****************************/ - -template -inline typename MatrixType::Scalar cofactor_3x3(const MatrixType& m) -{ - enum { - i1 = (i+1) % 3, - i2 = (i+2) % 3, - j1 = (j+1) % 3, - j2 = (j+2) % 3 - }; - return m.coeff(i1, j1) * m.coeff(i2, j2) - - m.coeff(i1, j2) * m.coeff(i2, j1); -} - -template -inline void compute_inverse_size3_helper( - const MatrixType& matrix, - const typename ResultType::Scalar& invdet, - const Matrix& cofactors_col0, - ResultType& result) -{ - result.row(0) = cofactors_col0 * invdet; - result.coeffRef(1,0) = cofactor_3x3(matrix) * invdet; - result.coeffRef(1,1) = cofactor_3x3(matrix) * invdet; - result.coeffRef(1,2) = cofactor_3x3(matrix) * invdet; - result.coeffRef(2,0) = cofactor_3x3(matrix) * invdet; - result.coeffRef(2,1) = cofactor_3x3(matrix) * invdet; - result.coeffRef(2,2) = cofactor_3x3(matrix) * invdet; -} - -template -struct compute_inverse -{ - static inline void run(const MatrixType& matrix, ResultType& result) - { - typedef typename ResultType::Scalar Scalar; - Matrix cofactors_col0; - cofactors_col0.coeffRef(0) = cofactor_3x3(matrix); - cofactors_col0.coeffRef(1) = cofactor_3x3(matrix); - cofactors_col0.coeffRef(2) = cofactor_3x3(matrix); - const Scalar det = (cofactors_col0.cwiseProduct(matrix.col(0))).sum(); - const Scalar invdet = Scalar(1) / det; - compute_inverse_size3_helper(matrix, invdet, cofactors_col0, result); - } -}; - -template -struct compute_inverse_and_det_with_check -{ - static inline void run( - const MatrixType& matrix, - const typename MatrixType::RealScalar& absDeterminantThreshold, - ResultType& inverse, - typename ResultType::Scalar& determinant, - bool& invertible - ) - { - using std::abs; - typedef typename ResultType::Scalar Scalar; - Matrix cofactors_col0; - cofactors_col0.coeffRef(0) = cofactor_3x3(matrix); - cofactors_col0.coeffRef(1) = cofactor_3x3(matrix); - cofactors_col0.coeffRef(2) = cofactor_3x3(matrix); - determinant = (cofactors_col0.cwiseProduct(matrix.col(0))).sum(); - invertible = abs(determinant) > absDeterminantThreshold; - if(!invertible) return; - const Scalar invdet = Scalar(1) / determinant; - compute_inverse_size3_helper(matrix, invdet, cofactors_col0, inverse); - } -}; - -/**************************** -*** Size 4 implementation *** -****************************/ - -template -inline const typename Derived::Scalar general_det3_helper -(const MatrixBase& matrix, int i1, int i2, int i3, int j1, int j2, int j3) -{ - return matrix.coeff(i1,j1) - * (matrix.coeff(i2,j2) * matrix.coeff(i3,j3) - matrix.coeff(i2,j3) * matrix.coeff(i3,j2)); -} - -template -inline typename MatrixType::Scalar cofactor_4x4(const MatrixType& matrix) -{ - enum { - i1 = (i+1) % 4, - i2 = (i+2) % 4, - i3 = (i+3) % 4, - j1 = (j+1) % 4, - j2 = (j+2) % 4, - j3 = (j+3) % 4 - }; - return general_det3_helper(matrix, i1, i2, i3, j1, j2, j3) - + general_det3_helper(matrix, i2, i3, i1, j1, j2, j3) - + general_det3_helper(matrix, i3, i1, i2, j1, j2, j3); -} - -template -struct compute_inverse_size4 -{ - static void run(const MatrixType& matrix, ResultType& result) - { - result.coeffRef(0,0) = cofactor_4x4(matrix); - result.coeffRef(1,0) = -cofactor_4x4(matrix); - result.coeffRef(2,0) = cofactor_4x4(matrix); - result.coeffRef(3,0) = -cofactor_4x4(matrix); - result.coeffRef(0,2) = cofactor_4x4(matrix); - result.coeffRef(1,2) = -cofactor_4x4(matrix); - result.coeffRef(2,2) = cofactor_4x4(matrix); - result.coeffRef(3,2) = -cofactor_4x4(matrix); - result.coeffRef(0,1) = -cofactor_4x4(matrix); - result.coeffRef(1,1) = cofactor_4x4(matrix); - result.coeffRef(2,1) = -cofactor_4x4(matrix); - result.coeffRef(3,1) = cofactor_4x4(matrix); - result.coeffRef(0,3) = -cofactor_4x4(matrix); - result.coeffRef(1,3) = cofactor_4x4(matrix); - result.coeffRef(2,3) = -cofactor_4x4(matrix); - result.coeffRef(3,3) = cofactor_4x4(matrix); - result /= (matrix.col(0).cwiseProduct(result.row(0).transpose())).sum(); - } -}; - -template -struct compute_inverse - : compute_inverse_size4 -{ -}; - -template -struct compute_inverse_and_det_with_check -{ - static inline void run( - const MatrixType& matrix, - const typename MatrixType::RealScalar& absDeterminantThreshold, - ResultType& inverse, - typename ResultType::Scalar& determinant, - bool& invertible - ) - { - using std::abs; - determinant = matrix.determinant(); - invertible = abs(determinant) > absDeterminantThreshold; - if(invertible) compute_inverse::run(matrix, inverse); - } -}; - -/************************* -*** MatrixBase methods *** -*************************/ - -template -struct traits > -{ - typedef typename MatrixType::PlainObject ReturnType; -}; - -template -struct inverse_impl : public ReturnByValue > -{ - typedef typename MatrixType::Index Index; - typedef typename internal::eval::type MatrixTypeNested; - typedef typename remove_all::type MatrixTypeNestedCleaned; - MatrixTypeNested m_matrix; - - inverse_impl(const MatrixType& matrix) - : m_matrix(matrix) - {} - - inline Index rows() const { return m_matrix.rows(); } - inline Index cols() const { return m_matrix.cols(); } - - template inline void evalTo(Dest& dst) const - { - const int Size = EIGEN_PLAIN_ENUM_MIN(MatrixType::ColsAtCompileTime,Dest::ColsAtCompileTime); - EIGEN_ONLY_USED_FOR_DEBUG(Size); - eigen_assert(( (Size<=1) || (Size>4) || (extract_data(m_matrix)!=extract_data(dst))) - && "Aliasing problem detected in inverse(), you need to do inverse().eval() here."); - - compute_inverse::run(m_matrix, dst); - } -}; - -} // end namespace internal - -/** \lu_module - * - * \returns the matrix inverse of this matrix. - * - * For small fixed sizes up to 4x4, this method uses cofactors. - * In the general case, this method uses class PartialPivLU. - * - * \note This matrix must be invertible, otherwise the result is undefined. If you need an - * invertibility check, do the following: - * \li for fixed sizes up to 4x4, use computeInverseAndDetWithCheck(). - * \li for the general case, use class FullPivLU. - * - * Example: \include MatrixBase_inverse.cpp - * Output: \verbinclude MatrixBase_inverse.out - * - * \sa computeInverseAndDetWithCheck() - */ -template -inline const internal::inverse_impl MatrixBase::inverse() const -{ - EIGEN_STATIC_ASSERT(!NumTraits::IsInteger,THIS_FUNCTION_IS_NOT_FOR_INTEGER_NUMERIC_TYPES) - eigen_assert(rows() == cols()); - return internal::inverse_impl(derived()); -} - -/** \lu_module - * - * Computation of matrix inverse and determinant, with invertibility check. - * - * This is only for fixed-size square matrices of size up to 4x4. - * - * \param inverse Reference to the matrix in which to store the inverse. - * \param determinant Reference to the variable in which to store the determinant. - * \param invertible Reference to the bool variable in which to store whether the matrix is invertible. - * \param absDeterminantThreshold Optional parameter controlling the invertibility check. - * The matrix will be declared invertible if the absolute value of its - * determinant is greater than this threshold. - * - * Example: \include MatrixBase_computeInverseAndDetWithCheck.cpp - * Output: \verbinclude MatrixBase_computeInverseAndDetWithCheck.out - * - * \sa inverse(), computeInverseWithCheck() - */ -template -template -inline void MatrixBase::computeInverseAndDetWithCheck( - ResultType& inverse, - typename ResultType::Scalar& determinant, - bool& invertible, - const RealScalar& absDeterminantThreshold - ) const -{ - // i'd love to put some static assertions there, but SFINAE means that they have no effect... - eigen_assert(rows() == cols()); - // for 2x2, it's worth giving a chance to avoid evaluating. - // for larger sizes, evaluating has negligible cost and limits code size. - typedef typename internal::conditional< - RowsAtCompileTime == 2, - typename internal::remove_all::type>::type, - PlainObject - >::type MatrixType; - internal::compute_inverse_and_det_with_check::run - (derived(), absDeterminantThreshold, inverse, determinant, invertible); -} - -/** \lu_module - * - * Computation of matrix inverse, with invertibility check. - * - * This is only for fixed-size square matrices of size up to 4x4. - * - * \param inverse Reference to the matrix in which to store the inverse. - * \param invertible Reference to the bool variable in which to store whether the matrix is invertible. - * \param absDeterminantThreshold Optional parameter controlling the invertibility check. - * The matrix will be declared invertible if the absolute value of its - * determinant is greater than this threshold. - * - * Example: \include MatrixBase_computeInverseWithCheck.cpp - * Output: \verbinclude MatrixBase_computeInverseWithCheck.out - * - * \sa inverse(), computeInverseAndDetWithCheck() - */ -template -template -inline void MatrixBase::computeInverseWithCheck( - ResultType& inverse, - bool& invertible, - const RealScalar& absDeterminantThreshold - ) const -{ - RealScalar determinant; - // i'd love to put some static assertions there, but SFINAE means that they have no effect... - eigen_assert(rows() == cols()); - computeInverseAndDetWithCheck(inverse,determinant,invertible,absDeterminantThreshold); -} - -} // end namespace Eigen - -#endif // EIGEN_INVERSE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/LU/PartialPivLU.h b/thirdparty/eigen-3.2.7/Eigen/src/LU/PartialPivLU.h deleted file mode 100644 index 7d1db948..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/LU/PartialPivLU.h +++ /dev/null @@ -1,509 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2006-2009 Benoit Jacob -// Copyright (C) 2009 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_PARTIALLU_H -#define EIGEN_PARTIALLU_H - -namespace Eigen { - -/** \ingroup LU_Module - * - * \class PartialPivLU - * - * \brief LU decomposition of a matrix with partial pivoting, and related features - * - * \param MatrixType the type of the matrix of which we are computing the LU decomposition - * - * This class represents a LU decomposition of a \b square \b invertible matrix, with partial pivoting: the matrix A - * is decomposed as A = PLU where L is unit-lower-triangular, U is upper-triangular, and P - * is a permutation matrix. - * - * Typically, partial pivoting LU decomposition is only considered numerically stable for square invertible - * matrices. Thus LAPACK's dgesv and dgesvx require the matrix to be square and invertible. The present class - * does the same. It will assert that the matrix is square, but it won't (actually it can't) check that the - * matrix is invertible: it is your task to check that you only use this decomposition on invertible matrices. - * - * The guaranteed safe alternative, working for all matrices, is the full pivoting LU decomposition, provided - * by class FullPivLU. - * - * This is \b not a rank-revealing LU decomposition. Many features are intentionally absent from this class, - * such as rank computation. If you need these features, use class FullPivLU. - * - * This LU decomposition is suitable to invert invertible matrices. It is what MatrixBase::inverse() uses - * in the general case. - * On the other hand, it is \b not suitable to determine whether a given matrix is invertible. - * - * The data of the LU decomposition can be directly accessed through the methods matrixLU(), permutationP(). - * - * \sa MatrixBase::partialPivLu(), MatrixBase::determinant(), MatrixBase::inverse(), MatrixBase::computeInverse(), class FullPivLU - */ -template class PartialPivLU -{ - public: - - typedef _MatrixType MatrixType; - enum { - RowsAtCompileTime = MatrixType::RowsAtCompileTime, - ColsAtCompileTime = MatrixType::ColsAtCompileTime, - Options = MatrixType::Options, - MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime, - MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime - }; - typedef typename MatrixType::Scalar Scalar; - typedef typename NumTraits::Real RealScalar; - typedef typename internal::traits::StorageKind StorageKind; - typedef typename MatrixType::Index Index; - typedef PermutationMatrix PermutationType; - typedef Transpositions TranspositionType; - - - /** - * \brief Default Constructor. - * - * The default constructor is useful in cases in which the user intends to - * perform decompositions via PartialPivLU::compute(const MatrixType&). - */ - PartialPivLU(); - - /** \brief Default Constructor with memory preallocation - * - * Like the default constructor but with preallocation of the internal data - * according to the specified problem \a size. - * \sa PartialPivLU() - */ - PartialPivLU(Index size); - - /** Constructor. - * - * \param matrix the matrix of which to compute the LU decomposition. - * - * \warning The matrix should have full rank (e.g. if it's square, it should be invertible). - * If you need to deal with non-full rank, use class FullPivLU instead. - */ - PartialPivLU(const MatrixType& matrix); - - PartialPivLU& compute(const MatrixType& matrix); - - /** \returns the LU decomposition matrix: the upper-triangular part is U, the - * unit-lower-triangular part is L (at least for square matrices; in the non-square - * case, special care is needed, see the documentation of class FullPivLU). - * - * \sa matrixL(), matrixU() - */ - inline const MatrixType& matrixLU() const - { - eigen_assert(m_isInitialized && "PartialPivLU is not initialized."); - return m_lu; - } - - /** \returns the permutation matrix P. - */ - inline const PermutationType& permutationP() const - { - eigen_assert(m_isInitialized && "PartialPivLU is not initialized."); - return m_p; - } - - /** This method returns the solution x to the equation Ax=b, where A is the matrix of which - * *this is the LU decomposition. - * - * \param b the right-hand-side of the equation to solve. Can be a vector or a matrix, - * the only requirement in order for the equation to make sense is that - * b.rows()==A.rows(), where A is the matrix of which *this is the LU decomposition. - * - * \returns the solution. - * - * Example: \include PartialPivLU_solve.cpp - * Output: \verbinclude PartialPivLU_solve.out - * - * Since this PartialPivLU class assumes anyway that the matrix A is invertible, the solution - * theoretically exists and is unique regardless of b. - * - * \sa TriangularView::solve(), inverse(), computeInverse() - */ - template - inline const internal::solve_retval - solve(const MatrixBase& b) const - { - eigen_assert(m_isInitialized && "PartialPivLU is not initialized."); - return internal::solve_retval(*this, b.derived()); - } - - /** \returns the inverse of the matrix of which *this is the LU decomposition. - * - * \warning The matrix being decomposed here is assumed to be invertible. If you need to check for - * invertibility, use class FullPivLU instead. - * - * \sa MatrixBase::inverse(), LU::inverse() - */ - inline const internal::solve_retval inverse() const - { - eigen_assert(m_isInitialized && "PartialPivLU is not initialized."); - return internal::solve_retval - (*this, MatrixType::Identity(m_lu.rows(), m_lu.cols())); - } - - /** \returns the determinant of the matrix of which - * *this is the LU decomposition. It has only linear complexity - * (that is, O(n) where n is the dimension of the square matrix) - * as the LU decomposition has already been computed. - * - * \note For fixed-size matrices of size up to 4, MatrixBase::determinant() offers - * optimized paths. - * - * \warning a determinant can be very big or small, so for matrices - * of large enough dimension, there is a risk of overflow/underflow. - * - * \sa MatrixBase::determinant() - */ - typename internal::traits::Scalar determinant() const; - - MatrixType reconstructedMatrix() const; - - inline Index rows() const { return m_lu.rows(); } - inline Index cols() const { return m_lu.cols(); } - - protected: - - static void check_template_parameters() - { - EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar); - } - - MatrixType m_lu; - PermutationType m_p; - TranspositionType m_rowsTranspositions; - Index m_det_p; - bool m_isInitialized; -}; - -template -PartialPivLU::PartialPivLU() - : m_lu(), - m_p(), - m_rowsTranspositions(), - m_det_p(0), - m_isInitialized(false) -{ -} - -template -PartialPivLU::PartialPivLU(Index size) - : m_lu(size, size), - m_p(size), - m_rowsTranspositions(size), - m_det_p(0), - m_isInitialized(false) -{ -} - -template -PartialPivLU::PartialPivLU(const MatrixType& matrix) - : m_lu(matrix.rows(), matrix.rows()), - m_p(matrix.rows()), - m_rowsTranspositions(matrix.rows()), - m_det_p(0), - m_isInitialized(false) -{ - compute(matrix); -} - -namespace internal { - -/** \internal This is the blocked version of fullpivlu_unblocked() */ -template -struct partial_lu_impl -{ - // FIXME add a stride to Map, so that the following mapping becomes easier, - // another option would be to create an expression being able to automatically - // warp any Map, Matrix, and Block expressions as a unique type, but since that's exactly - // a Map + stride, why not adding a stride to Map, and convenient ctors from a Matrix, - // and Block. - typedef Map > MapLU; - typedef Block MatrixType; - typedef Block BlockType; - typedef typename MatrixType::RealScalar RealScalar; - typedef typename MatrixType::Index Index; - - /** \internal performs the LU decomposition in-place of the matrix \a lu - * using an unblocked algorithm. - * - * In addition, this function returns the row transpositions in the - * vector \a row_transpositions which must have a size equal to the number - * of columns of the matrix \a lu, and an integer \a nb_transpositions - * which returns the actual number of transpositions. - * - * \returns The index of the first pivot which is exactly zero if any, or a negative number otherwise. - */ - static Index unblocked_lu(MatrixType& lu, PivIndex* row_transpositions, PivIndex& nb_transpositions) - { - const Index rows = lu.rows(); - const Index cols = lu.cols(); - const Index size = (std::min)(rows,cols); - nb_transpositions = 0; - Index first_zero_pivot = -1; - for(Index k = 0; k < size; ++k) - { - Index rrows = rows-k-1; - Index rcols = cols-k-1; - - Index row_of_biggest_in_col; - RealScalar biggest_in_corner - = lu.col(k).tail(rows-k).cwiseAbs().maxCoeff(&row_of_biggest_in_col); - row_of_biggest_in_col += k; - - row_transpositions[k] = PivIndex(row_of_biggest_in_col); - - if(biggest_in_corner != RealScalar(0)) - { - if(k != row_of_biggest_in_col) - { - lu.row(k).swap(lu.row(row_of_biggest_in_col)); - ++nb_transpositions; - } - - // FIXME shall we introduce a safe quotient expression in cas 1/lu.coeff(k,k) - // overflow but not the actual quotient? - lu.col(k).tail(rrows) /= lu.coeff(k,k); - } - else if(first_zero_pivot==-1) - { - // the pivot is exactly zero, we record the index of the first pivot which is exactly 0, - // and continue the factorization such we still have A = PLU - first_zero_pivot = k; - } - - if(k > > - */ - static Index blocked_lu(Index rows, Index cols, Scalar* lu_data, Index luStride, PivIndex* row_transpositions, PivIndex& nb_transpositions, Index maxBlockSize=256) - { - MapLU lu1(lu_data,StorageOrder==RowMajor?rows:luStride,StorageOrder==RowMajor?luStride:cols); - MatrixType lu(lu1,0,0,rows,cols); - - const Index size = (std::min)(rows,cols); - - // if the matrix is too small, no blocking: - if(size<=16) - { - return unblocked_lu(lu, row_transpositions, nb_transpositions); - } - - // automatically adjust the number of subdivisions to the size - // of the matrix so that there is enough sub blocks: - Index blockSize; - { - blockSize = size/8; - blockSize = (blockSize/16)*16; - blockSize = (std::min)((std::max)(blockSize,Index(8)), maxBlockSize); - } - - nb_transpositions = 0; - Index first_zero_pivot = -1; - for(Index k = 0; k < size; k+=blockSize) - { - Index bs = (std::min)(size-k,blockSize); // actual size of the block - Index trows = rows - k - bs; // trailing rows - Index tsize = size - k - bs; // trailing size - - // partition the matrix: - // A00 | A01 | A02 - // lu = A_0 | A_1 | A_2 = A10 | A11 | A12 - // A20 | A21 | A22 - BlockType A_0(lu,0,0,rows,k); - BlockType A_2(lu,0,k+bs,rows,tsize); - BlockType A11(lu,k,k,bs,bs); - BlockType A12(lu,k,k+bs,bs,tsize); - BlockType A21(lu,k+bs,k,trows,bs); - BlockType A22(lu,k+bs,k+bs,trows,tsize); - - PivIndex nb_transpositions_in_panel; - // recursively call the blocked LU algorithm on [A11^T A21^T]^T - // with a very small blocking size: - Index ret = blocked_lu(trows+bs, bs, &lu.coeffRef(k,k), luStride, - row_transpositions+k, nb_transpositions_in_panel, 16); - if(ret>=0 && first_zero_pivot==-1) - first_zero_pivot = k+ret; - - nb_transpositions += nb_transpositions_in_panel; - // update permutations and apply them to A_0 - for(Index i=k; i().solveInPlace(A12); - - A22.noalias() -= A21 * A12; - } - } - return first_zero_pivot; - } -}; - -/** \internal performs the LU decomposition with partial pivoting in-place. - */ -template -void partial_lu_inplace(MatrixType& lu, TranspositionType& row_transpositions, typename TranspositionType::Index& nb_transpositions) -{ - eigen_assert(lu.cols() == row_transpositions.size()); - eigen_assert((&row_transpositions.coeffRef(1)-&row_transpositions.coeffRef(0)) == 1); - - partial_lu_impl - - ::blocked_lu(lu.rows(), lu.cols(), &lu.coeffRef(0,0), lu.outerStride(), &row_transpositions.coeffRef(0), nb_transpositions); -} - -} // end namespace internal - -template -PartialPivLU& PartialPivLU::compute(const MatrixType& matrix) -{ - check_template_parameters(); - - // the row permutation is stored as int indices, so just to be sure: - eigen_assert(matrix.rows()::highest()); - - m_lu = matrix; - - eigen_assert(matrix.rows() == matrix.cols() && "PartialPivLU is only for square (and moreover invertible) matrices"); - const Index size = matrix.rows(); - - m_rowsTranspositions.resize(size); - - typename TranspositionType::Index nb_transpositions; - internal::partial_lu_inplace(m_lu, m_rowsTranspositions, nb_transpositions); - m_det_p = (nb_transpositions%2) ? -1 : 1; - - m_p = m_rowsTranspositions; - - m_isInitialized = true; - return *this; -} - -template -typename internal::traits::Scalar PartialPivLU::determinant() const -{ - eigen_assert(m_isInitialized && "PartialPivLU is not initialized."); - return Scalar(m_det_p) * m_lu.diagonal().prod(); -} - -/** \returns the matrix represented by the decomposition, - * i.e., it returns the product: P^{-1} L U. - * This function is provided for debug purpose. */ -template -MatrixType PartialPivLU::reconstructedMatrix() const -{ - eigen_assert(m_isInitialized && "LU is not initialized."); - // LU - MatrixType res = m_lu.template triangularView().toDenseMatrix() - * m_lu.template triangularView(); - - // P^{-1}(LU) - res = m_p.inverse() * res; - - return res; -} - -/***** Implementation of solve() *****************************************************/ - -namespace internal { - -template -struct solve_retval, Rhs> - : solve_retval_base, Rhs> -{ - EIGEN_MAKE_SOLVE_HELPERS(PartialPivLU<_MatrixType>,Rhs) - - template void evalTo(Dest& dst) const - { - /* The decomposition PA = LU can be rewritten as A = P^{-1} L U. - * So we proceed as follows: - * Step 1: compute c = Pb. - * Step 2: replace c by the solution x to Lx = c. - * Step 3: replace c by the solution x to Ux = c. - */ - - eigen_assert(rhs().rows() == dec().matrixLU().rows()); - - // Step 1 - dst = dec().permutationP() * rhs(); - - // Step 2 - dec().matrixLU().template triangularView().solveInPlace(dst); - - // Step 3 - dec().matrixLU().template triangularView().solveInPlace(dst); - } -}; - -} // end namespace internal - -/******** MatrixBase methods *******/ - -/** \lu_module - * - * \return the partial-pivoting LU decomposition of \c *this. - * - * \sa class PartialPivLU - */ -template -inline const PartialPivLU::PlainObject> -MatrixBase::partialPivLu() const -{ - return PartialPivLU(eval()); -} - -#if EIGEN2_SUPPORT_STAGE > STAGE20_RESOLVE_API_CONFLICTS -/** \lu_module - * - * Synonym of partialPivLu(). - * - * \return the partial-pivoting LU decomposition of \c *this. - * - * \sa class PartialPivLU - */ -template -inline const PartialPivLU::PlainObject> -MatrixBase::lu() const -{ - return PartialPivLU(eval()); -} -#endif - -} // end namespace Eigen - -#endif // EIGEN_PARTIALLU_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/LU/PartialPivLU_MKL.h b/thirdparty/eigen-3.2.7/Eigen/src/LU/PartialPivLU_MKL.h deleted file mode 100644 index 9035953c..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/LU/PartialPivLU_MKL.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - Copyright (c) 2011, Intel Corporation. All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of Intel Corporation nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - ******************************************************************************** - * Content : Eigen bindings to Intel(R) MKL - * LU decomposition with partial pivoting based on LAPACKE_?getrf function. - ******************************************************************************** -*/ - -#ifndef EIGEN_PARTIALLU_LAPACK_H -#define EIGEN_PARTIALLU_LAPACK_H - -#include "Eigen/src/Core/util/MKL_support.h" - -namespace Eigen { - -namespace internal { - -/** \internal Specialization for the data types supported by MKL */ - -#define EIGEN_MKL_LU_PARTPIV(EIGTYPE, MKLTYPE, MKLPREFIX) \ -template \ -struct partial_lu_impl \ -{ \ - /* \internal performs the LU decomposition in-place of the matrix represented */ \ - static lapack_int blocked_lu(lapack_int rows, lapack_int cols, EIGTYPE* lu_data, lapack_int luStride, lapack_int* row_transpositions, lapack_int& nb_transpositions, lapack_int maxBlockSize=256) \ - { \ - EIGEN_UNUSED_VARIABLE(maxBlockSize);\ - lapack_int matrix_order, first_zero_pivot; \ - lapack_int m, n, lda, *ipiv, info; \ - EIGTYPE* a; \ -/* Set up parameters for ?getrf */ \ - matrix_order = StorageOrder==RowMajor ? LAPACK_ROW_MAJOR : LAPACK_COL_MAJOR; \ - lda = luStride; \ - a = lu_data; \ - ipiv = row_transpositions; \ - m = rows; \ - n = cols; \ - nb_transpositions = 0; \ -\ - info = LAPACKE_##MKLPREFIX##getrf( matrix_order, m, n, (MKLTYPE*)a, lda, ipiv ); \ -\ - for(int i=0;i= 0); \ -/* something should be done with nb_transpositions */ \ -\ - first_zero_pivot = info; \ - return first_zero_pivot; \ - } \ -}; - -EIGEN_MKL_LU_PARTPIV(double, double, d) -EIGEN_MKL_LU_PARTPIV(float, float, s) -EIGEN_MKL_LU_PARTPIV(dcomplex, MKL_Complex16, z) -EIGEN_MKL_LU_PARTPIV(scomplex, MKL_Complex8, c) - -} // end namespace internal - -} // end namespace Eigen - -#endif // EIGEN_PARTIALLU_LAPACK_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/LU/arch/Inverse_SSE.h b/thirdparty/eigen-3.2.7/Eigen/src/LU/arch/Inverse_SSE.h deleted file mode 100644 index 60b7a237..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/LU/arch/Inverse_SSE.h +++ /dev/null @@ -1,329 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2001 Intel Corporation -// Copyright (C) 2010 Gael Guennebaud -// Copyright (C) 2009 Benoit Jacob -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -// The SSE code for the 4x4 float and double matrix inverse in this file -// comes from the following Intel's library: -// http://software.intel.com/en-us/articles/optimized-matrix-library-for-use-with-the-intel-pentiumr-4-processors-sse2-instructions/ -// -// Here is the respective copyright and license statement: -// -// Copyright (c) 2001 Intel Corporation. -// -// Permition is granted to use, copy, distribute and prepare derivative works -// of this library for any purpose and without fee, provided, that the above -// copyright notice and this statement appear in all copies. -// Intel makes no representations about the suitability of this software for -// any purpose, and specifically disclaims all warranties. -// See LEGAL.TXT for all the legal information. - -#ifndef EIGEN_INVERSE_SSE_H -#define EIGEN_INVERSE_SSE_H - -namespace Eigen { - -namespace internal { - -template -struct compute_inverse_size4 -{ - enum { - MatrixAlignment = bool(MatrixType::Flags&AlignedBit), - ResultAlignment = bool(ResultType::Flags&AlignedBit), - StorageOrdersMatch = (MatrixType::Flags&RowMajorBit) == (ResultType::Flags&RowMajorBit) - }; - - static void run(const MatrixType& matrix, ResultType& result) - { - EIGEN_ALIGN16 const unsigned int _Sign_PNNP[4] = { 0x00000000, 0x80000000, 0x80000000, 0x00000000 }; - - // Load the full matrix into registers - __m128 _L1 = matrix.template packet( 0); - __m128 _L2 = matrix.template packet( 4); - __m128 _L3 = matrix.template packet( 8); - __m128 _L4 = matrix.template packet(12); - - // The inverse is calculated using "Divide and Conquer" technique. The - // original matrix is divide into four 2x2 sub-matrices. Since each - // register holds four matrix element, the smaller matrices are - // represented as a registers. Hence we get a better locality of the - // calculations. - - __m128 A, B, C, D; // the four sub-matrices - if(!StorageOrdersMatch) - { - A = _mm_unpacklo_ps(_L1, _L2); - B = _mm_unpacklo_ps(_L3, _L4); - C = _mm_unpackhi_ps(_L1, _L2); - D = _mm_unpackhi_ps(_L3, _L4); - } - else - { - A = _mm_movelh_ps(_L1, _L2); - B = _mm_movehl_ps(_L2, _L1); - C = _mm_movelh_ps(_L3, _L4); - D = _mm_movehl_ps(_L4, _L3); - } - - __m128 iA, iB, iC, iD, // partial inverse of the sub-matrices - DC, AB; - __m128 dA, dB, dC, dD; // determinant of the sub-matrices - __m128 det, d, d1, d2; - __m128 rd; // reciprocal of the determinant - - // AB = A# * B - AB = _mm_mul_ps(_mm_shuffle_ps(A,A,0x0F), B); - AB = _mm_sub_ps(AB,_mm_mul_ps(_mm_shuffle_ps(A,A,0xA5), _mm_shuffle_ps(B,B,0x4E))); - // DC = D# * C - DC = _mm_mul_ps(_mm_shuffle_ps(D,D,0x0F), C); - DC = _mm_sub_ps(DC,_mm_mul_ps(_mm_shuffle_ps(D,D,0xA5), _mm_shuffle_ps(C,C,0x4E))); - - // dA = |A| - dA = _mm_mul_ps(_mm_shuffle_ps(A, A, 0x5F),A); - dA = _mm_sub_ss(dA, _mm_movehl_ps(dA,dA)); - // dB = |B| - dB = _mm_mul_ps(_mm_shuffle_ps(B, B, 0x5F),B); - dB = _mm_sub_ss(dB, _mm_movehl_ps(dB,dB)); - - // dC = |C| - dC = _mm_mul_ps(_mm_shuffle_ps(C, C, 0x5F),C); - dC = _mm_sub_ss(dC, _mm_movehl_ps(dC,dC)); - // dD = |D| - dD = _mm_mul_ps(_mm_shuffle_ps(D, D, 0x5F),D); - dD = _mm_sub_ss(dD, _mm_movehl_ps(dD,dD)); - - // d = trace(AB*DC) = trace(A#*B*D#*C) - d = _mm_mul_ps(_mm_shuffle_ps(DC,DC,0xD8),AB); - - // iD = C*A#*B - iD = _mm_mul_ps(_mm_shuffle_ps(C,C,0xA0), _mm_movelh_ps(AB,AB)); - iD = _mm_add_ps(iD,_mm_mul_ps(_mm_shuffle_ps(C,C,0xF5), _mm_movehl_ps(AB,AB))); - // iA = B*D#*C - iA = _mm_mul_ps(_mm_shuffle_ps(B,B,0xA0), _mm_movelh_ps(DC,DC)); - iA = _mm_add_ps(iA,_mm_mul_ps(_mm_shuffle_ps(B,B,0xF5), _mm_movehl_ps(DC,DC))); - - // d = trace(AB*DC) = trace(A#*B*D#*C) [continue] - d = _mm_add_ps(d, _mm_movehl_ps(d, d)); - d = _mm_add_ss(d, _mm_shuffle_ps(d, d, 1)); - d1 = _mm_mul_ss(dA,dD); - d2 = _mm_mul_ss(dB,dC); - - // iD = D*|A| - C*A#*B - iD = _mm_sub_ps(_mm_mul_ps(D,_mm_shuffle_ps(dA,dA,0)), iD); - - // iA = A*|D| - B*D#*C; - iA = _mm_sub_ps(_mm_mul_ps(A,_mm_shuffle_ps(dD,dD,0)), iA); - - // det = |A|*|D| + |B|*|C| - trace(A#*B*D#*C) - det = _mm_sub_ss(_mm_add_ss(d1,d2),d); - rd = _mm_div_ss(_mm_set_ss(1.0f), det); - -// #ifdef ZERO_SINGULAR -// rd = _mm_and_ps(_mm_cmpneq_ss(det,_mm_setzero_ps()), rd); -// #endif - - // iB = D * (A#B)# = D*B#*A - iB = _mm_mul_ps(D, _mm_shuffle_ps(AB,AB,0x33)); - iB = _mm_sub_ps(iB, _mm_mul_ps(_mm_shuffle_ps(D,D,0xB1), _mm_shuffle_ps(AB,AB,0x66))); - // iC = A * (D#C)# = A*C#*D - iC = _mm_mul_ps(A, _mm_shuffle_ps(DC,DC,0x33)); - iC = _mm_sub_ps(iC, _mm_mul_ps(_mm_shuffle_ps(A,A,0xB1), _mm_shuffle_ps(DC,DC,0x66))); - - rd = _mm_shuffle_ps(rd,rd,0); - rd = _mm_xor_ps(rd, _mm_load_ps((float*)_Sign_PNNP)); - - // iB = C*|B| - D*B#*A - iB = _mm_sub_ps(_mm_mul_ps(C,_mm_shuffle_ps(dB,dB,0)), iB); - - // iC = B*|C| - A*C#*D; - iC = _mm_sub_ps(_mm_mul_ps(B,_mm_shuffle_ps(dC,dC,0)), iC); - - // iX = iX / det - iA = _mm_mul_ps(rd,iA); - iB = _mm_mul_ps(rd,iB); - iC = _mm_mul_ps(rd,iC); - iD = _mm_mul_ps(rd,iD); - - result.template writePacket( 0, _mm_shuffle_ps(iA,iB,0x77)); - result.template writePacket( 4, _mm_shuffle_ps(iA,iB,0x22)); - result.template writePacket( 8, _mm_shuffle_ps(iC,iD,0x77)); - result.template writePacket(12, _mm_shuffle_ps(iC,iD,0x22)); - } - -}; - -template -struct compute_inverse_size4 -{ - enum { - MatrixAlignment = bool(MatrixType::Flags&AlignedBit), - ResultAlignment = bool(ResultType::Flags&AlignedBit), - StorageOrdersMatch = (MatrixType::Flags&RowMajorBit) == (ResultType::Flags&RowMajorBit) - }; - static void run(const MatrixType& matrix, ResultType& result) - { - const __m128d _Sign_NP = _mm_castsi128_pd(_mm_set_epi32(0x0,0x0,0x80000000,0x0)); - const __m128d _Sign_PN = _mm_castsi128_pd(_mm_set_epi32(0x80000000,0x0,0x0,0x0)); - - // The inverse is calculated using "Divide and Conquer" technique. The - // original matrix is divide into four 2x2 sub-matrices. Since each - // register of the matrix holds two element, the smaller matrices are - // consisted of two registers. Hence we get a better locality of the - // calculations. - - // the four sub-matrices - __m128d A1, A2, B1, B2, C1, C2, D1, D2; - - if(StorageOrdersMatch) - { - A1 = matrix.template packet( 0); B1 = matrix.template packet( 2); - A2 = matrix.template packet( 4); B2 = matrix.template packet( 6); - C1 = matrix.template packet( 8); D1 = matrix.template packet(10); - C2 = matrix.template packet(12); D2 = matrix.template packet(14); - } - else - { - __m128d tmp; - A1 = matrix.template packet( 0); C1 = matrix.template packet( 2); - A2 = matrix.template packet( 4); C2 = matrix.template packet( 6); - tmp = A1; - A1 = _mm_unpacklo_pd(A1,A2); - A2 = _mm_unpackhi_pd(tmp,A2); - tmp = C1; - C1 = _mm_unpacklo_pd(C1,C2); - C2 = _mm_unpackhi_pd(tmp,C2); - - B1 = matrix.template packet( 8); D1 = matrix.template packet(10); - B2 = matrix.template packet(12); D2 = matrix.template packet(14); - tmp = B1; - B1 = _mm_unpacklo_pd(B1,B2); - B2 = _mm_unpackhi_pd(tmp,B2); - tmp = D1; - D1 = _mm_unpacklo_pd(D1,D2); - D2 = _mm_unpackhi_pd(tmp,D2); - } - - __m128d iA1, iA2, iB1, iB2, iC1, iC2, iD1, iD2, // partial invese of the sub-matrices - DC1, DC2, AB1, AB2; - __m128d dA, dB, dC, dD; // determinant of the sub-matrices - __m128d det, d1, d2, rd; - - // dA = |A| - dA = _mm_shuffle_pd(A2, A2, 1); - dA = _mm_mul_pd(A1, dA); - dA = _mm_sub_sd(dA, _mm_shuffle_pd(dA,dA,3)); - // dB = |B| - dB = _mm_shuffle_pd(B2, B2, 1); - dB = _mm_mul_pd(B1, dB); - dB = _mm_sub_sd(dB, _mm_shuffle_pd(dB,dB,3)); - - // AB = A# * B - AB1 = _mm_mul_pd(B1, _mm_shuffle_pd(A2,A2,3)); - AB2 = _mm_mul_pd(B2, _mm_shuffle_pd(A1,A1,0)); - AB1 = _mm_sub_pd(AB1, _mm_mul_pd(B2, _mm_shuffle_pd(A1,A1,3))); - AB2 = _mm_sub_pd(AB2, _mm_mul_pd(B1, _mm_shuffle_pd(A2,A2,0))); - - // dC = |C| - dC = _mm_shuffle_pd(C2, C2, 1); - dC = _mm_mul_pd(C1, dC); - dC = _mm_sub_sd(dC, _mm_shuffle_pd(dC,dC,3)); - // dD = |D| - dD = _mm_shuffle_pd(D2, D2, 1); - dD = _mm_mul_pd(D1, dD); - dD = _mm_sub_sd(dD, _mm_shuffle_pd(dD,dD,3)); - - // DC = D# * C - DC1 = _mm_mul_pd(C1, _mm_shuffle_pd(D2,D2,3)); - DC2 = _mm_mul_pd(C2, _mm_shuffle_pd(D1,D1,0)); - DC1 = _mm_sub_pd(DC1, _mm_mul_pd(C2, _mm_shuffle_pd(D1,D1,3))); - DC2 = _mm_sub_pd(DC2, _mm_mul_pd(C1, _mm_shuffle_pd(D2,D2,0))); - - // rd = trace(AB*DC) = trace(A#*B*D#*C) - d1 = _mm_mul_pd(AB1, _mm_shuffle_pd(DC1, DC2, 0)); - d2 = _mm_mul_pd(AB2, _mm_shuffle_pd(DC1, DC2, 3)); - rd = _mm_add_pd(d1, d2); - rd = _mm_add_sd(rd, _mm_shuffle_pd(rd, rd,3)); - - // iD = C*A#*B - iD1 = _mm_mul_pd(AB1, _mm_shuffle_pd(C1,C1,0)); - iD2 = _mm_mul_pd(AB1, _mm_shuffle_pd(C2,C2,0)); - iD1 = _mm_add_pd(iD1, _mm_mul_pd(AB2, _mm_shuffle_pd(C1,C1,3))); - iD2 = _mm_add_pd(iD2, _mm_mul_pd(AB2, _mm_shuffle_pd(C2,C2,3))); - - // iA = B*D#*C - iA1 = _mm_mul_pd(DC1, _mm_shuffle_pd(B1,B1,0)); - iA2 = _mm_mul_pd(DC1, _mm_shuffle_pd(B2,B2,0)); - iA1 = _mm_add_pd(iA1, _mm_mul_pd(DC2, _mm_shuffle_pd(B1,B1,3))); - iA2 = _mm_add_pd(iA2, _mm_mul_pd(DC2, _mm_shuffle_pd(B2,B2,3))); - - // iD = D*|A| - C*A#*B - dA = _mm_shuffle_pd(dA,dA,0); - iD1 = _mm_sub_pd(_mm_mul_pd(D1, dA), iD1); - iD2 = _mm_sub_pd(_mm_mul_pd(D2, dA), iD2); - - // iA = A*|D| - B*D#*C; - dD = _mm_shuffle_pd(dD,dD,0); - iA1 = _mm_sub_pd(_mm_mul_pd(A1, dD), iA1); - iA2 = _mm_sub_pd(_mm_mul_pd(A2, dD), iA2); - - d1 = _mm_mul_sd(dA, dD); - d2 = _mm_mul_sd(dB, dC); - - // iB = D * (A#B)# = D*B#*A - iB1 = _mm_mul_pd(D1, _mm_shuffle_pd(AB2,AB1,1)); - iB2 = _mm_mul_pd(D2, _mm_shuffle_pd(AB2,AB1,1)); - iB1 = _mm_sub_pd(iB1, _mm_mul_pd(_mm_shuffle_pd(D1,D1,1), _mm_shuffle_pd(AB2,AB1,2))); - iB2 = _mm_sub_pd(iB2, _mm_mul_pd(_mm_shuffle_pd(D2,D2,1), _mm_shuffle_pd(AB2,AB1,2))); - - // det = |A|*|D| + |B|*|C| - trace(A#*B*D#*C) - det = _mm_add_sd(d1, d2); - det = _mm_sub_sd(det, rd); - - // iC = A * (D#C)# = A*C#*D - iC1 = _mm_mul_pd(A1, _mm_shuffle_pd(DC2,DC1,1)); - iC2 = _mm_mul_pd(A2, _mm_shuffle_pd(DC2,DC1,1)); - iC1 = _mm_sub_pd(iC1, _mm_mul_pd(_mm_shuffle_pd(A1,A1,1), _mm_shuffle_pd(DC2,DC1,2))); - iC2 = _mm_sub_pd(iC2, _mm_mul_pd(_mm_shuffle_pd(A2,A2,1), _mm_shuffle_pd(DC2,DC1,2))); - - rd = _mm_div_sd(_mm_set_sd(1.0), det); -// #ifdef ZERO_SINGULAR -// rd = _mm_and_pd(_mm_cmpneq_sd(det,_mm_setzero_pd()), rd); -// #endif - rd = _mm_shuffle_pd(rd,rd,0); - - // iB = C*|B| - D*B#*A - dB = _mm_shuffle_pd(dB,dB,0); - iB1 = _mm_sub_pd(_mm_mul_pd(C1, dB), iB1); - iB2 = _mm_sub_pd(_mm_mul_pd(C2, dB), iB2); - - d1 = _mm_xor_pd(rd, _Sign_PN); - d2 = _mm_xor_pd(rd, _Sign_NP); - - // iC = B*|C| - A*C#*D; - dC = _mm_shuffle_pd(dC,dC,0); - iC1 = _mm_sub_pd(_mm_mul_pd(B1, dC), iC1); - iC2 = _mm_sub_pd(_mm_mul_pd(B2, dC), iC2); - - result.template writePacket( 0, _mm_mul_pd(_mm_shuffle_pd(iA2, iA1, 3), d1)); // iA# / det - result.template writePacket( 4, _mm_mul_pd(_mm_shuffle_pd(iA2, iA1, 0), d2)); - result.template writePacket( 2, _mm_mul_pd(_mm_shuffle_pd(iB2, iB1, 3), d1)); // iB# / det - result.template writePacket( 6, _mm_mul_pd(_mm_shuffle_pd(iB2, iB1, 0), d2)); - result.template writePacket( 8, _mm_mul_pd(_mm_shuffle_pd(iC2, iC1, 3), d1)); // iC# / det - result.template writePacket(12, _mm_mul_pd(_mm_shuffle_pd(iC2, iC1, 0), d2)); - result.template writePacket(10, _mm_mul_pd(_mm_shuffle_pd(iD2, iD1, 3), d1)); // iD# / det - result.template writePacket(14, _mm_mul_pd(_mm_shuffle_pd(iD2, iD1, 0), d2)); - } -}; - -} // end namespace internal - -} // end namespace Eigen - -#endif // EIGEN_INVERSE_SSE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/MetisSupport/MetisSupport.h b/thirdparty/eigen-3.2.7/Eigen/src/MetisSupport/MetisSupport.h deleted file mode 100644 index f2bbef20..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/MetisSupport/MetisSupport.h +++ /dev/null @@ -1,137 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2012 Désiré Nuentsa-Wakam -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. -#ifndef METIS_SUPPORT_H -#define METIS_SUPPORT_H - -namespace Eigen { -/** - * Get the fill-reducing ordering from the METIS package - * - * If A is the original matrix and Ap is the permuted matrix, - * the fill-reducing permutation is defined as follows : - * Row (column) i of A is the matperm(i) row (column) of Ap. - * WARNING: As computed by METIS, this corresponds to the vector iperm (instead of perm) - */ -template -class MetisOrdering -{ -public: - typedef PermutationMatrix PermutationType; - typedef Matrix IndexVector; - - template - void get_symmetrized_graph(const MatrixType& A) - { - Index m = A.cols(); - eigen_assert((A.rows() == A.cols()) && "ONLY FOR SQUARED MATRICES"); - // Get the transpose of the input matrix - MatrixType At = A.transpose(); - // Get the number of nonzeros elements in each row/col of At+A - Index TotNz = 0; - IndexVector visited(m); - visited.setConstant(-1); - for (int j = 0; j < m; j++) - { - // Compute the union structure of of A(j,:) and At(j,:) - visited(j) = j; // Do not include the diagonal element - // Get the nonzeros in row/column j of A - for (typename MatrixType::InnerIterator it(A, j); it; ++it) - { - Index idx = it.index(); // Get the row index (for column major) or column index (for row major) - if (visited(idx) != j ) - { - visited(idx) = j; - ++TotNz; - } - } - //Get the nonzeros in row/column j of At - for (typename MatrixType::InnerIterator it(At, j); it; ++it) - { - Index idx = it.index(); - if(visited(idx) != j) - { - visited(idx) = j; - ++TotNz; - } - } - } - // Reserve place for A + At - m_indexPtr.resize(m+1); - m_innerIndices.resize(TotNz); - - // Now compute the real adjacency list of each column/row - visited.setConstant(-1); - Index CurNz = 0; - for (int j = 0; j < m; j++) - { - m_indexPtr(j) = CurNz; - - visited(j) = j; // Do not include the diagonal element - // Add the pattern of row/column j of A to A+At - for (typename MatrixType::InnerIterator it(A,j); it; ++it) - { - Index idx = it.index(); // Get the row index (for column major) or column index (for row major) - if (visited(idx) != j ) - { - visited(idx) = j; - m_innerIndices(CurNz) = idx; - CurNz++; - } - } - //Add the pattern of row/column j of At to A+At - for (typename MatrixType::InnerIterator it(At, j); it; ++it) - { - Index idx = it.index(); - if(visited(idx) != j) - { - visited(idx) = j; - m_innerIndices(CurNz) = idx; - ++CurNz; - } - } - } - m_indexPtr(m) = CurNz; - } - - template - void operator() (const MatrixType& A, PermutationType& matperm) - { - Index m = A.cols(); - IndexVector perm(m),iperm(m); - // First, symmetrize the matrix graph. - get_symmetrized_graph(A); - int output_error; - - // Call the fill-reducing routine from METIS - output_error = METIS_NodeND(&m, m_indexPtr.data(), m_innerIndices.data(), NULL, NULL, perm.data(), iperm.data()); - - if(output_error != METIS_OK) - { - //FIXME The ordering interface should define a class of possible errors - std::cerr << "ERROR WHILE CALLING THE METIS PACKAGE \n"; - return; - } - - // Get the fill-reducing permutation - //NOTE: If Ap is the permuted matrix then perm and iperm vectors are defined as follows - // Row (column) i of Ap is the perm(i) row(column) of A, and row (column) i of A is the iperm(i) row(column) of Ap - - matperm.resize(m); - for (int j = 0; j < m; j++) - matperm.indices()(iperm(j)) = j; - - } - - protected: - IndexVector m_indexPtr; // Pointer to the adjacenccy list of each row/column - IndexVector m_innerIndices; // Adjacency list -}; - -}// end namespace eigen -#endif diff --git a/thirdparty/eigen-3.2.7/Eigen/src/OrderingMethods/Amd.h b/thirdparty/eigen-3.2.7/Eigen/src/OrderingMethods/Amd.h deleted file mode 100644 index 70550b8a..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/OrderingMethods/Amd.h +++ /dev/null @@ -1,444 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2010 Gael Guennebaud - -/* - -NOTE: this routine has been adapted from the CSparse library: - -Copyright (c) 2006, Timothy A. Davis. -http://www.cise.ufl.edu/research/sparse/CSparse - -CSparse is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -CSparse is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this Module; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - -#include "../Core/util/NonMPL2.h" - -#ifndef EIGEN_SPARSE_AMD_H -#define EIGEN_SPARSE_AMD_H - -namespace Eigen { - -namespace internal { - -template inline T amd_flip(const T& i) { return -i-2; } -template inline T amd_unflip(const T& i) { return i<0 ? amd_flip(i) : i; } -template inline bool amd_marked(const T0* w, const T1& j) { return w[j]<0; } -template inline void amd_mark(const T0* w, const T1& j) { return w[j] = amd_flip(w[j]); } - -/* clear w */ -template -static int cs_wclear (Index mark, Index lemax, Index *w, Index n) -{ - Index k; - if(mark < 2 || (mark + lemax < 0)) - { - for(k = 0; k < n; k++) - if(w[k] != 0) - w[k] = 1; - mark = 2; - } - return (mark); /* at this point, w[0..n-1] < mark holds */ -} - -/* depth-first search and postorder of a tree rooted at node j */ -template -Index cs_tdfs(Index j, Index k, Index *head, const Index *next, Index *post, Index *stack) -{ - int i, p, top = 0; - if(!head || !next || !post || !stack) return (-1); /* check inputs */ - stack[0] = j; /* place j on the stack */ - while (top >= 0) /* while (stack is not empty) */ - { - p = stack[top]; /* p = top of stack */ - i = head[p]; /* i = youngest child of p */ - if(i == -1) - { - top--; /* p has no unordered children left */ - post[k++] = p; /* node p is the kth postordered node */ - } - else - { - head[p] = next[i]; /* remove i from children of p */ - stack[++top] = i; /* start dfs on child node i */ - } - } - return k; -} - - -/** \internal - * \ingroup OrderingMethods_Module - * Approximate minimum degree ordering algorithm. - * \returns the permutation P reducing the fill-in of the input matrix \a C - * The input matrix \a C must be a selfadjoint compressed column major SparseMatrix object. Both the upper and lower parts have to be stored, but the diagonal entries are optional. - * On exit the values of C are destroyed */ -template -void minimum_degree_ordering(SparseMatrix& C, PermutationMatrix& perm) -{ - using std::sqrt; - - int d, dk, dext, lemax = 0, e, elenk, eln, i, j, k, k1, - k2, k3, jlast, ln, dense, nzmax, mindeg = 0, nvi, nvj, nvk, mark, wnvi, - ok, nel = 0, p, p1, p2, p3, p4, pj, pk, pk1, pk2, pn, q, t; - unsigned int h; - - Index n = C.cols(); - dense = std::max (16, Index(10 * sqrt(double(n)))); /* find dense threshold */ - dense = std::min (n-2, dense); - - Index cnz = C.nonZeros(); - perm.resize(n+1); - t = cnz + cnz/5 + 2*n; /* add elbow room to C */ - C.resizeNonZeros(t); - - Index* W = new Index[8*(n+1)]; /* get workspace */ - Index* len = W; - Index* nv = W + (n+1); - Index* next = W + 2*(n+1); - Index* head = W + 3*(n+1); - Index* elen = W + 4*(n+1); - Index* degree = W + 5*(n+1); - Index* w = W + 6*(n+1); - Index* hhead = W + 7*(n+1); - Index* last = perm.indices().data(); /* use P as workspace for last */ - - /* --- Initialize quotient graph ---------------------------------------- */ - Index* Cp = C.outerIndexPtr(); - Index* Ci = C.innerIndexPtr(); - for(k = 0; k < n; k++) - len[k] = Cp[k+1] - Cp[k]; - len[n] = 0; - nzmax = t; - - for(i = 0; i <= n; i++) - { - head[i] = -1; // degree list i is empty - last[i] = -1; - next[i] = -1; - hhead[i] = -1; // hash list i is empty - nv[i] = 1; // node i is just one node - w[i] = 1; // node i is alive - elen[i] = 0; // Ek of node i is empty - degree[i] = len[i]; // degree of node i - } - mark = internal::cs_wclear(0, 0, w, n); /* clear w */ - - /* --- Initialize degree lists ------------------------------------------ */ - for(i = 0; i < n; i++) - { - bool has_diag = false; - for(p = Cp[i]; p dense || !has_diag) /* node i is dense or has no structural diagonal element */ - { - nv[i] = 0; /* absorb i into element n */ - elen[i] = -1; /* node i is dead */ - nel++; - Cp[i] = amd_flip (n); - nv[n]++; - } - else - { - if(head[d] != -1) last[head[d]] = i; - next[i] = head[d]; /* put node i in degree list d */ - head[d] = i; - } - } - - elen[n] = -2; /* n is a dead element */ - Cp[n] = -1; /* n is a root of assembly tree */ - w[n] = 0; /* n is a dead element */ - - while (nel < n) /* while (selecting pivots) do */ - { - /* --- Select node of minimum approximate degree -------------------- */ - for(k = -1; mindeg < n && (k = head[mindeg]) == -1; mindeg++) {} - if(next[k] != -1) last[next[k]] = -1; - head[mindeg] = next[k]; /* remove k from degree list */ - elenk = elen[k]; /* elenk = |Ek| */ - nvk = nv[k]; /* # of nodes k represents */ - nel += nvk; /* nv[k] nodes of A eliminated */ - - /* --- Garbage collection ------------------------------------------- */ - if(elenk > 0 && cnz + mindeg >= nzmax) - { - for(j = 0; j < n; j++) - { - if((p = Cp[j]) >= 0) /* j is a live node or element */ - { - Cp[j] = Ci[p]; /* save first entry of object */ - Ci[p] = amd_flip (j); /* first entry is now amd_flip(j) */ - } - } - for(q = 0, p = 0; p < cnz; ) /* scan all of memory */ - { - if((j = amd_flip (Ci[p++])) >= 0) /* found object j */ - { - Ci[q] = Cp[j]; /* restore first entry of object */ - Cp[j] = q++; /* new pointer to object j */ - for(k3 = 0; k3 < len[j]-1; k3++) Ci[q++] = Ci[p++]; - } - } - cnz = q; /* Ci[cnz...nzmax-1] now free */ - } - - /* --- Construct new element ---------------------------------------- */ - dk = 0; - nv[k] = -nvk; /* flag k as in Lk */ - p = Cp[k]; - pk1 = (elenk == 0) ? p : cnz; /* do in place if elen[k] == 0 */ - pk2 = pk1; - for(k1 = 1; k1 <= elenk + 1; k1++) - { - if(k1 > elenk) - { - e = k; /* search the nodes in k */ - pj = p; /* list of nodes starts at Ci[pj]*/ - ln = len[k] - elenk; /* length of list of nodes in k */ - } - else - { - e = Ci[p++]; /* search the nodes in e */ - pj = Cp[e]; - ln = len[e]; /* length of list of nodes in e */ - } - for(k2 = 1; k2 <= ln; k2++) - { - i = Ci[pj++]; - if((nvi = nv[i]) <= 0) continue; /* node i dead, or seen */ - dk += nvi; /* degree[Lk] += size of node i */ - nv[i] = -nvi; /* negate nv[i] to denote i in Lk*/ - Ci[pk2++] = i; /* place i in Lk */ - if(next[i] != -1) last[next[i]] = last[i]; - if(last[i] != -1) /* remove i from degree list */ - { - next[last[i]] = next[i]; - } - else - { - head[degree[i]] = next[i]; - } - } - if(e != k) - { - Cp[e] = amd_flip (k); /* absorb e into k */ - w[e] = 0; /* e is now a dead element */ - } - } - if(elenk != 0) cnz = pk2; /* Ci[cnz...nzmax] is free */ - degree[k] = dk; /* external degree of k - |Lk\i| */ - Cp[k] = pk1; /* element k is in Ci[pk1..pk2-1] */ - len[k] = pk2 - pk1; - elen[k] = -2; /* k is now an element */ - - /* --- Find set differences ----------------------------------------- */ - mark = internal::cs_wclear(mark, lemax, w, n); /* clear w if necessary */ - for(pk = pk1; pk < pk2; pk++) /* scan 1: find |Le\Lk| */ - { - i = Ci[pk]; - if((eln = elen[i]) <= 0) continue;/* skip if elen[i] empty */ - nvi = -nv[i]; /* nv[i] was negated */ - wnvi = mark - nvi; - for(p = Cp[i]; p <= Cp[i] + eln - 1; p++) /* scan Ei */ - { - e = Ci[p]; - if(w[e] >= mark) - { - w[e] -= nvi; /* decrement |Le\Lk| */ - } - else if(w[e] != 0) /* ensure e is a live element */ - { - w[e] = degree[e] + wnvi; /* 1st time e seen in scan 1 */ - } - } - } - - /* --- Degree update ------------------------------------------------ */ - for(pk = pk1; pk < pk2; pk++) /* scan2: degree update */ - { - i = Ci[pk]; /* consider node i in Lk */ - p1 = Cp[i]; - p2 = p1 + elen[i] - 1; - pn = p1; - for(h = 0, d = 0, p = p1; p <= p2; p++) /* scan Ei */ - { - e = Ci[p]; - if(w[e] != 0) /* e is an unabsorbed element */ - { - dext = w[e] - mark; /* dext = |Le\Lk| */ - if(dext > 0) - { - d += dext; /* sum up the set differences */ - Ci[pn++] = e; /* keep e in Ei */ - h += e; /* compute the hash of node i */ - } - else - { - Cp[e] = amd_flip (k); /* aggressive absorb. e->k */ - w[e] = 0; /* e is a dead element */ - } - } - } - elen[i] = pn - p1 + 1; /* elen[i] = |Ei| */ - p3 = pn; - p4 = p1 + len[i]; - for(p = p2 + 1; p < p4; p++) /* prune edges in Ai */ - { - j = Ci[p]; - if((nvj = nv[j]) <= 0) continue; /* node j dead or in Lk */ - d += nvj; /* degree(i) += |j| */ - Ci[pn++] = j; /* place j in node list of i */ - h += j; /* compute hash for node i */ - } - if(d == 0) /* check for mass elimination */ - { - Cp[i] = amd_flip (k); /* absorb i into k */ - nvi = -nv[i]; - dk -= nvi; /* |Lk| -= |i| */ - nvk += nvi; /* |k| += nv[i] */ - nel += nvi; - nv[i] = 0; - elen[i] = -1; /* node i is dead */ - } - else - { - degree[i] = std::min (degree[i], d); /* update degree(i) */ - Ci[pn] = Ci[p3]; /* move first node to end */ - Ci[p3] = Ci[p1]; /* move 1st el. to end of Ei */ - Ci[p1] = k; /* add k as 1st element in of Ei */ - len[i] = pn - p1 + 1; /* new len of adj. list of node i */ - h %= n; /* finalize hash of i */ - next[i] = hhead[h]; /* place i in hash bucket */ - hhead[h] = i; - last[i] = h; /* save hash of i in last[i] */ - } - } /* scan2 is done */ - degree[k] = dk; /* finalize |Lk| */ - lemax = std::max(lemax, dk); - mark = internal::cs_wclear(mark+lemax, lemax, w, n); /* clear w */ - - /* --- Supernode detection ------------------------------------------ */ - for(pk = pk1; pk < pk2; pk++) - { - i = Ci[pk]; - if(nv[i] >= 0) continue; /* skip if i is dead */ - h = last[i]; /* scan hash bucket of node i */ - i = hhead[h]; - hhead[h] = -1; /* hash bucket will be empty */ - for(; i != -1 && next[i] != -1; i = next[i], mark++) - { - ln = len[i]; - eln = elen[i]; - for(p = Cp[i]+1; p <= Cp[i] + ln-1; p++) w[Ci[p]] = mark; - jlast = i; - for(j = next[i]; j != -1; ) /* compare i with all j */ - { - ok = (len[j] == ln) && (elen[j] == eln); - for(p = Cp[j] + 1; ok && p <= Cp[j] + ln - 1; p++) - { - if(w[Ci[p]] != mark) ok = 0; /* compare i and j*/ - } - if(ok) /* i and j are identical */ - { - Cp[j] = amd_flip (i); /* absorb j into i */ - nv[i] += nv[j]; - nv[j] = 0; - elen[j] = -1; /* node j is dead */ - j = next[j]; /* delete j from hash bucket */ - next[jlast] = j; - } - else - { - jlast = j; /* j and i are different */ - j = next[j]; - } - } - } - } - - /* --- Finalize new element------------------------------------------ */ - for(p = pk1, pk = pk1; pk < pk2; pk++) /* finalize Lk */ - { - i = Ci[pk]; - if((nvi = -nv[i]) <= 0) continue;/* skip if i is dead */ - nv[i] = nvi; /* restore nv[i] */ - d = degree[i] + dk - nvi; /* compute external degree(i) */ - d = std::min (d, n - nel - nvi); - if(head[d] != -1) last[head[d]] = i; - next[i] = head[d]; /* put i back in degree list */ - last[i] = -1; - head[d] = i; - mindeg = std::min (mindeg, d); /* find new minimum degree */ - degree[i] = d; - Ci[p++] = i; /* place i in Lk */ - } - nv[k] = nvk; /* # nodes absorbed into k */ - if((len[k] = p-pk1) == 0) /* length of adj list of element k*/ - { - Cp[k] = -1; /* k is a root of the tree */ - w[k] = 0; /* k is now a dead element */ - } - if(elenk != 0) cnz = p; /* free unused space in Lk */ - } - - /* --- Postordering ----------------------------------------------------- */ - for(i = 0; i < n; i++) Cp[i] = amd_flip (Cp[i]);/* fix assembly tree */ - for(j = 0; j <= n; j++) head[j] = -1; - for(j = n; j >= 0; j--) /* place unordered nodes in lists */ - { - if(nv[j] > 0) continue; /* skip if j is an element */ - next[j] = head[Cp[j]]; /* place j in list of its parent */ - head[Cp[j]] = j; - } - for(e = n; e >= 0; e--) /* place elements in lists */ - { - if(nv[e] <= 0) continue; /* skip unless e is an element */ - if(Cp[e] != -1) - { - next[e] = head[Cp[e]]; /* place e in list of its parent */ - head[Cp[e]] = e; - } - } - for(k = 0, i = 0; i <= n; i++) /* postorder the assembly tree */ - { - if(Cp[i] == -1) k = internal::cs_tdfs(i, k, head, next, perm.indices().data(), w); - } - - perm.indices().conservativeResize(n); - - delete[] W; -} - -} // namespace internal - -} // end namespace Eigen - -#endif // EIGEN_SPARSE_AMD_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/OrderingMethods/Eigen_Colamd.h b/thirdparty/eigen-3.2.7/Eigen/src/OrderingMethods/Eigen_Colamd.h deleted file mode 100644 index 44548f66..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/OrderingMethods/Eigen_Colamd.h +++ /dev/null @@ -1,1850 +0,0 @@ -// // This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2012 Desire Nuentsa Wakam -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -// This file is modified from the colamd/symamd library. The copyright is below - -// The authors of the code itself are Stefan I. Larimore and Timothy A. -// Davis (davis@cise.ufl.edu), University of Florida. The algorithm was -// developed in collaboration with John Gilbert, Xerox PARC, and Esmond -// Ng, Oak Ridge National Laboratory. -// -// Date: -// -// September 8, 2003. Version 2.3. -// -// Acknowledgements: -// -// This work was supported by the National Science Foundation, under -// grants DMS-9504974 and DMS-9803599. -// -// Notice: -// -// Copyright (c) 1998-2003 by the University of Florida. -// All Rights Reserved. -// -// THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY -// EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK. -// -// Permission is hereby granted to use, copy, modify, and/or distribute -// this program, provided that the Copyright, this License, and the -// Availability of the original version is retained on all copies and made -// accessible to the end-user of any code or package that includes COLAMD -// or any modified version of COLAMD. -// -// Availability: -// -// The colamd/symamd library is available at -// -// http://www.cise.ufl.edu/research/sparse/colamd/ - -// This is the http://www.cise.ufl.edu/research/sparse/colamd/colamd.h -// file. It is required by the colamd.c, colamdmex.c, and symamdmex.c -// files, and by any C code that calls the routines whose prototypes are -// listed below, or that uses the colamd/symamd definitions listed below. - -#ifndef EIGEN_COLAMD_H -#define EIGEN_COLAMD_H - -namespace internal { -/* Ensure that debugging is turned off: */ -#ifndef COLAMD_NDEBUG -#define COLAMD_NDEBUG -#endif /* NDEBUG */ -/* ========================================================================== */ -/* === Knob and statistics definitions ====================================== */ -/* ========================================================================== */ - -/* size of the knobs [ ] array. Only knobs [0..1] are currently used. */ -#define COLAMD_KNOBS 20 - -/* number of output statistics. Only stats [0..6] are currently used. */ -#define COLAMD_STATS 20 - -/* knobs [0] and stats [0]: dense row knob and output statistic. */ -#define COLAMD_DENSE_ROW 0 - -/* knobs [1] and stats [1]: dense column knob and output statistic. */ -#define COLAMD_DENSE_COL 1 - -/* stats [2]: memory defragmentation count output statistic */ -#define COLAMD_DEFRAG_COUNT 2 - -/* stats [3]: colamd status: zero OK, > 0 warning or notice, < 0 error */ -#define COLAMD_STATUS 3 - -/* stats [4..6]: error info, or info on jumbled columns */ -#define COLAMD_INFO1 4 -#define COLAMD_INFO2 5 -#define COLAMD_INFO3 6 - -/* error codes returned in stats [3]: */ -#define COLAMD_OK (0) -#define COLAMD_OK_BUT_JUMBLED (1) -#define COLAMD_ERROR_A_not_present (-1) -#define COLAMD_ERROR_p_not_present (-2) -#define COLAMD_ERROR_nrow_negative (-3) -#define COLAMD_ERROR_ncol_negative (-4) -#define COLAMD_ERROR_nnz_negative (-5) -#define COLAMD_ERROR_p0_nonzero (-6) -#define COLAMD_ERROR_A_too_small (-7) -#define COLAMD_ERROR_col_length_negative (-8) -#define COLAMD_ERROR_row_index_out_of_bounds (-9) -#define COLAMD_ERROR_out_of_memory (-10) -#define COLAMD_ERROR_internal_error (-999) - -/* ========================================================================== */ -/* === Definitions ========================================================== */ -/* ========================================================================== */ - -#define COLAMD_MAX(a,b) (((a) > (b)) ? (a) : (b)) -#define COLAMD_MIN(a,b) (((a) < (b)) ? (a) : (b)) - -#define ONES_COMPLEMENT(r) (-(r)-1) - -/* -------------------------------------------------------------------------- */ - -#define COLAMD_EMPTY (-1) - -/* Row and column status */ -#define ALIVE (0) -#define DEAD (-1) - -/* Column status */ -#define DEAD_PRINCIPAL (-1) -#define DEAD_NON_PRINCIPAL (-2) - -/* Macros for row and column status update and checking. */ -#define ROW_IS_DEAD(r) ROW_IS_MARKED_DEAD (Row[r].shared2.mark) -#define ROW_IS_MARKED_DEAD(row_mark) (row_mark < ALIVE) -#define ROW_IS_ALIVE(r) (Row [r].shared2.mark >= ALIVE) -#define COL_IS_DEAD(c) (Col [c].start < ALIVE) -#define COL_IS_ALIVE(c) (Col [c].start >= ALIVE) -#define COL_IS_DEAD_PRINCIPAL(c) (Col [c].start == DEAD_PRINCIPAL) -#define KILL_ROW(r) { Row [r].shared2.mark = DEAD ; } -#define KILL_PRINCIPAL_COL(c) { Col [c].start = DEAD_PRINCIPAL ; } -#define KILL_NON_PRINCIPAL_COL(c) { Col [c].start = DEAD_NON_PRINCIPAL ; } - -/* ========================================================================== */ -/* === Colamd reporting mechanism =========================================== */ -/* ========================================================================== */ - -// == Row and Column structures == -template -struct colamd_col -{ - Index start ; /* index for A of first row in this column, or DEAD */ - /* if column is dead */ - Index length ; /* number of rows in this column */ - union - { - Index thickness ; /* number of original columns represented by this */ - /* col, if the column is alive */ - Index parent ; /* parent in parent tree super-column structure, if */ - /* the column is dead */ - } shared1 ; - union - { - Index score ; /* the score used to maintain heap, if col is alive */ - Index order ; /* pivot ordering of this column, if col is dead */ - } shared2 ; - union - { - Index headhash ; /* head of a hash bucket, if col is at the head of */ - /* a degree list */ - Index hash ; /* hash value, if col is not in a degree list */ - Index prev ; /* previous column in degree list, if col is in a */ - /* degree list (but not at the head of a degree list) */ - } shared3 ; - union - { - Index degree_next ; /* next column, if col is in a degree list */ - Index hash_next ; /* next column, if col is in a hash list */ - } shared4 ; - -}; - -template -struct Colamd_Row -{ - Index start ; /* index for A of first col in this row */ - Index length ; /* number of principal columns in this row */ - union - { - Index degree ; /* number of principal & non-principal columns in row */ - Index p ; /* used as a row pointer in init_rows_cols () */ - } shared1 ; - union - { - Index mark ; /* for computing set differences and marking dead rows*/ - Index first_column ;/* first column in row (used in garbage collection) */ - } shared2 ; - -}; - -/* ========================================================================== */ -/* === Colamd recommended memory size ======================================= */ -/* ========================================================================== */ - -/* - The recommended length Alen of the array A passed to colamd is given by - the COLAMD_RECOMMENDED (nnz, n_row, n_col) macro. It returns -1 if any - argument is negative. 2*nnz space is required for the row and column - indices of the matrix. colamd_c (n_col) + colamd_r (n_row) space is - required for the Col and Row arrays, respectively, which are internal to - colamd. An additional n_col space is the minimal amount of "elbow room", - and nnz/5 more space is recommended for run time efficiency. - - This macro is not needed when using symamd. - - Explicit typecast to Index added Sept. 23, 2002, COLAMD version 2.2, to avoid - gcc -pedantic warning messages. -*/ -template -inline Index colamd_c(Index n_col) -{ return Index( ((n_col) + 1) * sizeof (colamd_col) / sizeof (Index) ) ; } - -template -inline Index colamd_r(Index n_row) -{ return Index(((n_row) + 1) * sizeof (Colamd_Row) / sizeof (Index)); } - -// Prototypes of non-user callable routines -template -static Index init_rows_cols (Index n_row, Index n_col, Colamd_Row Row [], colamd_col col [], Index A [], Index p [], Index stats[COLAMD_STATS] ); - -template -static void init_scoring (Index n_row, Index n_col, Colamd_Row Row [], colamd_col Col [], Index A [], Index head [], double knobs[COLAMD_KNOBS], Index *p_n_row2, Index *p_n_col2, Index *p_max_deg); - -template -static Index find_ordering (Index n_row, Index n_col, Index Alen, Colamd_Row Row [], colamd_col Col [], Index A [], Index head [], Index n_col2, Index max_deg, Index pfree); - -template -static void order_children (Index n_col, colamd_col Col [], Index p []); - -template -static void detect_super_cols (colamd_col Col [], Index A [], Index head [], Index row_start, Index row_length ) ; - -template -static Index garbage_collection (Index n_row, Index n_col, Colamd_Row Row [], colamd_col Col [], Index A [], Index *pfree) ; - -template -static inline Index clear_mark (Index n_row, Colamd_Row Row [] ) ; - -/* === No debugging ========================================================= */ - -#define COLAMD_DEBUG0(params) ; -#define COLAMD_DEBUG1(params) ; -#define COLAMD_DEBUG2(params) ; -#define COLAMD_DEBUG3(params) ; -#define COLAMD_DEBUG4(params) ; - -#define COLAMD_ASSERT(expression) ((void) 0) - - -/** - * \brief Returns the recommended value of Alen - * - * Returns recommended value of Alen for use by colamd. - * Returns -1 if any input argument is negative. - * The use of this routine or macro is optional. - * Note that the macro uses its arguments more than once, - * so be careful for side effects, if you pass expressions as arguments to COLAMD_RECOMMENDED. - * - * \param nnz nonzeros in A - * \param n_row number of rows in A - * \param n_col number of columns in A - * \return recommended value of Alen for use by colamd - */ -template -inline Index colamd_recommended ( Index nnz, Index n_row, Index n_col) -{ - if ((nnz) < 0 || (n_row) < 0 || (n_col) < 0) - return (-1); - else - return (2 * (nnz) + colamd_c (n_col) + colamd_r (n_row) + (n_col) + ((nnz) / 5)); -} - -/** - * \brief set default parameters The use of this routine is optional. - * - * Colamd: rows with more than (knobs [COLAMD_DENSE_ROW] * n_col) - * entries are removed prior to ordering. Columns with more than - * (knobs [COLAMD_DENSE_COL] * n_row) entries are removed prior to - * ordering, and placed last in the output column ordering. - * - * COLAMD_DENSE_ROW and COLAMD_DENSE_COL are defined as 0 and 1, - * respectively, in colamd.h. Default values of these two knobs - * are both 0.5. Currently, only knobs [0] and knobs [1] are - * used, but future versions may use more knobs. If so, they will - * be properly set to their defaults by the future version of - * colamd_set_defaults, so that the code that calls colamd will - * not need to change, assuming that you either use - * colamd_set_defaults, or pass a (double *) NULL pointer as the - * knobs array to colamd or symamd. - * - * \param knobs parameter settings for colamd - */ - -static inline void colamd_set_defaults(double knobs[COLAMD_KNOBS]) -{ - /* === Local variables ================================================== */ - - int i ; - - if (!knobs) - { - return ; /* no knobs to initialize */ - } - for (i = 0 ; i < COLAMD_KNOBS ; i++) - { - knobs [i] = 0 ; - } - knobs [COLAMD_DENSE_ROW] = 0.5 ; /* ignore rows over 50% dense */ - knobs [COLAMD_DENSE_COL] = 0.5 ; /* ignore columns over 50% dense */ -} - -/** - * \brief Computes a column ordering using the column approximate minimum degree ordering - * - * Computes a column ordering (Q) of A such that P(AQ)=LU or - * (AQ)'AQ=LL' have less fill-in and require fewer floating point - * operations than factorizing the unpermuted matrix A or A'A, - * respectively. - * - * - * \param n_row number of rows in A - * \param n_col number of columns in A - * \param Alen, size of the array A - * \param A row indices of the matrix, of size ALen - * \param p column pointers of A, of size n_col+1 - * \param knobs parameter settings for colamd - * \param stats colamd output statistics and error codes - */ -template -static bool colamd(Index n_row, Index n_col, Index Alen, Index *A, Index *p, double knobs[COLAMD_KNOBS], Index stats[COLAMD_STATS]) -{ - /* === Local variables ================================================== */ - - Index i ; /* loop index */ - Index nnz ; /* nonzeros in A */ - Index Row_size ; /* size of Row [], in integers */ - Index Col_size ; /* size of Col [], in integers */ - Index need ; /* minimum required length of A */ - Colamd_Row *Row ; /* pointer into A of Row [0..n_row] array */ - colamd_col *Col ; /* pointer into A of Col [0..n_col] array */ - Index n_col2 ; /* number of non-dense, non-empty columns */ - Index n_row2 ; /* number of non-dense, non-empty rows */ - Index ngarbage ; /* number of garbage collections performed */ - Index max_deg ; /* maximum row degree */ - double default_knobs [COLAMD_KNOBS] ; /* default knobs array */ - - - /* === Check the input arguments ======================================== */ - - if (!stats) - { - COLAMD_DEBUG0 (("colamd: stats not present\n")) ; - return (false) ; - } - for (i = 0 ; i < COLAMD_STATS ; i++) - { - stats [i] = 0 ; - } - stats [COLAMD_STATUS] = COLAMD_OK ; - stats [COLAMD_INFO1] = -1 ; - stats [COLAMD_INFO2] = -1 ; - - if (!A) /* A is not present */ - { - stats [COLAMD_STATUS] = COLAMD_ERROR_A_not_present ; - COLAMD_DEBUG0 (("colamd: A not present\n")) ; - return (false) ; - } - - if (!p) /* p is not present */ - { - stats [COLAMD_STATUS] = COLAMD_ERROR_p_not_present ; - COLAMD_DEBUG0 (("colamd: p not present\n")) ; - return (false) ; - } - - if (n_row < 0) /* n_row must be >= 0 */ - { - stats [COLAMD_STATUS] = COLAMD_ERROR_nrow_negative ; - stats [COLAMD_INFO1] = n_row ; - COLAMD_DEBUG0 (("colamd: nrow negative %d\n", n_row)) ; - return (false) ; - } - - if (n_col < 0) /* n_col must be >= 0 */ - { - stats [COLAMD_STATUS] = COLAMD_ERROR_ncol_negative ; - stats [COLAMD_INFO1] = n_col ; - COLAMD_DEBUG0 (("colamd: ncol negative %d\n", n_col)) ; - return (false) ; - } - - nnz = p [n_col] ; - if (nnz < 0) /* nnz must be >= 0 */ - { - stats [COLAMD_STATUS] = COLAMD_ERROR_nnz_negative ; - stats [COLAMD_INFO1] = nnz ; - COLAMD_DEBUG0 (("colamd: number of entries negative %d\n", nnz)) ; - return (false) ; - } - - if (p [0] != 0) - { - stats [COLAMD_STATUS] = COLAMD_ERROR_p0_nonzero ; - stats [COLAMD_INFO1] = p [0] ; - COLAMD_DEBUG0 (("colamd: p[0] not zero %d\n", p [0])) ; - return (false) ; - } - - /* === If no knobs, set default knobs =================================== */ - - if (!knobs) - { - colamd_set_defaults (default_knobs) ; - knobs = default_knobs ; - } - - /* === Allocate the Row and Col arrays from array A ===================== */ - - Col_size = colamd_c (n_col) ; - Row_size = colamd_r (n_row) ; - need = 2*nnz + n_col + Col_size + Row_size ; - - if (need > Alen) - { - /* not enough space in array A to perform the ordering */ - stats [COLAMD_STATUS] = COLAMD_ERROR_A_too_small ; - stats [COLAMD_INFO1] = need ; - stats [COLAMD_INFO2] = Alen ; - COLAMD_DEBUG0 (("colamd: Need Alen >= %d, given only Alen = %d\n", need,Alen)); - return (false) ; - } - - Alen -= Col_size + Row_size ; - Col = (colamd_col *) &A [Alen] ; - Row = (Colamd_Row *) &A [Alen + Col_size] ; - - /* === Construct the row and column data structures ===================== */ - - if (!Eigen::internal::init_rows_cols (n_row, n_col, Row, Col, A, p, stats)) - { - /* input matrix is invalid */ - COLAMD_DEBUG0 (("colamd: Matrix invalid\n")) ; - return (false) ; - } - - /* === Initialize scores, kill dense rows/columns ======================= */ - - Eigen::internal::init_scoring (n_row, n_col, Row, Col, A, p, knobs, - &n_row2, &n_col2, &max_deg) ; - - /* === Order the supercolumns =========================================== */ - - ngarbage = Eigen::internal::find_ordering (n_row, n_col, Alen, Row, Col, A, p, - n_col2, max_deg, 2*nnz) ; - - /* === Order the non-principal columns ================================== */ - - Eigen::internal::order_children (n_col, Col, p) ; - - /* === Return statistics in stats ======================================= */ - - stats [COLAMD_DENSE_ROW] = n_row - n_row2 ; - stats [COLAMD_DENSE_COL] = n_col - n_col2 ; - stats [COLAMD_DEFRAG_COUNT] = ngarbage ; - COLAMD_DEBUG0 (("colamd: done.\n")) ; - return (true) ; -} - -/* ========================================================================== */ -/* === NON-USER-CALLABLE ROUTINES: ========================================== */ -/* ========================================================================== */ - -/* There are no user-callable routines beyond this point in the file */ - - -/* ========================================================================== */ -/* === init_rows_cols ======================================================= */ -/* ========================================================================== */ - -/* - Takes the column form of the matrix in A and creates the row form of the - matrix. Also, row and column attributes are stored in the Col and Row - structs. If the columns are un-sorted or contain duplicate row indices, - this routine will also sort and remove duplicate row indices from the - column form of the matrix. Returns false if the matrix is invalid, - true otherwise. Not user-callable. -*/ -template -static Index init_rows_cols /* returns true if OK, or false otherwise */ - ( - /* === Parameters ======================================================= */ - - Index n_row, /* number of rows of A */ - Index n_col, /* number of columns of A */ - Colamd_Row Row [], /* of size n_row+1 */ - colamd_col Col [], /* of size n_col+1 */ - Index A [], /* row indices of A, of size Alen */ - Index p [], /* pointers to columns in A, of size n_col+1 */ - Index stats [COLAMD_STATS] /* colamd statistics */ - ) -{ - /* === Local variables ================================================== */ - - Index col ; /* a column index */ - Index row ; /* a row index */ - Index *cp ; /* a column pointer */ - Index *cp_end ; /* a pointer to the end of a column */ - Index *rp ; /* a row pointer */ - Index *rp_end ; /* a pointer to the end of a row */ - Index last_row ; /* previous row */ - - /* === Initialize columns, and check column pointers ==================== */ - - for (col = 0 ; col < n_col ; col++) - { - Col [col].start = p [col] ; - Col [col].length = p [col+1] - p [col] ; - - if (Col [col].length < 0) - { - /* column pointers must be non-decreasing */ - stats [COLAMD_STATUS] = COLAMD_ERROR_col_length_negative ; - stats [COLAMD_INFO1] = col ; - stats [COLAMD_INFO2] = Col [col].length ; - COLAMD_DEBUG0 (("colamd: col %d length %d < 0\n", col, Col [col].length)) ; - return (false) ; - } - - Col [col].shared1.thickness = 1 ; - Col [col].shared2.score = 0 ; - Col [col].shared3.prev = COLAMD_EMPTY ; - Col [col].shared4.degree_next = COLAMD_EMPTY ; - } - - /* p [0..n_col] no longer needed, used as "head" in subsequent routines */ - - /* === Scan columns, compute row degrees, and check row indices ========= */ - - stats [COLAMD_INFO3] = 0 ; /* number of duplicate or unsorted row indices*/ - - for (row = 0 ; row < n_row ; row++) - { - Row [row].length = 0 ; - Row [row].shared2.mark = -1 ; - } - - for (col = 0 ; col < n_col ; col++) - { - last_row = -1 ; - - cp = &A [p [col]] ; - cp_end = &A [p [col+1]] ; - - while (cp < cp_end) - { - row = *cp++ ; - - /* make sure row indices within range */ - if (row < 0 || row >= n_row) - { - stats [COLAMD_STATUS] = COLAMD_ERROR_row_index_out_of_bounds ; - stats [COLAMD_INFO1] = col ; - stats [COLAMD_INFO2] = row ; - stats [COLAMD_INFO3] = n_row ; - COLAMD_DEBUG0 (("colamd: row %d col %d out of bounds\n", row, col)) ; - return (false) ; - } - - if (row <= last_row || Row [row].shared2.mark == col) - { - /* row index are unsorted or repeated (or both), thus col */ - /* is jumbled. This is a notice, not an error condition. */ - stats [COLAMD_STATUS] = COLAMD_OK_BUT_JUMBLED ; - stats [COLAMD_INFO1] = col ; - stats [COLAMD_INFO2] = row ; - (stats [COLAMD_INFO3]) ++ ; - COLAMD_DEBUG1 (("colamd: row %d col %d unsorted/duplicate\n",row,col)); - } - - if (Row [row].shared2.mark != col) - { - Row [row].length++ ; - } - else - { - /* this is a repeated entry in the column, */ - /* it will be removed */ - Col [col].length-- ; - } - - /* mark the row as having been seen in this column */ - Row [row].shared2.mark = col ; - - last_row = row ; - } - } - - /* === Compute row pointers ============================================= */ - - /* row form of the matrix starts directly after the column */ - /* form of matrix in A */ - Row [0].start = p [n_col] ; - Row [0].shared1.p = Row [0].start ; - Row [0].shared2.mark = -1 ; - for (row = 1 ; row < n_row ; row++) - { - Row [row].start = Row [row-1].start + Row [row-1].length ; - Row [row].shared1.p = Row [row].start ; - Row [row].shared2.mark = -1 ; - } - - /* === Create row form ================================================== */ - - if (stats [COLAMD_STATUS] == COLAMD_OK_BUT_JUMBLED) - { - /* if cols jumbled, watch for repeated row indices */ - for (col = 0 ; col < n_col ; col++) - { - cp = &A [p [col]] ; - cp_end = &A [p [col+1]] ; - while (cp < cp_end) - { - row = *cp++ ; - if (Row [row].shared2.mark != col) - { - A [(Row [row].shared1.p)++] = col ; - Row [row].shared2.mark = col ; - } - } - } - } - else - { - /* if cols not jumbled, we don't need the mark (this is faster) */ - for (col = 0 ; col < n_col ; col++) - { - cp = &A [p [col]] ; - cp_end = &A [p [col+1]] ; - while (cp < cp_end) - { - A [(Row [*cp++].shared1.p)++] = col ; - } - } - } - - /* === Clear the row marks and set row degrees ========================== */ - - for (row = 0 ; row < n_row ; row++) - { - Row [row].shared2.mark = 0 ; - Row [row].shared1.degree = Row [row].length ; - } - - /* === See if we need to re-create columns ============================== */ - - if (stats [COLAMD_STATUS] == COLAMD_OK_BUT_JUMBLED) - { - COLAMD_DEBUG0 (("colamd: reconstructing column form, matrix jumbled\n")) ; - - - /* === Compute col pointers ========================================= */ - - /* col form of the matrix starts at A [0]. */ - /* Note, we may have a gap between the col form and the row */ - /* form if there were duplicate entries, if so, it will be */ - /* removed upon the first garbage collection */ - Col [0].start = 0 ; - p [0] = Col [0].start ; - for (col = 1 ; col < n_col ; col++) - { - /* note that the lengths here are for pruned columns, i.e. */ - /* no duplicate row indices will exist for these columns */ - Col [col].start = Col [col-1].start + Col [col-1].length ; - p [col] = Col [col].start ; - } - - /* === Re-create col form =========================================== */ - - for (row = 0 ; row < n_row ; row++) - { - rp = &A [Row [row].start] ; - rp_end = rp + Row [row].length ; - while (rp < rp_end) - { - A [(p [*rp++])++] = row ; - } - } - } - - /* === Done. Matrix is not (or no longer) jumbled ====================== */ - - return (true) ; -} - - -/* ========================================================================== */ -/* === init_scoring ========================================================= */ -/* ========================================================================== */ - -/* - Kills dense or empty columns and rows, calculates an initial score for - each column, and places all columns in the degree lists. Not user-callable. -*/ -template -static void init_scoring - ( - /* === Parameters ======================================================= */ - - Index n_row, /* number of rows of A */ - Index n_col, /* number of columns of A */ - Colamd_Row Row [], /* of size n_row+1 */ - colamd_col Col [], /* of size n_col+1 */ - Index A [], /* column form and row form of A */ - Index head [], /* of size n_col+1 */ - double knobs [COLAMD_KNOBS],/* parameters */ - Index *p_n_row2, /* number of non-dense, non-empty rows */ - Index *p_n_col2, /* number of non-dense, non-empty columns */ - Index *p_max_deg /* maximum row degree */ - ) -{ - /* === Local variables ================================================== */ - - Index c ; /* a column index */ - Index r, row ; /* a row index */ - Index *cp ; /* a column pointer */ - Index deg ; /* degree of a row or column */ - Index *cp_end ; /* a pointer to the end of a column */ - Index *new_cp ; /* new column pointer */ - Index col_length ; /* length of pruned column */ - Index score ; /* current column score */ - Index n_col2 ; /* number of non-dense, non-empty columns */ - Index n_row2 ; /* number of non-dense, non-empty rows */ - Index dense_row_count ; /* remove rows with more entries than this */ - Index dense_col_count ; /* remove cols with more entries than this */ - Index min_score ; /* smallest column score */ - Index max_deg ; /* maximum row degree */ - Index next_col ; /* Used to add to degree list.*/ - - - /* === Extract knobs ==================================================== */ - - dense_row_count = COLAMD_MAX (0, COLAMD_MIN (knobs [COLAMD_DENSE_ROW] * n_col, n_col)) ; - dense_col_count = COLAMD_MAX (0, COLAMD_MIN (knobs [COLAMD_DENSE_COL] * n_row, n_row)) ; - COLAMD_DEBUG1 (("colamd: densecount: %d %d\n", dense_row_count, dense_col_count)) ; - max_deg = 0 ; - n_col2 = n_col ; - n_row2 = n_row ; - - /* === Kill empty columns =============================================== */ - - /* Put the empty columns at the end in their natural order, so that LU */ - /* factorization can proceed as far as possible. */ - for (c = n_col-1 ; c >= 0 ; c--) - { - deg = Col [c].length ; - if (deg == 0) - { - /* this is a empty column, kill and order it last */ - Col [c].shared2.order = --n_col2 ; - KILL_PRINCIPAL_COL (c) ; - } - } - COLAMD_DEBUG1 (("colamd: null columns killed: %d\n", n_col - n_col2)) ; - - /* === Kill dense columns =============================================== */ - - /* Put the dense columns at the end, in their natural order */ - for (c = n_col-1 ; c >= 0 ; c--) - { - /* skip any dead columns */ - if (COL_IS_DEAD (c)) - { - continue ; - } - deg = Col [c].length ; - if (deg > dense_col_count) - { - /* this is a dense column, kill and order it last */ - Col [c].shared2.order = --n_col2 ; - /* decrement the row degrees */ - cp = &A [Col [c].start] ; - cp_end = cp + Col [c].length ; - while (cp < cp_end) - { - Row [*cp++].shared1.degree-- ; - } - KILL_PRINCIPAL_COL (c) ; - } - } - COLAMD_DEBUG1 (("colamd: Dense and null columns killed: %d\n", n_col - n_col2)) ; - - /* === Kill dense and empty rows ======================================== */ - - for (r = 0 ; r < n_row ; r++) - { - deg = Row [r].shared1.degree ; - COLAMD_ASSERT (deg >= 0 && deg <= n_col) ; - if (deg > dense_row_count || deg == 0) - { - /* kill a dense or empty row */ - KILL_ROW (r) ; - --n_row2 ; - } - else - { - /* keep track of max degree of remaining rows */ - max_deg = COLAMD_MAX (max_deg, deg) ; - } - } - COLAMD_DEBUG1 (("colamd: Dense and null rows killed: %d\n", n_row - n_row2)) ; - - /* === Compute initial column scores ==================================== */ - - /* At this point the row degrees are accurate. They reflect the number */ - /* of "live" (non-dense) columns in each row. No empty rows exist. */ - /* Some "live" columns may contain only dead rows, however. These are */ - /* pruned in the code below. */ - - /* now find the initial matlab score for each column */ - for (c = n_col-1 ; c >= 0 ; c--) - { - /* skip dead column */ - if (COL_IS_DEAD (c)) - { - continue ; - } - score = 0 ; - cp = &A [Col [c].start] ; - new_cp = cp ; - cp_end = cp + Col [c].length ; - while (cp < cp_end) - { - /* get a row */ - row = *cp++ ; - /* skip if dead */ - if (ROW_IS_DEAD (row)) - { - continue ; - } - /* compact the column */ - *new_cp++ = row ; - /* add row's external degree */ - score += Row [row].shared1.degree - 1 ; - /* guard against integer overflow */ - score = COLAMD_MIN (score, n_col) ; - } - /* determine pruned column length */ - col_length = (Index) (new_cp - &A [Col [c].start]) ; - if (col_length == 0) - { - /* a newly-made null column (all rows in this col are "dense" */ - /* and have already been killed) */ - COLAMD_DEBUG2 (("Newly null killed: %d\n", c)) ; - Col [c].shared2.order = --n_col2 ; - KILL_PRINCIPAL_COL (c) ; - } - else - { - /* set column length and set score */ - COLAMD_ASSERT (score >= 0) ; - COLAMD_ASSERT (score <= n_col) ; - Col [c].length = col_length ; - Col [c].shared2.score = score ; - } - } - COLAMD_DEBUG1 (("colamd: Dense, null, and newly-null columns killed: %d\n", - n_col-n_col2)) ; - - /* At this point, all empty rows and columns are dead. All live columns */ - /* are "clean" (containing no dead rows) and simplicial (no supercolumns */ - /* yet). Rows may contain dead columns, but all live rows contain at */ - /* least one live column. */ - - /* === Initialize degree lists ========================================== */ - - - /* clear the hash buckets */ - for (c = 0 ; c <= n_col ; c++) - { - head [c] = COLAMD_EMPTY ; - } - min_score = n_col ; - /* place in reverse order, so low column indices are at the front */ - /* of the lists. This is to encourage natural tie-breaking */ - for (c = n_col-1 ; c >= 0 ; c--) - { - /* only add principal columns to degree lists */ - if (COL_IS_ALIVE (c)) - { - COLAMD_DEBUG4 (("place %d score %d minscore %d ncol %d\n", - c, Col [c].shared2.score, min_score, n_col)) ; - - /* === Add columns score to DList =============================== */ - - score = Col [c].shared2.score ; - - COLAMD_ASSERT (min_score >= 0) ; - COLAMD_ASSERT (min_score <= n_col) ; - COLAMD_ASSERT (score >= 0) ; - COLAMD_ASSERT (score <= n_col) ; - COLAMD_ASSERT (head [score] >= COLAMD_EMPTY) ; - - /* now add this column to dList at proper score location */ - next_col = head [score] ; - Col [c].shared3.prev = COLAMD_EMPTY ; - Col [c].shared4.degree_next = next_col ; - - /* if there already was a column with the same score, set its */ - /* previous pointer to this new column */ - if (next_col != COLAMD_EMPTY) - { - Col [next_col].shared3.prev = c ; - } - head [score] = c ; - - /* see if this score is less than current min */ - min_score = COLAMD_MIN (min_score, score) ; - - - } - } - - - /* === Return number of remaining columns, and max row degree =========== */ - - *p_n_col2 = n_col2 ; - *p_n_row2 = n_row2 ; - *p_max_deg = max_deg ; -} - - -/* ========================================================================== */ -/* === find_ordering ======================================================== */ -/* ========================================================================== */ - -/* - Order the principal columns of the supercolumn form of the matrix - (no supercolumns on input). Uses a minimum approximate column minimum - degree ordering method. Not user-callable. -*/ -template -static Index find_ordering /* return the number of garbage collections */ - ( - /* === Parameters ======================================================= */ - - Index n_row, /* number of rows of A */ - Index n_col, /* number of columns of A */ - Index Alen, /* size of A, 2*nnz + n_col or larger */ - Colamd_Row Row [], /* of size n_row+1 */ - colamd_col Col [], /* of size n_col+1 */ - Index A [], /* column form and row form of A */ - Index head [], /* of size n_col+1 */ - Index n_col2, /* Remaining columns to order */ - Index max_deg, /* Maximum row degree */ - Index pfree /* index of first free slot (2*nnz on entry) */ - ) -{ - /* === Local variables ================================================== */ - - Index k ; /* current pivot ordering step */ - Index pivot_col ; /* current pivot column */ - Index *cp ; /* a column pointer */ - Index *rp ; /* a row pointer */ - Index pivot_row ; /* current pivot row */ - Index *new_cp ; /* modified column pointer */ - Index *new_rp ; /* modified row pointer */ - Index pivot_row_start ; /* pointer to start of pivot row */ - Index pivot_row_degree ; /* number of columns in pivot row */ - Index pivot_row_length ; /* number of supercolumns in pivot row */ - Index pivot_col_score ; /* score of pivot column */ - Index needed_memory ; /* free space needed for pivot row */ - Index *cp_end ; /* pointer to the end of a column */ - Index *rp_end ; /* pointer to the end of a row */ - Index row ; /* a row index */ - Index col ; /* a column index */ - Index max_score ; /* maximum possible score */ - Index cur_score ; /* score of current column */ - unsigned int hash ; /* hash value for supernode detection */ - Index head_column ; /* head of hash bucket */ - Index first_col ; /* first column in hash bucket */ - Index tag_mark ; /* marker value for mark array */ - Index row_mark ; /* Row [row].shared2.mark */ - Index set_difference ; /* set difference size of row with pivot row */ - Index min_score ; /* smallest column score */ - Index col_thickness ; /* "thickness" (no. of columns in a supercol) */ - Index max_mark ; /* maximum value of tag_mark */ - Index pivot_col_thickness ; /* number of columns represented by pivot col */ - Index prev_col ; /* Used by Dlist operations. */ - Index next_col ; /* Used by Dlist operations. */ - Index ngarbage ; /* number of garbage collections performed */ - - - /* === Initialization and clear mark ==================================== */ - - max_mark = INT_MAX - n_col ; /* INT_MAX defined in */ - tag_mark = Eigen::internal::clear_mark (n_row, Row) ; - min_score = 0 ; - ngarbage = 0 ; - COLAMD_DEBUG1 (("colamd: Ordering, n_col2=%d\n", n_col2)) ; - - /* === Order the columns ================================================ */ - - for (k = 0 ; k < n_col2 ; /* 'k' is incremented below */) - { - - /* === Select pivot column, and order it ============================ */ - - /* make sure degree list isn't empty */ - COLAMD_ASSERT (min_score >= 0) ; - COLAMD_ASSERT (min_score <= n_col) ; - COLAMD_ASSERT (head [min_score] >= COLAMD_EMPTY) ; - - /* get pivot column from head of minimum degree list */ - while (head [min_score] == COLAMD_EMPTY && min_score < n_col) - { - min_score++ ; - } - pivot_col = head [min_score] ; - COLAMD_ASSERT (pivot_col >= 0 && pivot_col <= n_col) ; - next_col = Col [pivot_col].shared4.degree_next ; - head [min_score] = next_col ; - if (next_col != COLAMD_EMPTY) - { - Col [next_col].shared3.prev = COLAMD_EMPTY ; - } - - COLAMD_ASSERT (COL_IS_ALIVE (pivot_col)) ; - COLAMD_DEBUG3 (("Pivot col: %d\n", pivot_col)) ; - - /* remember score for defrag check */ - pivot_col_score = Col [pivot_col].shared2.score ; - - /* the pivot column is the kth column in the pivot order */ - Col [pivot_col].shared2.order = k ; - - /* increment order count by column thickness */ - pivot_col_thickness = Col [pivot_col].shared1.thickness ; - k += pivot_col_thickness ; - COLAMD_ASSERT (pivot_col_thickness > 0) ; - - /* === Garbage_collection, if necessary ============================= */ - - needed_memory = COLAMD_MIN (pivot_col_score, n_col - k) ; - if (pfree + needed_memory >= Alen) - { - pfree = Eigen::internal::garbage_collection (n_row, n_col, Row, Col, A, &A [pfree]) ; - ngarbage++ ; - /* after garbage collection we will have enough */ - COLAMD_ASSERT (pfree + needed_memory < Alen) ; - /* garbage collection has wiped out the Row[].shared2.mark array */ - tag_mark = Eigen::internal::clear_mark (n_row, Row) ; - - } - - /* === Compute pivot row pattern ==================================== */ - - /* get starting location for this new merged row */ - pivot_row_start = pfree ; - - /* initialize new row counts to zero */ - pivot_row_degree = 0 ; - - /* tag pivot column as having been visited so it isn't included */ - /* in merged pivot row */ - Col [pivot_col].shared1.thickness = -pivot_col_thickness ; - - /* pivot row is the union of all rows in the pivot column pattern */ - cp = &A [Col [pivot_col].start] ; - cp_end = cp + Col [pivot_col].length ; - while (cp < cp_end) - { - /* get a row */ - row = *cp++ ; - COLAMD_DEBUG4 (("Pivot col pattern %d %d\n", ROW_IS_ALIVE (row), row)) ; - /* skip if row is dead */ - if (ROW_IS_DEAD (row)) - { - continue ; - } - rp = &A [Row [row].start] ; - rp_end = rp + Row [row].length ; - while (rp < rp_end) - { - /* get a column */ - col = *rp++ ; - /* add the column, if alive and untagged */ - col_thickness = Col [col].shared1.thickness ; - if (col_thickness > 0 && COL_IS_ALIVE (col)) - { - /* tag column in pivot row */ - Col [col].shared1.thickness = -col_thickness ; - COLAMD_ASSERT (pfree < Alen) ; - /* place column in pivot row */ - A [pfree++] = col ; - pivot_row_degree += col_thickness ; - } - } - } - - /* clear tag on pivot column */ - Col [pivot_col].shared1.thickness = pivot_col_thickness ; - max_deg = COLAMD_MAX (max_deg, pivot_row_degree) ; - - - /* === Kill all rows used to construct pivot row ==================== */ - - /* also kill pivot row, temporarily */ - cp = &A [Col [pivot_col].start] ; - cp_end = cp + Col [pivot_col].length ; - while (cp < cp_end) - { - /* may be killing an already dead row */ - row = *cp++ ; - COLAMD_DEBUG3 (("Kill row in pivot col: %d\n", row)) ; - KILL_ROW (row) ; - } - - /* === Select a row index to use as the new pivot row =============== */ - - pivot_row_length = pfree - pivot_row_start ; - if (pivot_row_length > 0) - { - /* pick the "pivot" row arbitrarily (first row in col) */ - pivot_row = A [Col [pivot_col].start] ; - COLAMD_DEBUG3 (("Pivotal row is %d\n", pivot_row)) ; - } - else - { - /* there is no pivot row, since it is of zero length */ - pivot_row = COLAMD_EMPTY ; - COLAMD_ASSERT (pivot_row_length == 0) ; - } - COLAMD_ASSERT (Col [pivot_col].length > 0 || pivot_row_length == 0) ; - - /* === Approximate degree computation =============================== */ - - /* Here begins the computation of the approximate degree. The column */ - /* score is the sum of the pivot row "length", plus the size of the */ - /* set differences of each row in the column minus the pattern of the */ - /* pivot row itself. The column ("thickness") itself is also */ - /* excluded from the column score (we thus use an approximate */ - /* external degree). */ - - /* The time taken by the following code (compute set differences, and */ - /* add them up) is proportional to the size of the data structure */ - /* being scanned - that is, the sum of the sizes of each column in */ - /* the pivot row. Thus, the amortized time to compute a column score */ - /* is proportional to the size of that column (where size, in this */ - /* context, is the column "length", or the number of row indices */ - /* in that column). The number of row indices in a column is */ - /* monotonically non-decreasing, from the length of the original */ - /* column on input to colamd. */ - - /* === Compute set differences ====================================== */ - - COLAMD_DEBUG3 (("** Computing set differences phase. **\n")) ; - - /* pivot row is currently dead - it will be revived later. */ - - COLAMD_DEBUG3 (("Pivot row: ")) ; - /* for each column in pivot row */ - rp = &A [pivot_row_start] ; - rp_end = rp + pivot_row_length ; - while (rp < rp_end) - { - col = *rp++ ; - COLAMD_ASSERT (COL_IS_ALIVE (col) && col != pivot_col) ; - COLAMD_DEBUG3 (("Col: %d\n", col)) ; - - /* clear tags used to construct pivot row pattern */ - col_thickness = -Col [col].shared1.thickness ; - COLAMD_ASSERT (col_thickness > 0) ; - Col [col].shared1.thickness = col_thickness ; - - /* === Remove column from degree list =========================== */ - - cur_score = Col [col].shared2.score ; - prev_col = Col [col].shared3.prev ; - next_col = Col [col].shared4.degree_next ; - COLAMD_ASSERT (cur_score >= 0) ; - COLAMD_ASSERT (cur_score <= n_col) ; - COLAMD_ASSERT (cur_score >= COLAMD_EMPTY) ; - if (prev_col == COLAMD_EMPTY) - { - head [cur_score] = next_col ; - } - else - { - Col [prev_col].shared4.degree_next = next_col ; - } - if (next_col != COLAMD_EMPTY) - { - Col [next_col].shared3.prev = prev_col ; - } - - /* === Scan the column ========================================== */ - - cp = &A [Col [col].start] ; - cp_end = cp + Col [col].length ; - while (cp < cp_end) - { - /* get a row */ - row = *cp++ ; - row_mark = Row [row].shared2.mark ; - /* skip if dead */ - if (ROW_IS_MARKED_DEAD (row_mark)) - { - continue ; - } - COLAMD_ASSERT (row != pivot_row) ; - set_difference = row_mark - tag_mark ; - /* check if the row has been seen yet */ - if (set_difference < 0) - { - COLAMD_ASSERT (Row [row].shared1.degree <= max_deg) ; - set_difference = Row [row].shared1.degree ; - } - /* subtract column thickness from this row's set difference */ - set_difference -= col_thickness ; - COLAMD_ASSERT (set_difference >= 0) ; - /* absorb this row if the set difference becomes zero */ - if (set_difference == 0) - { - COLAMD_DEBUG3 (("aggressive absorption. Row: %d\n", row)) ; - KILL_ROW (row) ; - } - else - { - /* save the new mark */ - Row [row].shared2.mark = set_difference + tag_mark ; - } - } - } - - - /* === Add up set differences for each column ======================= */ - - COLAMD_DEBUG3 (("** Adding set differences phase. **\n")) ; - - /* for each column in pivot row */ - rp = &A [pivot_row_start] ; - rp_end = rp + pivot_row_length ; - while (rp < rp_end) - { - /* get a column */ - col = *rp++ ; - COLAMD_ASSERT (COL_IS_ALIVE (col) && col != pivot_col) ; - hash = 0 ; - cur_score = 0 ; - cp = &A [Col [col].start] ; - /* compact the column */ - new_cp = cp ; - cp_end = cp + Col [col].length ; - - COLAMD_DEBUG4 (("Adding set diffs for Col: %d.\n", col)) ; - - while (cp < cp_end) - { - /* get a row */ - row = *cp++ ; - COLAMD_ASSERT(row >= 0 && row < n_row) ; - row_mark = Row [row].shared2.mark ; - /* skip if dead */ - if (ROW_IS_MARKED_DEAD (row_mark)) - { - continue ; - } - COLAMD_ASSERT (row_mark > tag_mark) ; - /* compact the column */ - *new_cp++ = row ; - /* compute hash function */ - hash += row ; - /* add set difference */ - cur_score += row_mark - tag_mark ; - /* integer overflow... */ - cur_score = COLAMD_MIN (cur_score, n_col) ; - } - - /* recompute the column's length */ - Col [col].length = (Index) (new_cp - &A [Col [col].start]) ; - - /* === Further mass elimination ================================= */ - - if (Col [col].length == 0) - { - COLAMD_DEBUG4 (("further mass elimination. Col: %d\n", col)) ; - /* nothing left but the pivot row in this column */ - KILL_PRINCIPAL_COL (col) ; - pivot_row_degree -= Col [col].shared1.thickness ; - COLAMD_ASSERT (pivot_row_degree >= 0) ; - /* order it */ - Col [col].shared2.order = k ; - /* increment order count by column thickness */ - k += Col [col].shared1.thickness ; - } - else - { - /* === Prepare for supercolumn detection ==================== */ - - COLAMD_DEBUG4 (("Preparing supercol detection for Col: %d.\n", col)) ; - - /* save score so far */ - Col [col].shared2.score = cur_score ; - - /* add column to hash table, for supercolumn detection */ - hash %= n_col + 1 ; - - COLAMD_DEBUG4 ((" Hash = %d, n_col = %d.\n", hash, n_col)) ; - COLAMD_ASSERT (hash <= n_col) ; - - head_column = head [hash] ; - if (head_column > COLAMD_EMPTY) - { - /* degree list "hash" is non-empty, use prev (shared3) of */ - /* first column in degree list as head of hash bucket */ - first_col = Col [head_column].shared3.headhash ; - Col [head_column].shared3.headhash = col ; - } - else - { - /* degree list "hash" is empty, use head as hash bucket */ - first_col = - (head_column + 2) ; - head [hash] = - (col + 2) ; - } - Col [col].shared4.hash_next = first_col ; - - /* save hash function in Col [col].shared3.hash */ - Col [col].shared3.hash = (Index) hash ; - COLAMD_ASSERT (COL_IS_ALIVE (col)) ; - } - } - - /* The approximate external column degree is now computed. */ - - /* === Supercolumn detection ======================================== */ - - COLAMD_DEBUG3 (("** Supercolumn detection phase. **\n")) ; - - Eigen::internal::detect_super_cols (Col, A, head, pivot_row_start, pivot_row_length) ; - - /* === Kill the pivotal column ====================================== */ - - KILL_PRINCIPAL_COL (pivot_col) ; - - /* === Clear mark =================================================== */ - - tag_mark += (max_deg + 1) ; - if (tag_mark >= max_mark) - { - COLAMD_DEBUG2 (("clearing tag_mark\n")) ; - tag_mark = Eigen::internal::clear_mark (n_row, Row) ; - } - - /* === Finalize the new pivot row, and column scores ================ */ - - COLAMD_DEBUG3 (("** Finalize scores phase. **\n")) ; - - /* for each column in pivot row */ - rp = &A [pivot_row_start] ; - /* compact the pivot row */ - new_rp = rp ; - rp_end = rp + pivot_row_length ; - while (rp < rp_end) - { - col = *rp++ ; - /* skip dead columns */ - if (COL_IS_DEAD (col)) - { - continue ; - } - *new_rp++ = col ; - /* add new pivot row to column */ - A [Col [col].start + (Col [col].length++)] = pivot_row ; - - /* retrieve score so far and add on pivot row's degree. */ - /* (we wait until here for this in case the pivot */ - /* row's degree was reduced due to mass elimination). */ - cur_score = Col [col].shared2.score + pivot_row_degree ; - - /* calculate the max possible score as the number of */ - /* external columns minus the 'k' value minus the */ - /* columns thickness */ - max_score = n_col - k - Col [col].shared1.thickness ; - - /* make the score the external degree of the union-of-rows */ - cur_score -= Col [col].shared1.thickness ; - - /* make sure score is less or equal than the max score */ - cur_score = COLAMD_MIN (cur_score, max_score) ; - COLAMD_ASSERT (cur_score >= 0) ; - - /* store updated score */ - Col [col].shared2.score = cur_score ; - - /* === Place column back in degree list ========================= */ - - COLAMD_ASSERT (min_score >= 0) ; - COLAMD_ASSERT (min_score <= n_col) ; - COLAMD_ASSERT (cur_score >= 0) ; - COLAMD_ASSERT (cur_score <= n_col) ; - COLAMD_ASSERT (head [cur_score] >= COLAMD_EMPTY) ; - next_col = head [cur_score] ; - Col [col].shared4.degree_next = next_col ; - Col [col].shared3.prev = COLAMD_EMPTY ; - if (next_col != COLAMD_EMPTY) - { - Col [next_col].shared3.prev = col ; - } - head [cur_score] = col ; - - /* see if this score is less than current min */ - min_score = COLAMD_MIN (min_score, cur_score) ; - - } - - /* === Resurrect the new pivot row ================================== */ - - if (pivot_row_degree > 0) - { - /* update pivot row length to reflect any cols that were killed */ - /* during super-col detection and mass elimination */ - Row [pivot_row].start = pivot_row_start ; - Row [pivot_row].length = (Index) (new_rp - &A[pivot_row_start]) ; - Row [pivot_row].shared1.degree = pivot_row_degree ; - Row [pivot_row].shared2.mark = 0 ; - /* pivot row is no longer dead */ - } - } - - /* === All principal columns have now been ordered ====================== */ - - return (ngarbage) ; -} - - -/* ========================================================================== */ -/* === order_children ======================================================= */ -/* ========================================================================== */ - -/* - The find_ordering routine has ordered all of the principal columns (the - representatives of the supercolumns). The non-principal columns have not - yet been ordered. This routine orders those columns by walking up the - parent tree (a column is a child of the column which absorbed it). The - final permutation vector is then placed in p [0 ... n_col-1], with p [0] - being the first column, and p [n_col-1] being the last. It doesn't look - like it at first glance, but be assured that this routine takes time linear - in the number of columns. Although not immediately obvious, the time - taken by this routine is O (n_col), that is, linear in the number of - columns. Not user-callable. -*/ -template -static inline void order_children -( - /* === Parameters ======================================================= */ - - Index n_col, /* number of columns of A */ - colamd_col Col [], /* of size n_col+1 */ - Index p [] /* p [0 ... n_col-1] is the column permutation*/ - ) -{ - /* === Local variables ================================================== */ - - Index i ; /* loop counter for all columns */ - Index c ; /* column index */ - Index parent ; /* index of column's parent */ - Index order ; /* column's order */ - - /* === Order each non-principal column ================================== */ - - for (i = 0 ; i < n_col ; i++) - { - /* find an un-ordered non-principal column */ - COLAMD_ASSERT (COL_IS_DEAD (i)) ; - if (!COL_IS_DEAD_PRINCIPAL (i) && Col [i].shared2.order == COLAMD_EMPTY) - { - parent = i ; - /* once found, find its principal parent */ - do - { - parent = Col [parent].shared1.parent ; - } while (!COL_IS_DEAD_PRINCIPAL (parent)) ; - - /* now, order all un-ordered non-principal columns along path */ - /* to this parent. collapse tree at the same time */ - c = i ; - /* get order of parent */ - order = Col [parent].shared2.order ; - - do - { - COLAMD_ASSERT (Col [c].shared2.order == COLAMD_EMPTY) ; - - /* order this column */ - Col [c].shared2.order = order++ ; - /* collaps tree */ - Col [c].shared1.parent = parent ; - - /* get immediate parent of this column */ - c = Col [c].shared1.parent ; - - /* continue until we hit an ordered column. There are */ - /* guarranteed not to be anymore unordered columns */ - /* above an ordered column */ - } while (Col [c].shared2.order == COLAMD_EMPTY) ; - - /* re-order the super_col parent to largest order for this group */ - Col [parent].shared2.order = order ; - } - } - - /* === Generate the permutation ========================================= */ - - for (c = 0 ; c < n_col ; c++) - { - p [Col [c].shared2.order] = c ; - } -} - - -/* ========================================================================== */ -/* === detect_super_cols ==================================================== */ -/* ========================================================================== */ - -/* - Detects supercolumns by finding matches between columns in the hash buckets. - Check amongst columns in the set A [row_start ... row_start + row_length-1]. - The columns under consideration are currently *not* in the degree lists, - and have already been placed in the hash buckets. - - The hash bucket for columns whose hash function is equal to h is stored - as follows: - - if head [h] is >= 0, then head [h] contains a degree list, so: - - head [h] is the first column in degree bucket h. - Col [head [h]].headhash gives the first column in hash bucket h. - - otherwise, the degree list is empty, and: - - -(head [h] + 2) is the first column in hash bucket h. - - For a column c in a hash bucket, Col [c].shared3.prev is NOT a "previous - column" pointer. Col [c].shared3.hash is used instead as the hash number - for that column. The value of Col [c].shared4.hash_next is the next column - in the same hash bucket. - - Assuming no, or "few" hash collisions, the time taken by this routine is - linear in the sum of the sizes (lengths) of each column whose score has - just been computed in the approximate degree computation. - Not user-callable. -*/ -template -static void detect_super_cols -( - /* === Parameters ======================================================= */ - - colamd_col Col [], /* of size n_col+1 */ - Index A [], /* row indices of A */ - Index head [], /* head of degree lists and hash buckets */ - Index row_start, /* pointer to set of columns to check */ - Index row_length /* number of columns to check */ -) -{ - /* === Local variables ================================================== */ - - Index hash ; /* hash value for a column */ - Index *rp ; /* pointer to a row */ - Index c ; /* a column index */ - Index super_c ; /* column index of the column to absorb into */ - Index *cp1 ; /* column pointer for column super_c */ - Index *cp2 ; /* column pointer for column c */ - Index length ; /* length of column super_c */ - Index prev_c ; /* column preceding c in hash bucket */ - Index i ; /* loop counter */ - Index *rp_end ; /* pointer to the end of the row */ - Index col ; /* a column index in the row to check */ - Index head_column ; /* first column in hash bucket or degree list */ - Index first_col ; /* first column in hash bucket */ - - /* === Consider each column in the row ================================== */ - - rp = &A [row_start] ; - rp_end = rp + row_length ; - while (rp < rp_end) - { - col = *rp++ ; - if (COL_IS_DEAD (col)) - { - continue ; - } - - /* get hash number for this column */ - hash = Col [col].shared3.hash ; - COLAMD_ASSERT (hash <= n_col) ; - - /* === Get the first column in this hash bucket ===================== */ - - head_column = head [hash] ; - if (head_column > COLAMD_EMPTY) - { - first_col = Col [head_column].shared3.headhash ; - } - else - { - first_col = - (head_column + 2) ; - } - - /* === Consider each column in the hash bucket ====================== */ - - for (super_c = first_col ; super_c != COLAMD_EMPTY ; - super_c = Col [super_c].shared4.hash_next) - { - COLAMD_ASSERT (COL_IS_ALIVE (super_c)) ; - COLAMD_ASSERT (Col [super_c].shared3.hash == hash) ; - length = Col [super_c].length ; - - /* prev_c is the column preceding column c in the hash bucket */ - prev_c = super_c ; - - /* === Compare super_c with all columns after it ================ */ - - for (c = Col [super_c].shared4.hash_next ; - c != COLAMD_EMPTY ; c = Col [c].shared4.hash_next) - { - COLAMD_ASSERT (c != super_c) ; - COLAMD_ASSERT (COL_IS_ALIVE (c)) ; - COLAMD_ASSERT (Col [c].shared3.hash == hash) ; - - /* not identical if lengths or scores are different */ - if (Col [c].length != length || - Col [c].shared2.score != Col [super_c].shared2.score) - { - prev_c = c ; - continue ; - } - - /* compare the two columns */ - cp1 = &A [Col [super_c].start] ; - cp2 = &A [Col [c].start] ; - - for (i = 0 ; i < length ; i++) - { - /* the columns are "clean" (no dead rows) */ - COLAMD_ASSERT (ROW_IS_ALIVE (*cp1)) ; - COLAMD_ASSERT (ROW_IS_ALIVE (*cp2)) ; - /* row indices will same order for both supercols, */ - /* no gather scatter nessasary */ - if (*cp1++ != *cp2++) - { - break ; - } - } - - /* the two columns are different if the for-loop "broke" */ - if (i != length) - { - prev_c = c ; - continue ; - } - - /* === Got it! two columns are identical =================== */ - - COLAMD_ASSERT (Col [c].shared2.score == Col [super_c].shared2.score) ; - - Col [super_c].shared1.thickness += Col [c].shared1.thickness ; - Col [c].shared1.parent = super_c ; - KILL_NON_PRINCIPAL_COL (c) ; - /* order c later, in order_children() */ - Col [c].shared2.order = COLAMD_EMPTY ; - /* remove c from hash bucket */ - Col [prev_c].shared4.hash_next = Col [c].shared4.hash_next ; - } - } - - /* === Empty this hash bucket ======================================= */ - - if (head_column > COLAMD_EMPTY) - { - /* corresponding degree list "hash" is not empty */ - Col [head_column].shared3.headhash = COLAMD_EMPTY ; - } - else - { - /* corresponding degree list "hash" is empty */ - head [hash] = COLAMD_EMPTY ; - } - } -} - - -/* ========================================================================== */ -/* === garbage_collection =================================================== */ -/* ========================================================================== */ - -/* - Defragments and compacts columns and rows in the workspace A. Used when - all avaliable memory has been used while performing row merging. Returns - the index of the first free position in A, after garbage collection. The - time taken by this routine is linear is the size of the array A, which is - itself linear in the number of nonzeros in the input matrix. - Not user-callable. -*/ -template -static Index garbage_collection /* returns the new value of pfree */ - ( - /* === Parameters ======================================================= */ - - Index n_row, /* number of rows */ - Index n_col, /* number of columns */ - Colamd_Row Row [], /* row info */ - colamd_col Col [], /* column info */ - Index A [], /* A [0 ... Alen-1] holds the matrix */ - Index *pfree /* &A [0] ... pfree is in use */ - ) -{ - /* === Local variables ================================================== */ - - Index *psrc ; /* source pointer */ - Index *pdest ; /* destination pointer */ - Index j ; /* counter */ - Index r ; /* a row index */ - Index c ; /* a column index */ - Index length ; /* length of a row or column */ - - /* === Defragment the columns =========================================== */ - - pdest = &A[0] ; - for (c = 0 ; c < n_col ; c++) - { - if (COL_IS_ALIVE (c)) - { - psrc = &A [Col [c].start] ; - - /* move and compact the column */ - COLAMD_ASSERT (pdest <= psrc) ; - Col [c].start = (Index) (pdest - &A [0]) ; - length = Col [c].length ; - for (j = 0 ; j < length ; j++) - { - r = *psrc++ ; - if (ROW_IS_ALIVE (r)) - { - *pdest++ = r ; - } - } - Col [c].length = (Index) (pdest - &A [Col [c].start]) ; - } - } - - /* === Prepare to defragment the rows =================================== */ - - for (r = 0 ; r < n_row ; r++) - { - if (ROW_IS_ALIVE (r)) - { - if (Row [r].length == 0) - { - /* this row is of zero length. cannot compact it, so kill it */ - COLAMD_DEBUG3 (("Defrag row kill\n")) ; - KILL_ROW (r) ; - } - else - { - /* save first column index in Row [r].shared2.first_column */ - psrc = &A [Row [r].start] ; - Row [r].shared2.first_column = *psrc ; - COLAMD_ASSERT (ROW_IS_ALIVE (r)) ; - /* flag the start of the row with the one's complement of row */ - *psrc = ONES_COMPLEMENT (r) ; - - } - } - } - - /* === Defragment the rows ============================================== */ - - psrc = pdest ; - while (psrc < pfree) - { - /* find a negative number ... the start of a row */ - if (*psrc++ < 0) - { - psrc-- ; - /* get the row index */ - r = ONES_COMPLEMENT (*psrc) ; - COLAMD_ASSERT (r >= 0 && r < n_row) ; - /* restore first column index */ - *psrc = Row [r].shared2.first_column ; - COLAMD_ASSERT (ROW_IS_ALIVE (r)) ; - - /* move and compact the row */ - COLAMD_ASSERT (pdest <= psrc) ; - Row [r].start = (Index) (pdest - &A [0]) ; - length = Row [r].length ; - for (j = 0 ; j < length ; j++) - { - c = *psrc++ ; - if (COL_IS_ALIVE (c)) - { - *pdest++ = c ; - } - } - Row [r].length = (Index) (pdest - &A [Row [r].start]) ; - - } - } - /* ensure we found all the rows */ - COLAMD_ASSERT (debug_rows == 0) ; - - /* === Return the new value of pfree ==================================== */ - - return ((Index) (pdest - &A [0])) ; -} - - -/* ========================================================================== */ -/* === clear_mark =========================================================== */ -/* ========================================================================== */ - -/* - Clears the Row [].shared2.mark array, and returns the new tag_mark. - Return value is the new tag_mark. Not user-callable. -*/ -template -static inline Index clear_mark /* return the new value for tag_mark */ - ( - /* === Parameters ======================================================= */ - - Index n_row, /* number of rows in A */ - Colamd_Row Row [] /* Row [0 ... n_row-1].shared2.mark is set to zero */ - ) -{ - /* === Local variables ================================================== */ - - Index r ; - - for (r = 0 ; r < n_row ; r++) - { - if (ROW_IS_ALIVE (r)) - { - Row [r].shared2.mark = 0 ; - } - } - return (1) ; -} - - -} // namespace internal -#endif diff --git a/thirdparty/eigen-3.2.7/Eigen/src/OrderingMethods/Ordering.h b/thirdparty/eigen-3.2.7/Eigen/src/OrderingMethods/Ordering.h deleted file mode 100644 index f3c31f9c..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/OrderingMethods/Ordering.h +++ /dev/null @@ -1,154 +0,0 @@ - -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2012 Désiré Nuentsa-Wakam -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_ORDERING_H -#define EIGEN_ORDERING_H - -namespace Eigen { - -#include "Eigen_Colamd.h" - -namespace internal { - -/** \internal - * \ingroup OrderingMethods_Module - * \returns the symmetric pattern A^T+A from the input matrix A. - * FIXME: The values should not be considered here - */ -template -void ordering_helper_at_plus_a(const MatrixType& mat, MatrixType& symmat) -{ - MatrixType C; - C = mat.transpose(); // NOTE: Could be costly - for (int i = 0; i < C.rows(); i++) - { - for (typename MatrixType::InnerIterator it(C, i); it; ++it) - it.valueRef() = 0.0; - } - symmat = C + mat; -} - -} - -#ifndef EIGEN_MPL2_ONLY - -/** \ingroup OrderingMethods_Module - * \class AMDOrdering - * - * Functor computing the \em approximate \em minimum \em degree ordering - * If the matrix is not structurally symmetric, an ordering of A^T+A is computed - * \tparam Index The type of indices of the matrix - * \sa COLAMDOrdering - */ -template -class AMDOrdering -{ - public: - typedef PermutationMatrix PermutationType; - - /** Compute the permutation vector from a sparse matrix - * This routine is much faster if the input matrix is column-major - */ - template - void operator()(const MatrixType& mat, PermutationType& perm) - { - // Compute the symmetric pattern - SparseMatrix symm; - internal::ordering_helper_at_plus_a(mat,symm); - - // Call the AMD routine - //m_mat.prune(keep_diag()); - internal::minimum_degree_ordering(symm, perm); - } - - /** Compute the permutation with a selfadjoint matrix */ - template - void operator()(const SparseSelfAdjointView& mat, PermutationType& perm) - { - SparseMatrix C; C = mat; - - // Call the AMD routine - // m_mat.prune(keep_diag()); //Remove the diagonal elements - internal::minimum_degree_ordering(C, perm); - } -}; - -#endif // EIGEN_MPL2_ONLY - -/** \ingroup OrderingMethods_Module - * \class NaturalOrdering - * - * Functor computing the natural ordering (identity) - * - * \note Returns an empty permutation matrix - * \tparam Index The type of indices of the matrix - */ -template -class NaturalOrdering -{ - public: - typedef PermutationMatrix PermutationType; - - /** Compute the permutation vector from a column-major sparse matrix */ - template - void operator()(const MatrixType& /*mat*/, PermutationType& perm) - { - perm.resize(0); - } - -}; - -/** \ingroup OrderingMethods_Module - * \class COLAMDOrdering - * - * Functor computing the \em column \em approximate \em minimum \em degree ordering - * The matrix should be in column-major and \b compressed format (see SparseMatrix::makeCompressed()). - */ -template -class COLAMDOrdering -{ - public: - typedef PermutationMatrix PermutationType; - typedef Matrix IndexVector; - - /** Compute the permutation vector \a perm form the sparse matrix \a mat - * \warning The input sparse matrix \a mat must be in compressed mode (see SparseMatrix::makeCompressed()). - */ - template - void operator() (const MatrixType& mat, PermutationType& perm) - { - eigen_assert(mat.isCompressed() && "COLAMDOrdering requires a sparse matrix in compressed mode. Call .makeCompressed() before passing it to COLAMDOrdering"); - - Index m = mat.rows(); - Index n = mat.cols(); - Index nnz = mat.nonZeros(); - // Get the recommended value of Alen to be used by colamd - Index Alen = internal::colamd_recommended(nnz, m, n); - // Set the default parameters - double knobs [COLAMD_KNOBS]; - Index stats [COLAMD_STATS]; - internal::colamd_set_defaults(knobs); - - IndexVector p(n+1), A(Alen); - for(Index i=0; i <= n; i++) p(i) = mat.outerIndexPtr()[i]; - for(Index i=0; i < nnz; i++) A(i) = mat.innerIndexPtr()[i]; - // Call Colamd routine to compute the ordering - Index info = internal::colamd(m, n, Alen, A.data(), p.data(), knobs, stats); - EIGEN_UNUSED_VARIABLE(info); - eigen_assert( info && "COLAMD failed " ); - - perm.resize(n); - for (Index i = 0; i < n; i++) perm.indices()(p(i)) = i; - } -}; - -} // end namespace Eigen - -#endif diff --git a/thirdparty/eigen-3.2.7/Eigen/src/PaStiXSupport/PaStiXSupport.h b/thirdparty/eigen-3.2.7/Eigen/src/PaStiXSupport/PaStiXSupport.h deleted file mode 100644 index a955287d..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/PaStiXSupport/PaStiXSupport.h +++ /dev/null @@ -1,721 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2012 Désiré Nuentsa-Wakam -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_PASTIXSUPPORT_H -#define EIGEN_PASTIXSUPPORT_H - -namespace Eigen { - -/** \ingroup PaStiXSupport_Module - * \brief Interface to the PaStix solver - * - * This class is used to solve the linear systems A.X = B via the PaStix library. - * The matrix can be either real or complex, symmetric or not. - * - * \sa TutorialSparseDirectSolvers - */ -template class PastixLU; -template class PastixLLT; -template class PastixLDLT; - -namespace internal -{ - - template struct pastix_traits; - - template - struct pastix_traits< PastixLU<_MatrixType> > - { - typedef _MatrixType MatrixType; - typedef typename _MatrixType::Scalar Scalar; - typedef typename _MatrixType::RealScalar RealScalar; - typedef typename _MatrixType::Index Index; - }; - - template - struct pastix_traits< PastixLLT<_MatrixType,Options> > - { - typedef _MatrixType MatrixType; - typedef typename _MatrixType::Scalar Scalar; - typedef typename _MatrixType::RealScalar RealScalar; - typedef typename _MatrixType::Index Index; - }; - - template - struct pastix_traits< PastixLDLT<_MatrixType,Options> > - { - typedef _MatrixType MatrixType; - typedef typename _MatrixType::Scalar Scalar; - typedef typename _MatrixType::RealScalar RealScalar; - typedef typename _MatrixType::Index Index; - }; - - void eigen_pastix(pastix_data_t **pastix_data, int pastix_comm, int n, int *ptr, int *idx, float *vals, int *perm, int * invp, float *x, int nbrhs, int *iparm, double *dparm) - { - if (n == 0) { ptr = NULL; idx = NULL; vals = NULL; } - if (nbrhs == 0) {x = NULL; nbrhs=1;} - s_pastix(pastix_data, pastix_comm, n, ptr, idx, vals, perm, invp, x, nbrhs, iparm, dparm); - } - - void eigen_pastix(pastix_data_t **pastix_data, int pastix_comm, int n, int *ptr, int *idx, double *vals, int *perm, int * invp, double *x, int nbrhs, int *iparm, double *dparm) - { - if (n == 0) { ptr = NULL; idx = NULL; vals = NULL; } - if (nbrhs == 0) {x = NULL; nbrhs=1;} - d_pastix(pastix_data, pastix_comm, n, ptr, idx, vals, perm, invp, x, nbrhs, iparm, dparm); - } - - void eigen_pastix(pastix_data_t **pastix_data, int pastix_comm, int n, int *ptr, int *idx, std::complex *vals, int *perm, int * invp, std::complex *x, int nbrhs, int *iparm, double *dparm) - { - if (n == 0) { ptr = NULL; idx = NULL; vals = NULL; } - if (nbrhs == 0) {x = NULL; nbrhs=1;} - c_pastix(pastix_data, pastix_comm, n, ptr, idx, reinterpret_cast(vals), perm, invp, reinterpret_cast(x), nbrhs, iparm, dparm); - } - - void eigen_pastix(pastix_data_t **pastix_data, int pastix_comm, int n, int *ptr, int *idx, std::complex *vals, int *perm, int * invp, std::complex *x, int nbrhs, int *iparm, double *dparm) - { - if (n == 0) { ptr = NULL; idx = NULL; vals = NULL; } - if (nbrhs == 0) {x = NULL; nbrhs=1;} - z_pastix(pastix_data, pastix_comm, n, ptr, idx, reinterpret_cast(vals), perm, invp, reinterpret_cast(x), nbrhs, iparm, dparm); - } - - // Convert the matrix to Fortran-style Numbering - template - void c_to_fortran_numbering (MatrixType& mat) - { - if ( !(mat.outerIndexPtr()[0]) ) - { - int i; - for(i = 0; i <= mat.rows(); ++i) - ++mat.outerIndexPtr()[i]; - for(i = 0; i < mat.nonZeros(); ++i) - ++mat.innerIndexPtr()[i]; - } - } - - // Convert to C-style Numbering - template - void fortran_to_c_numbering (MatrixType& mat) - { - // Check the Numbering - if ( mat.outerIndexPtr()[0] == 1 ) - { // Convert to C-style numbering - int i; - for(i = 0; i <= mat.rows(); ++i) - --mat.outerIndexPtr()[i]; - for(i = 0; i < mat.nonZeros(); ++i) - --mat.innerIndexPtr()[i]; - } - } -} - -// This is the base class to interface with PaStiX functions. -// Users should not used this class directly. -template -class PastixBase : internal::noncopyable -{ - public: - typedef typename internal::pastix_traits::MatrixType _MatrixType; - typedef _MatrixType MatrixType; - typedef typename MatrixType::Scalar Scalar; - typedef typename MatrixType::RealScalar RealScalar; - typedef typename MatrixType::Index Index; - typedef Matrix Vector; - typedef SparseMatrix ColSpMatrix; - - public: - - PastixBase() : m_initisOk(false), m_analysisIsOk(false), m_factorizationIsOk(false), m_isInitialized(false), m_pastixdata(0), m_size(0) - { - init(); - } - - ~PastixBase() - { - clean(); - } - - /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. - * - * \sa compute() - */ - template - inline const internal::solve_retval - solve(const MatrixBase& b) const - { - eigen_assert(m_isInitialized && "Pastix solver is not initialized."); - eigen_assert(rows()==b.rows() - && "PastixBase::solve(): invalid number of rows of the right hand side matrix b"); - return internal::solve_retval(*this, b.derived()); - } - - template - bool _solve (const MatrixBase &b, MatrixBase &x) const; - - Derived& derived() - { - return *static_cast(this); - } - const Derived& derived() const - { - return *static_cast(this); - } - - /** Returns a reference to the integer vector IPARM of PaStiX parameters - * to modify the default parameters. - * The statistics related to the different phases of factorization and solve are saved here as well - * \sa analyzePattern() factorize() - */ - Array& iparm() - { - return m_iparm; - } - - /** Return a reference to a particular index parameter of the IPARM vector - * \sa iparm() - */ - - int& iparm(int idxparam) - { - return m_iparm(idxparam); - } - - /** Returns a reference to the double vector DPARM of PaStiX parameters - * The statistics related to the different phases of factorization and solve are saved here as well - * \sa analyzePattern() factorize() - */ - Array& dparm() - { - return m_dparm; - } - - - /** Return a reference to a particular index parameter of the DPARM vector - * \sa dparm() - */ - double& dparm(int idxparam) - { - return m_dparm(idxparam); - } - - inline Index cols() const { return m_size; } - inline Index rows() const { return m_size; } - - /** \brief Reports whether previous computation was successful. - * - * \returns \c Success if computation was succesful, - * \c NumericalIssue if the PaStiX reports a problem - * \c InvalidInput if the input matrix is invalid - * - * \sa iparm() - */ - ComputationInfo info() const - { - eigen_assert(m_isInitialized && "Decomposition is not initialized."); - return m_info; - } - - /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. - * - * \sa compute() - */ - template - inline const internal::sparse_solve_retval - solve(const SparseMatrixBase& b) const - { - eigen_assert(m_isInitialized && "Pastix LU, LLT or LDLT is not initialized."); - eigen_assert(rows()==b.rows() - && "PastixBase::solve(): invalid number of rows of the right hand side matrix b"); - return internal::sparse_solve_retval(*this, b.derived()); - } - - protected: - - // Initialize the Pastix data structure, check the matrix - void init(); - - // Compute the ordering and the symbolic factorization - void analyzePattern(ColSpMatrix& mat); - - // Compute the numerical factorization - void factorize(ColSpMatrix& mat); - - // Free all the data allocated by Pastix - void clean() - { - eigen_assert(m_initisOk && "The Pastix structure should be allocated first"); - m_iparm(IPARM_START_TASK) = API_TASK_CLEAN; - m_iparm(IPARM_END_TASK) = API_TASK_CLEAN; - internal::eigen_pastix(&m_pastixdata, MPI_COMM_WORLD, 0, 0, 0, (Scalar*)0, - m_perm.data(), m_invp.data(), 0, 0, m_iparm.data(), m_dparm.data()); - } - - void compute(ColSpMatrix& mat); - - int m_initisOk; - int m_analysisIsOk; - int m_factorizationIsOk; - bool m_isInitialized; - mutable ComputationInfo m_info; - mutable pastix_data_t *m_pastixdata; // Data structure for pastix - mutable int m_comm; // The MPI communicator identifier - mutable Matrix m_iparm; // integer vector for the input parameters - mutable Matrix m_dparm; // Scalar vector for the input parameters - mutable Matrix m_perm; // Permutation vector - mutable Matrix m_invp; // Inverse permutation vector - mutable int m_size; // Size of the matrix -}; - - /** Initialize the PaStiX data structure. - *A first call to this function fills iparm and dparm with the default PaStiX parameters - * \sa iparm() dparm() - */ -template -void PastixBase::init() -{ - m_size = 0; - m_iparm.setZero(IPARM_SIZE); - m_dparm.setZero(DPARM_SIZE); - - m_iparm(IPARM_MODIFY_PARAMETER) = API_NO; - pastix(&m_pastixdata, MPI_COMM_WORLD, - 0, 0, 0, 0, - 0, 0, 0, 1, m_iparm.data(), m_dparm.data()); - - m_iparm[IPARM_MATRIX_VERIFICATION] = API_NO; - m_iparm[IPARM_VERBOSE] = 2; - m_iparm[IPARM_ORDERING] = API_ORDER_SCOTCH; - m_iparm[IPARM_INCOMPLETE] = API_NO; - m_iparm[IPARM_OOC_LIMIT] = 2000; - m_iparm[IPARM_RHS_MAKING] = API_RHS_B; - m_iparm(IPARM_MATRIX_VERIFICATION) = API_NO; - - m_iparm(IPARM_START_TASK) = API_TASK_INIT; - m_iparm(IPARM_END_TASK) = API_TASK_INIT; - internal::eigen_pastix(&m_pastixdata, MPI_COMM_WORLD, 0, 0, 0, (Scalar*)0, - 0, 0, 0, 0, m_iparm.data(), m_dparm.data()); - - // Check the returned error - if(m_iparm(IPARM_ERROR_NUMBER)) { - m_info = InvalidInput; - m_initisOk = false; - } - else { - m_info = Success; - m_initisOk = true; - } -} - -template -void PastixBase::compute(ColSpMatrix& mat) -{ - eigen_assert(mat.rows() == mat.cols() && "The input matrix should be squared"); - - analyzePattern(mat); - factorize(mat); - - m_iparm(IPARM_MATRIX_VERIFICATION) = API_NO; - m_isInitialized = m_factorizationIsOk; -} - - -template -void PastixBase::analyzePattern(ColSpMatrix& mat) -{ - eigen_assert(m_initisOk && "The initialization of PaSTiX failed"); - - // clean previous calls - if(m_size>0) - clean(); - - m_size = mat.rows(); - m_perm.resize(m_size); - m_invp.resize(m_size); - - m_iparm(IPARM_START_TASK) = API_TASK_ORDERING; - m_iparm(IPARM_END_TASK) = API_TASK_ANALYSE; - internal::eigen_pastix(&m_pastixdata, MPI_COMM_WORLD, m_size, mat.outerIndexPtr(), mat.innerIndexPtr(), - mat.valuePtr(), m_perm.data(), m_invp.data(), 0, 0, m_iparm.data(), m_dparm.data()); - - // Check the returned error - if(m_iparm(IPARM_ERROR_NUMBER)) - { - m_info = NumericalIssue; - m_analysisIsOk = false; - } - else - { - m_info = Success; - m_analysisIsOk = true; - } -} - -template -void PastixBase::factorize(ColSpMatrix& mat) -{ -// if(&m_cpyMat != &mat) m_cpyMat = mat; - eigen_assert(m_analysisIsOk && "The analysis phase should be called before the factorization phase"); - m_iparm(IPARM_START_TASK) = API_TASK_NUMFACT; - m_iparm(IPARM_END_TASK) = API_TASK_NUMFACT; - m_size = mat.rows(); - - internal::eigen_pastix(&m_pastixdata, MPI_COMM_WORLD, m_size, mat.outerIndexPtr(), mat.innerIndexPtr(), - mat.valuePtr(), m_perm.data(), m_invp.data(), 0, 0, m_iparm.data(), m_dparm.data()); - - // Check the returned error - if(m_iparm(IPARM_ERROR_NUMBER)) - { - m_info = NumericalIssue; - m_factorizationIsOk = false; - m_isInitialized = false; - } - else - { - m_info = Success; - m_factorizationIsOk = true; - m_isInitialized = true; - } -} - -/* Solve the system */ -template -template -bool PastixBase::_solve (const MatrixBase &b, MatrixBase &x) const -{ - eigen_assert(m_isInitialized && "The matrix should be factorized first"); - EIGEN_STATIC_ASSERT((Dest::Flags&RowMajorBit)==0, - THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES); - int rhs = 1; - - x = b; /* on return, x is overwritten by the computed solution */ - - for (int i = 0; i < b.cols(); i++){ - m_iparm[IPARM_START_TASK] = API_TASK_SOLVE; - m_iparm[IPARM_END_TASK] = API_TASK_REFINE; - - internal::eigen_pastix(&m_pastixdata, MPI_COMM_WORLD, x.rows(), 0, 0, 0, - m_perm.data(), m_invp.data(), &x(0, i), rhs, m_iparm.data(), m_dparm.data()); - } - - // Check the returned error - m_info = m_iparm(IPARM_ERROR_NUMBER)==0 ? Success : NumericalIssue; - - return m_iparm(IPARM_ERROR_NUMBER)==0; -} - -/** \ingroup PaStiXSupport_Module - * \class PastixLU - * \brief Sparse direct LU solver based on PaStiX library - * - * This class is used to solve the linear systems A.X = B with a supernodal LU - * factorization in the PaStiX library. The matrix A should be squared and nonsingular - * PaStiX requires that the matrix A has a symmetric structural pattern. - * This interface can symmetrize the input matrix otherwise. - * The vectors or matrices X and B can be either dense or sparse. - * - * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> - * \tparam IsStrSym Indicates if the input matrix has a symmetric pattern, default is false - * NOTE : Note that if the analysis and factorization phase are called separately, - * the input matrix will be symmetrized at each call, hence it is advised to - * symmetrize the matrix in a end-user program and set \p IsStrSym to true - * - * \sa \ref TutorialSparseDirectSolvers - * - */ -template -class PastixLU : public PastixBase< PastixLU<_MatrixType> > -{ - public: - typedef _MatrixType MatrixType; - typedef PastixBase > Base; - typedef typename Base::ColSpMatrix ColSpMatrix; - typedef typename MatrixType::Index Index; - - public: - PastixLU() : Base() - { - init(); - } - - PastixLU(const MatrixType& matrix):Base() - { - init(); - compute(matrix); - } - /** Compute the LU supernodal factorization of \p matrix. - * iparm and dparm can be used to tune the PaStiX parameters. - * see the PaStiX user's manual - * \sa analyzePattern() factorize() - */ - void compute (const MatrixType& matrix) - { - m_structureIsUptodate = false; - ColSpMatrix temp; - grabMatrix(matrix, temp); - Base::compute(temp); - } - /** Compute the LU symbolic factorization of \p matrix using its sparsity pattern. - * Several ordering methods can be used at this step. See the PaStiX user's manual. - * The result of this operation can be used with successive matrices having the same pattern as \p matrix - * \sa factorize() - */ - void analyzePattern(const MatrixType& matrix) - { - m_structureIsUptodate = false; - ColSpMatrix temp; - grabMatrix(matrix, temp); - Base::analyzePattern(temp); - } - - /** Compute the LU supernodal factorization of \p matrix - * WARNING The matrix \p matrix should have the same structural pattern - * as the same used in the analysis phase. - * \sa analyzePattern() - */ - void factorize(const MatrixType& matrix) - { - ColSpMatrix temp; - grabMatrix(matrix, temp); - Base::factorize(temp); - } - protected: - - void init() - { - m_structureIsUptodate = false; - m_iparm(IPARM_SYM) = API_SYM_NO; - m_iparm(IPARM_FACTORIZATION) = API_FACT_LU; - } - - void grabMatrix(const MatrixType& matrix, ColSpMatrix& out) - { - if(IsStrSym) - out = matrix; - else - { - if(!m_structureIsUptodate) - { - // update the transposed structure - m_transposedStructure = matrix.transpose(); - - // Set the elements of the matrix to zero - for (Index j=0; j - * \tparam UpLo The part of the matrix to use : Lower or Upper. The default is Lower as required by PaStiX - * - * \sa \ref TutorialSparseDirectSolvers - */ -template -class PastixLLT : public PastixBase< PastixLLT<_MatrixType, _UpLo> > -{ - public: - typedef _MatrixType MatrixType; - typedef PastixBase > Base; - typedef typename Base::ColSpMatrix ColSpMatrix; - - public: - enum { UpLo = _UpLo }; - PastixLLT() : Base() - { - init(); - } - - PastixLLT(const MatrixType& matrix):Base() - { - init(); - compute(matrix); - } - - /** Compute the L factor of the LL^T supernodal factorization of \p matrix - * \sa analyzePattern() factorize() - */ - void compute (const MatrixType& matrix) - { - ColSpMatrix temp; - grabMatrix(matrix, temp); - Base::compute(temp); - } - - /** Compute the LL^T symbolic factorization of \p matrix using its sparsity pattern - * The result of this operation can be used with successive matrices having the same pattern as \p matrix - * \sa factorize() - */ - void analyzePattern(const MatrixType& matrix) - { - ColSpMatrix temp; - grabMatrix(matrix, temp); - Base::analyzePattern(temp); - } - /** Compute the LL^T supernodal numerical factorization of \p matrix - * \sa analyzePattern() - */ - void factorize(const MatrixType& matrix) - { - ColSpMatrix temp; - grabMatrix(matrix, temp); - Base::factorize(temp); - } - protected: - using Base::m_iparm; - - void init() - { - m_iparm(IPARM_SYM) = API_SYM_YES; - m_iparm(IPARM_FACTORIZATION) = API_FACT_LLT; - } - - void grabMatrix(const MatrixType& matrix, ColSpMatrix& out) - { - // Pastix supports only lower, column-major matrices - out.template selfadjointView() = matrix.template selfadjointView(); - internal::c_to_fortran_numbering(out); - } -}; - -/** \ingroup PaStiXSupport_Module - * \class PastixLDLT - * \brief A sparse direct supernodal Cholesky (LLT) factorization and solver based on the PaStiX library - * - * This class is used to solve the linear systems A.X = B via a LDL^T supernodal Cholesky factorization - * available in the PaStiX library. The matrix A should be symmetric and positive definite - * WARNING Selfadjoint complex matrices are not supported in the current version of PaStiX - * The vectors or matrices X and B can be either dense or sparse - * - * \tparam MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> - * \tparam UpLo The part of the matrix to use : Lower or Upper. The default is Lower as required by PaStiX - * - * \sa \ref TutorialSparseDirectSolvers - */ -template -class PastixLDLT : public PastixBase< PastixLDLT<_MatrixType, _UpLo> > -{ - public: - typedef _MatrixType MatrixType; - typedef PastixBase > Base; - typedef typename Base::ColSpMatrix ColSpMatrix; - - public: - enum { UpLo = _UpLo }; - PastixLDLT():Base() - { - init(); - } - - PastixLDLT(const MatrixType& matrix):Base() - { - init(); - compute(matrix); - } - - /** Compute the L and D factors of the LDL^T factorization of \p matrix - * \sa analyzePattern() factorize() - */ - void compute (const MatrixType& matrix) - { - ColSpMatrix temp; - grabMatrix(matrix, temp); - Base::compute(temp); - } - - /** Compute the LDL^T symbolic factorization of \p matrix using its sparsity pattern - * The result of this operation can be used with successive matrices having the same pattern as \p matrix - * \sa factorize() - */ - void analyzePattern(const MatrixType& matrix) - { - ColSpMatrix temp; - grabMatrix(matrix, temp); - Base::analyzePattern(temp); - } - /** Compute the LDL^T supernodal numerical factorization of \p matrix - * - */ - void factorize(const MatrixType& matrix) - { - ColSpMatrix temp; - grabMatrix(matrix, temp); - Base::factorize(temp); - } - - protected: - using Base::m_iparm; - - void init() - { - m_iparm(IPARM_SYM) = API_SYM_YES; - m_iparm(IPARM_FACTORIZATION) = API_FACT_LDLT; - } - - void grabMatrix(const MatrixType& matrix, ColSpMatrix& out) - { - // Pastix supports only lower, column-major matrices - out.template selfadjointView() = matrix.template selfadjointView(); - internal::c_to_fortran_numbering(out); - } -}; - -namespace internal { - -template -struct solve_retval, Rhs> - : solve_retval_base, Rhs> -{ - typedef PastixBase<_MatrixType> Dec; - EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs) - - template void evalTo(Dest& dst) const - { - dec()._solve(rhs(),dst); - } -}; - -template -struct sparse_solve_retval, Rhs> - : sparse_solve_retval_base, Rhs> -{ - typedef PastixBase<_MatrixType> Dec; - EIGEN_MAKE_SPARSE_SOLVE_HELPERS(Dec,Rhs) - - template void evalTo(Dest& dst) const - { - this->defaultEvalTo(dst); - } -}; - -} // end namespace internal - -} // end namespace Eigen - -#endif diff --git a/thirdparty/eigen-3.2.7/Eigen/src/PardisoSupport/PardisoSupport.h b/thirdparty/eigen-3.2.7/Eigen/src/PardisoSupport/PardisoSupport.h deleted file mode 100644 index 18cd7d88..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/PardisoSupport/PardisoSupport.h +++ /dev/null @@ -1,592 +0,0 @@ -/* - Copyright (c) 2011, Intel Corporation. All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of Intel Corporation nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - ******************************************************************************** - * Content : Eigen bindings to Intel(R) MKL PARDISO - ******************************************************************************** -*/ - -#ifndef EIGEN_PARDISOSUPPORT_H -#define EIGEN_PARDISOSUPPORT_H - -namespace Eigen { - -template class PardisoLU; -template class PardisoLLT; -template class PardisoLDLT; - -namespace internal -{ - template - struct pardiso_run_selector - { - static Index run( _MKL_DSS_HANDLE_t pt, Index maxfct, Index mnum, Index type, Index phase, Index n, void *a, - Index *ia, Index *ja, Index *perm, Index nrhs, Index *iparm, Index msglvl, void *b, void *x) - { - Index error = 0; - ::pardiso(pt, &maxfct, &mnum, &type, &phase, &n, a, ia, ja, perm, &nrhs, iparm, &msglvl, b, x, &error); - return error; - } - }; - template<> - struct pardiso_run_selector - { - typedef long long int Index; - static Index run( _MKL_DSS_HANDLE_t pt, Index maxfct, Index mnum, Index type, Index phase, Index n, void *a, - Index *ia, Index *ja, Index *perm, Index nrhs, Index *iparm, Index msglvl, void *b, void *x) - { - Index error = 0; - ::pardiso_64(pt, &maxfct, &mnum, &type, &phase, &n, a, ia, ja, perm, &nrhs, iparm, &msglvl, b, x, &error); - return error; - } - }; - - template struct pardiso_traits; - - template - struct pardiso_traits< PardisoLU<_MatrixType> > - { - typedef _MatrixType MatrixType; - typedef typename _MatrixType::Scalar Scalar; - typedef typename _MatrixType::RealScalar RealScalar; - typedef typename _MatrixType::Index Index; - }; - - template - struct pardiso_traits< PardisoLLT<_MatrixType, Options> > - { - typedef _MatrixType MatrixType; - typedef typename _MatrixType::Scalar Scalar; - typedef typename _MatrixType::RealScalar RealScalar; - typedef typename _MatrixType::Index Index; - }; - - template - struct pardiso_traits< PardisoLDLT<_MatrixType, Options> > - { - typedef _MatrixType MatrixType; - typedef typename _MatrixType::Scalar Scalar; - typedef typename _MatrixType::RealScalar RealScalar; - typedef typename _MatrixType::Index Index; - }; - -} - -template -class PardisoImpl -{ - typedef internal::pardiso_traits Traits; - public: - typedef typename Traits::MatrixType MatrixType; - typedef typename Traits::Scalar Scalar; - typedef typename Traits::RealScalar RealScalar; - typedef typename Traits::Index Index; - typedef SparseMatrix SparseMatrixType; - typedef Matrix VectorType; - typedef Matrix IntRowVectorType; - typedef Matrix IntColVectorType; - typedef Array ParameterType; - enum { - ScalarIsComplex = NumTraits::IsComplex - }; - - PardisoImpl() - { - eigen_assert((sizeof(Index) >= sizeof(_INTEGER_t) && sizeof(Index) <= 8) && "Non-supported index type"); - m_iparm.setZero(); - m_msglvl = 0; // No output - m_initialized = false; - } - - ~PardisoImpl() - { - pardisoRelease(); - } - - inline Index cols() const { return m_size; } - inline Index rows() const { return m_size; } - - /** \brief Reports whether previous computation was successful. - * - * \returns \c Success if computation was succesful, - * \c NumericalIssue if the matrix appears to be negative. - */ - ComputationInfo info() const - { - eigen_assert(m_initialized && "Decomposition is not initialized."); - return m_info; - } - - /** \warning for advanced usage only. - * \returns a reference to the parameter array controlling PARDISO. - * See the PARDISO manual to know how to use it. */ - ParameterType& pardisoParameterArray() - { - return m_iparm; - } - - /** Performs a symbolic decomposition on the sparcity of \a matrix. - * - * This function is particularly useful when solving for several problems having the same structure. - * - * \sa factorize() - */ - Derived& analyzePattern(const MatrixType& matrix); - - /** Performs a numeric decomposition of \a matrix - * - * The given matrix must has the same sparcity than the matrix on which the symbolic decomposition has been performed. - * - * \sa analyzePattern() - */ - Derived& factorize(const MatrixType& matrix); - - Derived& compute(const MatrixType& matrix); - - /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. - * - * \sa compute() - */ - template - inline const internal::solve_retval - solve(const MatrixBase& b) const - { - eigen_assert(m_initialized && "Pardiso solver is not initialized."); - eigen_assert(rows()==b.rows() - && "PardisoImpl::solve(): invalid number of rows of the right hand side matrix b"); - return internal::solve_retval(*this, b.derived()); - } - - /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. - * - * \sa compute() - */ - template - inline const internal::sparse_solve_retval - solve(const SparseMatrixBase& b) const - { - eigen_assert(m_initialized && "Pardiso solver is not initialized."); - eigen_assert(rows()==b.rows() - && "PardisoImpl::solve(): invalid number of rows of the right hand side matrix b"); - return internal::sparse_solve_retval(*this, b.derived()); - } - - Derived& derived() - { - return *static_cast(this); - } - const Derived& derived() const - { - return *static_cast(this); - } - - template - bool _solve(const MatrixBase &b, MatrixBase& x) const; - - protected: - void pardisoRelease() - { - if(m_initialized) // Factorization ran at least once - { - internal::pardiso_run_selector::run(m_pt, 1, 1, m_type, -1, m_size, 0, 0, 0, m_perm.data(), 0, - m_iparm.data(), m_msglvl, 0, 0); - } - } - - void pardisoInit(int type) - { - m_type = type; - bool symmetric = std::abs(m_type) < 10; - m_iparm[0] = 1; // No solver default - m_iparm[1] = 3; // use Metis for the ordering - m_iparm[2] = 1; // Numbers of processors, value of OMP_NUM_THREADS - m_iparm[3] = 0; // No iterative-direct algorithm - m_iparm[4] = 0; // No user fill-in reducing permutation - m_iparm[5] = 0; // Write solution into x - m_iparm[6] = 0; // Not in use - m_iparm[7] = 2; // Max numbers of iterative refinement steps - m_iparm[8] = 0; // Not in use - m_iparm[9] = 13; // Perturb the pivot elements with 1E-13 - m_iparm[10] = symmetric ? 0 : 1; // Use nonsymmetric permutation and scaling MPS - m_iparm[11] = 0; // Not in use - m_iparm[12] = symmetric ? 0 : 1; // Maximum weighted matching algorithm is switched-off (default for symmetric). - // Try m_iparm[12] = 1 in case of inappropriate accuracy - m_iparm[13] = 0; // Output: Number of perturbed pivots - m_iparm[14] = 0; // Not in use - m_iparm[15] = 0; // Not in use - m_iparm[16] = 0; // Not in use - m_iparm[17] = -1; // Output: Number of nonzeros in the factor LU - m_iparm[18] = -1; // Output: Mflops for LU factorization - m_iparm[19] = 0; // Output: Numbers of CG Iterations - - m_iparm[20] = 0; // 1x1 pivoting - m_iparm[26] = 0; // No matrix checker - m_iparm[27] = (sizeof(RealScalar) == 4) ? 1 : 0; - m_iparm[34] = 1; // C indexing - m_iparm[59] = 1; // Automatic switch between In-Core and Out-of-Core modes - } - - protected: - // cached data to reduce reallocation, etc. - - void manageErrorCode(Index error) - { - switch(error) - { - case 0: - m_info = Success; - break; - case -4: - case -7: - m_info = NumericalIssue; - break; - default: - m_info = InvalidInput; - } - } - - mutable SparseMatrixType m_matrix; - ComputationInfo m_info; - bool m_initialized, m_analysisIsOk, m_factorizationIsOk; - Index m_type, m_msglvl; - mutable void *m_pt[64]; - mutable ParameterType m_iparm; - mutable IntColVectorType m_perm; - Index m_size; - - private: - PardisoImpl(PardisoImpl &) {} -}; - -template -Derived& PardisoImpl::compute(const MatrixType& a) -{ - m_size = a.rows(); - eigen_assert(a.rows() == a.cols()); - - pardisoRelease(); - memset(m_pt, 0, sizeof(m_pt)); - m_perm.setZero(m_size); - derived().getMatrix(a); - - Index error; - error = internal::pardiso_run_selector::run(m_pt, 1, 1, m_type, 12, m_size, - m_matrix.valuePtr(), m_matrix.outerIndexPtr(), m_matrix.innerIndexPtr(), - m_perm.data(), 0, m_iparm.data(), m_msglvl, NULL, NULL); - - manageErrorCode(error); - m_analysisIsOk = true; - m_factorizationIsOk = true; - m_initialized = true; - return derived(); -} - -template -Derived& PardisoImpl::analyzePattern(const MatrixType& a) -{ - m_size = a.rows(); - eigen_assert(m_size == a.cols()); - - pardisoRelease(); - memset(m_pt, 0, sizeof(m_pt)); - m_perm.setZero(m_size); - derived().getMatrix(a); - - Index error; - error = internal::pardiso_run_selector::run(m_pt, 1, 1, m_type, 11, m_size, - m_matrix.valuePtr(), m_matrix.outerIndexPtr(), m_matrix.innerIndexPtr(), - m_perm.data(), 0, m_iparm.data(), m_msglvl, NULL, NULL); - - manageErrorCode(error); - m_analysisIsOk = true; - m_factorizationIsOk = false; - m_initialized = true; - return derived(); -} - -template -Derived& PardisoImpl::factorize(const MatrixType& a) -{ - eigen_assert(m_analysisIsOk && "You must first call analyzePattern()"); - eigen_assert(m_size == a.rows() && m_size == a.cols()); - - derived().getMatrix(a); - - Index error; - error = internal::pardiso_run_selector::run(m_pt, 1, 1, m_type, 22, m_size, - m_matrix.valuePtr(), m_matrix.outerIndexPtr(), m_matrix.innerIndexPtr(), - m_perm.data(), 0, m_iparm.data(), m_msglvl, NULL, NULL); - - manageErrorCode(error); - m_factorizationIsOk = true; - return derived(); -} - -template -template -bool PardisoImpl::_solve(const MatrixBase &b, MatrixBase& x) const -{ - if(m_iparm[0] == 0) // Factorization was not computed - return false; - - //Index n = m_matrix.rows(); - Index nrhs = Index(b.cols()); - eigen_assert(m_size==b.rows()); - eigen_assert(((MatrixBase::Flags & RowMajorBit) == 0 || nrhs == 1) && "Row-major right hand sides are not supported"); - eigen_assert(((MatrixBase::Flags & RowMajorBit) == 0 || nrhs == 1) && "Row-major matrices of unknowns are not supported"); - eigen_assert(((nrhs == 1) || b.outerStride() == b.rows())); - - -// switch (transposed) { -// case SvNoTrans : m_iparm[11] = 0 ; break; -// case SvTranspose : m_iparm[11] = 2 ; break; -// case SvAdjoint : m_iparm[11] = 1 ; break; -// default: -// //std::cerr << "Eigen: transposition option \"" << transposed << "\" not supported by the PARDISO backend\n"; -// m_iparm[11] = 0; -// } - - Scalar* rhs_ptr = const_cast(b.derived().data()); - Matrix tmp; - - // Pardiso cannot solve in-place - if(rhs_ptr == x.derived().data()) - { - tmp = b; - rhs_ptr = tmp.data(); - } - - Index error; - error = internal::pardiso_run_selector::run(m_pt, 1, 1, m_type, 33, m_size, - m_matrix.valuePtr(), m_matrix.outerIndexPtr(), m_matrix.innerIndexPtr(), - m_perm.data(), nrhs, m_iparm.data(), m_msglvl, - rhs_ptr, x.derived().data()); - - return error==0; -} - - -/** \ingroup PardisoSupport_Module - * \class PardisoLU - * \brief A sparse direct LU factorization and solver based on the PARDISO library - * - * This class allows to solve for A.X = B sparse linear problems via a direct LU factorization - * using the Intel MKL PARDISO library. The sparse matrix A must be squared and invertible. - * The vectors or matrices X and B can be either dense or sparse. - * - * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> - * - * \sa \ref TutorialSparseDirectSolvers - */ -template -class PardisoLU : public PardisoImpl< PardisoLU > -{ - protected: - typedef PardisoImpl< PardisoLU > Base; - typedef typename Base::Scalar Scalar; - typedef typename Base::RealScalar RealScalar; - using Base::pardisoInit; - using Base::m_matrix; - friend class PardisoImpl< PardisoLU >; - - public: - - using Base::compute; - using Base::solve; - - PardisoLU() - : Base() - { - pardisoInit(Base::ScalarIsComplex ? 13 : 11); - } - - PardisoLU(const MatrixType& matrix) - : Base() - { - pardisoInit(Base::ScalarIsComplex ? 13 : 11); - compute(matrix); - } - protected: - void getMatrix(const MatrixType& matrix) - { - m_matrix = matrix; - } - - private: - PardisoLU(PardisoLU& ) {} -}; - -/** \ingroup PardisoSupport_Module - * \class PardisoLLT - * \brief A sparse direct Cholesky (LLT) factorization and solver based on the PARDISO library - * - * This class allows to solve for A.X = B sparse linear problems via a LL^T Cholesky factorization - * using the Intel MKL PARDISO library. The sparse matrix A must be selfajoint and positive definite. - * The vectors or matrices X and B can be either dense or sparse. - * - * \tparam MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> - * \tparam UpLo can be any bitwise combination of Upper, Lower. The default is Upper, meaning only the upper triangular part has to be used. - * Upper|Lower can be used to tell both triangular parts can be used as input. - * - * \sa \ref TutorialSparseDirectSolvers - */ -template -class PardisoLLT : public PardisoImpl< PardisoLLT > -{ - protected: - typedef PardisoImpl< PardisoLLT > Base; - typedef typename Base::Scalar Scalar; - typedef typename Base::Index Index; - typedef typename Base::RealScalar RealScalar; - using Base::pardisoInit; - using Base::m_matrix; - friend class PardisoImpl< PardisoLLT >; - - public: - - enum { UpLo = _UpLo }; - using Base::compute; - using Base::solve; - - PardisoLLT() - : Base() - { - pardisoInit(Base::ScalarIsComplex ? 4 : 2); - } - - PardisoLLT(const MatrixType& matrix) - : Base() - { - pardisoInit(Base::ScalarIsComplex ? 4 : 2); - compute(matrix); - } - - protected: - - void getMatrix(const MatrixType& matrix) - { - // PARDISO supports only upper, row-major matrices - PermutationMatrix p_null; - m_matrix.resize(matrix.rows(), matrix.cols()); - m_matrix.template selfadjointView() = matrix.template selfadjointView().twistedBy(p_null); - } - - private: - PardisoLLT(PardisoLLT& ) {} -}; - -/** \ingroup PardisoSupport_Module - * \class PardisoLDLT - * \brief A sparse direct Cholesky (LDLT) factorization and solver based on the PARDISO library - * - * This class allows to solve for A.X = B sparse linear problems via a LDL^T Cholesky factorization - * using the Intel MKL PARDISO library. The sparse matrix A is assumed to be selfajoint and positive definite. - * For complex matrices, A can also be symmetric only, see the \a Options template parameter. - * The vectors or matrices X and B can be either dense or sparse. - * - * \tparam MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> - * \tparam Options can be any bitwise combination of Upper, Lower, and Symmetric. The default is Upper, meaning only the upper triangular part has to be used. - * Symmetric can be used for symmetric, non-selfadjoint complex matrices, the default being to assume a selfadjoint matrix. - * Upper|Lower can be used to tell both triangular parts can be used as input. - * - * \sa \ref TutorialSparseDirectSolvers - */ -template -class PardisoLDLT : public PardisoImpl< PardisoLDLT > -{ - protected: - typedef PardisoImpl< PardisoLDLT > Base; - typedef typename Base::Scalar Scalar; - typedef typename Base::Index Index; - typedef typename Base::RealScalar RealScalar; - using Base::pardisoInit; - using Base::m_matrix; - friend class PardisoImpl< PardisoLDLT >; - - public: - - using Base::compute; - using Base::solve; - enum { UpLo = Options&(Upper|Lower) }; - - PardisoLDLT() - : Base() - { - pardisoInit(Base::ScalarIsComplex ? ( bool(Options&Symmetric) ? 6 : -4 ) : -2); - } - - PardisoLDLT(const MatrixType& matrix) - : Base() - { - pardisoInit(Base::ScalarIsComplex ? ( bool(Options&Symmetric) ? 6 : -4 ) : -2); - compute(matrix); - } - - void getMatrix(const MatrixType& matrix) - { - // PARDISO supports only upper, row-major matrices - PermutationMatrix p_null; - m_matrix.resize(matrix.rows(), matrix.cols()); - m_matrix.template selfadjointView() = matrix.template selfadjointView().twistedBy(p_null); - } - - private: - PardisoLDLT(PardisoLDLT& ) {} -}; - -namespace internal { - -template -struct solve_retval, Rhs> - : solve_retval_base, Rhs> -{ - typedef PardisoImpl<_Derived> Dec; - EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs) - - template void evalTo(Dest& dst) const - { - dec()._solve(rhs(),dst); - } -}; - -template -struct sparse_solve_retval, Rhs> - : sparse_solve_retval_base, Rhs> -{ - typedef PardisoImpl Dec; - EIGEN_MAKE_SPARSE_SOLVE_HELPERS(Dec,Rhs) - - template void evalTo(Dest& dst) const - { - this->defaultEvalTo(dst); - } -}; - -} // end namespace internal - -} // end namespace Eigen - -#endif // EIGEN_PARDISOSUPPORT_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/QR/ColPivHouseholderQR.h b/thirdparty/eigen-3.2.7/Eigen/src/QR/ColPivHouseholderQR.h deleted file mode 100644 index 567eab7c..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/QR/ColPivHouseholderQR.h +++ /dev/null @@ -1,580 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2009 Gael Guennebaud -// Copyright (C) 2009 Benoit Jacob -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_COLPIVOTINGHOUSEHOLDERQR_H -#define EIGEN_COLPIVOTINGHOUSEHOLDERQR_H - -namespace Eigen { - -/** \ingroup QR_Module - * - * \class ColPivHouseholderQR - * - * \brief Householder rank-revealing QR decomposition of a matrix with column-pivoting - * - * \param MatrixType the type of the matrix of which we are computing the QR decomposition - * - * This class performs a rank-revealing QR decomposition of a matrix \b A into matrices \b P, \b Q and \b R - * such that - * \f[ - * \mathbf{A} \, \mathbf{P} = \mathbf{Q} \, \mathbf{R} - * \f] - * by using Householder transformations. Here, \b P is a permutation matrix, \b Q a unitary matrix and \b R an - * upper triangular matrix. - * - * This decomposition performs column pivoting in order to be rank-revealing and improve - * numerical stability. It is slower than HouseholderQR, and faster than FullPivHouseholderQR. - * - * \sa MatrixBase::colPivHouseholderQr() - */ -template class ColPivHouseholderQR -{ - public: - - typedef _MatrixType MatrixType; - enum { - RowsAtCompileTime = MatrixType::RowsAtCompileTime, - ColsAtCompileTime = MatrixType::ColsAtCompileTime, - Options = MatrixType::Options, - MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime, - MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime - }; - typedef typename MatrixType::Scalar Scalar; - typedef typename MatrixType::RealScalar RealScalar; - typedef typename MatrixType::Index Index; - typedef Matrix MatrixQType; - typedef typename internal::plain_diag_type::type HCoeffsType; - typedef PermutationMatrix PermutationType; - typedef typename internal::plain_row_type::type IntRowVectorType; - typedef typename internal::plain_row_type::type RowVectorType; - typedef typename internal::plain_row_type::type RealRowVectorType; - typedef HouseholderSequence::type> HouseholderSequenceType; - - private: - - typedef typename PermutationType::Index PermIndexType; - - public: - - /** - * \brief Default Constructor. - * - * The default constructor is useful in cases in which the user intends to - * perform decompositions via ColPivHouseholderQR::compute(const MatrixType&). - */ - ColPivHouseholderQR() - : m_qr(), - m_hCoeffs(), - m_colsPermutation(), - m_colsTranspositions(), - m_temp(), - m_colSqNorms(), - m_isInitialized(false), - m_usePrescribedThreshold(false) {} - - /** \brief Default Constructor with memory preallocation - * - * Like the default constructor but with preallocation of the internal data - * according to the specified problem \a size. - * \sa ColPivHouseholderQR() - */ - ColPivHouseholderQR(Index rows, Index cols) - : m_qr(rows, cols), - m_hCoeffs((std::min)(rows,cols)), - m_colsPermutation(PermIndexType(cols)), - m_colsTranspositions(cols), - m_temp(cols), - m_colSqNorms(cols), - m_isInitialized(false), - m_usePrescribedThreshold(false) {} - - /** \brief Constructs a QR factorization from a given matrix - * - * This constructor computes the QR factorization of the matrix \a matrix by calling - * the method compute(). It is a short cut for: - * - * \code - * ColPivHouseholderQR qr(matrix.rows(), matrix.cols()); - * qr.compute(matrix); - * \endcode - * - * \sa compute() - */ - ColPivHouseholderQR(const MatrixType& matrix) - : m_qr(matrix.rows(), matrix.cols()), - m_hCoeffs((std::min)(matrix.rows(),matrix.cols())), - m_colsPermutation(PermIndexType(matrix.cols())), - m_colsTranspositions(matrix.cols()), - m_temp(matrix.cols()), - m_colSqNorms(matrix.cols()), - m_isInitialized(false), - m_usePrescribedThreshold(false) - { - compute(matrix); - } - - /** This method finds a solution x to the equation Ax=b, where A is the matrix of which - * *this is the QR decomposition, if any exists. - * - * \param b the right-hand-side of the equation to solve. - * - * \returns a solution. - * - * \note The case where b is a matrix is not yet implemented. Also, this - * code is space inefficient. - * - * \note_about_checking_solutions - * - * \note_about_arbitrary_choice_of_solution - * - * Example: \include ColPivHouseholderQR_solve.cpp - * Output: \verbinclude ColPivHouseholderQR_solve.out - */ - template - inline const internal::solve_retval - solve(const MatrixBase& b) const - { - eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized."); - return internal::solve_retval(*this, b.derived()); - } - - HouseholderSequenceType householderQ(void) const; - HouseholderSequenceType matrixQ(void) const - { - return householderQ(); - } - - /** \returns a reference to the matrix where the Householder QR decomposition is stored - */ - const MatrixType& matrixQR() const - { - eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized."); - return m_qr; - } - - /** \returns a reference to the matrix where the result Householder QR is stored - * \warning The strict lower part of this matrix contains internal values. - * Only the upper triangular part should be referenced. To get it, use - * \code matrixR().template triangularView() \endcode - * For rank-deficient matrices, use - * \code - * matrixR().topLeftCorner(rank(), rank()).template triangularView() - * \endcode - */ - const MatrixType& matrixR() const - { - eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized."); - return m_qr; - } - - ColPivHouseholderQR& compute(const MatrixType& matrix); - - /** \returns a const reference to the column permutation matrix */ - const PermutationType& colsPermutation() const - { - eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized."); - return m_colsPermutation; - } - - /** \returns the absolute value of the determinant of the matrix of which - * *this is the QR decomposition. It has only linear complexity - * (that is, O(n) where n is the dimension of the square matrix) - * as the QR decomposition has already been computed. - * - * \note This is only for square matrices. - * - * \warning a determinant can be very big or small, so for matrices - * of large enough dimension, there is a risk of overflow/underflow. - * One way to work around that is to use logAbsDeterminant() instead. - * - * \sa logAbsDeterminant(), MatrixBase::determinant() - */ - typename MatrixType::RealScalar absDeterminant() const; - - /** \returns the natural log of the absolute value of the determinant of the matrix of which - * *this is the QR decomposition. It has only linear complexity - * (that is, O(n) where n is the dimension of the square matrix) - * as the QR decomposition has already been computed. - * - * \note This is only for square matrices. - * - * \note This method is useful to work around the risk of overflow/underflow that's inherent - * to determinant computation. - * - * \sa absDeterminant(), MatrixBase::determinant() - */ - typename MatrixType::RealScalar logAbsDeterminant() const; - - /** \returns the rank of the matrix of which *this is the QR decomposition. - * - * \note This method has to determine which pivots should be considered nonzero. - * For that, it uses the threshold value that you can control by calling - * setThreshold(const RealScalar&). - */ - inline Index rank() const - { - using std::abs; - eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized."); - RealScalar premultiplied_threshold = abs(m_maxpivot) * threshold(); - Index result = 0; - for(Index i = 0; i < m_nonzero_pivots; ++i) - result += (abs(m_qr.coeff(i,i)) > premultiplied_threshold); - return result; - } - - /** \returns the dimension of the kernel of the matrix of which *this is the QR decomposition. - * - * \note This method has to determine which pivots should be considered nonzero. - * For that, it uses the threshold value that you can control by calling - * setThreshold(const RealScalar&). - */ - inline Index dimensionOfKernel() const - { - eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized."); - return cols() - rank(); - } - - /** \returns true if the matrix of which *this is the QR decomposition represents an injective - * linear map, i.e. has trivial kernel; false otherwise. - * - * \note This method has to determine which pivots should be considered nonzero. - * For that, it uses the threshold value that you can control by calling - * setThreshold(const RealScalar&). - */ - inline bool isInjective() const - { - eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized."); - return rank() == cols(); - } - - /** \returns true if the matrix of which *this is the QR decomposition represents a surjective - * linear map; false otherwise. - * - * \note This method has to determine which pivots should be considered nonzero. - * For that, it uses the threshold value that you can control by calling - * setThreshold(const RealScalar&). - */ - inline bool isSurjective() const - { - eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized."); - return rank() == rows(); - } - - /** \returns true if the matrix of which *this is the QR decomposition is invertible. - * - * \note This method has to determine which pivots should be considered nonzero. - * For that, it uses the threshold value that you can control by calling - * setThreshold(const RealScalar&). - */ - inline bool isInvertible() const - { - eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized."); - return isInjective() && isSurjective(); - } - - /** \returns the inverse of the matrix of which *this is the QR decomposition. - * - * \note If this matrix is not invertible, the returned matrix has undefined coefficients. - * Use isInvertible() to first determine whether this matrix is invertible. - */ - inline const - internal::solve_retval - inverse() const - { - eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized."); - return internal::solve_retval - (*this, MatrixType::Identity(m_qr.rows(), m_qr.cols())); - } - - inline Index rows() const { return m_qr.rows(); } - inline Index cols() const { return m_qr.cols(); } - - /** \returns a const reference to the vector of Householder coefficients used to represent the factor \c Q. - * - * For advanced uses only. - */ - const HCoeffsType& hCoeffs() const { return m_hCoeffs; } - - /** Allows to prescribe a threshold to be used by certain methods, such as rank(), - * who need to determine when pivots are to be considered nonzero. This is not used for the - * QR decomposition itself. - * - * When it needs to get the threshold value, Eigen calls threshold(). By default, this - * uses a formula to automatically determine a reasonable threshold. - * Once you have called the present method setThreshold(const RealScalar&), - * your value is used instead. - * - * \param threshold The new value to use as the threshold. - * - * A pivot will be considered nonzero if its absolute value is strictly greater than - * \f$ \vert pivot \vert \leqslant threshold \times \vert maxpivot \vert \f$ - * where maxpivot is the biggest pivot. - * - * If you want to come back to the default behavior, call setThreshold(Default_t) - */ - ColPivHouseholderQR& setThreshold(const RealScalar& threshold) - { - m_usePrescribedThreshold = true; - m_prescribedThreshold = threshold; - return *this; - } - - /** Allows to come back to the default behavior, letting Eigen use its default formula for - * determining the threshold. - * - * You should pass the special object Eigen::Default as parameter here. - * \code qr.setThreshold(Eigen::Default); \endcode - * - * See the documentation of setThreshold(const RealScalar&). - */ - ColPivHouseholderQR& setThreshold(Default_t) - { - m_usePrescribedThreshold = false; - return *this; - } - - /** Returns the threshold that will be used by certain methods such as rank(). - * - * See the documentation of setThreshold(const RealScalar&). - */ - RealScalar threshold() const - { - eigen_assert(m_isInitialized || m_usePrescribedThreshold); - return m_usePrescribedThreshold ? m_prescribedThreshold - // this formula comes from experimenting (see "LU precision tuning" thread on the list) - // and turns out to be identical to Higham's formula used already in LDLt. - : NumTraits::epsilon() * RealScalar(m_qr.diagonalSize()); - } - - /** \returns the number of nonzero pivots in the QR decomposition. - * Here nonzero is meant in the exact sense, not in a fuzzy sense. - * So that notion isn't really intrinsically interesting, but it is - * still useful when implementing algorithms. - * - * \sa rank() - */ - inline Index nonzeroPivots() const - { - eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized."); - return m_nonzero_pivots; - } - - /** \returns the absolute value of the biggest pivot, i.e. the biggest - * diagonal coefficient of R. - */ - RealScalar maxPivot() const { return m_maxpivot; } - - /** \brief Reports whether the QR factorization was succesful. - * - * \note This function always returns \c Success. It is provided for compatibility - * with other factorization routines. - * \returns \c Success - */ - ComputationInfo info() const - { - eigen_assert(m_isInitialized && "Decomposition is not initialized."); - return Success; - } - - protected: - - static void check_template_parameters() - { - EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar); - } - - MatrixType m_qr; - HCoeffsType m_hCoeffs; - PermutationType m_colsPermutation; - IntRowVectorType m_colsTranspositions; - RowVectorType m_temp; - RealRowVectorType m_colSqNorms; - bool m_isInitialized, m_usePrescribedThreshold; - RealScalar m_prescribedThreshold, m_maxpivot; - Index m_nonzero_pivots; - Index m_det_pq; -}; - -template -typename MatrixType::RealScalar ColPivHouseholderQR::absDeterminant() const -{ - using std::abs; - eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized."); - eigen_assert(m_qr.rows() == m_qr.cols() && "You can't take the determinant of a non-square matrix!"); - return abs(m_qr.diagonal().prod()); -} - -template -typename MatrixType::RealScalar ColPivHouseholderQR::logAbsDeterminant() const -{ - eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized."); - eigen_assert(m_qr.rows() == m_qr.cols() && "You can't take the determinant of a non-square matrix!"); - return m_qr.diagonal().cwiseAbs().array().log().sum(); -} - -/** Performs the QR factorization of the given matrix \a matrix. The result of - * the factorization is stored into \c *this, and a reference to \c *this - * is returned. - * - * \sa class ColPivHouseholderQR, ColPivHouseholderQR(const MatrixType&) - */ -template -ColPivHouseholderQR& ColPivHouseholderQR::compute(const MatrixType& matrix) -{ - check_template_parameters(); - - using std::abs; - Index rows = matrix.rows(); - Index cols = matrix.cols(); - Index size = matrix.diagonalSize(); - - // the column permutation is stored as int indices, so just to be sure: - eigen_assert(cols<=NumTraits::highest()); - - m_qr = matrix; - m_hCoeffs.resize(size); - - m_temp.resize(cols); - - m_colsTranspositions.resize(matrix.cols()); - Index number_of_transpositions = 0; - - m_colSqNorms.resize(cols); - for(Index k = 0; k < cols; ++k) - m_colSqNorms.coeffRef(k) = m_qr.col(k).squaredNorm(); - - RealScalar threshold_helper = m_colSqNorms.maxCoeff() * numext::abs2(NumTraits::epsilon()) / RealScalar(rows); - - m_nonzero_pivots = size; // the generic case is that in which all pivots are nonzero (invertible case) - m_maxpivot = RealScalar(0); - - for(Index k = 0; k < size; ++k) - { - // first, we look up in our table m_colSqNorms which column has the biggest squared norm - Index biggest_col_index; - RealScalar biggest_col_sq_norm = m_colSqNorms.tail(cols-k).maxCoeff(&biggest_col_index); - biggest_col_index += k; - - // since our table m_colSqNorms accumulates imprecision at every step, we must now recompute - // the actual squared norm of the selected column. - // Note that not doing so does result in solve() sometimes returning inf/nan values - // when running the unit test with 1000 repetitions. - biggest_col_sq_norm = m_qr.col(biggest_col_index).tail(rows-k).squaredNorm(); - - // we store that back into our table: it can't hurt to correct our table. - m_colSqNorms.coeffRef(biggest_col_index) = biggest_col_sq_norm; - - // Track the number of meaningful pivots but do not stop the decomposition to make - // sure that the initial matrix is properly reproduced. See bug 941. - if(m_nonzero_pivots==size && biggest_col_sq_norm < threshold_helper * RealScalar(rows-k)) - m_nonzero_pivots = k; - - // apply the transposition to the columns - m_colsTranspositions.coeffRef(k) = biggest_col_index; - if(k != biggest_col_index) { - m_qr.col(k).swap(m_qr.col(biggest_col_index)); - std::swap(m_colSqNorms.coeffRef(k), m_colSqNorms.coeffRef(biggest_col_index)); - ++number_of_transpositions; - } - - // generate the householder vector, store it below the diagonal - RealScalar beta; - m_qr.col(k).tail(rows-k).makeHouseholderInPlace(m_hCoeffs.coeffRef(k), beta); - - // apply the householder transformation to the diagonal coefficient - m_qr.coeffRef(k,k) = beta; - - // remember the maximum absolute value of diagonal coefficients - if(abs(beta) > m_maxpivot) m_maxpivot = abs(beta); - - // apply the householder transformation - m_qr.bottomRightCorner(rows-k, cols-k-1) - .applyHouseholderOnTheLeft(m_qr.col(k).tail(rows-k-1), m_hCoeffs.coeffRef(k), &m_temp.coeffRef(k+1)); - - // update our table of squared norms of the columns - m_colSqNorms.tail(cols-k-1) -= m_qr.row(k).tail(cols-k-1).cwiseAbs2(); - } - - m_colsPermutation.setIdentity(PermIndexType(cols)); - for(PermIndexType k = 0; k < size/*m_nonzero_pivots*/; ++k) - m_colsPermutation.applyTranspositionOnTheRight(k, PermIndexType(m_colsTranspositions.coeff(k))); - - m_det_pq = (number_of_transpositions%2) ? -1 : 1; - m_isInitialized = true; - - return *this; -} - -namespace internal { - -template -struct solve_retval, Rhs> - : solve_retval_base, Rhs> -{ - EIGEN_MAKE_SOLVE_HELPERS(ColPivHouseholderQR<_MatrixType>,Rhs) - - template void evalTo(Dest& dst) const - { - eigen_assert(rhs().rows() == dec().rows()); - - const Index cols = dec().cols(), - nonzero_pivots = dec().nonzeroPivots(); - - if(nonzero_pivots == 0) - { - dst.setZero(); - return; - } - - typename Rhs::PlainObject c(rhs()); - - // Note that the matrix Q = H_0^* H_1^*... so its inverse is Q^* = (H_0 H_1 ...)^T - c.applyOnTheLeft(householderSequence(dec().matrixQR(), dec().hCoeffs()) - .setLength(dec().nonzeroPivots()) - .transpose() - ); - - dec().matrixR() - .topLeftCorner(nonzero_pivots, nonzero_pivots) - .template triangularView() - .solveInPlace(c.topRows(nonzero_pivots)); - - for(Index i = 0; i < nonzero_pivots; ++i) dst.row(dec().colsPermutation().indices().coeff(i)) = c.row(i); - for(Index i = nonzero_pivots; i < cols; ++i) dst.row(dec().colsPermutation().indices().coeff(i)).setZero(); - } -}; - -} // end namespace internal - -/** \returns the matrix Q as a sequence of householder transformations. - * You can extract the meaningful part only by using: - * \code qr.householderQ().setLength(qr.nonzeroPivots()) \endcode*/ -template -typename ColPivHouseholderQR::HouseholderSequenceType ColPivHouseholderQR - ::householderQ() const -{ - eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized."); - return HouseholderSequenceType(m_qr, m_hCoeffs.conjugate()); -} - -/** \return the column-pivoting Householder QR decomposition of \c *this. - * - * \sa class ColPivHouseholderQR - */ -template -const ColPivHouseholderQR::PlainObject> -MatrixBase::colPivHouseholderQr() const -{ - return ColPivHouseholderQR(eval()); -} - -} // end namespace Eigen - -#endif // EIGEN_COLPIVOTINGHOUSEHOLDERQR_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/QR/ColPivHouseholderQR_MKL.h b/thirdparty/eigen-3.2.7/Eigen/src/QR/ColPivHouseholderQR_MKL.h deleted file mode 100644 index b5b19832..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/QR/ColPivHouseholderQR_MKL.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - Copyright (c) 2011, Intel Corporation. All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of Intel Corporation nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - ******************************************************************************** - * Content : Eigen bindings to Intel(R) MKL - * Householder QR decomposition of a matrix with column pivoting based on - * LAPACKE_?geqp3 function. - ******************************************************************************** -*/ - -#ifndef EIGEN_COLPIVOTINGHOUSEHOLDERQR_MKL_H -#define EIGEN_COLPIVOTINGHOUSEHOLDERQR_MKL_H - -#include "Eigen/src/Core/util/MKL_support.h" - -namespace Eigen { - -/** \internal Specialization for the data types supported by MKL */ - -#define EIGEN_MKL_QR_COLPIV(EIGTYPE, MKLTYPE, MKLPREFIX, EIGCOLROW, MKLCOLROW) \ -template<> inline \ -ColPivHouseholderQR >& \ -ColPivHouseholderQR >::compute( \ - const Matrix& matrix) \ -\ -{ \ - using std::abs; \ - typedef Matrix MatrixType; \ - typedef MatrixType::Scalar Scalar; \ - typedef MatrixType::RealScalar RealScalar; \ - Index rows = matrix.rows();\ - Index cols = matrix.cols();\ - Index size = matrix.diagonalSize();\ -\ - m_qr = matrix;\ - m_hCoeffs.resize(size);\ -\ - m_colsTranspositions.resize(cols);\ - /*Index number_of_transpositions = 0;*/ \ -\ - m_nonzero_pivots = 0; \ - m_maxpivot = RealScalar(0);\ - m_colsPermutation.resize(cols); \ - m_colsPermutation.indices().setZero(); \ -\ - lapack_int lda = m_qr.outerStride(), i; \ - lapack_int matrix_order = MKLCOLROW; \ - LAPACKE_##MKLPREFIX##geqp3( matrix_order, rows, cols, (MKLTYPE*)m_qr.data(), lda, (lapack_int*)m_colsPermutation.indices().data(), (MKLTYPE*)m_hCoeffs.data()); \ - m_isInitialized = true; \ - m_maxpivot=m_qr.diagonal().cwiseAbs().maxCoeff(); \ - m_hCoeffs.adjointInPlace(); \ - RealScalar premultiplied_threshold = abs(m_maxpivot) * threshold(); \ - lapack_int *perm = m_colsPermutation.indices().data(); \ - for(i=0;i premultiplied_threshold);\ - } \ - for(i=0;i -// Copyright (C) 2009 Benoit Jacob -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_FULLPIVOTINGHOUSEHOLDERQR_H -#define EIGEN_FULLPIVOTINGHOUSEHOLDERQR_H - -namespace Eigen { - -namespace internal { - -template struct FullPivHouseholderQRMatrixQReturnType; - -template -struct traits > -{ - typedef typename MatrixType::PlainObject ReturnType; -}; - -} - -/** \ingroup QR_Module - * - * \class FullPivHouseholderQR - * - * \brief Householder rank-revealing QR decomposition of a matrix with full pivoting - * - * \param MatrixType the type of the matrix of which we are computing the QR decomposition - * - * This class performs a rank-revealing QR decomposition of a matrix \b A into matrices \b P, \b Q and \b R - * such that - * \f[ - * \mathbf{A} \, \mathbf{P} = \mathbf{Q} \, \mathbf{R} - * \f] - * by using Householder transformations. Here, \b P is a permutation matrix, \b Q a unitary matrix and \b R an - * upper triangular matrix. - * - * This decomposition performs a very prudent full pivoting in order to be rank-revealing and achieve optimal - * numerical stability. The trade-off is that it is slower than HouseholderQR and ColPivHouseholderQR. - * - * \sa MatrixBase::fullPivHouseholderQr() - */ -template class FullPivHouseholderQR -{ - public: - - typedef _MatrixType MatrixType; - enum { - RowsAtCompileTime = MatrixType::RowsAtCompileTime, - ColsAtCompileTime = MatrixType::ColsAtCompileTime, - Options = MatrixType::Options, - MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime, - MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime - }; - typedef typename MatrixType::Scalar Scalar; - typedef typename MatrixType::RealScalar RealScalar; - typedef typename MatrixType::Index Index; - typedef internal::FullPivHouseholderQRMatrixQReturnType MatrixQReturnType; - typedef typename internal::plain_diag_type::type HCoeffsType; - typedef Matrix IntDiagSizeVectorType; - typedef PermutationMatrix PermutationType; - typedef typename internal::plain_row_type::type RowVectorType; - typedef typename internal::plain_col_type::type ColVectorType; - - /** \brief Default Constructor. - * - * The default constructor is useful in cases in which the user intends to - * perform decompositions via FullPivHouseholderQR::compute(const MatrixType&). - */ - FullPivHouseholderQR() - : m_qr(), - m_hCoeffs(), - m_rows_transpositions(), - m_cols_transpositions(), - m_cols_permutation(), - m_temp(), - m_isInitialized(false), - m_usePrescribedThreshold(false) {} - - /** \brief Default Constructor with memory preallocation - * - * Like the default constructor but with preallocation of the internal data - * according to the specified problem \a size. - * \sa FullPivHouseholderQR() - */ - FullPivHouseholderQR(Index rows, Index cols) - : m_qr(rows, cols), - m_hCoeffs((std::min)(rows,cols)), - m_rows_transpositions((std::min)(rows,cols)), - m_cols_transpositions((std::min)(rows,cols)), - m_cols_permutation(cols), - m_temp(cols), - m_isInitialized(false), - m_usePrescribedThreshold(false) {} - - /** \brief Constructs a QR factorization from a given matrix - * - * This constructor computes the QR factorization of the matrix \a matrix by calling - * the method compute(). It is a short cut for: - * - * \code - * FullPivHouseholderQR qr(matrix.rows(), matrix.cols()); - * qr.compute(matrix); - * \endcode - * - * \sa compute() - */ - FullPivHouseholderQR(const MatrixType& matrix) - : m_qr(matrix.rows(), matrix.cols()), - m_hCoeffs((std::min)(matrix.rows(), matrix.cols())), - m_rows_transpositions((std::min)(matrix.rows(), matrix.cols())), - m_cols_transpositions((std::min)(matrix.rows(), matrix.cols())), - m_cols_permutation(matrix.cols()), - m_temp(matrix.cols()), - m_isInitialized(false), - m_usePrescribedThreshold(false) - { - compute(matrix); - } - - /** This method finds a solution x to the equation Ax=b, where A is the matrix of which - * \c *this is the QR decomposition. - * - * \param b the right-hand-side of the equation to solve. - * - * \returns the exact or least-square solution if the rank is greater or equal to the number of columns of A, - * and an arbitrary solution otherwise. - * - * \note The case where b is a matrix is not yet implemented. Also, this - * code is space inefficient. - * - * \note_about_checking_solutions - * - * \note_about_arbitrary_choice_of_solution - * - * Example: \include FullPivHouseholderQR_solve.cpp - * Output: \verbinclude FullPivHouseholderQR_solve.out - */ - template - inline const internal::solve_retval - solve(const MatrixBase& b) const - { - eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized."); - return internal::solve_retval(*this, b.derived()); - } - - /** \returns Expression object representing the matrix Q - */ - MatrixQReturnType matrixQ(void) const; - - /** \returns a reference to the matrix where the Householder QR decomposition is stored - */ - const MatrixType& matrixQR() const - { - eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized."); - return m_qr; - } - - FullPivHouseholderQR& compute(const MatrixType& matrix); - - /** \returns a const reference to the column permutation matrix */ - const PermutationType& colsPermutation() const - { - eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized."); - return m_cols_permutation; - } - - /** \returns a const reference to the vector of indices representing the rows transpositions */ - const IntDiagSizeVectorType& rowsTranspositions() const - { - eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized."); - return m_rows_transpositions; - } - - /** \returns the absolute value of the determinant of the matrix of which - * *this is the QR decomposition. It has only linear complexity - * (that is, O(n) where n is the dimension of the square matrix) - * as the QR decomposition has already been computed. - * - * \note This is only for square matrices. - * - * \warning a determinant can be very big or small, so for matrices - * of large enough dimension, there is a risk of overflow/underflow. - * One way to work around that is to use logAbsDeterminant() instead. - * - * \sa logAbsDeterminant(), MatrixBase::determinant() - */ - typename MatrixType::RealScalar absDeterminant() const; - - /** \returns the natural log of the absolute value of the determinant of the matrix of which - * *this is the QR decomposition. It has only linear complexity - * (that is, O(n) where n is the dimension of the square matrix) - * as the QR decomposition has already been computed. - * - * \note This is only for square matrices. - * - * \note This method is useful to work around the risk of overflow/underflow that's inherent - * to determinant computation. - * - * \sa absDeterminant(), MatrixBase::determinant() - */ - typename MatrixType::RealScalar logAbsDeterminant() const; - - /** \returns the rank of the matrix of which *this is the QR decomposition. - * - * \note This method has to determine which pivots should be considered nonzero. - * For that, it uses the threshold value that you can control by calling - * setThreshold(const RealScalar&). - */ - inline Index rank() const - { - using std::abs; - eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized."); - RealScalar premultiplied_threshold = abs(m_maxpivot) * threshold(); - Index result = 0; - for(Index i = 0; i < m_nonzero_pivots; ++i) - result += (abs(m_qr.coeff(i,i)) > premultiplied_threshold); - return result; - } - - /** \returns the dimension of the kernel of the matrix of which *this is the QR decomposition. - * - * \note This method has to determine which pivots should be considered nonzero. - * For that, it uses the threshold value that you can control by calling - * setThreshold(const RealScalar&). - */ - inline Index dimensionOfKernel() const - { - eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized."); - return cols() - rank(); - } - - /** \returns true if the matrix of which *this is the QR decomposition represents an injective - * linear map, i.e. has trivial kernel; false otherwise. - * - * \note This method has to determine which pivots should be considered nonzero. - * For that, it uses the threshold value that you can control by calling - * setThreshold(const RealScalar&). - */ - inline bool isInjective() const - { - eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized."); - return rank() == cols(); - } - - /** \returns true if the matrix of which *this is the QR decomposition represents a surjective - * linear map; false otherwise. - * - * \note This method has to determine which pivots should be considered nonzero. - * For that, it uses the threshold value that you can control by calling - * setThreshold(const RealScalar&). - */ - inline bool isSurjective() const - { - eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized."); - return rank() == rows(); - } - - /** \returns true if the matrix of which *this is the QR decomposition is invertible. - * - * \note This method has to determine which pivots should be considered nonzero. - * For that, it uses the threshold value that you can control by calling - * setThreshold(const RealScalar&). - */ - inline bool isInvertible() const - { - eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized."); - return isInjective() && isSurjective(); - } - - /** \returns the inverse of the matrix of which *this is the QR decomposition. - * - * \note If this matrix is not invertible, the returned matrix has undefined coefficients. - * Use isInvertible() to first determine whether this matrix is invertible. - */ inline const - internal::solve_retval - inverse() const - { - eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized."); - return internal::solve_retval - (*this, MatrixType::Identity(m_qr.rows(), m_qr.cols())); - } - - inline Index rows() const { return m_qr.rows(); } - inline Index cols() const { return m_qr.cols(); } - - /** \returns a const reference to the vector of Householder coefficients used to represent the factor \c Q. - * - * For advanced uses only. - */ - const HCoeffsType& hCoeffs() const { return m_hCoeffs; } - - /** Allows to prescribe a threshold to be used by certain methods, such as rank(), - * who need to determine when pivots are to be considered nonzero. This is not used for the - * QR decomposition itself. - * - * When it needs to get the threshold value, Eigen calls threshold(). By default, this - * uses a formula to automatically determine a reasonable threshold. - * Once you have called the present method setThreshold(const RealScalar&), - * your value is used instead. - * - * \param threshold The new value to use as the threshold. - * - * A pivot will be considered nonzero if its absolute value is strictly greater than - * \f$ \vert pivot \vert \leqslant threshold \times \vert maxpivot \vert \f$ - * where maxpivot is the biggest pivot. - * - * If you want to come back to the default behavior, call setThreshold(Default_t) - */ - FullPivHouseholderQR& setThreshold(const RealScalar& threshold) - { - m_usePrescribedThreshold = true; - m_prescribedThreshold = threshold; - return *this; - } - - /** Allows to come back to the default behavior, letting Eigen use its default formula for - * determining the threshold. - * - * You should pass the special object Eigen::Default as parameter here. - * \code qr.setThreshold(Eigen::Default); \endcode - * - * See the documentation of setThreshold(const RealScalar&). - */ - FullPivHouseholderQR& setThreshold(Default_t) - { - m_usePrescribedThreshold = false; - return *this; - } - - /** Returns the threshold that will be used by certain methods such as rank(). - * - * See the documentation of setThreshold(const RealScalar&). - */ - RealScalar threshold() const - { - eigen_assert(m_isInitialized || m_usePrescribedThreshold); - return m_usePrescribedThreshold ? m_prescribedThreshold - // this formula comes from experimenting (see "LU precision tuning" thread on the list) - // and turns out to be identical to Higham's formula used already in LDLt. - : NumTraits::epsilon() * RealScalar(m_qr.diagonalSize()); - } - - /** \returns the number of nonzero pivots in the QR decomposition. - * Here nonzero is meant in the exact sense, not in a fuzzy sense. - * So that notion isn't really intrinsically interesting, but it is - * still useful when implementing algorithms. - * - * \sa rank() - */ - inline Index nonzeroPivots() const - { - eigen_assert(m_isInitialized && "LU is not initialized."); - return m_nonzero_pivots; - } - - /** \returns the absolute value of the biggest pivot, i.e. the biggest - * diagonal coefficient of U. - */ - RealScalar maxPivot() const { return m_maxpivot; } - - protected: - - static void check_template_parameters() - { - EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar); - } - - MatrixType m_qr; - HCoeffsType m_hCoeffs; - IntDiagSizeVectorType m_rows_transpositions; - IntDiagSizeVectorType m_cols_transpositions; - PermutationType m_cols_permutation; - RowVectorType m_temp; - bool m_isInitialized, m_usePrescribedThreshold; - RealScalar m_prescribedThreshold, m_maxpivot; - Index m_nonzero_pivots; - RealScalar m_precision; - Index m_det_pq; -}; - -template -typename MatrixType::RealScalar FullPivHouseholderQR::absDeterminant() const -{ - using std::abs; - eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized."); - eigen_assert(m_qr.rows() == m_qr.cols() && "You can't take the determinant of a non-square matrix!"); - return abs(m_qr.diagonal().prod()); -} - -template -typename MatrixType::RealScalar FullPivHouseholderQR::logAbsDeterminant() const -{ - eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized."); - eigen_assert(m_qr.rows() == m_qr.cols() && "You can't take the determinant of a non-square matrix!"); - return m_qr.diagonal().cwiseAbs().array().log().sum(); -} - -/** Performs the QR factorization of the given matrix \a matrix. The result of - * the factorization is stored into \c *this, and a reference to \c *this - * is returned. - * - * \sa class FullPivHouseholderQR, FullPivHouseholderQR(const MatrixType&) - */ -template -FullPivHouseholderQR& FullPivHouseholderQR::compute(const MatrixType& matrix) -{ - check_template_parameters(); - - using std::abs; - Index rows = matrix.rows(); - Index cols = matrix.cols(); - Index size = (std::min)(rows,cols); - - m_qr = matrix; - m_hCoeffs.resize(size); - - m_temp.resize(cols); - - m_precision = NumTraits::epsilon() * RealScalar(size); - - m_rows_transpositions.resize(size); - m_cols_transpositions.resize(size); - Index number_of_transpositions = 0; - - RealScalar biggest(0); - - m_nonzero_pivots = size; // the generic case is that in which all pivots are nonzero (invertible case) - m_maxpivot = RealScalar(0); - - for (Index k = 0; k < size; ++k) - { - Index row_of_biggest_in_corner, col_of_biggest_in_corner; - RealScalar biggest_in_corner; - - biggest_in_corner = m_qr.bottomRightCorner(rows-k, cols-k) - .cwiseAbs() - .maxCoeff(&row_of_biggest_in_corner, &col_of_biggest_in_corner); - row_of_biggest_in_corner += k; - col_of_biggest_in_corner += k; - if(k==0) biggest = biggest_in_corner; - - // if the corner is negligible, then we have less than full rank, and we can finish early - if(internal::isMuchSmallerThan(biggest_in_corner, biggest, m_precision)) - { - m_nonzero_pivots = k; - for(Index i = k; i < size; i++) - { - m_rows_transpositions.coeffRef(i) = i; - m_cols_transpositions.coeffRef(i) = i; - m_hCoeffs.coeffRef(i) = Scalar(0); - } - break; - } - - m_rows_transpositions.coeffRef(k) = row_of_biggest_in_corner; - m_cols_transpositions.coeffRef(k) = col_of_biggest_in_corner; - if(k != row_of_biggest_in_corner) { - m_qr.row(k).tail(cols-k).swap(m_qr.row(row_of_biggest_in_corner).tail(cols-k)); - ++number_of_transpositions; - } - if(k != col_of_biggest_in_corner) { - m_qr.col(k).swap(m_qr.col(col_of_biggest_in_corner)); - ++number_of_transpositions; - } - - RealScalar beta; - m_qr.col(k).tail(rows-k).makeHouseholderInPlace(m_hCoeffs.coeffRef(k), beta); - m_qr.coeffRef(k,k) = beta; - - // remember the maximum absolute value of diagonal coefficients - if(abs(beta) > m_maxpivot) m_maxpivot = abs(beta); - - m_qr.bottomRightCorner(rows-k, cols-k-1) - .applyHouseholderOnTheLeft(m_qr.col(k).tail(rows-k-1), m_hCoeffs.coeffRef(k), &m_temp.coeffRef(k+1)); - } - - m_cols_permutation.setIdentity(cols); - for(Index k = 0; k < size; ++k) - m_cols_permutation.applyTranspositionOnTheRight(k, m_cols_transpositions.coeff(k)); - - m_det_pq = (number_of_transpositions%2) ? -1 : 1; - m_isInitialized = true; - - return *this; -} - -namespace internal { - -template -struct solve_retval, Rhs> - : solve_retval_base, Rhs> -{ - EIGEN_MAKE_SOLVE_HELPERS(FullPivHouseholderQR<_MatrixType>,Rhs) - - template void evalTo(Dest& dst) const - { - const Index rows = dec().rows(), cols = dec().cols(); - eigen_assert(rhs().rows() == rows); - - // FIXME introduce nonzeroPivots() and use it here. and more generally, - // make the same improvements in this dec as in FullPivLU. - if(dec().rank()==0) - { - dst.setZero(); - return; - } - - typename Rhs::PlainObject c(rhs()); - - Matrix temp(rhs().cols()); - for (Index k = 0; k < dec().rank(); ++k) - { - Index remainingSize = rows-k; - c.row(k).swap(c.row(dec().rowsTranspositions().coeff(k))); - c.bottomRightCorner(remainingSize, rhs().cols()) - .applyHouseholderOnTheLeft(dec().matrixQR().col(k).tail(remainingSize-1), - dec().hCoeffs().coeff(k), &temp.coeffRef(0)); - } - - dec().matrixQR() - .topLeftCorner(dec().rank(), dec().rank()) - .template triangularView() - .solveInPlace(c.topRows(dec().rank())); - - for(Index i = 0; i < dec().rank(); ++i) dst.row(dec().colsPermutation().indices().coeff(i)) = c.row(i); - for(Index i = dec().rank(); i < cols; ++i) dst.row(dec().colsPermutation().indices().coeff(i)).setZero(); - } -}; - -/** \ingroup QR_Module - * - * \brief Expression type for return value of FullPivHouseholderQR::matrixQ() - * - * \tparam MatrixType type of underlying dense matrix - */ -template struct FullPivHouseholderQRMatrixQReturnType - : public ReturnByValue > -{ -public: - typedef typename MatrixType::Index Index; - typedef typename FullPivHouseholderQR::IntDiagSizeVectorType IntDiagSizeVectorType; - typedef typename internal::plain_diag_type::type HCoeffsType; - typedef Matrix WorkVectorType; - - FullPivHouseholderQRMatrixQReturnType(const MatrixType& qr, - const HCoeffsType& hCoeffs, - const IntDiagSizeVectorType& rowsTranspositions) - : m_qr(qr), - m_hCoeffs(hCoeffs), - m_rowsTranspositions(rowsTranspositions) - {} - - template - void evalTo(ResultType& result) const - { - const Index rows = m_qr.rows(); - WorkVectorType workspace(rows); - evalTo(result, workspace); - } - - template - void evalTo(ResultType& result, WorkVectorType& workspace) const - { - using numext::conj; - // compute the product H'_0 H'_1 ... H'_n-1, - // where H_k is the k-th Householder transformation I - h_k v_k v_k' - // and v_k is the k-th Householder vector [1,m_qr(k+1,k), m_qr(k+2,k), ...] - const Index rows = m_qr.rows(); - const Index cols = m_qr.cols(); - const Index size = (std::min)(rows, cols); - workspace.resize(rows); - result.setIdentity(rows, rows); - for (Index k = size-1; k >= 0; k--) - { - result.block(k, k, rows-k, rows-k) - .applyHouseholderOnTheLeft(m_qr.col(k).tail(rows-k-1), conj(m_hCoeffs.coeff(k)), &workspace.coeffRef(k)); - result.row(k).swap(result.row(m_rowsTranspositions.coeff(k))); - } - } - - Index rows() const { return m_qr.rows(); } - Index cols() const { return m_qr.rows(); } - -protected: - typename MatrixType::Nested m_qr; - typename HCoeffsType::Nested m_hCoeffs; - typename IntDiagSizeVectorType::Nested m_rowsTranspositions; -}; - -} // end namespace internal - -template -inline typename FullPivHouseholderQR::MatrixQReturnType FullPivHouseholderQR::matrixQ() const -{ - eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized."); - return MatrixQReturnType(m_qr, m_hCoeffs, m_rows_transpositions); -} - -/** \return the full-pivoting Householder QR decomposition of \c *this. - * - * \sa class FullPivHouseholderQR - */ -template -const FullPivHouseholderQR::PlainObject> -MatrixBase::fullPivHouseholderQr() const -{ - return FullPivHouseholderQR(eval()); -} - -} // end namespace Eigen - -#endif // EIGEN_FULLPIVOTINGHOUSEHOLDERQR_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/QR/HouseholderQR.h b/thirdparty/eigen-3.2.7/Eigen/src/QR/HouseholderQR.h deleted file mode 100644 index 343a6649..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/QR/HouseholderQR.h +++ /dev/null @@ -1,388 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2010 Gael Guennebaud -// Copyright (C) 2009 Benoit Jacob -// Copyright (C) 2010 Vincent Lejeune -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_QR_H -#define EIGEN_QR_H - -namespace Eigen { - -/** \ingroup QR_Module - * - * - * \class HouseholderQR - * - * \brief Householder QR decomposition of a matrix - * - * \param MatrixType the type of the matrix of which we are computing the QR decomposition - * - * This class performs a QR decomposition of a matrix \b A into matrices \b Q and \b R - * such that - * \f[ - * \mathbf{A} = \mathbf{Q} \, \mathbf{R} - * \f] - * by using Householder transformations. Here, \b Q a unitary matrix and \b R an upper triangular matrix. - * The result is stored in a compact way compatible with LAPACK. - * - * Note that no pivoting is performed. This is \b not a rank-revealing decomposition. - * If you want that feature, use FullPivHouseholderQR or ColPivHouseholderQR instead. - * - * This Householder QR decomposition is faster, but less numerically stable and less feature-full than - * FullPivHouseholderQR or ColPivHouseholderQR. - * - * \sa MatrixBase::householderQr() - */ -template class HouseholderQR -{ - public: - - typedef _MatrixType MatrixType; - enum { - RowsAtCompileTime = MatrixType::RowsAtCompileTime, - ColsAtCompileTime = MatrixType::ColsAtCompileTime, - Options = MatrixType::Options, - MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime, - MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime - }; - typedef typename MatrixType::Scalar Scalar; - typedef typename MatrixType::RealScalar RealScalar; - typedef typename MatrixType::Index Index; - typedef Matrix MatrixQType; - typedef typename internal::plain_diag_type::type HCoeffsType; - typedef typename internal::plain_row_type::type RowVectorType; - typedef HouseholderSequence::type> HouseholderSequenceType; - - /** - * \brief Default Constructor. - * - * The default constructor is useful in cases in which the user intends to - * perform decompositions via HouseholderQR::compute(const MatrixType&). - */ - HouseholderQR() : m_qr(), m_hCoeffs(), m_temp(), m_isInitialized(false) {} - - /** \brief Default Constructor with memory preallocation - * - * Like the default constructor but with preallocation of the internal data - * according to the specified problem \a size. - * \sa HouseholderQR() - */ - HouseholderQR(Index rows, Index cols) - : m_qr(rows, cols), - m_hCoeffs((std::min)(rows,cols)), - m_temp(cols), - m_isInitialized(false) {} - - /** \brief Constructs a QR factorization from a given matrix - * - * This constructor computes the QR factorization of the matrix \a matrix by calling - * the method compute(). It is a short cut for: - * - * \code - * HouseholderQR qr(matrix.rows(), matrix.cols()); - * qr.compute(matrix); - * \endcode - * - * \sa compute() - */ - HouseholderQR(const MatrixType& matrix) - : m_qr(matrix.rows(), matrix.cols()), - m_hCoeffs((std::min)(matrix.rows(),matrix.cols())), - m_temp(matrix.cols()), - m_isInitialized(false) - { - compute(matrix); - } - - /** This method finds a solution x to the equation Ax=b, where A is the matrix of which - * *this is the QR decomposition, if any exists. - * - * \param b the right-hand-side of the equation to solve. - * - * \returns a solution. - * - * \note The case where b is a matrix is not yet implemented. Also, this - * code is space inefficient. - * - * \note_about_checking_solutions - * - * \note_about_arbitrary_choice_of_solution - * - * Example: \include HouseholderQR_solve.cpp - * Output: \verbinclude HouseholderQR_solve.out - */ - template - inline const internal::solve_retval - solve(const MatrixBase& b) const - { - eigen_assert(m_isInitialized && "HouseholderQR is not initialized."); - return internal::solve_retval(*this, b.derived()); - } - - /** This method returns an expression of the unitary matrix Q as a sequence of Householder transformations. - * - * The returned expression can directly be used to perform matrix products. It can also be assigned to a dense Matrix object. - * Here is an example showing how to recover the full or thin matrix Q, as well as how to perform matrix products using operator*: - * - * Example: \include HouseholderQR_householderQ.cpp - * Output: \verbinclude HouseholderQR_householderQ.out - */ - HouseholderSequenceType householderQ() const - { - eigen_assert(m_isInitialized && "HouseholderQR is not initialized."); - return HouseholderSequenceType(m_qr, m_hCoeffs.conjugate()); - } - - /** \returns a reference to the matrix where the Householder QR decomposition is stored - * in a LAPACK-compatible way. - */ - const MatrixType& matrixQR() const - { - eigen_assert(m_isInitialized && "HouseholderQR is not initialized."); - return m_qr; - } - - HouseholderQR& compute(const MatrixType& matrix); - - /** \returns the absolute value of the determinant of the matrix of which - * *this is the QR decomposition. It has only linear complexity - * (that is, O(n) where n is the dimension of the square matrix) - * as the QR decomposition has already been computed. - * - * \note This is only for square matrices. - * - * \warning a determinant can be very big or small, so for matrices - * of large enough dimension, there is a risk of overflow/underflow. - * One way to work around that is to use logAbsDeterminant() instead. - * - * \sa logAbsDeterminant(), MatrixBase::determinant() - */ - typename MatrixType::RealScalar absDeterminant() const; - - /** \returns the natural log of the absolute value of the determinant of the matrix of which - * *this is the QR decomposition. It has only linear complexity - * (that is, O(n) where n is the dimension of the square matrix) - * as the QR decomposition has already been computed. - * - * \note This is only for square matrices. - * - * \note This method is useful to work around the risk of overflow/underflow that's inherent - * to determinant computation. - * - * \sa absDeterminant(), MatrixBase::determinant() - */ - typename MatrixType::RealScalar logAbsDeterminant() const; - - inline Index rows() const { return m_qr.rows(); } - inline Index cols() const { return m_qr.cols(); } - - /** \returns a const reference to the vector of Householder coefficients used to represent the factor \c Q. - * - * For advanced uses only. - */ - const HCoeffsType& hCoeffs() const { return m_hCoeffs; } - - protected: - - static void check_template_parameters() - { - EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar); - } - - MatrixType m_qr; - HCoeffsType m_hCoeffs; - RowVectorType m_temp; - bool m_isInitialized; -}; - -template -typename MatrixType::RealScalar HouseholderQR::absDeterminant() const -{ - using std::abs; - eigen_assert(m_isInitialized && "HouseholderQR is not initialized."); - eigen_assert(m_qr.rows() == m_qr.cols() && "You can't take the determinant of a non-square matrix!"); - return abs(m_qr.diagonal().prod()); -} - -template -typename MatrixType::RealScalar HouseholderQR::logAbsDeterminant() const -{ - eigen_assert(m_isInitialized && "HouseholderQR is not initialized."); - eigen_assert(m_qr.rows() == m_qr.cols() && "You can't take the determinant of a non-square matrix!"); - return m_qr.diagonal().cwiseAbs().array().log().sum(); -} - -namespace internal { - -/** \internal */ -template -void householder_qr_inplace_unblocked(MatrixQR& mat, HCoeffs& hCoeffs, typename MatrixQR::Scalar* tempData = 0) -{ - typedef typename MatrixQR::Index Index; - typedef typename MatrixQR::Scalar Scalar; - typedef typename MatrixQR::RealScalar RealScalar; - Index rows = mat.rows(); - Index cols = mat.cols(); - Index size = (std::min)(rows,cols); - - eigen_assert(hCoeffs.size() == size); - - typedef Matrix TempType; - TempType tempVector; - if(tempData==0) - { - tempVector.resize(cols); - tempData = tempVector.data(); - } - - for(Index k = 0; k < size; ++k) - { - Index remainingRows = rows - k; - Index remainingCols = cols - k - 1; - - RealScalar beta; - mat.col(k).tail(remainingRows).makeHouseholderInPlace(hCoeffs.coeffRef(k), beta); - mat.coeffRef(k,k) = beta; - - // apply H to remaining part of m_qr from the left - mat.bottomRightCorner(remainingRows, remainingCols) - .applyHouseholderOnTheLeft(mat.col(k).tail(remainingRows-1), hCoeffs.coeffRef(k), tempData+k+1); - } -} - -/** \internal */ -template -struct householder_qr_inplace_blocked -{ - // This is specialized for MKL-supported Scalar types in HouseholderQR_MKL.h - static void run(MatrixQR& mat, HCoeffs& hCoeffs, - typename MatrixQR::Index maxBlockSize=32, - typename MatrixQR::Scalar* tempData = 0) - { - typedef typename MatrixQR::Index Index; - typedef typename MatrixQR::Scalar Scalar; - typedef Block BlockType; - - Index rows = mat.rows(); - Index cols = mat.cols(); - Index size = (std::min)(rows, cols); - - typedef Matrix TempType; - TempType tempVector; - if(tempData==0) - { - tempVector.resize(cols); - tempData = tempVector.data(); - } - - Index blockSize = (std::min)(maxBlockSize,size); - - Index k = 0; - for (k = 0; k < size; k += blockSize) - { - Index bs = (std::min)(size-k,blockSize); // actual size of the block - Index tcols = cols - k - bs; // trailing columns - Index brows = rows-k; // rows of the block - - // partition the matrix: - // A00 | A01 | A02 - // mat = A10 | A11 | A12 - // A20 | A21 | A22 - // and performs the qr dec of [A11^T A12^T]^T - // and update [A21^T A22^T]^T using level 3 operations. - // Finally, the algorithm continue on A22 - - BlockType A11_21 = mat.block(k,k,brows,bs); - Block hCoeffsSegment = hCoeffs.segment(k,bs); - - householder_qr_inplace_unblocked(A11_21, hCoeffsSegment, tempData); - - if(tcols) - { - BlockType A21_22 = mat.block(k,k+bs,brows,tcols); - apply_block_householder_on_the_left(A21_22,A11_21,hCoeffsSegment.adjoint()); - } - } - } -}; - -template -struct solve_retval, Rhs> - : solve_retval_base, Rhs> -{ - EIGEN_MAKE_SOLVE_HELPERS(HouseholderQR<_MatrixType>,Rhs) - - template void evalTo(Dest& dst) const - { - const Index rows = dec().rows(), cols = dec().cols(); - const Index rank = (std::min)(rows, cols); - eigen_assert(rhs().rows() == rows); - - typename Rhs::PlainObject c(rhs()); - - // Note that the matrix Q = H_0^* H_1^*... so its inverse is Q^* = (H_0 H_1 ...)^T - c.applyOnTheLeft(householderSequence( - dec().matrixQR().leftCols(rank), - dec().hCoeffs().head(rank)).transpose() - ); - - dec().matrixQR() - .topLeftCorner(rank, rank) - .template triangularView() - .solveInPlace(c.topRows(rank)); - - dst.topRows(rank) = c.topRows(rank); - dst.bottomRows(cols-rank).setZero(); - } -}; - -} // end namespace internal - -/** Performs the QR factorization of the given matrix \a matrix. The result of - * the factorization is stored into \c *this, and a reference to \c *this - * is returned. - * - * \sa class HouseholderQR, HouseholderQR(const MatrixType&) - */ -template -HouseholderQR& HouseholderQR::compute(const MatrixType& matrix) -{ - check_template_parameters(); - - Index rows = matrix.rows(); - Index cols = matrix.cols(); - Index size = (std::min)(rows,cols); - - m_qr = matrix; - m_hCoeffs.resize(size); - - m_temp.resize(cols); - - internal::householder_qr_inplace_blocked::run(m_qr, m_hCoeffs, 48, m_temp.data()); - - m_isInitialized = true; - return *this; -} - -/** \return the Householder QR decomposition of \c *this. - * - * \sa class HouseholderQR - */ -template -const HouseholderQR::PlainObject> -MatrixBase::householderQr() const -{ - return HouseholderQR(eval()); -} - -} // end namespace Eigen - -#endif // EIGEN_QR_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/QR/HouseholderQR_MKL.h b/thirdparty/eigen-3.2.7/Eigen/src/QR/HouseholderQR_MKL.h deleted file mode 100644 index b80f1b48..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/QR/HouseholderQR_MKL.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - Copyright (c) 2011, Intel Corporation. All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of Intel Corporation nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - ******************************************************************************** - * Content : Eigen bindings to Intel(R) MKL - * Householder QR decomposition of a matrix w/o pivoting based on - * LAPACKE_?geqrf function. - ******************************************************************************** -*/ - -#ifndef EIGEN_QR_MKL_H -#define EIGEN_QR_MKL_H - -#include "../Core/util/MKL_support.h" - -namespace Eigen { - - namespace internal { - - /** \internal Specialization for the data types supported by MKL */ - -#define EIGEN_MKL_QR_NOPIV(EIGTYPE, MKLTYPE, MKLPREFIX) \ -template \ -struct householder_qr_inplace_blocked \ -{ \ - static void run(MatrixQR& mat, HCoeffs& hCoeffs, \ - typename MatrixQR::Index = 32, \ - typename MatrixQR::Scalar* = 0) \ - { \ - lapack_int m = (lapack_int) mat.rows(); \ - lapack_int n = (lapack_int) mat.cols(); \ - lapack_int lda = (lapack_int) mat.outerStride(); \ - lapack_int matrix_order = (MatrixQR::IsRowMajor) ? LAPACK_ROW_MAJOR : LAPACK_COL_MAJOR; \ - LAPACKE_##MKLPREFIX##geqrf( matrix_order, m, n, (MKLTYPE*)mat.data(), lda, (MKLTYPE*)hCoeffs.data()); \ - hCoeffs.adjointInPlace(); \ - } \ -}; - -EIGEN_MKL_QR_NOPIV(double, double, d) -EIGEN_MKL_QR_NOPIV(float, float, s) -EIGEN_MKL_QR_NOPIV(dcomplex, MKL_Complex16, z) -EIGEN_MKL_QR_NOPIV(scomplex, MKL_Complex8, c) - -} // end namespace internal - -} // end namespace Eigen - -#endif // EIGEN_QR_MKL_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h b/thirdparty/eigen-3.2.7/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h deleted file mode 100644 index 36138101..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h +++ /dev/null @@ -1,338 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2012 Desire Nuentsa -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_SUITESPARSEQRSUPPORT_H -#define EIGEN_SUITESPARSEQRSUPPORT_H - -namespace Eigen { - - template class SPQR; - template struct SPQRMatrixQReturnType; - template struct SPQRMatrixQTransposeReturnType; - template struct SPQR_QProduct; - namespace internal { - template struct traits > - { - typedef typename SPQRType::MatrixType ReturnType; - }; - template struct traits > - { - typedef typename SPQRType::MatrixType ReturnType; - }; - template struct traits > - { - typedef typename Derived::PlainObject ReturnType; - }; - } // End namespace internal - -/** - * \ingroup SPQRSupport_Module - * \class SPQR - * \brief Sparse QR factorization based on SuiteSparseQR library - * - * This class is used to perform a multithreaded and multifrontal rank-revealing QR decomposition - * of sparse matrices. The result is then used to solve linear leasts_square systems. - * Clearly, a QR factorization is returned such that A*P = Q*R where : - * - * P is the column permutation. Use colsPermutation() to get it. - * - * Q is the orthogonal matrix represented as Householder reflectors. - * Use matrixQ() to get an expression and matrixQ().transpose() to get the transpose. - * You can then apply it to a vector. - * - * R is the sparse triangular factor. Use matrixQR() to get it as SparseMatrix. - * NOTE : The Index type of R is always SuiteSparse_long. You can get it with SPQR::Index - * - * \tparam _MatrixType The type of the sparse matrix A, must be a column-major SparseMatrix<> - * NOTE - * - */ -template -class SPQR -{ - public: - typedef typename _MatrixType::Scalar Scalar; - typedef typename _MatrixType::RealScalar RealScalar; - typedef SuiteSparse_long Index ; - typedef SparseMatrix MatrixType; - typedef PermutationMatrix PermutationType; - public: - SPQR() - : m_isInitialized(false), m_ordering(SPQR_ORDERING_DEFAULT), m_allow_tol(SPQR_DEFAULT_TOL), m_tolerance (NumTraits::epsilon()), m_useDefaultThreshold(true) - { - cholmod_l_start(&m_cc); - } - - SPQR(const _MatrixType& matrix) - : m_isInitialized(false), m_ordering(SPQR_ORDERING_DEFAULT), m_allow_tol(SPQR_DEFAULT_TOL), m_tolerance (NumTraits::epsilon()), m_useDefaultThreshold(true) - { - cholmod_l_start(&m_cc); - compute(matrix); - } - - ~SPQR() - { - SPQR_free(); - cholmod_l_finish(&m_cc); - } - void SPQR_free() - { - cholmod_l_free_sparse(&m_H, &m_cc); - cholmod_l_free_sparse(&m_cR, &m_cc); - cholmod_l_free_dense(&m_HTau, &m_cc); - std::free(m_E); - std::free(m_HPinv); - } - - void compute(const _MatrixType& matrix) - { - if(m_isInitialized) SPQR_free(); - - MatrixType mat(matrix); - - /* Compute the default threshold as in MatLab, see: - * Tim Davis, "Algorithm 915, SuiteSparseQR: Multifrontal Multithreaded Rank-Revealing - * Sparse QR Factorization, ACM Trans. on Math. Soft. 38(1), 2011, Page 8:3 - */ - RealScalar pivotThreshold = m_tolerance; - if(m_useDefaultThreshold) - { - using std::max; - RealScalar max2Norm = 0.0; - for (int j = 0; j < mat.cols(); j++) max2Norm = (max)(max2Norm, mat.col(j).norm()); - if(max2Norm==RealScalar(0)) - max2Norm = RealScalar(1); - pivotThreshold = 20 * (mat.rows() + mat.cols()) * max2Norm * NumTraits::epsilon(); - } - - cholmod_sparse A; - A = viewAsCholmod(mat); - Index col = matrix.cols(); - m_rank = SuiteSparseQR(m_ordering, pivotThreshold, col, &A, - &m_cR, &m_E, &m_H, &m_HPinv, &m_HTau, &m_cc); - - if (!m_cR) - { - m_info = NumericalIssue; - m_isInitialized = false; - return; - } - m_info = Success; - m_isInitialized = true; - m_isRUpToDate = false; - } - /** - * Get the number of rows of the input matrix and the Q matrix - */ - inline Index rows() const {return m_cR->nrow; } - - /** - * Get the number of columns of the input matrix. - */ - inline Index cols() const { return m_cR->ncol; } - - /** \returns the solution X of \f$ A X = B \f$ using the current decomposition of A. - * - * \sa compute() - */ - template - inline const internal::solve_retval solve(const MatrixBase& B) const - { - eigen_assert(m_isInitialized && " The QR factorization should be computed first, call compute()"); - eigen_assert(this->rows()==B.rows() - && "SPQR::solve(): invalid number of rows of the right hand side matrix B"); - return internal::solve_retval(*this, B.derived()); - } - - template - void _solve(const MatrixBase &b, MatrixBase &dest) const - { - eigen_assert(m_isInitialized && " The QR factorization should be computed first, call compute()"); - eigen_assert(b.cols()==1 && "This method is for vectors only"); - - //Compute Q^T * b - typename Dest::PlainObject y, y2; - y = matrixQ().transpose() * b; - - // Solves with the triangular matrix R - Index rk = this->rank(); - y2 = y; - y.resize((std::max)(cols(),Index(y.rows())),y.cols()); - y.topRows(rk) = this->matrixR().topLeftCorner(rk, rk).template triangularView().solve(y2.topRows(rk)); - - // Apply the column permutation - // colsPermutation() performs a copy of the permutation, - // so let's apply it manually: - for(Index i = 0; i < rk; ++i) dest.row(m_E[i]) = y.row(i); - for(Index i = rk; i < cols(); ++i) dest.row(m_E[i]).setZero(); - -// y.bottomRows(y.rows()-rk).setZero(); -// dest = colsPermutation() * y.topRows(cols()); - - m_info = Success; - } - - /** \returns the sparse triangular factor R. It is a sparse matrix - */ - const MatrixType matrixR() const - { - eigen_assert(m_isInitialized && " The QR factorization should be computed first, call compute()"); - if(!m_isRUpToDate) { - m_R = viewAsEigen(*m_cR); - m_isRUpToDate = true; - } - return m_R; - } - /// Get an expression of the matrix Q - SPQRMatrixQReturnType matrixQ() const - { - return SPQRMatrixQReturnType(*this); - } - /// Get the permutation that was applied to columns of A - PermutationType colsPermutation() const - { - eigen_assert(m_isInitialized && "Decomposition is not initialized."); - Index n = m_cR->ncol; - PermutationType colsPerm(n); - for(Index j = 0; j friend struct SPQR_QProduct; -}; - -template -struct SPQR_QProduct : ReturnByValue > -{ - typedef typename SPQRType::Scalar Scalar; - typedef typename SPQRType::Index Index; - //Define the constructor to get reference to argument types - SPQR_QProduct(const SPQRType& spqr, const Derived& other, bool transpose) : m_spqr(spqr),m_other(other),m_transpose(transpose) {} - - inline Index rows() const { return m_transpose ? m_spqr.rows() : m_spqr.cols(); } - inline Index cols() const { return m_other.cols(); } - // Assign to a vector - template - void evalTo(ResType& res) const - { - cholmod_dense y_cd; - cholmod_dense *x_cd; - int method = m_transpose ? SPQR_QTX : SPQR_QX; - cholmod_common *cc = m_spqr.cholmodCommon(); - y_cd = viewAsCholmod(m_other.const_cast_derived()); - x_cd = SuiteSparseQR_qmult(method, m_spqr.m_H, m_spqr.m_HTau, m_spqr.m_HPinv, &y_cd, cc); - res = Matrix::Map(reinterpret_cast(x_cd->x), x_cd->nrow, x_cd->ncol); - cholmod_l_free_dense(&x_cd, cc); - } - const SPQRType& m_spqr; - const Derived& m_other; - bool m_transpose; - -}; -template -struct SPQRMatrixQReturnType{ - - SPQRMatrixQReturnType(const SPQRType& spqr) : m_spqr(spqr) {} - template - SPQR_QProduct operator*(const MatrixBase& other) - { - return SPQR_QProduct(m_spqr,other.derived(),false); - } - SPQRMatrixQTransposeReturnType adjoint() const - { - return SPQRMatrixQTransposeReturnType(m_spqr); - } - // To use for operations with the transpose of Q - SPQRMatrixQTransposeReturnType transpose() const - { - return SPQRMatrixQTransposeReturnType(m_spqr); - } - const SPQRType& m_spqr; -}; - -template -struct SPQRMatrixQTransposeReturnType{ - SPQRMatrixQTransposeReturnType(const SPQRType& spqr) : m_spqr(spqr) {} - template - SPQR_QProduct operator*(const MatrixBase& other) - { - return SPQR_QProduct(m_spqr,other.derived(), true); - } - const SPQRType& m_spqr; -}; - -namespace internal { - -template -struct solve_retval, Rhs> - : solve_retval_base, Rhs> -{ - typedef SPQR<_MatrixType> Dec; - EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs) - - template void evalTo(Dest& dst) const - { - dec()._solve(rhs(),dst); - } -}; - -} // end namespace internal - -}// End namespace Eigen -#endif diff --git a/thirdparty/eigen-3.2.7/Eigen/src/SVD/JacobiSVD.h b/thirdparty/eigen-3.2.7/Eigen/src/SVD/JacobiSVD.h deleted file mode 100644 index 1b297741..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/SVD/JacobiSVD.h +++ /dev/null @@ -1,976 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2009-2010 Benoit Jacob -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_JACOBISVD_H -#define EIGEN_JACOBISVD_H - -namespace Eigen { - -namespace internal { -// forward declaration (needed by ICC) -// the empty body is required by MSVC -template::IsComplex> -struct svd_precondition_2x2_block_to_be_real {}; - -/*** QR preconditioners (R-SVD) - *** - *** Their role is to reduce the problem of computing the SVD to the case of a square matrix. - *** This approach, known as R-SVD, is an optimization for rectangular-enough matrices, and is a requirement for - *** JacobiSVD which by itself is only able to work on square matrices. - ***/ - -enum { PreconditionIfMoreColsThanRows, PreconditionIfMoreRowsThanCols }; - -template -struct qr_preconditioner_should_do_anything -{ - enum { a = MatrixType::RowsAtCompileTime != Dynamic && - MatrixType::ColsAtCompileTime != Dynamic && - MatrixType::ColsAtCompileTime <= MatrixType::RowsAtCompileTime, - b = MatrixType::RowsAtCompileTime != Dynamic && - MatrixType::ColsAtCompileTime != Dynamic && - MatrixType::RowsAtCompileTime <= MatrixType::ColsAtCompileTime, - ret = !( (QRPreconditioner == NoQRPreconditioner) || - (Case == PreconditionIfMoreColsThanRows && bool(a)) || - (Case == PreconditionIfMoreRowsThanCols && bool(b)) ) - }; -}; - -template::ret -> struct qr_preconditioner_impl {}; - -template -class qr_preconditioner_impl -{ -public: - typedef typename MatrixType::Index Index; - void allocate(const JacobiSVD&) {} - bool run(JacobiSVD&, const MatrixType&) - { - return false; - } -}; - -/*** preconditioner using FullPivHouseholderQR ***/ - -template -class qr_preconditioner_impl -{ -public: - typedef typename MatrixType::Index Index; - typedef typename MatrixType::Scalar Scalar; - enum - { - RowsAtCompileTime = MatrixType::RowsAtCompileTime, - MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime - }; - typedef Matrix WorkspaceType; - - void allocate(const JacobiSVD& svd) - { - if (svd.rows() != m_qr.rows() || svd.cols() != m_qr.cols()) - { - m_qr.~QRType(); - ::new (&m_qr) QRType(svd.rows(), svd.cols()); - } - if (svd.m_computeFullU) m_workspace.resize(svd.rows()); - } - - bool run(JacobiSVD& svd, const MatrixType& matrix) - { - if(matrix.rows() > matrix.cols()) - { - m_qr.compute(matrix); - svd.m_workMatrix = m_qr.matrixQR().block(0,0,matrix.cols(),matrix.cols()).template triangularView(); - if(svd.m_computeFullU) m_qr.matrixQ().evalTo(svd.m_matrixU, m_workspace); - if(svd.computeV()) svd.m_matrixV = m_qr.colsPermutation(); - return true; - } - return false; - } -private: - typedef FullPivHouseholderQR QRType; - QRType m_qr; - WorkspaceType m_workspace; -}; - -template -class qr_preconditioner_impl -{ -public: - typedef typename MatrixType::Index Index; - typedef typename MatrixType::Scalar Scalar; - enum - { - RowsAtCompileTime = MatrixType::RowsAtCompileTime, - ColsAtCompileTime = MatrixType::ColsAtCompileTime, - MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime, - MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime, - Options = MatrixType::Options - }; - typedef Matrix - TransposeTypeWithSameStorageOrder; - - void allocate(const JacobiSVD& svd) - { - if (svd.cols() != m_qr.rows() || svd.rows() != m_qr.cols()) - { - m_qr.~QRType(); - ::new (&m_qr) QRType(svd.cols(), svd.rows()); - } - m_adjoint.resize(svd.cols(), svd.rows()); - if (svd.m_computeFullV) m_workspace.resize(svd.cols()); - } - - bool run(JacobiSVD& svd, const MatrixType& matrix) - { - if(matrix.cols() > matrix.rows()) - { - m_adjoint = matrix.adjoint(); - m_qr.compute(m_adjoint); - svd.m_workMatrix = m_qr.matrixQR().block(0,0,matrix.rows(),matrix.rows()).template triangularView().adjoint(); - if(svd.m_computeFullV) m_qr.matrixQ().evalTo(svd.m_matrixV, m_workspace); - if(svd.computeU()) svd.m_matrixU = m_qr.colsPermutation(); - return true; - } - else return false; - } -private: - typedef FullPivHouseholderQR QRType; - QRType m_qr; - TransposeTypeWithSameStorageOrder m_adjoint; - typename internal::plain_row_type::type m_workspace; -}; - -/*** preconditioner using ColPivHouseholderQR ***/ - -template -class qr_preconditioner_impl -{ -public: - typedef typename MatrixType::Index Index; - - void allocate(const JacobiSVD& svd) - { - if (svd.rows() != m_qr.rows() || svd.cols() != m_qr.cols()) - { - m_qr.~QRType(); - ::new (&m_qr) QRType(svd.rows(), svd.cols()); - } - if (svd.m_computeFullU) m_workspace.resize(svd.rows()); - else if (svd.m_computeThinU) m_workspace.resize(svd.cols()); - } - - bool run(JacobiSVD& svd, const MatrixType& matrix) - { - if(matrix.rows() > matrix.cols()) - { - m_qr.compute(matrix); - svd.m_workMatrix = m_qr.matrixQR().block(0,0,matrix.cols(),matrix.cols()).template triangularView(); - if(svd.m_computeFullU) m_qr.householderQ().evalTo(svd.m_matrixU, m_workspace); - else if(svd.m_computeThinU) - { - svd.m_matrixU.setIdentity(matrix.rows(), matrix.cols()); - m_qr.householderQ().applyThisOnTheLeft(svd.m_matrixU, m_workspace); - } - if(svd.computeV()) svd.m_matrixV = m_qr.colsPermutation(); - return true; - } - return false; - } - -private: - typedef ColPivHouseholderQR QRType; - QRType m_qr; - typename internal::plain_col_type::type m_workspace; -}; - -template -class qr_preconditioner_impl -{ -public: - typedef typename MatrixType::Index Index; - typedef typename MatrixType::Scalar Scalar; - enum - { - RowsAtCompileTime = MatrixType::RowsAtCompileTime, - ColsAtCompileTime = MatrixType::ColsAtCompileTime, - MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime, - MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime, - Options = MatrixType::Options - }; - - typedef Matrix - TransposeTypeWithSameStorageOrder; - - void allocate(const JacobiSVD& svd) - { - if (svd.cols() != m_qr.rows() || svd.rows() != m_qr.cols()) - { - m_qr.~QRType(); - ::new (&m_qr) QRType(svd.cols(), svd.rows()); - } - if (svd.m_computeFullV) m_workspace.resize(svd.cols()); - else if (svd.m_computeThinV) m_workspace.resize(svd.rows()); - m_adjoint.resize(svd.cols(), svd.rows()); - } - - bool run(JacobiSVD& svd, const MatrixType& matrix) - { - if(matrix.cols() > matrix.rows()) - { - m_adjoint = matrix.adjoint(); - m_qr.compute(m_adjoint); - - svd.m_workMatrix = m_qr.matrixQR().block(0,0,matrix.rows(),matrix.rows()).template triangularView().adjoint(); - if(svd.m_computeFullV) m_qr.householderQ().evalTo(svd.m_matrixV, m_workspace); - else if(svd.m_computeThinV) - { - svd.m_matrixV.setIdentity(matrix.cols(), matrix.rows()); - m_qr.householderQ().applyThisOnTheLeft(svd.m_matrixV, m_workspace); - } - if(svd.computeU()) svd.m_matrixU = m_qr.colsPermutation(); - return true; - } - else return false; - } - -private: - typedef ColPivHouseholderQR QRType; - QRType m_qr; - TransposeTypeWithSameStorageOrder m_adjoint; - typename internal::plain_row_type::type m_workspace; -}; - -/*** preconditioner using HouseholderQR ***/ - -template -class qr_preconditioner_impl -{ -public: - typedef typename MatrixType::Index Index; - - void allocate(const JacobiSVD& svd) - { - if (svd.rows() != m_qr.rows() || svd.cols() != m_qr.cols()) - { - m_qr.~QRType(); - ::new (&m_qr) QRType(svd.rows(), svd.cols()); - } - if (svd.m_computeFullU) m_workspace.resize(svd.rows()); - else if (svd.m_computeThinU) m_workspace.resize(svd.cols()); - } - - bool run(JacobiSVD& svd, const MatrixType& matrix) - { - if(matrix.rows() > matrix.cols()) - { - m_qr.compute(matrix); - svd.m_workMatrix = m_qr.matrixQR().block(0,0,matrix.cols(),matrix.cols()).template triangularView(); - if(svd.m_computeFullU) m_qr.householderQ().evalTo(svd.m_matrixU, m_workspace); - else if(svd.m_computeThinU) - { - svd.m_matrixU.setIdentity(matrix.rows(), matrix.cols()); - m_qr.householderQ().applyThisOnTheLeft(svd.m_matrixU, m_workspace); - } - if(svd.computeV()) svd.m_matrixV.setIdentity(matrix.cols(), matrix.cols()); - return true; - } - return false; - } -private: - typedef HouseholderQR QRType; - QRType m_qr; - typename internal::plain_col_type::type m_workspace; -}; - -template -class qr_preconditioner_impl -{ -public: - typedef typename MatrixType::Index Index; - typedef typename MatrixType::Scalar Scalar; - enum - { - RowsAtCompileTime = MatrixType::RowsAtCompileTime, - ColsAtCompileTime = MatrixType::ColsAtCompileTime, - MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime, - MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime, - Options = MatrixType::Options - }; - - typedef Matrix - TransposeTypeWithSameStorageOrder; - - void allocate(const JacobiSVD& svd) - { - if (svd.cols() != m_qr.rows() || svd.rows() != m_qr.cols()) - { - m_qr.~QRType(); - ::new (&m_qr) QRType(svd.cols(), svd.rows()); - } - if (svd.m_computeFullV) m_workspace.resize(svd.cols()); - else if (svd.m_computeThinV) m_workspace.resize(svd.rows()); - m_adjoint.resize(svd.cols(), svd.rows()); - } - - bool run(JacobiSVD& svd, const MatrixType& matrix) - { - if(matrix.cols() > matrix.rows()) - { - m_adjoint = matrix.adjoint(); - m_qr.compute(m_adjoint); - - svd.m_workMatrix = m_qr.matrixQR().block(0,0,matrix.rows(),matrix.rows()).template triangularView().adjoint(); - if(svd.m_computeFullV) m_qr.householderQ().evalTo(svd.m_matrixV, m_workspace); - else if(svd.m_computeThinV) - { - svd.m_matrixV.setIdentity(matrix.cols(), matrix.rows()); - m_qr.householderQ().applyThisOnTheLeft(svd.m_matrixV, m_workspace); - } - if(svd.computeU()) svd.m_matrixU.setIdentity(matrix.rows(), matrix.rows()); - return true; - } - else return false; - } - -private: - typedef HouseholderQR QRType; - QRType m_qr; - TransposeTypeWithSameStorageOrder m_adjoint; - typename internal::plain_row_type::type m_workspace; -}; - -/*** 2x2 SVD implementation - *** - *** JacobiSVD consists in performing a series of 2x2 SVD subproblems - ***/ - -template -struct svd_precondition_2x2_block_to_be_real -{ - typedef JacobiSVD SVD; - typedef typename SVD::Index Index; - static void run(typename SVD::WorkMatrixType&, SVD&, Index, Index) {} -}; - -template -struct svd_precondition_2x2_block_to_be_real -{ - typedef JacobiSVD SVD; - typedef typename MatrixType::Scalar Scalar; - typedef typename MatrixType::RealScalar RealScalar; - typedef typename SVD::Index Index; - static void run(typename SVD::WorkMatrixType& work_matrix, SVD& svd, Index p, Index q) - { - using std::sqrt; - Scalar z; - JacobiRotation rot; - RealScalar n = sqrt(numext::abs2(work_matrix.coeff(p,p)) + numext::abs2(work_matrix.coeff(q,p))); - - if(n==0) - { - z = abs(work_matrix.coeff(p,q)) / work_matrix.coeff(p,q); - work_matrix.row(p) *= z; - if(svd.computeU()) svd.m_matrixU.col(p) *= conj(z); - if(work_matrix.coeff(q,q)!=Scalar(0)) - { - z = abs(work_matrix.coeff(q,q)) / work_matrix.coeff(q,q); - work_matrix.row(q) *= z; - if(svd.computeU()) svd.m_matrixU.col(q) *= conj(z); - } - // otherwise the second row is already zero, so we have nothing to do. - } - else - { - rot.c() = conj(work_matrix.coeff(p,p)) / n; - rot.s() = work_matrix.coeff(q,p) / n; - work_matrix.applyOnTheLeft(p,q,rot); - if(svd.computeU()) svd.m_matrixU.applyOnTheRight(p,q,rot.adjoint()); - if(work_matrix.coeff(p,q) != Scalar(0)) - { - Scalar z = abs(work_matrix.coeff(p,q)) / work_matrix.coeff(p,q); - work_matrix.col(q) *= z; - if(svd.computeV()) svd.m_matrixV.col(q) *= z; - } - if(work_matrix.coeff(q,q) != Scalar(0)) - { - z = abs(work_matrix.coeff(q,q)) / work_matrix.coeff(q,q); - work_matrix.row(q) *= z; - if(svd.computeU()) svd.m_matrixU.col(q) *= conj(z); - } - } - } -}; - -template -void real_2x2_jacobi_svd(const MatrixType& matrix, Index p, Index q, - JacobiRotation *j_left, - JacobiRotation *j_right) -{ - using std::sqrt; - using std::abs; - Matrix m; - m << numext::real(matrix.coeff(p,p)), numext::real(matrix.coeff(p,q)), - numext::real(matrix.coeff(q,p)), numext::real(matrix.coeff(q,q)); - JacobiRotation rot1; - RealScalar t = m.coeff(0,0) + m.coeff(1,1); - RealScalar d = m.coeff(1,0) - m.coeff(0,1); - if(t == RealScalar(0)) - { - rot1.c() = RealScalar(0); - rot1.s() = d > RealScalar(0) ? RealScalar(1) : RealScalar(-1); - } - else - { - RealScalar t2d2 = numext::hypot(t,d); - rot1.c() = abs(t)/t2d2; - rot1.s() = d/t2d2; - if(tmakeJacobi(m,0,1); - *j_left = rot1 * j_right->transpose(); -} - -} // end namespace internal - -/** \ingroup SVD_Module - * - * - * \class JacobiSVD - * - * \brief Two-sided Jacobi SVD decomposition of a rectangular matrix - * - * \param MatrixType the type of the matrix of which we are computing the SVD decomposition - * \param QRPreconditioner this optional parameter allows to specify the type of QR decomposition that will be used internally - * for the R-SVD step for non-square matrices. See discussion of possible values below. - * - * SVD decomposition consists in decomposing any n-by-p matrix \a A as a product - * \f[ A = U S V^* \f] - * where \a U is a n-by-n unitary, \a V is a p-by-p unitary, and \a S is a n-by-p real positive matrix which is zero outside of its main diagonal; - * the diagonal entries of S are known as the \em singular \em values of \a A and the columns of \a U and \a V are known as the left - * and right \em singular \em vectors of \a A respectively. - * - * Singular values are always sorted in decreasing order. - * - * This JacobiSVD decomposition computes only the singular values by default. If you want \a U or \a V, you need to ask for them explicitly. - * - * You can ask for only \em thin \a U or \a V to be computed, meaning the following. In case of a rectangular n-by-p matrix, letting \a m be the - * smaller value among \a n and \a p, there are only \a m singular vectors; the remaining columns of \a U and \a V do not correspond to actual - * singular vectors. Asking for \em thin \a U or \a V means asking for only their \a m first columns to be formed. So \a U is then a n-by-m matrix, - * and \a V is then a p-by-m matrix. Notice that thin \a U and \a V are all you need for (least squares) solving. - * - * Here's an example demonstrating basic usage: - * \include JacobiSVD_basic.cpp - * Output: \verbinclude JacobiSVD_basic.out - * - * This JacobiSVD class is a two-sided Jacobi R-SVD decomposition, ensuring optimal reliability and accuracy. The downside is that it's slower than - * bidiagonalizing SVD algorithms for large square matrices; however its complexity is still \f$ O(n^2p) \f$ where \a n is the smaller dimension and - * \a p is the greater dimension, meaning that it is still of the same order of complexity as the faster bidiagonalizing R-SVD algorithms. - * In particular, like any R-SVD, it takes advantage of non-squareness in that its complexity is only linear in the greater dimension. - * - * If the input matrix has inf or nan coefficients, the result of the computation is undefined, but the computation is guaranteed to - * terminate in finite (and reasonable) time. - * - * The possible values for QRPreconditioner are: - * \li ColPivHouseholderQRPreconditioner is the default. In practice it's very safe. It uses column-pivoting QR. - * \li FullPivHouseholderQRPreconditioner, is the safest and slowest. It uses full-pivoting QR. - * Contrary to other QRs, it doesn't allow computing thin unitaries. - * \li HouseholderQRPreconditioner is the fastest, and less safe and accurate than the pivoting variants. It uses non-pivoting QR. - * This is very similar in safety and accuracy to the bidiagonalization process used by bidiagonalizing SVD algorithms (since bidiagonalization - * is inherently non-pivoting). However the resulting SVD is still more reliable than bidiagonalizing SVDs because the Jacobi-based iterarive - * process is more reliable than the optimized bidiagonal SVD iterations. - * \li NoQRPreconditioner allows not to use a QR preconditioner at all. This is useful if you know that you will only be computing - * JacobiSVD decompositions of square matrices. Non-square matrices require a QR preconditioner. Using this option will result in - * faster compilation and smaller executable code. It won't significantly speed up computation, since JacobiSVD is always checking - * if QR preconditioning is needed before applying it anyway. - * - * \sa MatrixBase::jacobiSvd() - */ -template class JacobiSVD -{ - public: - - typedef _MatrixType MatrixType; - typedef typename MatrixType::Scalar Scalar; - typedef typename NumTraits::Real RealScalar; - typedef typename MatrixType::Index Index; - enum { - RowsAtCompileTime = MatrixType::RowsAtCompileTime, - ColsAtCompileTime = MatrixType::ColsAtCompileTime, - DiagSizeAtCompileTime = EIGEN_SIZE_MIN_PREFER_DYNAMIC(RowsAtCompileTime,ColsAtCompileTime), - MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime, - MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime, - MaxDiagSizeAtCompileTime = EIGEN_SIZE_MIN_PREFER_FIXED(MaxRowsAtCompileTime,MaxColsAtCompileTime), - MatrixOptions = MatrixType::Options - }; - - typedef Matrix - MatrixUType; - typedef Matrix - MatrixVType; - typedef typename internal::plain_diag_type::type SingularValuesType; - typedef typename internal::plain_row_type::type RowType; - typedef typename internal::plain_col_type::type ColType; - typedef Matrix - WorkMatrixType; - - /** \brief Default Constructor. - * - * The default constructor is useful in cases in which the user intends to - * perform decompositions via JacobiSVD::compute(const MatrixType&). - */ - JacobiSVD() - : m_isInitialized(false), - m_isAllocated(false), - m_usePrescribedThreshold(false), - m_computationOptions(0), - m_rows(-1), m_cols(-1), m_diagSize(0) - {} - - - /** \brief Default Constructor with memory preallocation - * - * Like the default constructor but with preallocation of the internal data - * according to the specified problem size. - * \sa JacobiSVD() - */ - JacobiSVD(Index rows, Index cols, unsigned int computationOptions = 0) - : m_isInitialized(false), - m_isAllocated(false), - m_usePrescribedThreshold(false), - m_computationOptions(0), - m_rows(-1), m_cols(-1) - { - allocate(rows, cols, computationOptions); - } - - /** \brief Constructor performing the decomposition of given matrix. - * - * \param matrix the matrix to decompose - * \param computationOptions optional parameter allowing to specify if you want full or thin U or V unitaries to be computed. - * By default, none is computed. This is a bit-field, the possible bits are #ComputeFullU, #ComputeThinU, - * #ComputeFullV, #ComputeThinV. - * - * Thin unitaries are only available if your matrix type has a Dynamic number of columns (for example MatrixXf). They also are not - * available with the (non-default) FullPivHouseholderQR preconditioner. - */ - JacobiSVD(const MatrixType& matrix, unsigned int computationOptions = 0) - : m_isInitialized(false), - m_isAllocated(false), - m_usePrescribedThreshold(false), - m_computationOptions(0), - m_rows(-1), m_cols(-1) - { - compute(matrix, computationOptions); - } - - /** \brief Method performing the decomposition of given matrix using custom options. - * - * \param matrix the matrix to decompose - * \param computationOptions optional parameter allowing to specify if you want full or thin U or V unitaries to be computed. - * By default, none is computed. This is a bit-field, the possible bits are #ComputeFullU, #ComputeThinU, - * #ComputeFullV, #ComputeThinV. - * - * Thin unitaries are only available if your matrix type has a Dynamic number of columns (for example MatrixXf). They also are not - * available with the (non-default) FullPivHouseholderQR preconditioner. - */ - JacobiSVD& compute(const MatrixType& matrix, unsigned int computationOptions); - - /** \brief Method performing the decomposition of given matrix using current options. - * - * \param matrix the matrix to decompose - * - * This method uses the current \a computationOptions, as already passed to the constructor or to compute(const MatrixType&, unsigned int). - */ - JacobiSVD& compute(const MatrixType& matrix) - { - return compute(matrix, m_computationOptions); - } - - /** \returns the \a U matrix. - * - * For the SVD decomposition of a n-by-p matrix, letting \a m be the minimum of \a n and \a p, - * the U matrix is n-by-n if you asked for #ComputeFullU, and is n-by-m if you asked for #ComputeThinU. - * - * The \a m first columns of \a U are the left singular vectors of the matrix being decomposed. - * - * This method asserts that you asked for \a U to be computed. - */ - const MatrixUType& matrixU() const - { - eigen_assert(m_isInitialized && "JacobiSVD is not initialized."); - eigen_assert(computeU() && "This JacobiSVD decomposition didn't compute U. Did you ask for it?"); - return m_matrixU; - } - - /** \returns the \a V matrix. - * - * For the SVD decomposition of a n-by-p matrix, letting \a m be the minimum of \a n and \a p, - * the V matrix is p-by-p if you asked for #ComputeFullV, and is p-by-m if you asked for ComputeThinV. - * - * The \a m first columns of \a V are the right singular vectors of the matrix being decomposed. - * - * This method asserts that you asked for \a V to be computed. - */ - const MatrixVType& matrixV() const - { - eigen_assert(m_isInitialized && "JacobiSVD is not initialized."); - eigen_assert(computeV() && "This JacobiSVD decomposition didn't compute V. Did you ask for it?"); - return m_matrixV; - } - - /** \returns the vector of singular values. - * - * For the SVD decomposition of a n-by-p matrix, letting \a m be the minimum of \a n and \a p, the - * returned vector has size \a m. Singular values are always sorted in decreasing order. - */ - const SingularValuesType& singularValues() const - { - eigen_assert(m_isInitialized && "JacobiSVD is not initialized."); - return m_singularValues; - } - - /** \returns true if \a U (full or thin) is asked for in this SVD decomposition */ - inline bool computeU() const { return m_computeFullU || m_computeThinU; } - /** \returns true if \a V (full or thin) is asked for in this SVD decomposition */ - inline bool computeV() const { return m_computeFullV || m_computeThinV; } - - /** \returns a (least squares) solution of \f$ A x = b \f$ using the current SVD decomposition of A. - * - * \param b the right-hand-side of the equation to solve. - * - * \note Solving requires both U and V to be computed. Thin U and V are enough, there is no need for full U or V. - * - * \note SVD solving is implicitly least-squares. Thus, this method serves both purposes of exact solving and least-squares solving. - * In other words, the returned solution is guaranteed to minimize the Euclidean norm \f$ \Vert A x - b \Vert \f$. - */ - template - inline const internal::solve_retval - solve(const MatrixBase& b) const - { - eigen_assert(m_isInitialized && "JacobiSVD is not initialized."); - eigen_assert(computeU() && computeV() && "JacobiSVD::solve() requires both unitaries U and V to be computed (thin unitaries suffice)."); - return internal::solve_retval(*this, b.derived()); - } - - /** \returns the number of singular values that are not exactly 0 */ - Index nonzeroSingularValues() const - { - eigen_assert(m_isInitialized && "JacobiSVD is not initialized."); - return m_nonzeroSingularValues; - } - - /** \returns the rank of the matrix of which \c *this is the SVD. - * - * \note This method has to determine which singular values should be considered nonzero. - * For that, it uses the threshold value that you can control by calling - * setThreshold(const RealScalar&). - */ - inline Index rank() const - { - using std::abs; - eigen_assert(m_isInitialized && "JacobiSVD is not initialized."); - if(m_singularValues.size()==0) return 0; - RealScalar premultiplied_threshold = m_singularValues.coeff(0) * threshold(); - Index i = m_nonzeroSingularValues-1; - while(i>=0 && m_singularValues.coeff(i) < premultiplied_threshold) --i; - return i+1; - } - - /** Allows to prescribe a threshold to be used by certain methods, such as rank() and solve(), - * which need to determine when singular values are to be considered nonzero. - * This is not used for the SVD decomposition itself. - * - * When it needs to get the threshold value, Eigen calls threshold(). - * The default is \c NumTraits::epsilon() - * - * \param threshold The new value to use as the threshold. - * - * A singular value will be considered nonzero if its value is strictly greater than - * \f$ \vert singular value \vert \leqslant threshold \times \vert max singular value \vert \f$. - * - * If you want to come back to the default behavior, call setThreshold(Default_t) - */ - JacobiSVD& setThreshold(const RealScalar& threshold) - { - m_usePrescribedThreshold = true; - m_prescribedThreshold = threshold; - return *this; - } - - /** Allows to come back to the default behavior, letting Eigen use its default formula for - * determining the threshold. - * - * You should pass the special object Eigen::Default as parameter here. - * \code svd.setThreshold(Eigen::Default); \endcode - * - * See the documentation of setThreshold(const RealScalar&). - */ - JacobiSVD& setThreshold(Default_t) - { - m_usePrescribedThreshold = false; - return *this; - } - - /** Returns the threshold that will be used by certain methods such as rank(). - * - * See the documentation of setThreshold(const RealScalar&). - */ - RealScalar threshold() const - { - eigen_assert(m_isInitialized || m_usePrescribedThreshold); - return m_usePrescribedThreshold ? m_prescribedThreshold - : (std::max)(1,m_diagSize)*NumTraits::epsilon(); - } - - inline Index rows() const { return m_rows; } - inline Index cols() const { return m_cols; } - - private: - void allocate(Index rows, Index cols, unsigned int computationOptions); - - static void check_template_parameters() - { - EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar); - } - - protected: - MatrixUType m_matrixU; - MatrixVType m_matrixV; - SingularValuesType m_singularValues; - WorkMatrixType m_workMatrix; - bool m_isInitialized, m_isAllocated, m_usePrescribedThreshold; - bool m_computeFullU, m_computeThinU; - bool m_computeFullV, m_computeThinV; - unsigned int m_computationOptions; - Index m_nonzeroSingularValues, m_rows, m_cols, m_diagSize; - RealScalar m_prescribedThreshold; - - template - friend struct internal::svd_precondition_2x2_block_to_be_real; - template - friend struct internal::qr_preconditioner_impl; - - internal::qr_preconditioner_impl m_qr_precond_morecols; - internal::qr_preconditioner_impl m_qr_precond_morerows; - MatrixType m_scaledMatrix; -}; - -template -void JacobiSVD::allocate(Index rows, Index cols, unsigned int computationOptions) -{ - eigen_assert(rows >= 0 && cols >= 0); - - if (m_isAllocated && - rows == m_rows && - cols == m_cols && - computationOptions == m_computationOptions) - { - return; - } - - m_rows = rows; - m_cols = cols; - m_isInitialized = false; - m_isAllocated = true; - m_computationOptions = computationOptions; - m_computeFullU = (computationOptions & ComputeFullU) != 0; - m_computeThinU = (computationOptions & ComputeThinU) != 0; - m_computeFullV = (computationOptions & ComputeFullV) != 0; - m_computeThinV = (computationOptions & ComputeThinV) != 0; - eigen_assert(!(m_computeFullU && m_computeThinU) && "JacobiSVD: you can't ask for both full and thin U"); - eigen_assert(!(m_computeFullV && m_computeThinV) && "JacobiSVD: you can't ask for both full and thin V"); - eigen_assert(EIGEN_IMPLIES(m_computeThinU || m_computeThinV, MatrixType::ColsAtCompileTime==Dynamic) && - "JacobiSVD: thin U and V are only available when your matrix has a dynamic number of columns."); - if (QRPreconditioner == FullPivHouseholderQRPreconditioner) - { - eigen_assert(!(m_computeThinU || m_computeThinV) && - "JacobiSVD: can't compute thin U or thin V with the FullPivHouseholderQR preconditioner. " - "Use the ColPivHouseholderQR preconditioner instead."); - } - m_diagSize = (std::min)(m_rows, m_cols); - m_singularValues.resize(m_diagSize); - if(RowsAtCompileTime==Dynamic) - m_matrixU.resize(m_rows, m_computeFullU ? m_rows - : m_computeThinU ? m_diagSize - : 0); - if(ColsAtCompileTime==Dynamic) - m_matrixV.resize(m_cols, m_computeFullV ? m_cols - : m_computeThinV ? m_diagSize - : 0); - m_workMatrix.resize(m_diagSize, m_diagSize); - - if(m_cols>m_rows) m_qr_precond_morecols.allocate(*this); - if(m_rows>m_cols) m_qr_precond_morerows.allocate(*this); - if(m_cols!=m_cols) m_scaledMatrix.resize(rows,cols); -} - -template -JacobiSVD& -JacobiSVD::compute(const MatrixType& matrix, unsigned int computationOptions) -{ - check_template_parameters(); - - using std::abs; - allocate(matrix.rows(), matrix.cols(), computationOptions); - - // currently we stop when we reach precision 2*epsilon as the last bit of precision can require an unreasonable number of iterations, - // only worsening the precision of U and V as we accumulate more rotations - const RealScalar precision = RealScalar(2) * NumTraits::epsilon(); - - // limit for very small denormal numbers to be considered zero in order to avoid infinite loops (see bug 286) - const RealScalar considerAsZero = RealScalar(2) * std::numeric_limits::denorm_min(); - - // Scaling factor to reduce over/under-flows - RealScalar scale = matrix.cwiseAbs().maxCoeff(); - if(scale==RealScalar(0)) scale = RealScalar(1); - - /*** step 1. The R-SVD step: we use a QR decomposition to reduce to the case of a square matrix */ - - if(m_rows!=m_cols) - { - m_scaledMatrix = matrix / scale; - m_qr_precond_morecols.run(*this, m_scaledMatrix); - m_qr_precond_morerows.run(*this, m_scaledMatrix); - } - else - { - m_workMatrix = matrix.block(0,0,m_diagSize,m_diagSize) / scale; - if(m_computeFullU) m_matrixU.setIdentity(m_rows,m_rows); - if(m_computeThinU) m_matrixU.setIdentity(m_rows,m_diagSize); - if(m_computeFullV) m_matrixV.setIdentity(m_cols,m_cols); - if(m_computeThinV) m_matrixV.setIdentity(m_cols, m_diagSize); - } - - /*** step 2. The main Jacobi SVD iteration. ***/ - - bool finished = false; - while(!finished) - { - finished = true; - - // do a sweep: for all index pairs (p,q), perform SVD of the corresponding 2x2 sub-matrix - - for(Index p = 1; p < m_diagSize; ++p) - { - for(Index q = 0; q < p; ++q) - { - // if this 2x2 sub-matrix is not diagonal already... - // notice that this comparison will evaluate to false if any NaN is involved, ensuring that NaN's don't - // keep us iterating forever. Similarly, small denormal numbers are considered zero. - using std::max; - RealScalar threshold = (max)(considerAsZero, precision * (max)(abs(m_workMatrix.coeff(p,p)), - abs(m_workMatrix.coeff(q,q)))); - // We compare both values to threshold instead of calling max to be robust to NaN (See bug 791) - if(abs(m_workMatrix.coeff(p,q))>threshold || abs(m_workMatrix.coeff(q,p)) > threshold) - { - finished = false; - - // perform SVD decomposition of 2x2 sub-matrix corresponding to indices p,q to make it diagonal - internal::svd_precondition_2x2_block_to_be_real::run(m_workMatrix, *this, p, q); - JacobiRotation j_left, j_right; - internal::real_2x2_jacobi_svd(m_workMatrix, p, q, &j_left, &j_right); - - // accumulate resulting Jacobi rotations - m_workMatrix.applyOnTheLeft(p,q,j_left); - if(computeU()) m_matrixU.applyOnTheRight(p,q,j_left.transpose()); - - m_workMatrix.applyOnTheRight(p,q,j_right); - if(computeV()) m_matrixV.applyOnTheRight(p,q,j_right); - } - } - } - } - - /*** step 3. The work matrix is now diagonal, so ensure it's positive so its diagonal entries are the singular values ***/ - - for(Index i = 0; i < m_diagSize; ++i) - { - RealScalar a = abs(m_workMatrix.coeff(i,i)); - m_singularValues.coeffRef(i) = a; - if(computeU() && (a!=RealScalar(0))) m_matrixU.col(i) *= m_workMatrix.coeff(i,i)/a; - } - - /*** step 4. Sort singular values in descending order and compute the number of nonzero singular values ***/ - - m_nonzeroSingularValues = m_diagSize; - for(Index i = 0; i < m_diagSize; i++) - { - Index pos; - RealScalar maxRemainingSingularValue = m_singularValues.tail(m_diagSize-i).maxCoeff(&pos); - if(maxRemainingSingularValue == RealScalar(0)) - { - m_nonzeroSingularValues = i; - break; - } - if(pos) - { - pos += i; - std::swap(m_singularValues.coeffRef(i), m_singularValues.coeffRef(pos)); - if(computeU()) m_matrixU.col(pos).swap(m_matrixU.col(i)); - if(computeV()) m_matrixV.col(pos).swap(m_matrixV.col(i)); - } - } - - m_singularValues *= scale; - - m_isInitialized = true; - return *this; -} - -namespace internal { -template -struct solve_retval, Rhs> - : solve_retval_base, Rhs> -{ - typedef JacobiSVD<_MatrixType, QRPreconditioner> JacobiSVDType; - EIGEN_MAKE_SOLVE_HELPERS(JacobiSVDType,Rhs) - - template void evalTo(Dest& dst) const - { - eigen_assert(rhs().rows() == dec().rows()); - - // A = U S V^* - // So A^{-1} = V S^{-1} U^* - - Matrix tmp; - Index rank = dec().rank(); - - tmp.noalias() = dec().matrixU().leftCols(rank).adjoint() * rhs(); - tmp = dec().singularValues().head(rank).asDiagonal().inverse() * tmp; - dst = dec().matrixV().leftCols(rank) * tmp; - } -}; -} // end namespace internal - -/** \svd_module - * - * \return the singular value decomposition of \c *this computed by two-sided - * Jacobi transformations. - * - * \sa class JacobiSVD - */ -template -JacobiSVD::PlainObject> -MatrixBase::jacobiSvd(unsigned int computationOptions) const -{ - return JacobiSVD(*this, computationOptions); -} - -} // end namespace Eigen - -#endif // EIGEN_JACOBISVD_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/SVD/JacobiSVD_MKL.h b/thirdparty/eigen-3.2.7/Eigen/src/SVD/JacobiSVD_MKL.h deleted file mode 100644 index decda754..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/SVD/JacobiSVD_MKL.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - Copyright (c) 2011, Intel Corporation. All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of Intel Corporation nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - ******************************************************************************** - * Content : Eigen bindings to Intel(R) MKL - * Singular Value Decomposition - SVD. - ******************************************************************************** -*/ - -#ifndef EIGEN_JACOBISVD_MKL_H -#define EIGEN_JACOBISVD_MKL_H - -#include "Eigen/src/Core/util/MKL_support.h" - -namespace Eigen { - -/** \internal Specialization for the data types supported by MKL */ - -#define EIGEN_MKL_SVD(EIGTYPE, MKLTYPE, MKLRTYPE, MKLPREFIX, EIGCOLROW, MKLCOLROW) \ -template<> inline \ -JacobiSVD, ColPivHouseholderQRPreconditioner>& \ -JacobiSVD, ColPivHouseholderQRPreconditioner>::compute(const Matrix& matrix, unsigned int computationOptions) \ -{ \ - typedef Matrix MatrixType; \ - typedef MatrixType::Scalar Scalar; \ - typedef MatrixType::RealScalar RealScalar; \ - allocate(matrix.rows(), matrix.cols(), computationOptions); \ -\ - /*const RealScalar precision = RealScalar(2) * NumTraits::epsilon();*/ \ - m_nonzeroSingularValues = m_diagSize; \ -\ - lapack_int lda = matrix.outerStride(), ldu, ldvt; \ - lapack_int matrix_order = MKLCOLROW; \ - char jobu, jobvt; \ - MKLTYPE *u, *vt, dummy; \ - jobu = (m_computeFullU) ? 'A' : (m_computeThinU) ? 'S' : 'N'; \ - jobvt = (m_computeFullV) ? 'A' : (m_computeThinV) ? 'S' : 'N'; \ - if (computeU()) { \ - ldu = m_matrixU.outerStride(); \ - u = (MKLTYPE*)m_matrixU.data(); \ - } else { ldu=1; u=&dummy; }\ - MatrixType localV; \ - ldvt = (m_computeFullV) ? m_cols : (m_computeThinV) ? m_diagSize : 1; \ - if (computeV()) { \ - localV.resize(ldvt, m_cols); \ - vt = (MKLTYPE*)localV.data(); \ - } else { ldvt=1; vt=&dummy; }\ - Matrix superb; superb.resize(m_diagSize, 1); \ - MatrixType m_temp; m_temp = matrix; \ - LAPACKE_##MKLPREFIX##gesvd( matrix_order, jobu, jobvt, m_rows, m_cols, (MKLTYPE*)m_temp.data(), lda, (MKLRTYPE*)m_singularValues.data(), u, ldu, vt, ldvt, superb.data()); \ - if (computeV()) m_matrixV = localV.adjoint(); \ - /* for(int i=0;i -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_BIDIAGONALIZATION_H -#define EIGEN_BIDIAGONALIZATION_H - -namespace Eigen { - -namespace internal { -// UpperBidiagonalization will probably be replaced by a Bidiagonalization class, don't want to make it stable API. -// At the same time, it's useful to keep for now as it's about the only thing that is testing the BandMatrix class. - -template class UpperBidiagonalization -{ - public: - - typedef _MatrixType MatrixType; - enum { - RowsAtCompileTime = MatrixType::RowsAtCompileTime, - ColsAtCompileTime = MatrixType::ColsAtCompileTime, - ColsAtCompileTimeMinusOne = internal::decrement_size::ret - }; - typedef typename MatrixType::Scalar Scalar; - typedef typename MatrixType::RealScalar RealScalar; - typedef typename MatrixType::Index Index; - typedef Matrix RowVectorType; - typedef Matrix ColVectorType; - typedef BandMatrix BidiagonalType; - typedef Matrix DiagVectorType; - typedef Matrix SuperDiagVectorType; - typedef HouseholderSequence< - const MatrixType, - CwiseUnaryOp, const Diagonal > - > HouseholderUSequenceType; - typedef HouseholderSequence< - const typename internal::remove_all::type, - Diagonal, - OnTheRight - > HouseholderVSequenceType; - - /** - * \brief Default Constructor. - * - * The default constructor is useful in cases in which the user intends to - * perform decompositions via Bidiagonalization::compute(const MatrixType&). - */ - UpperBidiagonalization() : m_householder(), m_bidiagonal(), m_isInitialized(false) {} - - UpperBidiagonalization(const MatrixType& matrix) - : m_householder(matrix.rows(), matrix.cols()), - m_bidiagonal(matrix.cols(), matrix.cols()), - m_isInitialized(false) - { - compute(matrix); - } - - UpperBidiagonalization& compute(const MatrixType& matrix); - - const MatrixType& householder() const { return m_householder; } - const BidiagonalType& bidiagonal() const { return m_bidiagonal; } - - const HouseholderUSequenceType householderU() const - { - eigen_assert(m_isInitialized && "UpperBidiagonalization is not initialized."); - return HouseholderUSequenceType(m_householder, m_householder.diagonal().conjugate()); - } - - const HouseholderVSequenceType householderV() // const here gives nasty errors and i'm lazy - { - eigen_assert(m_isInitialized && "UpperBidiagonalization is not initialized."); - return HouseholderVSequenceType(m_householder.conjugate(), m_householder.const_derived().template diagonal<1>()) - .setLength(m_householder.cols()-1) - .setShift(1); - } - - protected: - MatrixType m_householder; - BidiagonalType m_bidiagonal; - bool m_isInitialized; -}; - -template -UpperBidiagonalization<_MatrixType>& UpperBidiagonalization<_MatrixType>::compute(const _MatrixType& matrix) -{ - Index rows = matrix.rows(); - Index cols = matrix.cols(); - - eigen_assert(rows >= cols && "UpperBidiagonalization is only for matrices satisfying rows>=cols."); - - m_householder = matrix; - - ColVectorType temp(rows); - - for (Index k = 0; /* breaks at k==cols-1 below */ ; ++k) - { - Index remainingRows = rows - k; - Index remainingCols = cols - k - 1; - - // construct left householder transform in-place in m_householder - m_householder.col(k).tail(remainingRows) - .makeHouseholderInPlace(m_householder.coeffRef(k,k), - m_bidiagonal.template diagonal<0>().coeffRef(k)); - // apply householder transform to remaining part of m_householder on the left - m_householder.bottomRightCorner(remainingRows, remainingCols) - .applyHouseholderOnTheLeft(m_householder.col(k).tail(remainingRows-1), - m_householder.coeff(k,k), - temp.data()); - - if(k == cols-1) break; - - // construct right householder transform in-place in m_householder - m_householder.row(k).tail(remainingCols) - .makeHouseholderInPlace(m_householder.coeffRef(k,k+1), - m_bidiagonal.template diagonal<1>().coeffRef(k)); - // apply householder transform to remaining part of m_householder on the left - m_householder.bottomRightCorner(remainingRows-1, remainingCols) - .applyHouseholderOnTheRight(m_householder.row(k).tail(remainingCols-1).transpose(), - m_householder.coeff(k,k+1), - temp.data()); - } - m_isInitialized = true; - return *this; -} - -#if 0 -/** \return the Householder QR decomposition of \c *this. - * - * \sa class Bidiagonalization - */ -template -const UpperBidiagonalization::PlainObject> -MatrixBase::bidiagonalization() const -{ - return UpperBidiagonalization(eval()); -} -#endif - -} // end namespace internal - -} // end namespace Eigen - -#endif // EIGEN_BIDIAGONALIZATION_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/SparseCholesky/SimplicialCholesky.h b/thirdparty/eigen-3.2.7/Eigen/src/SparseCholesky/SimplicialCholesky.h deleted file mode 100644 index e1f96ba5..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/SparseCholesky/SimplicialCholesky.h +++ /dev/null @@ -1,671 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2012 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_SIMPLICIAL_CHOLESKY_H -#define EIGEN_SIMPLICIAL_CHOLESKY_H - -namespace Eigen { - -enum SimplicialCholeskyMode { - SimplicialCholeskyLLT, - SimplicialCholeskyLDLT -}; - -/** \ingroup SparseCholesky_Module - * \brief A direct sparse Cholesky factorizations - * - * These classes provide LL^T and LDL^T Cholesky factorizations of sparse matrices that are - * selfadjoint and positive definite. The factorization allows for solving A.X = B where - * X and B can be either dense or sparse. - * - * In order to reduce the fill-in, a symmetric permutation P is applied prior to the factorization - * such that the factorized matrix is P A P^-1. - * - * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> - * \tparam _UpLo the triangular part that will be used for the computations. It can be Lower - * or Upper. Default is Lower. - * - */ -template -class SimplicialCholeskyBase : internal::noncopyable -{ - public: - typedef typename internal::traits::MatrixType MatrixType; - typedef typename internal::traits::OrderingType OrderingType; - enum { UpLo = internal::traits::UpLo }; - typedef typename MatrixType::Scalar Scalar; - typedef typename MatrixType::RealScalar RealScalar; - typedef typename MatrixType::Index Index; - typedef SparseMatrix CholMatrixType; - typedef Matrix VectorType; - - public: - - /** Default constructor */ - SimplicialCholeskyBase() - : m_info(Success), m_isInitialized(false), m_shiftOffset(0), m_shiftScale(1) - {} - - SimplicialCholeskyBase(const MatrixType& matrix) - : m_info(Success), m_isInitialized(false), m_shiftOffset(0), m_shiftScale(1) - { - derived().compute(matrix); - } - - ~SimplicialCholeskyBase() - { - } - - Derived& derived() { return *static_cast(this); } - const Derived& derived() const { return *static_cast(this); } - - inline Index cols() const { return m_matrix.cols(); } - inline Index rows() const { return m_matrix.rows(); } - - /** \brief Reports whether previous computation was successful. - * - * \returns \c Success if computation was succesful, - * \c NumericalIssue if the matrix.appears to be negative. - */ - ComputationInfo info() const - { - eigen_assert(m_isInitialized && "Decomposition is not initialized."); - return m_info; - } - - /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. - * - * \sa compute() - */ - template - inline const internal::solve_retval - solve(const MatrixBase& b) const - { - eigen_assert(m_isInitialized && "Simplicial LLT or LDLT is not initialized."); - eigen_assert(rows()==b.rows() - && "SimplicialCholeskyBase::solve(): invalid number of rows of the right hand side matrix b"); - return internal::solve_retval(*this, b.derived()); - } - - /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. - * - * \sa compute() - */ - template - inline const internal::sparse_solve_retval - solve(const SparseMatrixBase& b) const - { - eigen_assert(m_isInitialized && "Simplicial LLT or LDLT is not initialized."); - eigen_assert(rows()==b.rows() - && "SimplicialCholesky::solve(): invalid number of rows of the right hand side matrix b"); - return internal::sparse_solve_retval(*this, b.derived()); - } - - /** \returns the permutation P - * \sa permutationPinv() */ - const PermutationMatrix& permutationP() const - { return m_P; } - - /** \returns the inverse P^-1 of the permutation P - * \sa permutationP() */ - const PermutationMatrix& permutationPinv() const - { return m_Pinv; } - - /** Sets the shift parameters that will be used to adjust the diagonal coefficients during the numerical factorization. - * - * During the numerical factorization, the diagonal coefficients are transformed by the following linear model:\n - * \c d_ii = \a offset + \a scale * \c d_ii - * - * The default is the identity transformation with \a offset=0, and \a scale=1. - * - * \returns a reference to \c *this. - */ - Derived& setShift(const RealScalar& offset, const RealScalar& scale = 1) - { - m_shiftOffset = offset; - m_shiftScale = scale; - return derived(); - } - -#ifndef EIGEN_PARSED_BY_DOXYGEN - /** \internal */ - template - void dumpMemory(Stream& s) - { - int total = 0; - s << " L: " << ((total+=(m_matrix.cols()+1) * sizeof(int) + m_matrix.nonZeros()*(sizeof(int)+sizeof(Scalar))) >> 20) << "Mb" << "\n"; - s << " diag: " << ((total+=m_diag.size() * sizeof(Scalar)) >> 20) << "Mb" << "\n"; - s << " tree: " << ((total+=m_parent.size() * sizeof(int)) >> 20) << "Mb" << "\n"; - s << " nonzeros: " << ((total+=m_nonZerosPerCol.size() * sizeof(int)) >> 20) << "Mb" << "\n"; - s << " perm: " << ((total+=m_P.size() * sizeof(int)) >> 20) << "Mb" << "\n"; - s << " perm^-1: " << ((total+=m_Pinv.size() * sizeof(int)) >> 20) << "Mb" << "\n"; - s << " TOTAL: " << (total>> 20) << "Mb" << "\n"; - } - - /** \internal */ - template - void _solve(const MatrixBase &b, MatrixBase &dest) const - { - eigen_assert(m_factorizationIsOk && "The decomposition is not in a valid state for solving, you must first call either compute() or symbolic()/numeric()"); - eigen_assert(m_matrix.rows()==b.rows()); - - if(m_info!=Success) - return; - - if(m_P.size()>0) - dest = m_P * b; - else - dest = b; - - if(m_matrix.nonZeros()>0) // otherwise L==I - derived().matrixL().solveInPlace(dest); - - if(m_diag.size()>0) - dest = m_diag.asDiagonal().inverse() * dest; - - if (m_matrix.nonZeros()>0) // otherwise U==I - derived().matrixU().solveInPlace(dest); - - if(m_P.size()>0) - dest = m_Pinv * dest; - } - -#endif // EIGEN_PARSED_BY_DOXYGEN - - protected: - - /** Computes the sparse Cholesky decomposition of \a matrix */ - template - void compute(const MatrixType& matrix) - { - eigen_assert(matrix.rows()==matrix.cols()); - Index size = matrix.cols(); - CholMatrixType ap(size,size); - ordering(matrix, ap); - analyzePattern_preordered(ap, DoLDLT); - factorize_preordered(ap); - } - - template - void factorize(const MatrixType& a) - { - eigen_assert(a.rows()==a.cols()); - int size = a.cols(); - CholMatrixType ap(size,size); - ap.template selfadjointView() = a.template selfadjointView().twistedBy(m_P); - factorize_preordered(ap); - } - - template - void factorize_preordered(const CholMatrixType& a); - - void analyzePattern(const MatrixType& a, bool doLDLT) - { - eigen_assert(a.rows()==a.cols()); - int size = a.cols(); - CholMatrixType ap(size,size); - ordering(a, ap); - analyzePattern_preordered(ap,doLDLT); - } - void analyzePattern_preordered(const CholMatrixType& a, bool doLDLT); - - void ordering(const MatrixType& a, CholMatrixType& ap); - - /** keeps off-diagonal entries; drops diagonal entries */ - struct keep_diag { - inline bool operator() (const Index& row, const Index& col, const Scalar&) const - { - return row!=col; - } - }; - - mutable ComputationInfo m_info; - bool m_isInitialized; - bool m_factorizationIsOk; - bool m_analysisIsOk; - - CholMatrixType m_matrix; - VectorType m_diag; // the diagonal coefficients (LDLT mode) - VectorXi m_parent; // elimination tree - VectorXi m_nonZerosPerCol; - PermutationMatrix m_P; // the permutation - PermutationMatrix m_Pinv; // the inverse permutation - - RealScalar m_shiftOffset; - RealScalar m_shiftScale; -}; - -template > class SimplicialLLT; -template > class SimplicialLDLT; -template > class SimplicialCholesky; - -namespace internal { - -template struct traits > -{ - typedef _MatrixType MatrixType; - typedef _Ordering OrderingType; - enum { UpLo = _UpLo }; - typedef typename MatrixType::Scalar Scalar; - typedef typename MatrixType::Index Index; - typedef SparseMatrix CholMatrixType; - typedef SparseTriangularView MatrixL; - typedef SparseTriangularView MatrixU; - static inline MatrixL getL(const MatrixType& m) { return m; } - static inline MatrixU getU(const MatrixType& m) { return m.adjoint(); } -}; - -template struct traits > -{ - typedef _MatrixType MatrixType; - typedef _Ordering OrderingType; - enum { UpLo = _UpLo }; - typedef typename MatrixType::Scalar Scalar; - typedef typename MatrixType::Index Index; - typedef SparseMatrix CholMatrixType; - typedef SparseTriangularView MatrixL; - typedef SparseTriangularView MatrixU; - static inline MatrixL getL(const MatrixType& m) { return m; } - static inline MatrixU getU(const MatrixType& m) { return m.adjoint(); } -}; - -template struct traits > -{ - typedef _MatrixType MatrixType; - typedef _Ordering OrderingType; - enum { UpLo = _UpLo }; -}; - -} - -/** \ingroup SparseCholesky_Module - * \class SimplicialLLT - * \brief A direct sparse LLT Cholesky factorizations - * - * This class provides a LL^T Cholesky factorizations of sparse matrices that are - * selfadjoint and positive definite. The factorization allows for solving A.X = B where - * X and B can be either dense or sparse. - * - * In order to reduce the fill-in, a symmetric permutation P is applied prior to the factorization - * such that the factorized matrix is P A P^-1. - * - * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> - * \tparam _UpLo the triangular part that will be used for the computations. It can be Lower - * or Upper. Default is Lower. - * \tparam _Ordering The ordering method to use, either AMDOrdering<> or NaturalOrdering<>. Default is AMDOrdering<> - * - * \sa class SimplicialLDLT, class AMDOrdering, class NaturalOrdering - */ -template - class SimplicialLLT : public SimplicialCholeskyBase > -{ -public: - typedef _MatrixType MatrixType; - enum { UpLo = _UpLo }; - typedef SimplicialCholeskyBase Base; - typedef typename MatrixType::Scalar Scalar; - typedef typename MatrixType::RealScalar RealScalar; - typedef typename MatrixType::Index Index; - typedef SparseMatrix CholMatrixType; - typedef Matrix VectorType; - typedef internal::traits Traits; - typedef typename Traits::MatrixL MatrixL; - typedef typename Traits::MatrixU MatrixU; -public: - /** Default constructor */ - SimplicialLLT() : Base() {} - /** Constructs and performs the LLT factorization of \a matrix */ - SimplicialLLT(const MatrixType& matrix) - : Base(matrix) {} - - /** \returns an expression of the factor L */ - inline const MatrixL matrixL() const { - eigen_assert(Base::m_factorizationIsOk && "Simplicial LLT not factorized"); - return Traits::getL(Base::m_matrix); - } - - /** \returns an expression of the factor U (= L^*) */ - inline const MatrixU matrixU() const { - eigen_assert(Base::m_factorizationIsOk && "Simplicial LLT not factorized"); - return Traits::getU(Base::m_matrix); - } - - /** Computes the sparse Cholesky decomposition of \a matrix */ - SimplicialLLT& compute(const MatrixType& matrix) - { - Base::template compute(matrix); - return *this; - } - - /** Performs a symbolic decomposition on the sparcity of \a matrix. - * - * This function is particularly useful when solving for several problems having the same structure. - * - * \sa factorize() - */ - void analyzePattern(const MatrixType& a) - { - Base::analyzePattern(a, false); - } - - /** Performs a numeric decomposition of \a matrix - * - * The given matrix must has the same sparcity than the matrix on which the symbolic decomposition has been performed. - * - * \sa analyzePattern() - */ - void factorize(const MatrixType& a) - { - Base::template factorize(a); - } - - /** \returns the determinant of the underlying matrix from the current factorization */ - Scalar determinant() const - { - Scalar detL = Base::m_matrix.diagonal().prod(); - return numext::abs2(detL); - } -}; - -/** \ingroup SparseCholesky_Module - * \class SimplicialLDLT - * \brief A direct sparse LDLT Cholesky factorizations without square root. - * - * This class provides a LDL^T Cholesky factorizations without square root of sparse matrices that are - * selfadjoint and positive definite. The factorization allows for solving A.X = B where - * X and B can be either dense or sparse. - * - * In order to reduce the fill-in, a symmetric permutation P is applied prior to the factorization - * such that the factorized matrix is P A P^-1. - * - * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> - * \tparam _UpLo the triangular part that will be used for the computations. It can be Lower - * or Upper. Default is Lower. - * \tparam _Ordering The ordering method to use, either AMDOrdering<> or NaturalOrdering<>. Default is AMDOrdering<> - * - * \sa class SimplicialLLT, class AMDOrdering, class NaturalOrdering - */ -template - class SimplicialLDLT : public SimplicialCholeskyBase > -{ -public: - typedef _MatrixType MatrixType; - enum { UpLo = _UpLo }; - typedef SimplicialCholeskyBase Base; - typedef typename MatrixType::Scalar Scalar; - typedef typename MatrixType::RealScalar RealScalar; - typedef typename MatrixType::Index Index; - typedef SparseMatrix CholMatrixType; - typedef Matrix VectorType; - typedef internal::traits Traits; - typedef typename Traits::MatrixL MatrixL; - typedef typename Traits::MatrixU MatrixU; -public: - /** Default constructor */ - SimplicialLDLT() : Base() {} - - /** Constructs and performs the LLT factorization of \a matrix */ - SimplicialLDLT(const MatrixType& matrix) - : Base(matrix) {} - - /** \returns a vector expression of the diagonal D */ - inline const VectorType vectorD() const { - eigen_assert(Base::m_factorizationIsOk && "Simplicial LDLT not factorized"); - return Base::m_diag; - } - /** \returns an expression of the factor L */ - inline const MatrixL matrixL() const { - eigen_assert(Base::m_factorizationIsOk && "Simplicial LDLT not factorized"); - return Traits::getL(Base::m_matrix); - } - - /** \returns an expression of the factor U (= L^*) */ - inline const MatrixU matrixU() const { - eigen_assert(Base::m_factorizationIsOk && "Simplicial LDLT not factorized"); - return Traits::getU(Base::m_matrix); - } - - /** Computes the sparse Cholesky decomposition of \a matrix */ - SimplicialLDLT& compute(const MatrixType& matrix) - { - Base::template compute(matrix); - return *this; - } - - /** Performs a symbolic decomposition on the sparcity of \a matrix. - * - * This function is particularly useful when solving for several problems having the same structure. - * - * \sa factorize() - */ - void analyzePattern(const MatrixType& a) - { - Base::analyzePattern(a, true); - } - - /** Performs a numeric decomposition of \a matrix - * - * The given matrix must has the same sparcity than the matrix on which the symbolic decomposition has been performed. - * - * \sa analyzePattern() - */ - void factorize(const MatrixType& a) - { - Base::template factorize(a); - } - - /** \returns the determinant of the underlying matrix from the current factorization */ - Scalar determinant() const - { - return Base::m_diag.prod(); - } -}; - -/** \deprecated use SimplicialLDLT or class SimplicialLLT - * \ingroup SparseCholesky_Module - * \class SimplicialCholesky - * - * \sa class SimplicialLDLT, class SimplicialLLT - */ -template - class SimplicialCholesky : public SimplicialCholeskyBase > -{ -public: - typedef _MatrixType MatrixType; - enum { UpLo = _UpLo }; - typedef SimplicialCholeskyBase Base; - typedef typename MatrixType::Scalar Scalar; - typedef typename MatrixType::RealScalar RealScalar; - typedef typename MatrixType::Index Index; - typedef SparseMatrix CholMatrixType; - typedef Matrix VectorType; - typedef internal::traits Traits; - typedef internal::traits > LDLTTraits; - typedef internal::traits > LLTTraits; - public: - SimplicialCholesky() : Base(), m_LDLT(true) {} - - SimplicialCholesky(const MatrixType& matrix) - : Base(), m_LDLT(true) - { - compute(matrix); - } - - SimplicialCholesky& setMode(SimplicialCholeskyMode mode) - { - switch(mode) - { - case SimplicialCholeskyLLT: - m_LDLT = false; - break; - case SimplicialCholeskyLDLT: - m_LDLT = true; - break; - default: - break; - } - - return *this; - } - - inline const VectorType vectorD() const { - eigen_assert(Base::m_factorizationIsOk && "Simplicial Cholesky not factorized"); - return Base::m_diag; - } - inline const CholMatrixType rawMatrix() const { - eigen_assert(Base::m_factorizationIsOk && "Simplicial Cholesky not factorized"); - return Base::m_matrix; - } - - /** Computes the sparse Cholesky decomposition of \a matrix */ - SimplicialCholesky& compute(const MatrixType& matrix) - { - if(m_LDLT) - Base::template compute(matrix); - else - Base::template compute(matrix); - return *this; - } - - /** Performs a symbolic decomposition on the sparcity of \a matrix. - * - * This function is particularly useful when solving for several problems having the same structure. - * - * \sa factorize() - */ - void analyzePattern(const MatrixType& a) - { - Base::analyzePattern(a, m_LDLT); - } - - /** Performs a numeric decomposition of \a matrix - * - * The given matrix must has the same sparcity than the matrix on which the symbolic decomposition has been performed. - * - * \sa analyzePattern() - */ - void factorize(const MatrixType& a) - { - if(m_LDLT) - Base::template factorize(a); - else - Base::template factorize(a); - } - - /** \internal */ - template - void _solve(const MatrixBase &b, MatrixBase &dest) const - { - eigen_assert(Base::m_factorizationIsOk && "The decomposition is not in a valid state for solving, you must first call either compute() or symbolic()/numeric()"); - eigen_assert(Base::m_matrix.rows()==b.rows()); - - if(Base::m_info!=Success) - return; - - if(Base::m_P.size()>0) - dest = Base::m_P * b; - else - dest = b; - - if(Base::m_matrix.nonZeros()>0) // otherwise L==I - { - if(m_LDLT) - LDLTTraits::getL(Base::m_matrix).solveInPlace(dest); - else - LLTTraits::getL(Base::m_matrix).solveInPlace(dest); - } - - if(Base::m_diag.size()>0) - dest = Base::m_diag.asDiagonal().inverse() * dest; - - if (Base::m_matrix.nonZeros()>0) // otherwise I==I - { - if(m_LDLT) - LDLTTraits::getU(Base::m_matrix).solveInPlace(dest); - else - LLTTraits::getU(Base::m_matrix).solveInPlace(dest); - } - - if(Base::m_P.size()>0) - dest = Base::m_Pinv * dest; - } - - Scalar determinant() const - { - if(m_LDLT) - { - return Base::m_diag.prod(); - } - else - { - Scalar detL = Diagonal(Base::m_matrix).prod(); - return numext::abs2(detL); - } - } - - protected: - bool m_LDLT; -}; - -template -void SimplicialCholeskyBase::ordering(const MatrixType& a, CholMatrixType& ap) -{ - eigen_assert(a.rows()==a.cols()); - const Index size = a.rows(); - // Note that amd compute the inverse permutation - { - CholMatrixType C; - C = a.template selfadjointView(); - - OrderingType ordering; - ordering(C,m_Pinv); - } - - if(m_Pinv.size()>0) - m_P = m_Pinv.inverse(); - else - m_P.resize(0); - - ap.resize(size,size); - ap.template selfadjointView() = a.template selfadjointView().twistedBy(m_P); -} - -namespace internal { - -template -struct solve_retval, Rhs> - : solve_retval_base, Rhs> -{ - typedef SimplicialCholeskyBase Dec; - EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs) - - template void evalTo(Dest& dst) const - { - dec().derived()._solve(rhs(),dst); - } -}; - -template -struct sparse_solve_retval, Rhs> - : sparse_solve_retval_base, Rhs> -{ - typedef SimplicialCholeskyBase Dec; - EIGEN_MAKE_SPARSE_SOLVE_HELPERS(Dec,Rhs) - - template void evalTo(Dest& dst) const - { - this->defaultEvalTo(dst); - } -}; - -} // end namespace internal - -} // end namespace Eigen - -#endif // EIGEN_SIMPLICIAL_CHOLESKY_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/SparseCholesky/SimplicialCholesky_impl.h b/thirdparty/eigen-3.2.7/Eigen/src/SparseCholesky/SimplicialCholesky_impl.h deleted file mode 100644 index 7aaf702b..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/SparseCholesky/SimplicialCholesky_impl.h +++ /dev/null @@ -1,199 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2012 Gael Guennebaud - -/* - -NOTE: thes functions vave been adapted from the LDL library: - -LDL Copyright (c) 2005 by Timothy A. Davis. All Rights Reserved. - -LDL License: - - Your use or distribution of LDL or any modified version of - LDL implies that you agree to this License. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 - USA - - Permission is hereby granted to use or copy this program under the - terms of the GNU LGPL, provided that the Copyright, this License, - and the Availability of the original version is retained on all copies. - User documentation of any code that uses this code or any modified - version of this code must cite the Copyright, this License, the - Availability note, and "Used by permission." Permission to modify - the code and to distribute modified code is granted, provided the - Copyright, this License, and the Availability note are retained, - and a notice that the code was modified is included. - */ - -#include "../Core/util/NonMPL2.h" - -#ifndef EIGEN_SIMPLICIAL_CHOLESKY_IMPL_H -#define EIGEN_SIMPLICIAL_CHOLESKY_IMPL_H - -namespace Eigen { - -template -void SimplicialCholeskyBase::analyzePattern_preordered(const CholMatrixType& ap, bool doLDLT) -{ - const Index size = ap.rows(); - m_matrix.resize(size, size); - m_parent.resize(size); - m_nonZerosPerCol.resize(size); - - ei_declare_aligned_stack_constructed_variable(Index, tags, size, 0); - - for(Index k = 0; k < size; ++k) - { - /* L(k,:) pattern: all nodes reachable in etree from nz in A(0:k-1,k) */ - m_parent[k] = -1; /* parent of k is not yet known */ - tags[k] = k; /* mark node k as visited */ - m_nonZerosPerCol[k] = 0; /* count of nonzeros in column k of L */ - for(typename CholMatrixType::InnerIterator it(ap,k); it; ++it) - { - Index i = it.index(); - if(i < k) - { - /* follow path from i to root of etree, stop at flagged node */ - for(; tags[i] != k; i = m_parent[i]) - { - /* find parent of i if not yet determined */ - if (m_parent[i] == -1) - m_parent[i] = k; - m_nonZerosPerCol[i]++; /* L (k,i) is nonzero */ - tags[i] = k; /* mark i as visited */ - } - } - } - } - - /* construct Lp index array from m_nonZerosPerCol column counts */ - Index* Lp = m_matrix.outerIndexPtr(); - Lp[0] = 0; - for(Index k = 0; k < size; ++k) - Lp[k+1] = Lp[k] + m_nonZerosPerCol[k] + (doLDLT ? 0 : 1); - - m_matrix.resizeNonZeros(Lp[size]); - - m_isInitialized = true; - m_info = Success; - m_analysisIsOk = true; - m_factorizationIsOk = false; -} - - -template -template -void SimplicialCholeskyBase::factorize_preordered(const CholMatrixType& ap) -{ - using std::sqrt; - - eigen_assert(m_analysisIsOk && "You must first call analyzePattern()"); - eigen_assert(ap.rows()==ap.cols()); - const Index size = ap.rows(); - eigen_assert(m_parent.size()==size); - eigen_assert(m_nonZerosPerCol.size()==size); - - const Index* Lp = m_matrix.outerIndexPtr(); - Index* Li = m_matrix.innerIndexPtr(); - Scalar* Lx = m_matrix.valuePtr(); - - ei_declare_aligned_stack_constructed_variable(Scalar, y, size, 0); - ei_declare_aligned_stack_constructed_variable(Index, pattern, size, 0); - ei_declare_aligned_stack_constructed_variable(Index, tags, size, 0); - - bool ok = true; - m_diag.resize(DoLDLT ? size : 0); - - for(Index k = 0; k < size; ++k) - { - // compute nonzero pattern of kth row of L, in topological order - y[k] = 0.0; // Y(0:k) is now all zero - Index top = size; // stack for pattern is empty - tags[k] = k; // mark node k as visited - m_nonZerosPerCol[k] = 0; // count of nonzeros in column k of L - for(typename MatrixType::InnerIterator it(ap,k); it; ++it) - { - Index i = it.index(); - if(i <= k) - { - y[i] += numext::conj(it.value()); /* scatter A(i,k) into Y (sum duplicates) */ - Index len; - for(len = 0; tags[i] != k; i = m_parent[i]) - { - pattern[len++] = i; /* L(k,i) is nonzero */ - tags[i] = k; /* mark i as visited */ - } - while(len > 0) - pattern[--top] = pattern[--len]; - } - } - - /* compute numerical values kth row of L (a sparse triangular solve) */ - - RealScalar d = numext::real(y[k]) * m_shiftScale + m_shiftOffset; // get D(k,k), apply the shift function, and clear Y(k) - y[k] = 0.0; - for(; top < size; ++top) - { - Index i = pattern[top]; /* pattern[top:n-1] is pattern of L(:,k) */ - Scalar yi = y[i]; /* get and clear Y(i) */ - y[i] = 0.0; - - /* the nonzero entry L(k,i) */ - Scalar l_ki; - if(DoLDLT) - l_ki = yi / m_diag[i]; - else - yi = l_ki = yi / Lx[Lp[i]]; - - Index p2 = Lp[i] + m_nonZerosPerCol[i]; - Index p; - for(p = Lp[i] + (DoLDLT ? 0 : 1); p < p2; ++p) - y[Li[p]] -= numext::conj(Lx[p]) * yi; - d -= numext::real(l_ki * numext::conj(yi)); - Li[p] = k; /* store L(k,i) in column form of L */ - Lx[p] = l_ki; - ++m_nonZerosPerCol[i]; /* increment count of nonzeros in col i */ - } - if(DoLDLT) - { - m_diag[k] = d; - if(d == RealScalar(0)) - { - ok = false; /* failure, D(k,k) is zero */ - break; - } - } - else - { - Index p = Lp[k] + m_nonZerosPerCol[k]++; - Li[p] = k ; /* store L(k,k) = sqrt (d) in column k */ - if(d <= RealScalar(0)) { - ok = false; /* failure, matrix is not positive definite */ - break; - } - Lx[p] = sqrt(d) ; - } - } - - m_info = ok ? Success : NumericalIssue; - m_factorizationIsOk = true; -} - -} // end namespace Eigen - -#endif // EIGEN_SIMPLICIAL_CHOLESKY_IMPL_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/AmbiVector.h b/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/AmbiVector.h deleted file mode 100644 index 220c6451..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/AmbiVector.h +++ /dev/null @@ -1,373 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_AMBIVECTOR_H -#define EIGEN_AMBIVECTOR_H - -namespace Eigen { - -namespace internal { - -/** \internal - * Hybrid sparse/dense vector class designed for intensive read-write operations. - * - * See BasicSparseLLT and SparseProduct for usage examples. - */ -template -class AmbiVector -{ - public: - typedef _Scalar Scalar; - typedef _Index Index; - typedef typename NumTraits::Real RealScalar; - - AmbiVector(Index size) - : m_buffer(0), m_zero(0), m_size(0), m_allocatedSize(0), m_allocatedElements(0), m_mode(-1) - { - resize(size); - } - - void init(double estimatedDensity); - void init(int mode); - - Index nonZeros() const; - - /** Specifies a sub-vector to work on */ - void setBounds(Index start, Index end) { m_start = start; m_end = end; } - - void setZero(); - - void restart(); - Scalar& coeffRef(Index i); - Scalar& coeff(Index i); - - class Iterator; - - ~AmbiVector() { delete[] m_buffer; } - - void resize(Index size) - { - if (m_allocatedSize < size) - reallocate(size); - m_size = size; - } - - Index size() const { return m_size; } - - protected: - - void reallocate(Index size) - { - // if the size of the matrix is not too large, let's allocate a bit more than needed such - // that we can handle dense vector even in sparse mode. - delete[] m_buffer; - if (size<1000) - { - Index allocSize = (size * sizeof(ListEl) + sizeof(Scalar) - 1)/sizeof(Scalar); - m_allocatedElements = (allocSize*sizeof(Scalar))/sizeof(ListEl); - m_buffer = new Scalar[allocSize]; - } - else - { - m_allocatedElements = (size*sizeof(Scalar))/sizeof(ListEl); - m_buffer = new Scalar[size]; - } - m_size = size; - m_start = 0; - m_end = m_size; - } - - void reallocateSparse() - { - Index copyElements = m_allocatedElements; - m_allocatedElements = (std::min)(Index(m_allocatedElements*1.5),m_size); - Index allocSize = m_allocatedElements * sizeof(ListEl); - allocSize = (allocSize + sizeof(Scalar) - 1)/sizeof(Scalar); - Scalar* newBuffer = new Scalar[allocSize]; - memcpy(newBuffer, m_buffer, copyElements * sizeof(ListEl)); - delete[] m_buffer; - m_buffer = newBuffer; - } - - protected: - // element type of the linked list - struct ListEl - { - Index next; - Index index; - Scalar value; - }; - - // used to store data in both mode - Scalar* m_buffer; - Scalar m_zero; - Index m_size; - Index m_start; - Index m_end; - Index m_allocatedSize; - Index m_allocatedElements; - Index m_mode; - - // linked list mode - Index m_llStart; - Index m_llCurrent; - Index m_llSize; -}; - -/** \returns the number of non zeros in the current sub vector */ -template -_Index AmbiVector<_Scalar,_Index>::nonZeros() const -{ - if (m_mode==IsSparse) - return m_llSize; - else - return m_end - m_start; -} - -template -void AmbiVector<_Scalar,_Index>::init(double estimatedDensity) -{ - if (estimatedDensity>0.1) - init(IsDense); - else - init(IsSparse); -} - -template -void AmbiVector<_Scalar,_Index>::init(int mode) -{ - m_mode = mode; - if (m_mode==IsSparse) - { - m_llSize = 0; - m_llStart = -1; - } -} - -/** Must be called whenever we might perform a write access - * with an index smaller than the previous one. - * - * Don't worry, this function is extremely cheap. - */ -template -void AmbiVector<_Scalar,_Index>::restart() -{ - m_llCurrent = m_llStart; -} - -/** Set all coefficients of current subvector to zero */ -template -void AmbiVector<_Scalar,_Index>::setZero() -{ - if (m_mode==IsDense) - { - for (Index i=m_start; i -_Scalar& AmbiVector<_Scalar,_Index>::coeffRef(_Index i) -{ - if (m_mode==IsDense) - return m_buffer[i]; - else - { - ListEl* EIGEN_RESTRICT llElements = reinterpret_cast(m_buffer); - // TODO factorize the following code to reduce code generation - eigen_assert(m_mode==IsSparse); - if (m_llSize==0) - { - // this is the first element - m_llStart = 0; - m_llCurrent = 0; - ++m_llSize; - llElements[0].value = Scalar(0); - llElements[0].index = i; - llElements[0].next = -1; - return llElements[0].value; - } - else if (i=llElements[m_llCurrent].index && "you must call restart() before inserting an element with lower or equal index"); - while (nextel >= 0 && llElements[nextel].index<=i) - { - m_llCurrent = nextel; - nextel = llElements[nextel].next; - } - - if (llElements[m_llCurrent].index==i) - { - // the coefficient already exists and we found it ! - return llElements[m_llCurrent].value; - } - else - { - if (m_llSize>=m_allocatedElements) - { - reallocateSparse(); - llElements = reinterpret_cast(m_buffer); - } - eigen_internal_assert(m_llSize -_Scalar& AmbiVector<_Scalar,_Index>::coeff(_Index i) -{ - if (m_mode==IsDense) - return m_buffer[i]; - else - { - ListEl* EIGEN_RESTRICT llElements = reinterpret_cast(m_buffer); - eigen_assert(m_mode==IsSparse); - if ((m_llSize==0) || (i= 0 && llElements[elid].index -class AmbiVector<_Scalar,_Index>::Iterator -{ - public: - typedef _Scalar Scalar; - typedef typename NumTraits::Real RealScalar; - - /** Default constructor - * \param vec the vector on which we iterate - * \param epsilon the minimal value used to prune zero coefficients. - * In practice, all coefficients having a magnitude smaller than \a epsilon - * are skipped. - */ - Iterator(const AmbiVector& vec, const RealScalar& epsilon = 0) - : m_vector(vec) - { - using std::abs; - m_epsilon = epsilon; - m_isDense = m_vector.m_mode==IsDense; - if (m_isDense) - { - m_currentEl = 0; // this is to avoid a compilation warning - m_cachedValue = 0; // this is to avoid a compilation warning - m_cachedIndex = m_vector.m_start-1; - ++(*this); - } - else - { - ListEl* EIGEN_RESTRICT llElements = reinterpret_cast(m_vector.m_buffer); - m_currentEl = m_vector.m_llStart; - while (m_currentEl>=0 && abs(llElements[m_currentEl].value)<=m_epsilon) - m_currentEl = llElements[m_currentEl].next; - if (m_currentEl<0) - { - m_cachedValue = 0; // this is to avoid a compilation warning - m_cachedIndex = -1; - } - else - { - m_cachedIndex = llElements[m_currentEl].index; - m_cachedValue = llElements[m_currentEl].value; - } - } - } - - Index index() const { return m_cachedIndex; } - Scalar value() const { return m_cachedValue; } - - operator bool() const { return m_cachedIndex>=0; } - - Iterator& operator++() - { - using std::abs; - if (m_isDense) - { - do { - ++m_cachedIndex; - } while (m_cachedIndex(m_vector.m_buffer); - do { - m_currentEl = llElements[m_currentEl].next; - } while (m_currentEl>=0 && abs(llElements[m_currentEl].value) -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_COMPRESSED_STORAGE_H -#define EIGEN_COMPRESSED_STORAGE_H - -namespace Eigen { - -namespace internal { - -/** \internal - * Stores a sparse set of values as a list of values and a list of indices. - * - */ -template -class CompressedStorage -{ - public: - - typedef _Scalar Scalar; - typedef _Index Index; - - protected: - - typedef typename NumTraits::Real RealScalar; - - public: - - CompressedStorage() - : m_values(0), m_indices(0), m_size(0), m_allocatedSize(0) - {} - - CompressedStorage(size_t size) - : m_values(0), m_indices(0), m_size(0), m_allocatedSize(0) - { - resize(size); - } - - CompressedStorage(const CompressedStorage& other) - : m_values(0), m_indices(0), m_size(0), m_allocatedSize(0) - { - *this = other; - } - - CompressedStorage& operator=(const CompressedStorage& other) - { - resize(other.size()); - internal::smart_copy(other.m_values, other.m_values + m_size, m_values); - internal::smart_copy(other.m_indices, other.m_indices + m_size, m_indices); - return *this; - } - - void swap(CompressedStorage& other) - { - std::swap(m_values, other.m_values); - std::swap(m_indices, other.m_indices); - std::swap(m_size, other.m_size); - std::swap(m_allocatedSize, other.m_allocatedSize); - } - - ~CompressedStorage() - { - delete[] m_values; - delete[] m_indices; - } - - void reserve(size_t size) - { - size_t newAllocatedSize = m_size + size; - if (newAllocatedSize > m_allocatedSize) - reallocate(newAllocatedSize); - } - - void squeeze() - { - if (m_allocatedSize>m_size) - reallocate(m_size); - } - - void resize(size_t size, double reserveSizeFactor = 0) - { - if (m_allocatedSize(m_size); - resize(m_size+1, 1); - m_values[id] = v; - m_indices[id] = i; - } - - inline size_t size() const { return m_size; } - inline size_t allocatedSize() const { return m_allocatedSize; } - inline void clear() { m_size = 0; } - - inline Scalar& value(size_t i) { return m_values[i]; } - inline const Scalar& value(size_t i) const { return m_values[i]; } - - inline Index& index(size_t i) { return m_indices[i]; } - inline const Index& index(size_t i) const { return m_indices[i]; } - - static CompressedStorage Map(Index* indices, Scalar* values, size_t size) - { - CompressedStorage res; - res.m_indices = indices; - res.m_values = values; - res.m_allocatedSize = res.m_size = size; - return res; - } - - /** \returns the largest \c k such that for all \c j in [0,k) index[\c j]\<\a key */ - inline Index searchLowerIndex(Index key) const - { - return searchLowerIndex(0, m_size, key); - } - - /** \returns the largest \c k in [start,end) such that for all \c j in [start,k) index[\c j]\<\a key */ - inline Index searchLowerIndex(size_t start, size_t end, Index key) const - { - while(end>start) - { - size_t mid = (end+start)>>1; - if (m_indices[mid](start); - } - - /** \returns the stored value at index \a key - * If the value does not exist, then the value \a defaultValue is returned without any insertion. */ - inline Scalar at(Index key, const Scalar& defaultValue = Scalar(0)) const - { - if (m_size==0) - return defaultValue; - else if (key==m_indices[m_size-1]) - return m_values[m_size-1]; - // ^^ optimization: let's first check if it is the last coefficient - // (very common in high level algorithms) - const size_t id = searchLowerIndex(0,m_size-1,key); - return ((id=end) - return Scalar(0); - else if (end>start && key==m_indices[end-1]) - return m_values[end-1]; - // ^^ optimization: let's first check if it is the last coefficient - // (very common in high level algorithms) - const size_t id = searchLowerIndex(start,end-1,key); - return ((id=m_size || m_indices[id]!=key) - { - resize(m_size+1,1); - for (size_t j=m_size-1; j>id; --j) - { - m_indices[j] = m_indices[j-1]; - m_values[j] = m_values[j-1]; - } - m_indices[id] = key; - m_values[id] = defaultValue; - } - return m_values[id]; - } - - void prune(const Scalar& reference, const RealScalar& epsilon = NumTraits::dummy_precision()) - { - size_t k = 0; - size_t n = size(); - for (size_t i=0; i -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_CONSERVATIVESPARSESPARSEPRODUCT_H -#define EIGEN_CONSERVATIVESPARSESPARSEPRODUCT_H - -namespace Eigen { - -namespace internal { - -template -static void conservative_sparse_sparse_product_impl(const Lhs& lhs, const Rhs& rhs, ResultType& res) -{ - typedef typename remove_all::type::Scalar Scalar; - typedef typename remove_all::type::Index Index; - - // make sure to call innerSize/outerSize since we fake the storage order. - Index rows = lhs.innerSize(); - Index cols = rhs.outerSize(); - eigen_assert(lhs.outerSize() == rhs.innerSize()); - - std::vector mask(rows,false); - Matrix values(rows); - Matrix indices(rows); - - // estimate the number of non zero entries - // given a rhs column containing Y non zeros, we assume that the respective Y columns - // of the lhs differs in average of one non zeros, thus the number of non zeros for - // the product of a rhs column with the lhs is X+Y where X is the average number of non zero - // per column of the lhs. - // Therefore, we have nnz(lhs*rhs) = nnz(lhs) + nnz(rhs) - Index estimated_nnz_prod = lhs.nonZeros() + rhs.nonZeros(); - - res.setZero(); - res.reserve(Index(estimated_nnz_prod)); - // we compute each column of the result, one after the other - for (Index j=0; j use a quick sort - // otherwise => loop through the entire vector - // In order to avoid to perform an expensive log2 when the - // result is clearly very sparse we use a linear bound up to 200. - //if((nnz<200 && nnz1) std::sort(indices.data(),indices.data()+nnz); - for(Index k=0; k::Flags&RowMajorBit) ? RowMajor : ColMajor, - int RhsStorageOrder = (traits::Flags&RowMajorBit) ? RowMajor : ColMajor, - int ResStorageOrder = (traits::Flags&RowMajorBit) ? RowMajor : ColMajor> -struct conservative_sparse_sparse_product_selector; - -template -struct conservative_sparse_sparse_product_selector -{ - typedef typename remove_all::type LhsCleaned; - typedef typename LhsCleaned::Scalar Scalar; - - static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) - { - typedef SparseMatrix RowMajorMatrix; - typedef SparseMatrix ColMajorMatrix; - ColMajorMatrix resCol(lhs.rows(),rhs.cols()); - internal::conservative_sparse_sparse_product_impl(lhs, rhs, resCol); - // sort the non zeros: - RowMajorMatrix resRow(resCol); - res = resRow; - } -}; - -template -struct conservative_sparse_sparse_product_selector -{ - static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) - { - typedef SparseMatrix RowMajorMatrix; - RowMajorMatrix rhsRow = rhs; - RowMajorMatrix resRow(lhs.rows(), rhs.cols()); - internal::conservative_sparse_sparse_product_impl(rhsRow, lhs, resRow); - res = resRow; - } -}; - -template -struct conservative_sparse_sparse_product_selector -{ - static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) - { - typedef SparseMatrix RowMajorMatrix; - RowMajorMatrix lhsRow = lhs; - RowMajorMatrix resRow(lhs.rows(), rhs.cols()); - internal::conservative_sparse_sparse_product_impl(rhs, lhsRow, resRow); - res = resRow; - } -}; - -template -struct conservative_sparse_sparse_product_selector -{ - static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) - { - typedef SparseMatrix RowMajorMatrix; - RowMajorMatrix resRow(lhs.rows(), rhs.cols()); - internal::conservative_sparse_sparse_product_impl(rhs, lhs, resRow); - res = resRow; - } -}; - - -template -struct conservative_sparse_sparse_product_selector -{ - typedef typename traits::type>::Scalar Scalar; - - static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) - { - typedef SparseMatrix ColMajorMatrix; - ColMajorMatrix resCol(lhs.rows(), rhs.cols()); - internal::conservative_sparse_sparse_product_impl(lhs, rhs, resCol); - res = resCol; - } -}; - -template -struct conservative_sparse_sparse_product_selector -{ - static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) - { - typedef SparseMatrix ColMajorMatrix; - ColMajorMatrix lhsCol = lhs; - ColMajorMatrix resCol(lhs.rows(), rhs.cols()); - internal::conservative_sparse_sparse_product_impl(lhsCol, rhs, resCol); - res = resCol; - } -}; - -template -struct conservative_sparse_sparse_product_selector -{ - static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) - { - typedef SparseMatrix ColMajorMatrix; - ColMajorMatrix rhsCol = rhs; - ColMajorMatrix resCol(lhs.rows(), rhs.cols()); - internal::conservative_sparse_sparse_product_impl(lhs, rhsCol, resCol); - res = resCol; - } -}; - -template -struct conservative_sparse_sparse_product_selector -{ - static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) - { - typedef SparseMatrix RowMajorMatrix; - typedef SparseMatrix ColMajorMatrix; - RowMajorMatrix resRow(lhs.rows(),rhs.cols()); - internal::conservative_sparse_sparse_product_impl(rhs, lhs, resRow); - // sort the non zeros: - ColMajorMatrix resCol(resRow); - res = resCol; - } -}; - -} // end namespace internal - -} // end namespace Eigen - -#endif // EIGEN_CONSERVATIVESPARSESPARSEPRODUCT_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/MappedSparseMatrix.h b/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/MappedSparseMatrix.h deleted file mode 100644 index ab1a266a..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/MappedSparseMatrix.h +++ /dev/null @@ -1,181 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_MAPPED_SPARSEMATRIX_H -#define EIGEN_MAPPED_SPARSEMATRIX_H - -namespace Eigen { - -/** \class MappedSparseMatrix - * - * \brief Sparse matrix - * - * \param _Scalar the scalar type, i.e. the type of the coefficients - * - * See http://www.netlib.org/linalg/html_templates/node91.html for details on the storage scheme. - * - */ -namespace internal { -template -struct traits > : traits > -{}; -} - -template -class MappedSparseMatrix - : public SparseMatrixBase > -{ - public: - EIGEN_SPARSE_PUBLIC_INTERFACE(MappedSparseMatrix) - enum { IsRowMajor = Base::IsRowMajor }; - - protected: - - Index m_outerSize; - Index m_innerSize; - Index m_nnz; - Index* m_outerIndex; - Index* m_innerIndices; - Scalar* m_values; - - public: - - inline Index rows() const { return IsRowMajor ? m_outerSize : m_innerSize; } - inline Index cols() const { return IsRowMajor ? m_innerSize : m_outerSize; } - inline Index innerSize() const { return m_innerSize; } - inline Index outerSize() const { return m_outerSize; } - - bool isCompressed() const { return true; } - - //---------------------------------------- - // direct access interface - inline const Scalar* valuePtr() const { return m_values; } - inline Scalar* valuePtr() { return m_values; } - - inline const Index* innerIndexPtr() const { return m_innerIndices; } - inline Index* innerIndexPtr() { return m_innerIndices; } - - inline const Index* outerIndexPtr() const { return m_outerIndex; } - inline Index* outerIndexPtr() { return m_outerIndex; } - //---------------------------------------- - - inline Scalar coeff(Index row, Index col) const - { - const Index outer = IsRowMajor ? row : col; - const Index inner = IsRowMajor ? col : row; - - Index start = m_outerIndex[outer]; - Index end = m_outerIndex[outer+1]; - if (start==end) - return Scalar(0); - else if (end>0 && inner==m_innerIndices[end-1]) - return m_values[end-1]; - // ^^ optimization: let's first check if it is the last coefficient - // (very common in high level algorithms) - - const Index* r = std::lower_bound(&m_innerIndices[start],&m_innerIndices[end-1],inner); - const Index id = r-&m_innerIndices[0]; - return ((*r==inner) && (id=start && "you probably called coeffRef on a non finalized matrix"); - eigen_assert(end>start && "coeffRef cannot be called on a zero coefficient"); - Index* r = std::lower_bound(&m_innerIndices[start],&m_innerIndices[end],inner); - const Index id = r-&m_innerIndices[0]; - eigen_assert((*r==inner) && (id -class MappedSparseMatrix::InnerIterator -{ - public: - InnerIterator(const MappedSparseMatrix& mat, Index outer) - : m_matrix(mat), - m_outer(outer), - m_id(mat.outerIndexPtr()[outer]), - m_start(m_id), - m_end(mat.outerIndexPtr()[outer+1]) - {} - - inline InnerIterator& operator++() { m_id++; return *this; } - - inline Scalar value() const { return m_matrix.valuePtr()[m_id]; } - inline Scalar& valueRef() { return const_cast(m_matrix.valuePtr()[m_id]); } - - inline Index index() const { return m_matrix.innerIndexPtr()[m_id]; } - inline Index row() const { return IsRowMajor ? m_outer : index(); } - inline Index col() const { return IsRowMajor ? index() : m_outer; } - - inline operator bool() const { return (m_id < m_end) && (m_id>=m_start); } - - protected: - const MappedSparseMatrix& m_matrix; - const Index m_outer; - Index m_id; - const Index m_start; - const Index m_end; -}; - -template -class MappedSparseMatrix::ReverseInnerIterator -{ - public: - ReverseInnerIterator(const MappedSparseMatrix& mat, Index outer) - : m_matrix(mat), - m_outer(outer), - m_id(mat.outerIndexPtr()[outer+1]), - m_start(mat.outerIndexPtr()[outer]), - m_end(m_id) - {} - - inline ReverseInnerIterator& operator--() { m_id--; return *this; } - - inline Scalar value() const { return m_matrix.valuePtr()[m_id-1]; } - inline Scalar& valueRef() { return const_cast(m_matrix.valuePtr()[m_id-1]); } - - inline Index index() const { return m_matrix.innerIndexPtr()[m_id-1]; } - inline Index row() const { return IsRowMajor ? m_outer : index(); } - inline Index col() const { return IsRowMajor ? index() : m_outer; } - - inline operator bool() const { return (m_id <= m_end) && (m_id>m_start); } - - protected: - const MappedSparseMatrix& m_matrix; - const Index m_outer; - Index m_id; - const Index m_start; - const Index m_end; -}; - -} // end namespace Eigen - -#endif // EIGEN_MAPPED_SPARSEMATRIX_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseBlock.h b/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseBlock.h deleted file mode 100644 index 0c90bafb..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseBlock.h +++ /dev/null @@ -1,537 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2009 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_SPARSE_BLOCK_H -#define EIGEN_SPARSE_BLOCK_H - -namespace Eigen { - -template -class BlockImpl - : public SparseMatrixBase > -{ - typedef typename internal::remove_all::type _MatrixTypeNested; - typedef Block BlockType; -public: - enum { IsRowMajor = internal::traits::IsRowMajor }; -protected: - enum { OuterSize = IsRowMajor ? BlockRows : BlockCols }; -public: - EIGEN_SPARSE_PUBLIC_INTERFACE(BlockType) - - class InnerIterator: public XprType::InnerIterator - { - typedef typename BlockImpl::Index Index; - public: - inline InnerIterator(const BlockType& xpr, Index outer) - : XprType::InnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer) - {} - inline Index row() const { return IsRowMajor ? m_outer : this->index(); } - inline Index col() const { return IsRowMajor ? this->index() : m_outer; } - protected: - Index m_outer; - }; - class ReverseInnerIterator: public XprType::ReverseInnerIterator - { - typedef typename BlockImpl::Index Index; - public: - inline ReverseInnerIterator(const BlockType& xpr, Index outer) - : XprType::ReverseInnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer) - {} - inline Index row() const { return IsRowMajor ? m_outer : this->index(); } - inline Index col() const { return IsRowMajor ? this->index() : m_outer; } - protected: - Index m_outer; - }; - - inline BlockImpl(const XprType& xpr, int i) - : m_matrix(xpr), m_outerStart(i), m_outerSize(OuterSize) - {} - - inline BlockImpl(const XprType& xpr, int startRow, int startCol, int blockRows, int blockCols) - : m_matrix(xpr), m_outerStart(IsRowMajor ? startRow : startCol), m_outerSize(IsRowMajor ? blockRows : blockCols) - {} - - inline const Scalar coeff(int row, int col) const - { - return m_matrix.coeff(row + IsRowMajor ? m_outerStart : 0, col +IsRowMajor ? 0 : m_outerStart); - } - - inline const Scalar coeff(int index) const - { - return m_matrix.coeff(IsRowMajor ? m_outerStart : index, IsRowMajor ? index : m_outerStart); - } - - EIGEN_STRONG_INLINE Index rows() const { return IsRowMajor ? m_outerSize.value() : m_matrix.rows(); } - EIGEN_STRONG_INLINE Index cols() const { return IsRowMajor ? m_matrix.cols() : m_outerSize.value(); } - - protected: - - typename XprType::Nested m_matrix; - Index m_outerStart; - const internal::variable_if_dynamic m_outerSize; - - EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl) - private: - Index nonZeros() const; -}; - - -/*************************************************************************** -* specialisation for SparseMatrix -***************************************************************************/ - -template -class BlockImpl,BlockRows,BlockCols,true,Sparse> - : public SparseMatrixBase,BlockRows,BlockCols,true> > -{ - typedef SparseMatrix<_Scalar, _Options, _Index> SparseMatrixType; - typedef typename internal::remove_all::type _MatrixTypeNested; - typedef Block BlockType; - typedef Block ConstBlockType; -public: - enum { IsRowMajor = internal::traits::IsRowMajor }; - EIGEN_SPARSE_PUBLIC_INTERFACE(BlockType) -protected: - enum { OuterSize = IsRowMajor ? BlockRows : BlockCols }; -public: - - class InnerIterator: public SparseMatrixType::InnerIterator - { - public: - inline InnerIterator(const BlockType& xpr, Index outer) - : SparseMatrixType::InnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer) - {} - inline Index row() const { return IsRowMajor ? m_outer : this->index(); } - inline Index col() const { return IsRowMajor ? this->index() : m_outer; } - protected: - Index m_outer; - }; - class ReverseInnerIterator: public SparseMatrixType::ReverseInnerIterator - { - public: - inline ReverseInnerIterator(const BlockType& xpr, Index outer) - : SparseMatrixType::ReverseInnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer) - {} - inline Index row() const { return IsRowMajor ? m_outer : this->index(); } - inline Index col() const { return IsRowMajor ? this->index() : m_outer; } - protected: - Index m_outer; - }; - - inline BlockImpl(const SparseMatrixType& xpr, int i) - : m_matrix(xpr), m_outerStart(i), m_outerSize(OuterSize) - {} - - inline BlockImpl(const SparseMatrixType& xpr, int startRow, int startCol, int blockRows, int blockCols) - : m_matrix(xpr), m_outerStart(IsRowMajor ? startRow : startCol), m_outerSize(IsRowMajor ? blockRows : blockCols) - {} - - template - inline BlockType& operator=(const SparseMatrixBase& other) - { - typedef typename internal::remove_all::type _NestedMatrixType; - _NestedMatrixType& matrix = const_cast<_NestedMatrixType&>(m_matrix);; - // This assignement is slow if this vector set is not empty - // and/or it is not at the end of the nonzeros of the underlying matrix. - - // 1 - eval to a temporary to avoid transposition and/or aliasing issues - SparseMatrix tmp(other); - - // 2 - let's check whether there is enough allocated memory - Index nnz = tmp.nonZeros(); - Index start = m_outerStart==0 ? 0 : matrix.outerIndexPtr()[m_outerStart]; // starting position of the current block - Index end = m_matrix.outerIndexPtr()[m_outerStart+m_outerSize.value()]; // ending posiiton of the current block - Index block_size = end - start; // available room in the current block - Index tail_size = m_matrix.outerIndexPtr()[m_matrix.outerSize()] - end; - - Index free_size = m_matrix.isCompressed() - ? Index(matrix.data().allocatedSize()) + block_size - : block_size; - - if(nnz>free_size) - { - // realloc manually to reduce copies - typename SparseMatrixType::Storage newdata(m_matrix.data().allocatedSize() - block_size + nnz); - - std::memcpy(&newdata.value(0), &m_matrix.data().value(0), start*sizeof(Scalar)); - std::memcpy(&newdata.index(0), &m_matrix.data().index(0), start*sizeof(Index)); - - std::memcpy(&newdata.value(start), &tmp.data().value(0), nnz*sizeof(Scalar)); - std::memcpy(&newdata.index(start), &tmp.data().index(0), nnz*sizeof(Index)); - - std::memcpy(&newdata.value(start+nnz), &matrix.data().value(end), tail_size*sizeof(Scalar)); - std::memcpy(&newdata.index(start+nnz), &matrix.data().index(end), tail_size*sizeof(Index)); - - newdata.resize(m_matrix.outerIndexPtr()[m_matrix.outerSize()] - block_size + nnz); - - matrix.data().swap(newdata); - } - else - { - // no need to realloc, simply copy the tail at its respective position and insert tmp - matrix.data().resize(start + nnz + tail_size); - - std::memmove(&matrix.data().value(start+nnz), &matrix.data().value(end), tail_size*sizeof(Scalar)); - std::memmove(&matrix.data().index(start+nnz), &matrix.data().index(end), tail_size*sizeof(Index)); - - std::memcpy(&matrix.data().value(start), &tmp.data().value(0), nnz*sizeof(Scalar)); - std::memcpy(&matrix.data().index(start), &tmp.data().index(0), nnz*sizeof(Index)); - } - - // update innerNonZeros - if(!m_matrix.isCompressed()) - for(Index j=0; j(other); - } - - inline const Scalar* valuePtr() const - { return m_matrix.valuePtr() + m_matrix.outerIndexPtr()[m_outerStart]; } - inline Scalar* valuePtr() - { return m_matrix.const_cast_derived().valuePtr() + m_matrix.outerIndexPtr()[m_outerStart]; } - - inline const Index* innerIndexPtr() const - { return m_matrix.innerIndexPtr() + m_matrix.outerIndexPtr()[m_outerStart]; } - inline Index* innerIndexPtr() - { return m_matrix.const_cast_derived().innerIndexPtr() + m_matrix.outerIndexPtr()[m_outerStart]; } - - inline const Index* outerIndexPtr() const - { return m_matrix.outerIndexPtr() + m_outerStart; } - inline Index* outerIndexPtr() - { return m_matrix.const_cast_derived().outerIndexPtr() + m_outerStart; } - - Index nonZeros() const - { - if(m_matrix.isCompressed()) - return std::size_t(m_matrix.outerIndexPtr()[m_outerStart+m_outerSize.value()]) - - std::size_t(m_matrix.outerIndexPtr()[m_outerStart]); - else if(m_outerSize.value()==0) - return 0; - else - return Map >(m_matrix.innerNonZeroPtr()+m_outerStart, m_outerSize.value()).sum(); - } - - inline Scalar& coeffRef(int row, int col) - { - return m_matrix.const_cast_derived().coeffRef(row + (IsRowMajor ? m_outerStart : 0), col + (IsRowMajor ? 0 : m_outerStart)); - } - - inline const Scalar coeff(int row, int col) const - { - return m_matrix.coeff(row + (IsRowMajor ? m_outerStart : 0), col + (IsRowMajor ? 0 : m_outerStart)); - } - - inline const Scalar coeff(int index) const - { - return m_matrix.coeff(IsRowMajor ? m_outerStart : index, IsRowMajor ? index : m_outerStart); - } - - const Scalar& lastCoeff() const - { - EIGEN_STATIC_ASSERT_VECTOR_ONLY(BlockImpl); - eigen_assert(nonZeros()>0); - if(m_matrix.isCompressed()) - return m_matrix.valuePtr()[m_matrix.outerIndexPtr()[m_outerStart+1]-1]; - else - return m_matrix.valuePtr()[m_matrix.outerIndexPtr()[m_outerStart]+m_matrix.innerNonZeroPtr()[m_outerStart]-1]; - } - - EIGEN_STRONG_INLINE Index rows() const { return IsRowMajor ? m_outerSize.value() : m_matrix.rows(); } - EIGEN_STRONG_INLINE Index cols() const { return IsRowMajor ? m_matrix.cols() : m_outerSize.value(); } - - protected: - - typename SparseMatrixType::Nested m_matrix; - Index m_outerStart; - const internal::variable_if_dynamic m_outerSize; - -}; - - -template -class BlockImpl,BlockRows,BlockCols,true,Sparse> - : public SparseMatrixBase,BlockRows,BlockCols,true> > -{ - typedef SparseMatrix<_Scalar, _Options, _Index> SparseMatrixType; - typedef typename internal::remove_all::type _MatrixTypeNested; - typedef Block BlockType; -public: - enum { IsRowMajor = internal::traits::IsRowMajor }; - EIGEN_SPARSE_PUBLIC_INTERFACE(BlockType) -protected: - enum { OuterSize = IsRowMajor ? BlockRows : BlockCols }; -public: - - class InnerIterator: public SparseMatrixType::InnerIterator - { - public: - inline InnerIterator(const BlockType& xpr, Index outer) - : SparseMatrixType::InnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer) - {} - inline Index row() const { return IsRowMajor ? m_outer : this->index(); } - inline Index col() const { return IsRowMajor ? this->index() : m_outer; } - protected: - Index m_outer; - }; - class ReverseInnerIterator: public SparseMatrixType::ReverseInnerIterator - { - public: - inline ReverseInnerIterator(const BlockType& xpr, Index outer) - : SparseMatrixType::ReverseInnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer) - {} - inline Index row() const { return IsRowMajor ? m_outer : this->index(); } - inline Index col() const { return IsRowMajor ? this->index() : m_outer; } - protected: - Index m_outer; - }; - - inline BlockImpl(const SparseMatrixType& xpr, int i) - : m_matrix(xpr), m_outerStart(i), m_outerSize(OuterSize) - {} - - inline BlockImpl(const SparseMatrixType& xpr, int startRow, int startCol, int blockRows, int blockCols) - : m_matrix(xpr), m_outerStart(IsRowMajor ? startRow : startCol), m_outerSize(IsRowMajor ? blockRows : blockCols) - {} - - inline const Scalar* valuePtr() const - { return m_matrix.valuePtr() + m_matrix.outerIndexPtr()[m_outerStart]; } - - inline const Index* innerIndexPtr() const - { return m_matrix.innerIndexPtr() + m_matrix.outerIndexPtr()[m_outerStart]; } - - inline const Index* outerIndexPtr() const - { return m_matrix.outerIndexPtr() + m_outerStart; } - - Index nonZeros() const - { - if(m_matrix.isCompressed()) - return std::size_t(m_matrix.outerIndexPtr()[m_outerStart+m_outerSize.value()]) - - std::size_t(m_matrix.outerIndexPtr()[m_outerStart]); - else if(m_outerSize.value()==0) - return 0; - else - return Map >(m_matrix.innerNonZeroPtr()+m_outerStart, m_outerSize.value()).sum(); - } - - inline const Scalar coeff(int row, int col) const - { - return m_matrix.coeff(row + (IsRowMajor ? m_outerStart : 0), col + (IsRowMajor ? 0 : m_outerStart)); - } - - inline const Scalar coeff(int index) const - { - return m_matrix.coeff(IsRowMajor ? m_outerStart : index, IsRowMajor ? index : m_outerStart); - } - - const Scalar& lastCoeff() const - { - EIGEN_STATIC_ASSERT_VECTOR_ONLY(BlockImpl); - eigen_assert(nonZeros()>0); - if(m_matrix.isCompressed()) - return m_matrix.valuePtr()[m_matrix.outerIndexPtr()[m_outerStart+1]-1]; - else - return m_matrix.valuePtr()[m_matrix.outerIndexPtr()[m_outerStart]+m_matrix.innerNonZeroPtr()[m_outerStart]-1]; - } - - EIGEN_STRONG_INLINE Index rows() const { return IsRowMajor ? m_outerSize.value() : m_matrix.rows(); } - EIGEN_STRONG_INLINE Index cols() const { return IsRowMajor ? m_matrix.cols() : m_outerSize.value(); } - - protected: - - typename SparseMatrixType::Nested m_matrix; - Index m_outerStart; - const internal::variable_if_dynamic m_outerSize; - -}; - -//---------- - -/** \returns the \a outer -th column (resp. row) of the matrix \c *this if \c *this - * is col-major (resp. row-major). - */ -template -typename SparseMatrixBase::InnerVectorReturnType SparseMatrixBase::innerVector(Index outer) -{ return InnerVectorReturnType(derived(), outer); } - -/** \returns the \a outer -th column (resp. row) of the matrix \c *this if \c *this - * is col-major (resp. row-major). Read-only. - */ -template -const typename SparseMatrixBase::ConstInnerVectorReturnType SparseMatrixBase::innerVector(Index outer) const -{ return ConstInnerVectorReturnType(derived(), outer); } - -/** \returns the \a outer -th column (resp. row) of the matrix \c *this if \c *this - * is col-major (resp. row-major). - */ -template -typename SparseMatrixBase::InnerVectorsReturnType -SparseMatrixBase::innerVectors(Index outerStart, Index outerSize) -{ - return Block(derived(), - IsRowMajor ? outerStart : 0, IsRowMajor ? 0 : outerStart, - IsRowMajor ? outerSize : rows(), IsRowMajor ? cols() : outerSize); - -} - -/** \returns the \a outer -th column (resp. row) of the matrix \c *this if \c *this - * is col-major (resp. row-major). Read-only. - */ -template -const typename SparseMatrixBase::ConstInnerVectorsReturnType -SparseMatrixBase::innerVectors(Index outerStart, Index outerSize) const -{ - return Block(derived(), - IsRowMajor ? outerStart : 0, IsRowMajor ? 0 : outerStart, - IsRowMajor ? outerSize : rows(), IsRowMajor ? cols() : outerSize); - -} - -/** Generic implementation of sparse Block expression. - * Real-only. - */ -template -class BlockImpl - : public SparseMatrixBase >, internal::no_assignment_operator -{ - typedef typename internal::remove_all::type _MatrixTypeNested; - typedef Block BlockType; -public: - enum { IsRowMajor = internal::traits::IsRowMajor }; - EIGEN_SPARSE_PUBLIC_INTERFACE(BlockType) - - /** Column or Row constructor - */ - inline BlockImpl(const XprType& xpr, int i) - : m_matrix(xpr), - m_startRow( (BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) ? i : 0), - m_startCol( (BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) ? i : 0), - m_blockRows(BlockRows==1 ? 1 : xpr.rows()), - m_blockCols(BlockCols==1 ? 1 : xpr.cols()) - {} - - /** Dynamic-size constructor - */ - inline BlockImpl(const XprType& xpr, int startRow, int startCol, int blockRows, int blockCols) - : m_matrix(xpr), m_startRow(startRow), m_startCol(startCol), m_blockRows(blockRows), m_blockCols(blockCols) - {} - - inline int rows() const { return m_blockRows.value(); } - inline int cols() const { return m_blockCols.value(); } - - inline Scalar& coeffRef(int row, int col) - { - return m_matrix.const_cast_derived() - .coeffRef(row + m_startRow.value(), col + m_startCol.value()); - } - - inline const Scalar coeff(int row, int col) const - { - return m_matrix.coeff(row + m_startRow.value(), col + m_startCol.value()); - } - - inline Scalar& coeffRef(int index) - { - return m_matrix.const_cast_derived() - .coeffRef(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index), - m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0)); - } - - inline const Scalar coeff(int index) const - { - return m_matrix - .coeff(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index), - m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0)); - } - - inline const _MatrixTypeNested& nestedExpression() const { return m_matrix; } - - class InnerIterator : public _MatrixTypeNested::InnerIterator - { - typedef typename _MatrixTypeNested::InnerIterator Base; - const BlockType& m_block; - Index m_end; - public: - - EIGEN_STRONG_INLINE InnerIterator(const BlockType& block, Index outer) - : Base(block.derived().nestedExpression(), outer + (IsRowMajor ? block.m_startRow.value() : block.m_startCol.value())), - m_block(block), - m_end(IsRowMajor ? block.m_startCol.value()+block.m_blockCols.value() : block.m_startRow.value()+block.m_blockRows.value()) - { - while( (Base::operator bool()) && (Base::index() < (IsRowMajor ? m_block.m_startCol.value() : m_block.m_startRow.value())) ) - Base::operator++(); - } - - inline Index index() const { return Base::index() - (IsRowMajor ? m_block.m_startCol.value() : m_block.m_startRow.value()); } - inline Index outer() const { return Base::outer() - (IsRowMajor ? m_block.m_startRow.value() : m_block.m_startCol.value()); } - inline Index row() const { return Base::row() - m_block.m_startRow.value(); } - inline Index col() const { return Base::col() - m_block.m_startCol.value(); } - - inline operator bool() const { return Base::operator bool() && Base::index() < m_end; } - }; - class ReverseInnerIterator : public _MatrixTypeNested::ReverseInnerIterator - { - typedef typename _MatrixTypeNested::ReverseInnerIterator Base; - const BlockType& m_block; - Index m_begin; - public: - - EIGEN_STRONG_INLINE ReverseInnerIterator(const BlockType& block, Index outer) - : Base(block.derived().nestedExpression(), outer + (IsRowMajor ? block.m_startRow.value() : block.m_startCol.value())), - m_block(block), - m_begin(IsRowMajor ? block.m_startCol.value() : block.m_startRow.value()) - { - while( (Base::operator bool()) && (Base::index() >= (IsRowMajor ? m_block.m_startCol.value()+block.m_blockCols.value() : m_block.m_startRow.value()+block.m_blockRows.value())) ) - Base::operator--(); - } - - inline Index index() const { return Base::index() - (IsRowMajor ? m_block.m_startCol.value() : m_block.m_startRow.value()); } - inline Index outer() const { return Base::outer() - (IsRowMajor ? m_block.m_startRow.value() : m_block.m_startCol.value()); } - inline Index row() const { return Base::row() - m_block.m_startRow.value(); } - inline Index col() const { return Base::col() - m_block.m_startCol.value(); } - - inline operator bool() const { return Base::operator bool() && Base::index() >= m_begin; } - }; - protected: - friend class InnerIterator; - friend class ReverseInnerIterator; - - EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl) - - typename XprType::Nested m_matrix; - const internal::variable_if_dynamic m_startRow; - const internal::variable_if_dynamic m_startCol; - const internal::variable_if_dynamic m_blockRows; - const internal::variable_if_dynamic m_blockCols; - -}; - -} // end namespace Eigen - -#endif // EIGEN_SPARSE_BLOCK_H - diff --git a/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseColEtree.h b/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseColEtree.h deleted file mode 100644 index f8745f46..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseColEtree.h +++ /dev/null @@ -1,206 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2012 Désiré Nuentsa-Wakam -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - - -/* - - * NOTE: This file is the modified version of sp_coletree.c file in SuperLU - - * -- SuperLU routine (version 3.1) -- - * Univ. of California Berkeley, Xerox Palo Alto Research Center, - * and Lawrence Berkeley National Lab. - * August 1, 2008 - * - * Copyright (c) 1994 by Xerox Corporation. All rights reserved. - * - * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY - * EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK. - * - * Permission is hereby granted to use or copy this program for any - * purpose, provided the above notices are retained on all copies. - * Permission to modify the code and to distribute modified code is - * granted, provided the above notices are retained, and a notice that - * the code was modified is included with the above copyright notice. - */ -#ifndef SPARSE_COLETREE_H -#define SPARSE_COLETREE_H - -namespace Eigen { - -namespace internal { - -/** Find the root of the tree/set containing the vertex i : Use Path halving */ -template -Index etree_find (Index i, IndexVector& pp) -{ - Index p = pp(i); // Parent - Index gp = pp(p); // Grand parent - while (gp != p) - { - pp(i) = gp; // Parent pointer on find path is changed to former grand parent - i = gp; - p = pp(i); - gp = pp(p); - } - return p; -} - -/** Compute the column elimination tree of a sparse matrix - * \param mat The matrix in column-major format. - * \param parent The elimination tree - * \param firstRowElt The column index of the first element in each row - * \param perm The permutation to apply to the column of \b mat - */ -template -int coletree(const MatrixType& mat, IndexVector& parent, IndexVector& firstRowElt, typename MatrixType::Index *perm=0) -{ - typedef typename MatrixType::Index Index; - Index nc = mat.cols(); // Number of columns - Index m = mat.rows(); - Index diagSize = (std::min)(nc,m); - IndexVector root(nc); // root of subtree of etree - root.setZero(); - IndexVector pp(nc); // disjoint sets - pp.setZero(); // Initialize disjoint sets - parent.resize(mat.cols()); - //Compute first nonzero column in each row - Index row,col; - firstRowElt.resize(m); - firstRowElt.setConstant(nc); - firstRowElt.segment(0, diagSize).setLinSpaced(diagSize, 0, diagSize-1); - bool found_diag; - for (col = 0; col < nc; col++) - { - Index pcol = col; - if(perm) pcol = perm[col]; - for (typename MatrixType::InnerIterator it(mat, pcol); it; ++it) - { - row = it.row(); - firstRowElt(row) = (std::min)(firstRowElt(row), col); - } - } - /* Compute etree by Liu's algorithm for symmetric matrices, - except use (firstRowElt[r],c) in place of an edge (r,c) of A. - Thus each row clique in A'*A is replaced by a star - centered at its first vertex, which has the same fill. */ - Index rset, cset, rroot; - for (col = 0; col < nc; col++) - { - found_diag = col>=m; - pp(col) = col; - cset = col; - root(cset) = col; - parent(col) = nc; - /* The diagonal element is treated here even if it does not exist in the matrix - * hence the loop is executed once more */ - Index pcol = col; - if(perm) pcol = perm[col]; - for (typename MatrixType::InnerIterator it(mat, pcol); it||!found_diag; ++it) - { // A sequence of interleaved find and union is performed - Index i = col; - if(it) i = it.index(); - if (i == col) found_diag = true; - - row = firstRowElt(i); - if (row >= col) continue; - rset = internal::etree_find(row, pp); // Find the name of the set containing row - rroot = root(rset); - if (rroot != col) - { - parent(rroot) = col; - pp(cset) = rset; - cset = rset; - root(cset) = col; - } - } - } - return 0; -} - -/** - * Depth-first search from vertex n. No recursion. - * This routine was contributed by Cédric Doucet, CEDRAT Group, Meylan, France. -*/ -template -void nr_etdfs (Index n, IndexVector& parent, IndexVector& first_kid, IndexVector& next_kid, IndexVector& post, Index postnum) -{ - Index current = n, first, next; - while (postnum != n) - { - // No kid for the current node - first = first_kid(current); - - // no kid for the current node - if (first == -1) - { - // Numbering this node because it has no kid - post(current) = postnum++; - - // looking for the next kid - next = next_kid(current); - while (next == -1) - { - // No more kids : back to the parent node - current = parent(current); - // numbering the parent node - post(current) = postnum++; - - // Get the next kid - next = next_kid(current); - } - // stopping criterion - if (postnum == n+1) return; - - // Updating current node - current = next; - } - else - { - current = first; - } - } -} - - -/** - * \brief Post order a tree - * \param n the number of nodes - * \param parent Input tree - * \param post postordered tree - */ -template -void treePostorder(Index n, IndexVector& parent, IndexVector& post) -{ - IndexVector first_kid, next_kid; // Linked list of children - Index postnum; - // Allocate storage for working arrays and results - first_kid.resize(n+1); - next_kid.setZero(n+1); - post.setZero(n+1); - - // Set up structure describing children - Index v, dad; - first_kid.setConstant(-1); - for (v = n-1; v >= 0; v--) - { - dad = parent(v); - next_kid(v) = first_kid(dad); - first_kid(dad) = v; - } - - // Depth-first search from dummy root vertex #n - postnum = 0; - internal::nr_etdfs(n, parent, first_kid, next_kid, post, postnum); -} - -} // end namespace internal - -} // end namespace Eigen - -#endif // SPARSE_COLETREE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseCwiseBinaryOp.h b/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseCwiseBinaryOp.h deleted file mode 100644 index 4ca91283..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseCwiseBinaryOp.h +++ /dev/null @@ -1,325 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_SPARSE_CWISE_BINARY_OP_H -#define EIGEN_SPARSE_CWISE_BINARY_OP_H - -namespace Eigen { - -// Here we have to handle 3 cases: -// 1 - sparse op dense -// 2 - dense op sparse -// 3 - sparse op sparse -// We also need to implement a 4th iterator for: -// 4 - dense op dense -// Finally, we also need to distinguish between the product and other operations : -// configuration returned mode -// 1 - sparse op dense product sparse -// generic dense -// 2 - dense op sparse product sparse -// generic dense -// 3 - sparse op sparse product sparse -// generic sparse -// 4 - dense op dense product dense -// generic dense - -namespace internal { - -template<> struct promote_storage_type -{ typedef Sparse ret; }; - -template<> struct promote_storage_type -{ typedef Sparse ret; }; - -template::StorageKind, - typename _RhsStorageMode = typename traits::StorageKind> -class sparse_cwise_binary_op_inner_iterator_selector; - -} // end namespace internal - -template -class CwiseBinaryOpImpl - : public SparseMatrixBase > -{ - public: - class InnerIterator; - class ReverseInnerIterator; - typedef CwiseBinaryOp Derived; - EIGEN_SPARSE_PUBLIC_INTERFACE(Derived) - CwiseBinaryOpImpl() - { - typedef typename internal::traits::StorageKind LhsStorageKind; - typedef typename internal::traits::StorageKind RhsStorageKind; - EIGEN_STATIC_ASSERT(( - (!internal::is_same::value) - || ((Lhs::Flags&RowMajorBit) == (Rhs::Flags&RowMajorBit))), - THE_STORAGE_ORDER_OF_BOTH_SIDES_MUST_MATCH); - } -}; - -template -class CwiseBinaryOpImpl::InnerIterator - : public internal::sparse_cwise_binary_op_inner_iterator_selector::InnerIterator> -{ - public: - typedef typename Lhs::Index Index; - typedef internal::sparse_cwise_binary_op_inner_iterator_selector< - BinaryOp,Lhs,Rhs, InnerIterator> Base; - - // NOTE: we have to prefix Index by "typename Lhs::" to avoid an ICE with VC11 - EIGEN_STRONG_INLINE InnerIterator(const CwiseBinaryOpImpl& binOp, typename Lhs::Index outer) - : Base(binOp.derived(),outer) - {} -}; - -/*************************************************************************** -* Implementation of inner-iterators -***************************************************************************/ - -// template struct internal::func_is_conjunction { enum { ret = false }; }; -// template struct internal::func_is_conjunction > { enum { ret = true }; }; - -// TODO generalize the internal::scalar_product_op specialization to all conjunctions if any ! - -namespace internal { - -// sparse - sparse (generic) -template -class sparse_cwise_binary_op_inner_iterator_selector -{ - typedef CwiseBinaryOp CwiseBinaryXpr; - typedef typename traits::Scalar Scalar; - typedef typename traits::_LhsNested _LhsNested; - typedef typename traits::_RhsNested _RhsNested; - typedef typename _LhsNested::InnerIterator LhsIterator; - typedef typename _RhsNested::InnerIterator RhsIterator; - typedef typename Lhs::Index Index; - - public: - - EIGEN_STRONG_INLINE sparse_cwise_binary_op_inner_iterator_selector(const CwiseBinaryXpr& xpr, Index outer) - : m_lhsIter(xpr.lhs(),outer), m_rhsIter(xpr.rhs(),outer), m_functor(xpr.functor()) - { - this->operator++(); - } - - EIGEN_STRONG_INLINE Derived& operator++() - { - if (m_lhsIter && m_rhsIter && (m_lhsIter.index() == m_rhsIter.index())) - { - m_id = m_lhsIter.index(); - m_value = m_functor(m_lhsIter.value(), m_rhsIter.value()); - ++m_lhsIter; - ++m_rhsIter; - } - else if (m_lhsIter && (!m_rhsIter || (m_lhsIter.index() < m_rhsIter.index()))) - { - m_id = m_lhsIter.index(); - m_value = m_functor(m_lhsIter.value(), Scalar(0)); - ++m_lhsIter; - } - else if (m_rhsIter && (!m_lhsIter || (m_lhsIter.index() > m_rhsIter.index()))) - { - m_id = m_rhsIter.index(); - m_value = m_functor(Scalar(0), m_rhsIter.value()); - ++m_rhsIter; - } - else - { - m_value = 0; // this is to avoid a compilation warning - m_id = -1; - } - return *static_cast(this); - } - - EIGEN_STRONG_INLINE Scalar value() const { return m_value; } - - EIGEN_STRONG_INLINE Index index() const { return m_id; } - EIGEN_STRONG_INLINE Index row() const { return Lhs::IsRowMajor ? m_lhsIter.row() : index(); } - EIGEN_STRONG_INLINE Index col() const { return Lhs::IsRowMajor ? index() : m_lhsIter.col(); } - - EIGEN_STRONG_INLINE operator bool() const { return m_id>=0; } - - protected: - LhsIterator m_lhsIter; - RhsIterator m_rhsIter; - const BinaryOp& m_functor; - Scalar m_value; - Index m_id; -}; - -// sparse - sparse (product) -template -class sparse_cwise_binary_op_inner_iterator_selector, Lhs, Rhs, Derived, Sparse, Sparse> -{ - typedef scalar_product_op BinaryFunc; - typedef CwiseBinaryOp CwiseBinaryXpr; - typedef typename CwiseBinaryXpr::Scalar Scalar; - typedef typename traits::_LhsNested _LhsNested; - typedef typename _LhsNested::InnerIterator LhsIterator; - typedef typename traits::_RhsNested _RhsNested; - typedef typename _RhsNested::InnerIterator RhsIterator; - typedef typename Lhs::Index Index; - public: - - EIGEN_STRONG_INLINE sparse_cwise_binary_op_inner_iterator_selector(const CwiseBinaryXpr& xpr, Index outer) - : m_lhsIter(xpr.lhs(),outer), m_rhsIter(xpr.rhs(),outer), m_functor(xpr.functor()) - { - while (m_lhsIter && m_rhsIter && (m_lhsIter.index() != m_rhsIter.index())) - { - if (m_lhsIter.index() < m_rhsIter.index()) - ++m_lhsIter; - else - ++m_rhsIter; - } - } - - EIGEN_STRONG_INLINE Derived& operator++() - { - ++m_lhsIter; - ++m_rhsIter; - while (m_lhsIter && m_rhsIter && (m_lhsIter.index() != m_rhsIter.index())) - { - if (m_lhsIter.index() < m_rhsIter.index()) - ++m_lhsIter; - else - ++m_rhsIter; - } - return *static_cast(this); - } - - EIGEN_STRONG_INLINE Scalar value() const { return m_functor(m_lhsIter.value(), m_rhsIter.value()); } - - EIGEN_STRONG_INLINE Index index() const { return m_lhsIter.index(); } - EIGEN_STRONG_INLINE Index row() const { return m_lhsIter.row(); } - EIGEN_STRONG_INLINE Index col() const { return m_lhsIter.col(); } - - EIGEN_STRONG_INLINE operator bool() const { return (m_lhsIter && m_rhsIter); } - - protected: - LhsIterator m_lhsIter; - RhsIterator m_rhsIter; - const BinaryFunc& m_functor; -}; - -// sparse - dense (product) -template -class sparse_cwise_binary_op_inner_iterator_selector, Lhs, Rhs, Derived, Sparse, Dense> -{ - typedef scalar_product_op BinaryFunc; - typedef CwiseBinaryOp CwiseBinaryXpr; - typedef typename CwiseBinaryXpr::Scalar Scalar; - typedef typename traits::_LhsNested _LhsNested; - typedef typename traits::RhsNested RhsNested; - typedef typename _LhsNested::InnerIterator LhsIterator; - typedef typename Lhs::Index Index; - enum { IsRowMajor = (int(Lhs::Flags)&RowMajorBit)==RowMajorBit }; - public: - - EIGEN_STRONG_INLINE sparse_cwise_binary_op_inner_iterator_selector(const CwiseBinaryXpr& xpr, Index outer) - : m_rhs(xpr.rhs()), m_lhsIter(xpr.lhs(),outer), m_functor(xpr.functor()), m_outer(outer) - {} - - EIGEN_STRONG_INLINE Derived& operator++() - { - ++m_lhsIter; - return *static_cast(this); - } - - EIGEN_STRONG_INLINE Scalar value() const - { return m_functor(m_lhsIter.value(), - m_rhs.coeff(IsRowMajor?m_outer:m_lhsIter.index(),IsRowMajor?m_lhsIter.index():m_outer)); } - - EIGEN_STRONG_INLINE Index index() const { return m_lhsIter.index(); } - EIGEN_STRONG_INLINE Index row() const { return m_lhsIter.row(); } - EIGEN_STRONG_INLINE Index col() const { return m_lhsIter.col(); } - - EIGEN_STRONG_INLINE operator bool() const { return m_lhsIter; } - - protected: - RhsNested m_rhs; - LhsIterator m_lhsIter; - const BinaryFunc m_functor; - const Index m_outer; -}; - -// sparse - dense (product) -template -class sparse_cwise_binary_op_inner_iterator_selector, Lhs, Rhs, Derived, Dense, Sparse> -{ - typedef scalar_product_op BinaryFunc; - typedef CwiseBinaryOp CwiseBinaryXpr; - typedef typename CwiseBinaryXpr::Scalar Scalar; - typedef typename traits::_RhsNested _RhsNested; - typedef typename _RhsNested::InnerIterator RhsIterator; - typedef typename Lhs::Index Index; - - enum { IsRowMajor = (int(Rhs::Flags)&RowMajorBit)==RowMajorBit }; - public: - - EIGEN_STRONG_INLINE sparse_cwise_binary_op_inner_iterator_selector(const CwiseBinaryXpr& xpr, Index outer) - : m_xpr(xpr), m_rhsIter(xpr.rhs(),outer), m_functor(xpr.functor()), m_outer(outer) - {} - - EIGEN_STRONG_INLINE Derived& operator++() - { - ++m_rhsIter; - return *static_cast(this); - } - - EIGEN_STRONG_INLINE Scalar value() const - { return m_functor(m_xpr.lhs().coeff(IsRowMajor?m_outer:m_rhsIter.index(),IsRowMajor?m_rhsIter.index():m_outer), m_rhsIter.value()); } - - EIGEN_STRONG_INLINE Index index() const { return m_rhsIter.index(); } - EIGEN_STRONG_INLINE Index row() const { return m_rhsIter.row(); } - EIGEN_STRONG_INLINE Index col() const { return m_rhsIter.col(); } - - EIGEN_STRONG_INLINE operator bool() const { return m_rhsIter; } - - protected: - const CwiseBinaryXpr& m_xpr; - RhsIterator m_rhsIter; - const BinaryFunc& m_functor; - const Index m_outer; -}; - -} // end namespace internal - -/*************************************************************************** -* Implementation of SparseMatrixBase and SparseCwise functions/operators -***************************************************************************/ - -template -template -EIGEN_STRONG_INLINE Derived & -SparseMatrixBase::operator-=(const SparseMatrixBase &other) -{ - return derived() = derived() - other.derived(); -} - -template -template -EIGEN_STRONG_INLINE Derived & -SparseMatrixBase::operator+=(const SparseMatrixBase& other) -{ - return derived() = derived() + other.derived(); -} - -template -template -EIGEN_STRONG_INLINE const typename SparseMatrixBase::template CwiseProductDenseReturnType::Type -SparseMatrixBase::cwiseProduct(const MatrixBase &other) const -{ - return typename CwiseProductDenseReturnType::Type(derived(), other.derived()); -} - -} // end namespace Eigen - -#endif // EIGEN_SPARSE_CWISE_BINARY_OP_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseCwiseUnaryOp.h b/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseCwiseUnaryOp.h deleted file mode 100644 index 5a50c780..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseCwiseUnaryOp.h +++ /dev/null @@ -1,163 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2010 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_SPARSE_CWISE_UNARY_OP_H -#define EIGEN_SPARSE_CWISE_UNARY_OP_H - -namespace Eigen { - -template -class CwiseUnaryOpImpl - : public SparseMatrixBase > -{ - public: - - class InnerIterator; - class ReverseInnerIterator; - - typedef CwiseUnaryOp Derived; - EIGEN_SPARSE_PUBLIC_INTERFACE(Derived) - - protected: - typedef typename internal::traits::_XprTypeNested _MatrixTypeNested; - typedef typename _MatrixTypeNested::InnerIterator MatrixTypeIterator; - typedef typename _MatrixTypeNested::ReverseInnerIterator MatrixTypeReverseIterator; -}; - -template -class CwiseUnaryOpImpl::InnerIterator - : public CwiseUnaryOpImpl::MatrixTypeIterator -{ - typedef typename CwiseUnaryOpImpl::Scalar Scalar; - typedef typename CwiseUnaryOpImpl::MatrixTypeIterator Base; - public: - - EIGEN_STRONG_INLINE InnerIterator(const CwiseUnaryOpImpl& unaryOp, typename CwiseUnaryOpImpl::Index outer) - : Base(unaryOp.derived().nestedExpression(),outer), m_functor(unaryOp.derived().functor()) - {} - - EIGEN_STRONG_INLINE InnerIterator& operator++() - { Base::operator++(); return *this; } - - EIGEN_STRONG_INLINE typename CwiseUnaryOpImpl::Scalar value() const { return m_functor(Base::value()); } - - protected: - const UnaryOp m_functor; - private: - typename CwiseUnaryOpImpl::Scalar& valueRef(); -}; - -template -class CwiseUnaryOpImpl::ReverseInnerIterator - : public CwiseUnaryOpImpl::MatrixTypeReverseIterator -{ - typedef typename CwiseUnaryOpImpl::Scalar Scalar; - typedef typename CwiseUnaryOpImpl::MatrixTypeReverseIterator Base; - public: - - EIGEN_STRONG_INLINE ReverseInnerIterator(const CwiseUnaryOpImpl& unaryOp, typename CwiseUnaryOpImpl::Index outer) - : Base(unaryOp.derived().nestedExpression(),outer), m_functor(unaryOp.derived().functor()) - {} - - EIGEN_STRONG_INLINE ReverseInnerIterator& operator--() - { Base::operator--(); return *this; } - - EIGEN_STRONG_INLINE typename CwiseUnaryOpImpl::Scalar value() const { return m_functor(Base::value()); } - - protected: - const UnaryOp m_functor; - private: - typename CwiseUnaryOpImpl::Scalar& valueRef(); -}; - -template -class CwiseUnaryViewImpl - : public SparseMatrixBase > -{ - public: - - class InnerIterator; - class ReverseInnerIterator; - - typedef CwiseUnaryView Derived; - EIGEN_SPARSE_PUBLIC_INTERFACE(Derived) - - protected: - typedef typename internal::traits::_MatrixTypeNested _MatrixTypeNested; - typedef typename _MatrixTypeNested::InnerIterator MatrixTypeIterator; - typedef typename _MatrixTypeNested::ReverseInnerIterator MatrixTypeReverseIterator; -}; - -template -class CwiseUnaryViewImpl::InnerIterator - : public CwiseUnaryViewImpl::MatrixTypeIterator -{ - typedef typename CwiseUnaryViewImpl::Scalar Scalar; - typedef typename CwiseUnaryViewImpl::MatrixTypeIterator Base; - public: - - EIGEN_STRONG_INLINE InnerIterator(const CwiseUnaryViewImpl& unaryOp, typename CwiseUnaryViewImpl::Index outer) - : Base(unaryOp.derived().nestedExpression(),outer), m_functor(unaryOp.derived().functor()) - {} - - EIGEN_STRONG_INLINE InnerIterator& operator++() - { Base::operator++(); return *this; } - - EIGEN_STRONG_INLINE typename CwiseUnaryViewImpl::Scalar value() const { return m_functor(Base::value()); } - EIGEN_STRONG_INLINE typename CwiseUnaryViewImpl::Scalar& valueRef() { return m_functor(Base::valueRef()); } - - protected: - const ViewOp m_functor; -}; - -template -class CwiseUnaryViewImpl::ReverseInnerIterator - : public CwiseUnaryViewImpl::MatrixTypeReverseIterator -{ - typedef typename CwiseUnaryViewImpl::Scalar Scalar; - typedef typename CwiseUnaryViewImpl::MatrixTypeReverseIterator Base; - public: - - EIGEN_STRONG_INLINE ReverseInnerIterator(const CwiseUnaryViewImpl& unaryOp, typename CwiseUnaryViewImpl::Index outer) - : Base(unaryOp.derived().nestedExpression(),outer), m_functor(unaryOp.derived().functor()) - {} - - EIGEN_STRONG_INLINE ReverseInnerIterator& operator--() - { Base::operator--(); return *this; } - - EIGEN_STRONG_INLINE typename CwiseUnaryViewImpl::Scalar value() const { return m_functor(Base::value()); } - EIGEN_STRONG_INLINE typename CwiseUnaryViewImpl::Scalar& valueRef() { return m_functor(Base::valueRef()); } - - protected: - const ViewOp m_functor; -}; - -template -EIGEN_STRONG_INLINE Derived& -SparseMatrixBase::operator*=(const Scalar& other) -{ - for (Index j=0; j -EIGEN_STRONG_INLINE Derived& -SparseMatrixBase::operator/=(const Scalar& other) -{ - for (Index j=0; j -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_SPARSEDENSEPRODUCT_H -#define EIGEN_SPARSEDENSEPRODUCT_H - -namespace Eigen { - -template struct SparseDenseProductReturnType -{ - typedef SparseTimeDenseProduct Type; -}; - -template struct SparseDenseProductReturnType -{ - typedef typename internal::conditional< - Lhs::IsRowMajor, - SparseDenseOuterProduct, - SparseDenseOuterProduct >::type Type; -}; - -template struct DenseSparseProductReturnType -{ - typedef DenseTimeSparseProduct Type; -}; - -template struct DenseSparseProductReturnType -{ - typedef typename internal::conditional< - Rhs::IsRowMajor, - SparseDenseOuterProduct, - SparseDenseOuterProduct >::type Type; -}; - -namespace internal { - -template -struct traits > -{ - typedef Sparse StorageKind; - typedef typename scalar_product_traits::Scalar, - typename traits::Scalar>::ReturnType Scalar; - typedef typename Lhs::Index Index; - typedef typename Lhs::Nested LhsNested; - typedef typename Rhs::Nested RhsNested; - typedef typename remove_all::type _LhsNested; - typedef typename remove_all::type _RhsNested; - - enum { - LhsCoeffReadCost = traits<_LhsNested>::CoeffReadCost, - RhsCoeffReadCost = traits<_RhsNested>::CoeffReadCost, - - RowsAtCompileTime = Tr ? int(traits::RowsAtCompileTime) : int(traits::RowsAtCompileTime), - ColsAtCompileTime = Tr ? int(traits::ColsAtCompileTime) : int(traits::ColsAtCompileTime), - MaxRowsAtCompileTime = Tr ? int(traits::MaxRowsAtCompileTime) : int(traits::MaxRowsAtCompileTime), - MaxColsAtCompileTime = Tr ? int(traits::MaxColsAtCompileTime) : int(traits::MaxColsAtCompileTime), - - Flags = Tr ? RowMajorBit : 0, - - CoeffReadCost = LhsCoeffReadCost + RhsCoeffReadCost + NumTraits::MulCost - }; -}; - -} // end namespace internal - -template -class SparseDenseOuterProduct - : public SparseMatrixBase > -{ - public: - - typedef SparseMatrixBase Base; - EIGEN_DENSE_PUBLIC_INTERFACE(SparseDenseOuterProduct) - typedef internal::traits Traits; - - private: - - typedef typename Traits::LhsNested LhsNested; - typedef typename Traits::RhsNested RhsNested; - typedef typename Traits::_LhsNested _LhsNested; - typedef typename Traits::_RhsNested _RhsNested; - - public: - - class InnerIterator; - - EIGEN_STRONG_INLINE SparseDenseOuterProduct(const Lhs& lhs, const Rhs& rhs) - : m_lhs(lhs), m_rhs(rhs) - { - EIGEN_STATIC_ASSERT(!Tr,YOU_MADE_A_PROGRAMMING_MISTAKE); - } - - EIGEN_STRONG_INLINE SparseDenseOuterProduct(const Rhs& rhs, const Lhs& lhs) - : m_lhs(lhs), m_rhs(rhs) - { - EIGEN_STATIC_ASSERT(Tr,YOU_MADE_A_PROGRAMMING_MISTAKE); - } - - EIGEN_STRONG_INLINE Index rows() const { return Tr ? m_rhs.rows() : m_lhs.rows(); } - EIGEN_STRONG_INLINE Index cols() const { return Tr ? m_lhs.cols() : m_rhs.cols(); } - - EIGEN_STRONG_INLINE const _LhsNested& lhs() const { return m_lhs; } - EIGEN_STRONG_INLINE const _RhsNested& rhs() const { return m_rhs; } - - protected: - LhsNested m_lhs; - RhsNested m_rhs; -}; - -template -class SparseDenseOuterProduct::InnerIterator : public _LhsNested::InnerIterator -{ - typedef typename _LhsNested::InnerIterator Base; - typedef typename SparseDenseOuterProduct::Index Index; - public: - EIGEN_STRONG_INLINE InnerIterator(const SparseDenseOuterProduct& prod, Index outer) - : Base(prod.lhs(), 0), m_outer(outer), m_factor(get(prod.rhs(), outer, typename internal::traits::StorageKind() )) - { } - - inline Index outer() const { return m_outer; } - inline Index row() const { return Transpose ? m_outer : Base::index(); } - inline Index col() const { return Transpose ? Base::index() : m_outer; } - - inline Scalar value() const { return Base::value() * m_factor; } - - protected: - static Scalar get(const _RhsNested &rhs, Index outer, Dense = Dense()) - { - return rhs.coeff(outer); - } - - static Scalar get(const _RhsNested &rhs, Index outer, Sparse = Sparse()) - { - typename Traits::_RhsNested::InnerIterator it(rhs, outer); - if (it && it.index()==0) - return it.value(); - - return Scalar(0); - } - - Index m_outer; - Scalar m_factor; -}; - -namespace internal { -template -struct traits > - : traits, Lhs, Rhs> > -{ - typedef Dense StorageKind; - typedef MatrixXpr XprKind; -}; - -template -struct sparse_time_dense_product_impl; - -template -struct sparse_time_dense_product_impl -{ - typedef typename internal::remove_all::type Lhs; - typedef typename internal::remove_all::type Rhs; - typedef typename internal::remove_all::type Res; - typedef typename Lhs::Index Index; - typedef typename Lhs::InnerIterator LhsInnerIterator; - static void run(const SparseLhsType& lhs, const DenseRhsType& rhs, DenseResType& res, const typename Res::Scalar& alpha) - { - for(Index c=0; c -struct sparse_time_dense_product_impl -{ - typedef typename internal::remove_all::type Lhs; - typedef typename internal::remove_all::type Rhs; - typedef typename internal::remove_all::type Res; - typedef typename Lhs::InnerIterator LhsInnerIterator; - typedef typename Lhs::Index Index; - static void run(const SparseLhsType& lhs, const DenseRhsType& rhs, DenseResType& res, const typename Res::Scalar& alpha) - { - for(Index c=0; c -struct sparse_time_dense_product_impl -{ - typedef typename internal::remove_all::type Lhs; - typedef typename internal::remove_all::type Rhs; - typedef typename internal::remove_all::type Res; - typedef typename Lhs::InnerIterator LhsInnerIterator; - typedef typename Lhs::Index Index; - static void run(const SparseLhsType& lhs, const DenseRhsType& rhs, DenseResType& res, const typename Res::Scalar& alpha) - { - for(Index j=0; j -struct sparse_time_dense_product_impl -{ - typedef typename internal::remove_all::type Lhs; - typedef typename internal::remove_all::type Rhs; - typedef typename internal::remove_all::type Res; - typedef typename Lhs::InnerIterator LhsInnerIterator; - typedef typename Lhs::Index Index; - static void run(const SparseLhsType& lhs, const DenseRhsType& rhs, DenseResType& res, const typename Res::Scalar& alpha) - { - for(Index j=0; j -inline void sparse_time_dense_product(const SparseLhsType& lhs, const DenseRhsType& rhs, DenseResType& res, const AlphaType& alpha) -{ - sparse_time_dense_product_impl::run(lhs, rhs, res, alpha); -} - -} // end namespace internal - -template -class SparseTimeDenseProduct - : public ProductBase, Lhs, Rhs> -{ - public: - EIGEN_PRODUCT_PUBLIC_INTERFACE(SparseTimeDenseProduct) - - SparseTimeDenseProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs) - {} - - template void scaleAndAddTo(Dest& dest, const Scalar& alpha) const - { - internal::sparse_time_dense_product(m_lhs, m_rhs, dest, alpha); - } - - private: - SparseTimeDenseProduct& operator=(const SparseTimeDenseProduct&); -}; - - -// dense = dense * sparse -namespace internal { -template -struct traits > - : traits, Lhs, Rhs> > -{ - typedef Dense StorageKind; -}; -} // end namespace internal - -template -class DenseTimeSparseProduct - : public ProductBase, Lhs, Rhs> -{ - public: - EIGEN_PRODUCT_PUBLIC_INTERFACE(DenseTimeSparseProduct) - - DenseTimeSparseProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs) - {} - - template void scaleAndAddTo(Dest& dest, const Scalar& alpha) const - { - Transpose lhs_t(m_lhs); - Transpose rhs_t(m_rhs); - Transpose dest_t(dest); - internal::sparse_time_dense_product(rhs_t, lhs_t, dest_t, alpha); - } - - private: - DenseTimeSparseProduct& operator=(const DenseTimeSparseProduct&); -}; - -} // end namespace Eigen - -#endif // EIGEN_SPARSEDENSEPRODUCT_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseDiagonalProduct.h b/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseDiagonalProduct.h deleted file mode 100644 index 1bb590e6..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseDiagonalProduct.h +++ /dev/null @@ -1,196 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2009 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_SPARSE_DIAGONAL_PRODUCT_H -#define EIGEN_SPARSE_DIAGONAL_PRODUCT_H - -namespace Eigen { - -// The product of a diagonal matrix with a sparse matrix can be easily -// implemented using expression template. -// We have two consider very different cases: -// 1 - diag * row-major sparse -// => each inner vector <=> scalar * sparse vector product -// => so we can reuse CwiseUnaryOp::InnerIterator -// 2 - diag * col-major sparse -// => each inner vector <=> densevector * sparse vector cwise product -// => again, we can reuse specialization of CwiseBinaryOp::InnerIterator -// for that particular case -// The two other cases are symmetric. - -namespace internal { - -template -struct traits > -{ - typedef typename remove_all::type _Lhs; - typedef typename remove_all::type _Rhs; - typedef typename _Lhs::Scalar Scalar; - typedef typename promote_index_type::Index, - typename traits::Index>::type Index; - typedef Sparse StorageKind; - typedef MatrixXpr XprKind; - enum { - RowsAtCompileTime = _Lhs::RowsAtCompileTime, - ColsAtCompileTime = _Rhs::ColsAtCompileTime, - - MaxRowsAtCompileTime = _Lhs::MaxRowsAtCompileTime, - MaxColsAtCompileTime = _Rhs::MaxColsAtCompileTime, - - SparseFlags = is_diagonal<_Lhs>::ret ? int(_Rhs::Flags) : int(_Lhs::Flags), - Flags = (SparseFlags&RowMajorBit), - CoeffReadCost = Dynamic - }; -}; - -enum {SDP_IsDiagonal, SDP_IsSparseRowMajor, SDP_IsSparseColMajor}; -template -class sparse_diagonal_product_inner_iterator_selector; - -} // end namespace internal - -template -class SparseDiagonalProduct - : public SparseMatrixBase >, - internal::no_assignment_operator -{ - typedef typename Lhs::Nested LhsNested; - typedef typename Rhs::Nested RhsNested; - - typedef typename internal::remove_all::type _LhsNested; - typedef typename internal::remove_all::type _RhsNested; - - enum { - LhsMode = internal::is_diagonal<_LhsNested>::ret ? internal::SDP_IsDiagonal - : (_LhsNested::Flags&RowMajorBit) ? internal::SDP_IsSparseRowMajor : internal::SDP_IsSparseColMajor, - RhsMode = internal::is_diagonal<_RhsNested>::ret ? internal::SDP_IsDiagonal - : (_RhsNested::Flags&RowMajorBit) ? internal::SDP_IsSparseRowMajor : internal::SDP_IsSparseColMajor - }; - - public: - - EIGEN_SPARSE_PUBLIC_INTERFACE(SparseDiagonalProduct) - - typedef internal::sparse_diagonal_product_inner_iterator_selector - <_LhsNested,_RhsNested,SparseDiagonalProduct,LhsMode,RhsMode> InnerIterator; - - // We do not want ReverseInnerIterator for diagonal-sparse products, - // but this dummy declaration is needed to make diag * sparse * diag compile. - class ReverseInnerIterator; - - EIGEN_STRONG_INLINE SparseDiagonalProduct(const Lhs& lhs, const Rhs& rhs) - : m_lhs(lhs), m_rhs(rhs) - { - eigen_assert(lhs.cols() == rhs.rows() && "invalid sparse matrix * diagonal matrix product"); - } - - EIGEN_STRONG_INLINE Index rows() const { return m_lhs.rows(); } - EIGEN_STRONG_INLINE Index cols() const { return m_rhs.cols(); } - - EIGEN_STRONG_INLINE const _LhsNested& lhs() const { return m_lhs; } - EIGEN_STRONG_INLINE const _RhsNested& rhs() const { return m_rhs; } - - protected: - LhsNested m_lhs; - RhsNested m_rhs; -}; - -namespace internal { - -template -class sparse_diagonal_product_inner_iterator_selector - - : public CwiseUnaryOp,const Rhs>::InnerIterator -{ - typedef typename CwiseUnaryOp,const Rhs>::InnerIterator Base; - typedef typename Lhs::Index Index; - public: - inline sparse_diagonal_product_inner_iterator_selector( - const SparseDiagonalProductType& expr, Index outer) - : Base(expr.rhs()*(expr.lhs().diagonal().coeff(outer)), outer) - {} -}; - -template -class sparse_diagonal_product_inner_iterator_selector - - : public CwiseBinaryOp< - scalar_product_op, - const typename Rhs::ConstInnerVectorReturnType, - const typename Lhs::DiagonalVectorType>::InnerIterator -{ - typedef typename CwiseBinaryOp< - scalar_product_op, - const typename Rhs::ConstInnerVectorReturnType, - const typename Lhs::DiagonalVectorType>::InnerIterator Base; - typedef typename Lhs::Index Index; - Index m_outer; - public: - inline sparse_diagonal_product_inner_iterator_selector( - const SparseDiagonalProductType& expr, Index outer) - : Base(expr.rhs().innerVector(outer) .cwiseProduct(expr.lhs().diagonal()), 0), m_outer(outer) - {} - - inline Index outer() const { return m_outer; } - inline Index col() const { return m_outer; } -}; - -template -class sparse_diagonal_product_inner_iterator_selector - - : public CwiseUnaryOp,const Lhs>::InnerIterator -{ - typedef typename CwiseUnaryOp,const Lhs>::InnerIterator Base; - typedef typename Lhs::Index Index; - public: - inline sparse_diagonal_product_inner_iterator_selector( - const SparseDiagonalProductType& expr, Index outer) - : Base(expr.lhs()*expr.rhs().diagonal().coeff(outer), outer) - {} -}; - -template -class sparse_diagonal_product_inner_iterator_selector - - : public CwiseBinaryOp< - scalar_product_op, - const typename Lhs::ConstInnerVectorReturnType, - const Transpose >::InnerIterator -{ - typedef typename CwiseBinaryOp< - scalar_product_op, - const typename Lhs::ConstInnerVectorReturnType, - const Transpose >::InnerIterator Base; - typedef typename Lhs::Index Index; - Index m_outer; - public: - inline sparse_diagonal_product_inner_iterator_selector( - const SparseDiagonalProductType& expr, Index outer) - : Base(expr.lhs().innerVector(outer) .cwiseProduct(expr.rhs().diagonal().transpose()), 0), m_outer(outer) - {} - - inline Index outer() const { return m_outer; } - inline Index row() const { return m_outer; } -}; - -} // end namespace internal - -// SparseMatrixBase functions - -template -template -const SparseDiagonalProduct -SparseMatrixBase::operator*(const DiagonalBase &other) const -{ - return SparseDiagonalProduct(this->derived(), other.derived()); -} - -} // end namespace Eigen - -#endif // EIGEN_SPARSE_DIAGONAL_PRODUCT_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseDot.h b/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseDot.h deleted file mode 100644 index db39c9ae..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseDot.h +++ /dev/null @@ -1,101 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_SPARSE_DOT_H -#define EIGEN_SPARSE_DOT_H - -namespace Eigen { - -template -template -typename internal::traits::Scalar -SparseMatrixBase::dot(const MatrixBase& other) const -{ - EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) - EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived) - EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(Derived,OtherDerived) - EIGEN_STATIC_ASSERT((internal::is_same::value), - YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) - - eigen_assert(size() == other.size()); - eigen_assert(other.size()>0 && "you are using a non initialized vector"); - - typename Derived::InnerIterator i(derived(),0); - Scalar res(0); - while (i) - { - res += numext::conj(i.value()) * other.coeff(i.index()); - ++i; - } - return res; -} - -template -template -typename internal::traits::Scalar -SparseMatrixBase::dot(const SparseMatrixBase& other) const -{ - EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) - EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived) - EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(Derived,OtherDerived) - EIGEN_STATIC_ASSERT((internal::is_same::value), - YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) - - eigen_assert(size() == other.size()); - - typedef typename Derived::Nested Nested; - typedef typename OtherDerived::Nested OtherNested; - typedef typename internal::remove_all::type NestedCleaned; - typedef typename internal::remove_all::type OtherNestedCleaned; - - Nested nthis(derived()); - OtherNested nother(other.derived()); - - typename NestedCleaned::InnerIterator i(nthis,0); - typename OtherNestedCleaned::InnerIterator j(nother,0); - Scalar res(0); - while (i && j) - { - if (i.index()==j.index()) - { - res += numext::conj(i.value()) * j.value(); - ++i; ++j; - } - else if (i.index() -inline typename NumTraits::Scalar>::Real -SparseMatrixBase::squaredNorm() const -{ - return numext::real((*this).cwiseAbs2().sum()); -} - -template -inline typename NumTraits::Scalar>::Real -SparseMatrixBase::norm() const -{ - using std::sqrt; - return sqrt(squaredNorm()); -} - -template -inline typename NumTraits::Scalar>::Real -SparseMatrixBase::blueNorm() const -{ - return internal::blueNorm_impl(*this); -} -} // end namespace Eigen - -#endif // EIGEN_SPARSE_DOT_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseFuzzy.h b/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseFuzzy.h deleted file mode 100644 index 45f36e9e..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseFuzzy.h +++ /dev/null @@ -1,26 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_SPARSE_FUZZY_H -#define EIGEN_SPARSE_FUZZY_H - -// template -// template -// bool SparseMatrixBase::isApprox( -// const OtherDerived& other, -// typename NumTraits::Real prec -// ) const -// { -// const typename internal::nested::type nested(derived()); -// const typename internal::nested::type otherNested(other.derived()); -// return (nested - otherNested).cwise().abs2().sum() -// <= prec * prec * (std::min)(nested.cwise().abs2().sum(), otherNested.cwise().abs2().sum()); -// } - -#endif // EIGEN_SPARSE_FUZZY_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseMatrix.h b/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseMatrix.h deleted file mode 100644 index 2ff20155..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseMatrix.h +++ /dev/null @@ -1,1262 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2010 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_SPARSEMATRIX_H -#define EIGEN_SPARSEMATRIX_H - -namespace Eigen { - -/** \ingroup SparseCore_Module - * - * \class SparseMatrix - * - * \brief A versatible sparse matrix representation - * - * This class implements a more versatile variants of the common \em compressed row/column storage format. - * Each colmun's (resp. row) non zeros are stored as a pair of value with associated row (resp. colmiun) index. - * All the non zeros are stored in a single large buffer. Unlike the \em compressed format, there might be extra - * space inbetween the nonzeros of two successive colmuns (resp. rows) such that insertion of new non-zero - * can be done with limited memory reallocation and copies. - * - * A call to the function makeCompressed() turns the matrix into the standard \em compressed format - * compatible with many library. - * - * More details on this storage sceheme are given in the \ref TutorialSparse "manual pages". - * - * \tparam _Scalar the scalar type, i.e. the type of the coefficients - * \tparam _Options Union of bit flags controlling the storage scheme. Currently the only possibility - * is ColMajor or RowMajor. The default is 0 which means column-major. - * \tparam _Index the type of the indices. It has to be a \b signed type (e.g., short, int, std::ptrdiff_t). Default is \c int. - * - * This class can be extended with the help of the plugin mechanism described on the page - * \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_SPARSEMATRIX_PLUGIN. - */ - -namespace internal { -template -struct traits > -{ - typedef _Scalar Scalar; - typedef _Index Index; - typedef Sparse StorageKind; - typedef MatrixXpr XprKind; - enum { - RowsAtCompileTime = Dynamic, - ColsAtCompileTime = Dynamic, - MaxRowsAtCompileTime = Dynamic, - MaxColsAtCompileTime = Dynamic, - Flags = _Options | NestByRefBit | LvalueBit, - CoeffReadCost = NumTraits::ReadCost, - SupportedAccessPatterns = InnerRandomAccessPattern - }; -}; - -template -struct traits, DiagIndex> > -{ - typedef SparseMatrix<_Scalar, _Options, _Index> MatrixType; - typedef typename nested::type MatrixTypeNested; - typedef typename remove_reference::type _MatrixTypeNested; - - typedef _Scalar Scalar; - typedef Dense StorageKind; - typedef _Index Index; - typedef MatrixXpr XprKind; - - enum { - RowsAtCompileTime = Dynamic, - ColsAtCompileTime = 1, - MaxRowsAtCompileTime = Dynamic, - MaxColsAtCompileTime = 1, - Flags = 0, - CoeffReadCost = _MatrixTypeNested::CoeffReadCost*10 - }; -}; - -} // end namespace internal - -template -class SparseMatrix - : public SparseMatrixBase > -{ - public: - EIGEN_SPARSE_PUBLIC_INTERFACE(SparseMatrix) - EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(SparseMatrix, +=) - EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(SparseMatrix, -=) - - typedef MappedSparseMatrix Map; - using Base::IsRowMajor; - typedef internal::CompressedStorage Storage; - enum { - Options = _Options - }; - - protected: - - typedef SparseMatrix TransposedSparseMatrix; - - Index m_outerSize; - Index m_innerSize; - Index* m_outerIndex; - Index* m_innerNonZeros; // optional, if null then the data is compressed - Storage m_data; - - Eigen::Map > innerNonZeros() { return Eigen::Map >(m_innerNonZeros, m_innerNonZeros?m_outerSize:0); } - const Eigen::Map > innerNonZeros() const { return Eigen::Map >(m_innerNonZeros, m_innerNonZeros?m_outerSize:0); } - - public: - - /** \returns whether \c *this is in compressed form. */ - inline bool isCompressed() const { return m_innerNonZeros==0; } - - /** \returns the number of rows of the matrix */ - inline Index rows() const { return IsRowMajor ? m_outerSize : m_innerSize; } - /** \returns the number of columns of the matrix */ - inline Index cols() const { return IsRowMajor ? m_innerSize : m_outerSize; } - - /** \returns the number of rows (resp. columns) of the matrix if the storage order column major (resp. row major) */ - inline Index innerSize() const { return m_innerSize; } - /** \returns the number of columns (resp. rows) of the matrix if the storage order column major (resp. row major) */ - inline Index outerSize() const { return m_outerSize; } - - /** \returns a const pointer to the array of values. - * This function is aimed at interoperability with other libraries. - * \sa innerIndexPtr(), outerIndexPtr() */ - inline const Scalar* valuePtr() const { return &m_data.value(0); } - /** \returns a non-const pointer to the array of values. - * This function is aimed at interoperability with other libraries. - * \sa innerIndexPtr(), outerIndexPtr() */ - inline Scalar* valuePtr() { return &m_data.value(0); } - - /** \returns a const pointer to the array of inner indices. - * This function is aimed at interoperability with other libraries. - * \sa valuePtr(), outerIndexPtr() */ - inline const Index* innerIndexPtr() const { return &m_data.index(0); } - /** \returns a non-const pointer to the array of inner indices. - * This function is aimed at interoperability with other libraries. - * \sa valuePtr(), outerIndexPtr() */ - inline Index* innerIndexPtr() { return &m_data.index(0); } - - /** \returns a const pointer to the array of the starting positions of the inner vectors. - * This function is aimed at interoperability with other libraries. - * \sa valuePtr(), innerIndexPtr() */ - inline const Index* outerIndexPtr() const { return m_outerIndex; } - /** \returns a non-const pointer to the array of the starting positions of the inner vectors. - * This function is aimed at interoperability with other libraries. - * \sa valuePtr(), innerIndexPtr() */ - inline Index* outerIndexPtr() { return m_outerIndex; } - - /** \returns a const pointer to the array of the number of non zeros of the inner vectors. - * This function is aimed at interoperability with other libraries. - * \warning it returns the null pointer 0 in compressed mode */ - inline const Index* innerNonZeroPtr() const { return m_innerNonZeros; } - /** \returns a non-const pointer to the array of the number of non zeros of the inner vectors. - * This function is aimed at interoperability with other libraries. - * \warning it returns the null pointer 0 in compressed mode */ - inline Index* innerNonZeroPtr() { return m_innerNonZeros; } - - /** \internal */ - inline Storage& data() { return m_data; } - /** \internal */ - inline const Storage& data() const { return m_data; } - - /** \returns the value of the matrix at position \a i, \a j - * This function returns Scalar(0) if the element is an explicit \em zero */ - inline Scalar coeff(Index row, Index col) const - { - eigen_assert(row>=0 && row=0 && col=0 && row=0 && col=start && "you probably called coeffRef on a non finalized matrix"); - if(end<=start) - return insert(row,col); - const Index p = m_data.searchLowerIndex(start,end-1,inner); - if((p=0 && row=0 && col::Constant(outerSize(), 2)); - } - return insertUncompressed(row,col); - } - - public: - - class InnerIterator; - class ReverseInnerIterator; - - /** Removes all non zeros but keep allocated memory */ - inline void setZero() - { - m_data.clear(); - memset(m_outerIndex, 0, (m_outerSize+1)*sizeof(Index)); - if(m_innerNonZeros) - memset(m_innerNonZeros, 0, (m_outerSize)*sizeof(Index)); - } - - /** \returns the number of non zero coefficients */ - inline Index nonZeros() const - { - if(m_innerNonZeros) - return innerNonZeros().sum(); - return static_cast(m_data.size()); - } - - /** Preallocates \a reserveSize non zeros. - * - * Precondition: the matrix must be in compressed mode. */ - inline void reserve(Index reserveSize) - { - eigen_assert(isCompressed() && "This function does not make sense in non compressed mode."); - m_data.reserve(reserveSize); - } - - #ifdef EIGEN_PARSED_BY_DOXYGEN - /** Preallocates \a reserveSize[\c j] non zeros for each column (resp. row) \c j. - * - * This function turns the matrix in non-compressed mode */ - template - inline void reserve(const SizesType& reserveSizes); - #else - template - inline void reserve(const SizesType& reserveSizes, const typename SizesType::value_type& enableif = typename SizesType::value_type()) - { - EIGEN_UNUSED_VARIABLE(enableif); - reserveInnerVectors(reserveSizes); - } - template - inline void reserve(const SizesType& reserveSizes, const typename SizesType::Scalar& enableif = - #if (!defined(_MSC_VER)) || (_MSC_VER>=1500) // MSVC 2005 fails to compile with this typename - typename - #endif - SizesType::Scalar()) - { - EIGEN_UNUSED_VARIABLE(enableif); - reserveInnerVectors(reserveSizes); - } - #endif // EIGEN_PARSED_BY_DOXYGEN - protected: - template - inline void reserveInnerVectors(const SizesType& reserveSizes) - { - if(isCompressed()) - { - std::size_t totalReserveSize = 0; - // turn the matrix into non-compressed mode - m_innerNonZeros = static_cast(std::malloc(m_outerSize * sizeof(Index))); - if (!m_innerNonZeros) internal::throw_std_bad_alloc(); - - // temporarily use m_innerSizes to hold the new starting points. - Index* newOuterIndex = m_innerNonZeros; - - Index count = 0; - for(Index j=0; j=0; --j) - { - Index innerNNZ = previousOuterIndex - m_outerIndex[j]; - for(Index i=innerNNZ-1; i>=0; --i) - { - m_data.index(newOuterIndex[j]+i) = m_data.index(m_outerIndex[j]+i); - m_data.value(newOuterIndex[j]+i) = m_data.value(m_outerIndex[j]+i); - } - previousOuterIndex = m_outerIndex[j]; - m_outerIndex[j] = newOuterIndex[j]; - m_innerNonZeros[j] = innerNNZ; - } - m_outerIndex[m_outerSize] = m_outerIndex[m_outerSize-1] + m_innerNonZeros[m_outerSize-1] + reserveSizes[m_outerSize-1]; - - m_data.resize(m_outerIndex[m_outerSize]); - } - else - { - Index* newOuterIndex = static_cast(std::malloc((m_outerSize+1)*sizeof(Index))); - if (!newOuterIndex) internal::throw_std_bad_alloc(); - - Index count = 0; - for(Index j=0; j(reserveSizes[j], alreadyReserved); - count += toReserve + m_innerNonZeros[j]; - } - newOuterIndex[m_outerSize] = count; - - m_data.resize(count); - for(Index j=m_outerSize-1; j>=0; --j) - { - Index offset = newOuterIndex[j] - m_outerIndex[j]; - if(offset>0) - { - Index innerNNZ = m_innerNonZeros[j]; - for(Index i=innerNNZ-1; i>=0; --i) - { - m_data.index(newOuterIndex[j]+i) = m_data.index(m_outerIndex[j]+i); - m_data.value(newOuterIndex[j]+i) = m_data.value(m_outerIndex[j]+i); - } - } - } - - std::swap(m_outerIndex, newOuterIndex); - std::free(newOuterIndex); - } - - } - public: - - //--- low level purely coherent filling --- - - /** \internal - * \returns a reference to the non zero coefficient at position \a row, \a col assuming that: - * - the nonzero does not already exist - * - the new coefficient is the last one according to the storage order - * - * Before filling a given inner vector you must call the statVec(Index) function. - * - * After an insertion session, you should call the finalize() function. - * - * \sa insert, insertBackByOuterInner, startVec */ - inline Scalar& insertBack(Index row, Index col) - { - return insertBackByOuterInner(IsRowMajor?row:col, IsRowMajor?col:row); - } - - /** \internal - * \sa insertBack, startVec */ - inline Scalar& insertBackByOuterInner(Index outer, Index inner) - { - eigen_assert(size_t(m_outerIndex[outer+1]) == m_data.size() && "Invalid ordered insertion (invalid outer index)"); - eigen_assert( (m_outerIndex[outer+1]-m_outerIndex[outer]==0 || m_data.index(m_data.size()-1)(m_data.size()); - Index i = m_outerSize; - // find the last filled column - while (i>=0 && m_outerIndex[i]==0) - --i; - ++i; - while (i<=m_outerSize) - { - m_outerIndex[i] = size; - ++i; - } - } - } - - //--- - - template - void setFromTriplets(const InputIterators& begin, const InputIterators& end); - - void sumupDuplicates(); - - //--- - - /** \internal - * same as insert(Index,Index) except that the indices are given relative to the storage order */ - Scalar& insertByOuterInner(Index j, Index i) - { - return insert(IsRowMajor ? j : i, IsRowMajor ? i : j); - } - - /** Turns the matrix into the \em compressed format. - */ - void makeCompressed() - { - if(isCompressed()) - return; - - Index oldStart = m_outerIndex[1]; - m_outerIndex[1] = m_innerNonZeros[0]; - for(Index j=1; j0) - { - for(Index k=0; k(std::malloc(m_outerSize * sizeof(Index))); - for (Index i = 0; i < m_outerSize; i++) - { - m_innerNonZeros[i] = m_outerIndex[i+1] - m_outerIndex[i]; - } - } - - /** Suppresses all nonzeros which are \b much \b smaller \b than \a reference under the tolerence \a epsilon */ - void prune(const Scalar& reference, const RealScalar& epsilon = NumTraits::dummy_precision()) - { - prune(default_prunning_func(reference,epsilon)); - } - - /** Turns the matrix into compressed format, and suppresses all nonzeros which do not satisfy the predicate \a keep. - * The functor type \a KeepFunc must implement the following function: - * \code - * bool operator() (const Index& row, const Index& col, const Scalar& value) const; - * \endcode - * \sa prune(Scalar,RealScalar) - */ - template - void prune(const KeepFunc& keep = KeepFunc()) - { - // TODO optimize the uncompressed mode to avoid moving and allocating the data twice - // TODO also implement a unit test - makeCompressed(); - - Index k = 0; - for(Index j=0; jrows() == rows && this->cols() == cols) return; - - // If one dimension is null, then there is nothing to be preserved - if(rows==0 || cols==0) return resize(rows,cols); - - Index innerChange = IsRowMajor ? cols - this->cols() : rows - this->rows(); - Index outerChange = IsRowMajor ? rows - this->rows() : cols - this->cols(); - Index newInnerSize = IsRowMajor ? cols : rows; - - // Deals with inner non zeros - if (m_innerNonZeros) - { - // Resize m_innerNonZeros - Index *newInnerNonZeros = static_cast(std::realloc(m_innerNonZeros, (m_outerSize + outerChange) * sizeof(Index))); - if (!newInnerNonZeros) internal::throw_std_bad_alloc(); - m_innerNonZeros = newInnerNonZeros; - - for(Index i=m_outerSize; i(std::malloc((m_outerSize+outerChange+1) * sizeof(Index))); - if (!m_innerNonZeros) internal::throw_std_bad_alloc(); - for(Index i = 0; i < m_outerSize; i++) - m_innerNonZeros[i] = m_outerIndex[i+1] - m_outerIndex[i]; - } - - // Change the m_innerNonZeros in case of a decrease of inner size - if (m_innerNonZeros && innerChange < 0) - { - for(Index i = 0; i < m_outerSize + (std::min)(outerChange, Index(0)); i++) - { - Index &n = m_innerNonZeros[i]; - Index start = m_outerIndex[i]; - while (n > 0 && m_data.index(start+n-1) >= newInnerSize) --n; - } - } - - m_innerSize = newInnerSize; - - // Re-allocate outer index structure if necessary - if (outerChange == 0) - return; - - Index *newOuterIndex = static_cast(std::realloc(m_outerIndex, (m_outerSize + outerChange + 1) * sizeof(Index))); - if (!newOuterIndex) internal::throw_std_bad_alloc(); - m_outerIndex = newOuterIndex; - if (outerChange > 0) - { - Index last = m_outerSize == 0 ? 0 : m_outerIndex[m_outerSize]; - for(Index i=m_outerSize; i(std::malloc((outerSize + 1) * sizeof(Index))); - if (!m_outerIndex) internal::throw_std_bad_alloc(); - - m_outerSize = outerSize; - } - if(m_innerNonZeros) - { - std::free(m_innerNonZeros); - m_innerNonZeros = 0; - } - memset(m_outerIndex, 0, (m_outerSize+1)*sizeof(Index)); - } - - /** \internal - * Resize the nonzero vector to \a size */ - void resizeNonZeros(Index size) - { - // TODO remove this function - m_data.resize(size); - } - - /** \returns a const expression of the diagonal coefficients */ - const Diagonal diagonal() const { return *this; } - - /** Default constructor yielding an empty \c 0 \c x \c 0 matrix */ - inline SparseMatrix() - : m_outerSize(-1), m_innerSize(0), m_outerIndex(0), m_innerNonZeros(0) - { - check_template_parameters(); - resize(0, 0); - } - - /** Constructs a \a rows \c x \a cols empty matrix */ - inline SparseMatrix(Index rows, Index cols) - : m_outerSize(0), m_innerSize(0), m_outerIndex(0), m_innerNonZeros(0) - { - check_template_parameters(); - resize(rows, cols); - } - - /** Constructs a sparse matrix from the sparse expression \a other */ - template - inline SparseMatrix(const SparseMatrixBase& other) - : m_outerSize(0), m_innerSize(0), m_outerIndex(0), m_innerNonZeros(0) - { - EIGEN_STATIC_ASSERT((internal::is_same::value), - YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) - check_template_parameters(); - *this = other.derived(); - } - - /** Constructs a sparse matrix from the sparse selfadjoint view \a other */ - template - inline SparseMatrix(const SparseSelfAdjointView& other) - : m_outerSize(0), m_innerSize(0), m_outerIndex(0), m_innerNonZeros(0) - { - check_template_parameters(); - *this = other; - } - - /** Copy constructor (it performs a deep copy) */ - inline SparseMatrix(const SparseMatrix& other) - : Base(), m_outerSize(0), m_innerSize(0), m_outerIndex(0), m_innerNonZeros(0) - { - check_template_parameters(); - *this = other.derived(); - } - - /** \brief Copy constructor with in-place evaluation */ - template - SparseMatrix(const ReturnByValue& other) - : Base(), m_outerSize(0), m_innerSize(0), m_outerIndex(0), m_innerNonZeros(0) - { - check_template_parameters(); - initAssignment(other); - other.evalTo(*this); - } - - /** Swaps the content of two sparse matrices of the same type. - * This is a fast operation that simply swaps the underlying pointers and parameters. */ - inline void swap(SparseMatrix& other) - { - //EIGEN_DBG_SPARSE(std::cout << "SparseMatrix:: swap\n"); - std::swap(m_outerIndex, other.m_outerIndex); - std::swap(m_innerSize, other.m_innerSize); - std::swap(m_outerSize, other.m_outerSize); - std::swap(m_innerNonZeros, other.m_innerNonZeros); - m_data.swap(other.m_data); - } - - /** Sets *this to the identity matrix. - * This function also turns the matrix into compressed mode, and drop any reserved memory. */ - inline void setIdentity() - { - eigen_assert(rows() == cols() && "ONLY FOR SQUARED MATRICES"); - this->m_data.resize(rows()); - Eigen::Map >(&this->m_data.index(0), rows()).setLinSpaced(0, rows()-1); - Eigen::Map >(&this->m_data.value(0), rows()).setOnes(); - Eigen::Map >(this->m_outerIndex, rows()+1).setLinSpaced(0, rows()); - std::free(m_innerNonZeros); - m_innerNonZeros = 0; - } - inline SparseMatrix& operator=(const SparseMatrix& other) - { - if (other.isRValue()) - { - swap(other.const_cast_derived()); - } - else if(this!=&other) - { - initAssignment(other); - if(other.isCompressed()) - { - memcpy(m_outerIndex, other.m_outerIndex, (m_outerSize+1)*sizeof(Index)); - m_data = other.m_data; - } - else - { - Base::operator=(other); - } - } - return *this; - } - - #ifndef EIGEN_PARSED_BY_DOXYGEN - template - inline SparseMatrix& operator=(const SparseSparseProduct& product) - { return Base::operator=(product); } - - template - inline SparseMatrix& operator=(const ReturnByValue& other) - { - initAssignment(other); - return Base::operator=(other.derived()); - } - - template - inline SparseMatrix& operator=(const EigenBase& other) - { return Base::operator=(other.derived()); } - #endif - - template - EIGEN_DONT_INLINE SparseMatrix& operator=(const SparseMatrixBase& other); - - friend std::ostream & operator << (std::ostream & s, const SparseMatrix& m) - { - EIGEN_DBG_SPARSE( - s << "Nonzero entries:\n"; - if(m.isCompressed()) - for (Index i=0; i&>(m); - return s; - } - - /** Destructor */ - inline ~SparseMatrix() - { - std::free(m_outerIndex); - std::free(m_innerNonZeros); - } - -#ifndef EIGEN_PARSED_BY_DOXYGEN - /** Overloaded for performance */ - Scalar sum() const; -#endif - -# ifdef EIGEN_SPARSEMATRIX_PLUGIN -# include EIGEN_SPARSEMATRIX_PLUGIN -# endif - -protected: - - template - void initAssignment(const Other& other) - { - resize(other.rows(), other.cols()); - if(m_innerNonZeros) - { - std::free(m_innerNonZeros); - m_innerNonZeros = 0; - } - } - - /** \internal - * \sa insert(Index,Index) */ - EIGEN_DONT_INLINE Scalar& insertCompressed(Index row, Index col); - - /** \internal - * A vector object that is equal to 0 everywhere but v at the position i */ - class SingletonVector - { - Index m_index; - Index m_value; - public: - typedef Index value_type; - SingletonVector(Index i, Index v) - : m_index(i), m_value(v) - {} - - Index operator[](Index i) const { return i==m_index ? m_value : 0; } - }; - - /** \internal - * \sa insert(Index,Index) */ - EIGEN_DONT_INLINE Scalar& insertUncompressed(Index row, Index col); - -public: - /** \internal - * \sa insert(Index,Index) */ - EIGEN_STRONG_INLINE Scalar& insertBackUncompressed(Index row, Index col) - { - const Index outer = IsRowMajor ? row : col; - const Index inner = IsRowMajor ? col : row; - - eigen_assert(!isCompressed()); - eigen_assert(m_innerNonZeros[outer]<=(m_outerIndex[outer+1] - m_outerIndex[outer])); - - Index p = m_outerIndex[outer] + m_innerNonZeros[outer]++; - m_data.index(p) = inner; - return (m_data.value(p) = 0); - } - -private: - static void check_template_parameters() - { - EIGEN_STATIC_ASSERT(NumTraits::IsSigned,THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE); - EIGEN_STATIC_ASSERT((Options&(ColMajor|RowMajor))==Options,INVALID_MATRIX_TEMPLATE_PARAMETERS); - } - - struct default_prunning_func { - default_prunning_func(const Scalar& ref, const RealScalar& eps) : reference(ref), epsilon(eps) {} - inline bool operator() (const Index&, const Index&, const Scalar& value) const - { - return !internal::isMuchSmallerThan(value, reference, epsilon); - } - Scalar reference; - RealScalar epsilon; - }; -}; - -template -class SparseMatrix::InnerIterator -{ - public: - InnerIterator(const SparseMatrix& mat, Index outer) - : m_values(mat.valuePtr()), m_indices(mat.innerIndexPtr()), m_outer(outer), m_id(mat.m_outerIndex[outer]) - { - if(mat.isCompressed()) - m_end = mat.m_outerIndex[outer+1]; - else - m_end = m_id + mat.m_innerNonZeros[outer]; - } - - inline InnerIterator& operator++() { m_id++; return *this; } - - inline const Scalar& value() const { return m_values[m_id]; } - inline Scalar& valueRef() { return const_cast(m_values[m_id]); } - - inline Index index() const { return m_indices[m_id]; } - inline Index outer() const { return m_outer; } - inline Index row() const { return IsRowMajor ? m_outer : index(); } - inline Index col() const { return IsRowMajor ? index() : m_outer; } - - inline operator bool() const { return (m_id < m_end); } - - protected: - const Scalar* m_values; - const Index* m_indices; - const Index m_outer; - Index m_id; - Index m_end; -}; - -template -class SparseMatrix::ReverseInnerIterator -{ - public: - ReverseInnerIterator(const SparseMatrix& mat, Index outer) - : m_values(mat.valuePtr()), m_indices(mat.innerIndexPtr()), m_outer(outer), m_start(mat.m_outerIndex[outer]) - { - if(mat.isCompressed()) - m_id = mat.m_outerIndex[outer+1]; - else - m_id = m_start + mat.m_innerNonZeros[outer]; - } - - inline ReverseInnerIterator& operator--() { --m_id; return *this; } - - inline const Scalar& value() const { return m_values[m_id-1]; } - inline Scalar& valueRef() { return const_cast(m_values[m_id-1]); } - - inline Index index() const { return m_indices[m_id-1]; } - inline Index outer() const { return m_outer; } - inline Index row() const { return IsRowMajor ? m_outer : index(); } - inline Index col() const { return IsRowMajor ? index() : m_outer; } - - inline operator bool() const { return (m_id > m_start); } - - protected: - const Scalar* m_values; - const Index* m_indices; - const Index m_outer; - Index m_id; - const Index m_start; -}; - -namespace internal { - -template -void set_from_triplets(const InputIterator& begin, const InputIterator& end, SparseMatrixType& mat, int Options = 0) -{ - EIGEN_UNUSED_VARIABLE(Options); - enum { IsRowMajor = SparseMatrixType::IsRowMajor }; - typedef typename SparseMatrixType::Scalar Scalar; - typedef typename SparseMatrixType::Index Index; - SparseMatrix trMat(mat.rows(),mat.cols()); - - if(begin!=end) - { - // pass 1: count the nnz per inner-vector - Matrix wi(trMat.outerSize()); - wi.setZero(); - for(InputIterator it(begin); it!=end; ++it) - { - eigen_assert(it->row()>=0 && it->row()col()>=0 && it->col()col() : it->row())++; - } - - // pass 2: insert all the elements into trMat - trMat.reserve(wi); - for(InputIterator it(begin); it!=end; ++it) - trMat.insertBackUncompressed(it->row(),it->col()) = it->value(); - - // pass 3: - trMat.sumupDuplicates(); - } - - // pass 4: transposed copy -> implicit sorting - mat = trMat; -} - -} - - -/** Fill the matrix \c *this with the list of \em triplets defined by the iterator range \a begin - \a end. - * - * A \em triplet is a tuple (i,j,value) defining a non-zero element. - * The input list of triplets does not have to be sorted, and can contains duplicated elements. - * In any case, the result is a \b sorted and \b compressed sparse matrix where the duplicates have been summed up. - * This is a \em O(n) operation, with \em n the number of triplet elements. - * The initial contents of \c *this is destroyed. - * The matrix \c *this must be properly resized beforehand using the SparseMatrix(Index,Index) constructor, - * or the resize(Index,Index) method. The sizes are not extracted from the triplet list. - * - * The \a InputIterators value_type must provide the following interface: - * \code - * Scalar value() const; // the value - * Scalar row() const; // the row index i - * Scalar col() const; // the column index j - * \endcode - * See for instance the Eigen::Triplet template class. - * - * Here is a typical usage example: - * \code - typedef Triplet T; - std::vector tripletList; - triplets.reserve(estimation_of_entries); - for(...) - { - // ... - tripletList.push_back(T(i,j,v_ij)); - } - SparseMatrixType m(rows,cols); - m.setFromTriplets(tripletList.begin(), tripletList.end()); - // m is ready to go! - * \endcode - * - * \warning The list of triplets is read multiple times (at least twice). Therefore, it is not recommended to define - * an abstract iterator over a complex data-structure that would be expensive to evaluate. The triplets should rather - * be explicitely stored into a std::vector for instance. - */ -template -template -void SparseMatrix::setFromTriplets(const InputIterators& begin, const InputIterators& end) -{ - internal::set_from_triplets(begin, end, *this); -} - -/** \internal */ -template -void SparseMatrix::sumupDuplicates() -{ - eigen_assert(!isCompressed()); - // TODO, in practice we should be able to use m_innerNonZeros for that task - Matrix wi(innerSize()); - wi.fill(-1); - Index count = 0; - // for each inner-vector, wi[inner_index] will hold the position of first element into the index/value buffers - for(Index j=0; j=start) - { - // we already meet this entry => accumulate it - m_data.value(wi(i)) += m_data.value(k); - } - else - { - m_data.value(count) = m_data.value(k); - m_data.index(count) = m_data.index(k); - wi(i) = count; - ++count; - } - } - m_outerIndex[j] = start; - } - m_outerIndex[m_outerSize] = count; - - // turn the matrix into compressed form - std::free(m_innerNonZeros); - m_innerNonZeros = 0; - m_data.resize(m_outerIndex[m_outerSize]); -} - -template -template -EIGEN_DONT_INLINE SparseMatrix& SparseMatrix::operator=(const SparseMatrixBase& other) -{ - EIGEN_STATIC_ASSERT((internal::is_same::value), - YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) - - const bool needToTranspose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit); - if (needToTranspose) - { - // two passes algorithm: - // 1 - compute the number of coeffs per dest inner vector - // 2 - do the actual copy/eval - // Since each coeff of the rhs has to be evaluated twice, let's evaluate it if needed - typedef typename internal::nested::type OtherCopy; - typedef typename internal::remove_all::type _OtherCopy; - OtherCopy otherCopy(other.derived()); - - SparseMatrix dest(other.rows(),other.cols()); - Eigen::Map > (dest.m_outerIndex,dest.outerSize()).setZero(); - - // pass 1 - // FIXME the above copy could be merged with that pass - for (Index j=0; j positions(dest.outerSize()); - for (Index j=0; jswap(dest); - return *this; - } - else - { - if(other.isRValue()) - initAssignment(other.derived()); - // there is no special optimization - return Base::operator=(other.derived()); - } -} - -template -EIGEN_DONT_INLINE typename SparseMatrix<_Scalar,_Options,_Index>::Scalar& SparseMatrix<_Scalar,_Options,_Index>::insertUncompressed(Index row, Index col) -{ - eigen_assert(!isCompressed()); - - const Index outer = IsRowMajor ? row : col; - const Index inner = IsRowMajor ? col : row; - - Index room = m_outerIndex[outer+1] - m_outerIndex[outer]; - Index innerNNZ = m_innerNonZeros[outer]; - if(innerNNZ>=room) - { - // this inner vector is full, we need to reallocate the whole buffer :( - reserve(SingletonVector(outer,std::max(2,innerNNZ))); - } - - Index startId = m_outerIndex[outer]; - Index p = startId + m_innerNonZeros[outer]; - while ( (p > startId) && (m_data.index(p-1) > inner) ) - { - m_data.index(p) = m_data.index(p-1); - m_data.value(p) = m_data.value(p-1); - --p; - } - eigen_assert((p<=startId || m_data.index(p-1)!=inner) && "you cannot insert an element that already exist, you must call coeffRef to this end"); - - m_innerNonZeros[outer]++; - - m_data.index(p) = inner; - return (m_data.value(p) = 0); -} - -template -EIGEN_DONT_INLINE typename SparseMatrix<_Scalar,_Options,_Index>::Scalar& SparseMatrix<_Scalar,_Options,_Index>::insertCompressed(Index row, Index col) -{ - eigen_assert(isCompressed()); - - const Index outer = IsRowMajor ? row : col; - const Index inner = IsRowMajor ? col : row; - - Index previousOuter = outer; - if (m_outerIndex[outer+1]==0) - { - // we start a new inner vector - while (previousOuter>=0 && m_outerIndex[previousOuter]==0) - { - m_outerIndex[previousOuter] = static_cast(m_data.size()); - --previousOuter; - } - m_outerIndex[outer+1] = m_outerIndex[outer]; - } - - // here we have to handle the tricky case where the outerIndex array - // starts with: [ 0 0 0 0 0 1 ...] and we are inserted in, e.g., - // the 2nd inner vector... - bool isLastVec = (!(previousOuter==-1 && m_data.size()!=0)) - && (size_t(m_outerIndex[outer+1]) == m_data.size()); - - size_t startId = m_outerIndex[outer]; - // FIXME let's make sure sizeof(long int) == sizeof(size_t) - size_t p = m_outerIndex[outer+1]; - ++m_outerIndex[outer+1]; - - double reallocRatio = 1; - if (m_data.allocatedSize()<=m_data.size()) - { - // if there is no preallocated memory, let's reserve a minimum of 32 elements - if (m_data.size()==0) - { - m_data.reserve(32); - } - else - { - // we need to reallocate the data, to reduce multiple reallocations - // we use a smart resize algorithm based on the current filling ratio - // in addition, we use double to avoid integers overflows - double nnzEstimate = double(m_outerIndex[outer])*double(m_outerSize)/double(outer+1); - reallocRatio = (nnzEstimate-double(m_data.size()))/double(m_data.size()); - // furthermore we bound the realloc ratio to: - // 1) reduce multiple minor realloc when the matrix is almost filled - // 2) avoid to allocate too much memory when the matrix is almost empty - reallocRatio = (std::min)((std::max)(reallocRatio,1.5),8.); - } - } - m_data.resize(m_data.size()+1,reallocRatio); - - if (!isLastVec) - { - if (previousOuter==-1) - { - // oops wrong guess. - // let's correct the outer offsets - for (Index k=0; k<=(outer+1); ++k) - m_outerIndex[k] = 0; - Index k=outer+1; - while(m_outerIndex[k]==0) - m_outerIndex[k++] = 1; - while (k<=m_outerSize && m_outerIndex[k]!=0) - m_outerIndex[k++]++; - p = 0; - --k; - k = m_outerIndex[k]-1; - while (k>0) - { - m_data.index(k) = m_data.index(k-1); - m_data.value(k) = m_data.value(k-1); - k--; - } - } - else - { - // we are not inserting into the last inner vec - // update outer indices: - Index j = outer+2; - while (j<=m_outerSize && m_outerIndex[j]!=0) - m_outerIndex[j++]++; - --j; - // shift data of last vecs: - Index k = m_outerIndex[j]-1; - while (k>=Index(p)) - { - m_data.index(k) = m_data.index(k-1); - m_data.value(k) = m_data.value(k-1); - k--; - } - } - } - - while ( (p > startId) && (m_data.index(p-1) > inner) ) - { - m_data.index(p) = m_data.index(p-1); - m_data.value(p) = m_data.value(p-1); - --p; - } - - m_data.index(p) = inner; - return (m_data.value(p) = 0); -} - -} // end namespace Eigen - -#endif // EIGEN_SPARSEMATRIX_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseMatrixBase.h b/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseMatrixBase.h deleted file mode 100644 index 9341d9ad..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseMatrixBase.h +++ /dev/null @@ -1,461 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2011 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_SPARSEMATRIXBASE_H -#define EIGEN_SPARSEMATRIXBASE_H - -namespace Eigen { - -/** \ingroup SparseCore_Module - * - * \class SparseMatrixBase - * - * \brief Base class of any sparse matrices or sparse expressions - * - * \tparam Derived - * - * This class can be extended with the help of the plugin mechanism described on the page - * \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_SPARSEMATRIXBASE_PLUGIN. - */ -template class SparseMatrixBase -#ifndef EIGEN_PARSED_BY_DOXYGEN - : public internal::special_scalar_op_base::Scalar, - typename NumTraits::Scalar>::Real, - EigenBase > -#else - : public EigenBase -#endif // not EIGEN_PARSED_BY_DOXYGEN -{ - public: - - typedef typename internal::traits::Scalar Scalar; - typedef typename internal::packet_traits::type PacketScalar; - typedef typename internal::traits::StorageKind StorageKind; - typedef typename internal::traits::Index Index; - typedef typename internal::add_const_on_value_type_if_arithmetic< - typename internal::packet_traits::type - >::type PacketReturnType; - - typedef SparseMatrixBase StorageBaseType; - - template - Derived& operator=(const EigenBase &other) - { - other.derived().evalTo(derived()); - return derived(); - } - - enum { - - RowsAtCompileTime = internal::traits::RowsAtCompileTime, - /**< The number of rows at compile-time. This is just a copy of the value provided - * by the \a Derived type. If a value is not known at compile-time, - * it is set to the \a Dynamic constant. - * \sa MatrixBase::rows(), MatrixBase::cols(), ColsAtCompileTime, SizeAtCompileTime */ - - ColsAtCompileTime = internal::traits::ColsAtCompileTime, - /**< The number of columns at compile-time. This is just a copy of the value provided - * by the \a Derived type. If a value is not known at compile-time, - * it is set to the \a Dynamic constant. - * \sa MatrixBase::rows(), MatrixBase::cols(), RowsAtCompileTime, SizeAtCompileTime */ - - - SizeAtCompileTime = (internal::size_at_compile_time::RowsAtCompileTime, - internal::traits::ColsAtCompileTime>::ret), - /**< This is equal to the number of coefficients, i.e. the number of - * rows times the number of columns, or to \a Dynamic if this is not - * known at compile-time. \sa RowsAtCompileTime, ColsAtCompileTime */ - - MaxRowsAtCompileTime = RowsAtCompileTime, - MaxColsAtCompileTime = ColsAtCompileTime, - - MaxSizeAtCompileTime = (internal::size_at_compile_time::ret), - - IsVectorAtCompileTime = RowsAtCompileTime == 1 || ColsAtCompileTime == 1, - /**< This is set to true if either the number of rows or the number of - * columns is known at compile-time to be equal to 1. Indeed, in that case, - * we are dealing with a column-vector (if there is only one column) or with - * a row-vector (if there is only one row). */ - - Flags = internal::traits::Flags, - /**< This stores expression \ref flags flags which may or may not be inherited by new expressions - * constructed from this one. See the \ref flags "list of flags". - */ - - CoeffReadCost = internal::traits::CoeffReadCost, - /**< This is a rough measure of how expensive it is to read one coefficient from - * this expression. - */ - - IsRowMajor = Flags&RowMajorBit ? 1 : 0, - - InnerSizeAtCompileTime = int(IsVectorAtCompileTime) ? int(SizeAtCompileTime) - : int(IsRowMajor) ? int(ColsAtCompileTime) : int(RowsAtCompileTime), - - #ifndef EIGEN_PARSED_BY_DOXYGEN - _HasDirectAccess = (int(Flags)&DirectAccessBit) ? 1 : 0 // workaround sunCC - #endif - }; - - /** \internal the return type of MatrixBase::adjoint() */ - typedef typename internal::conditional::IsComplex, - CwiseUnaryOp, Eigen::Transpose >, - Transpose - >::type AdjointReturnType; - - - typedef SparseMatrix PlainObject; - - -#ifndef EIGEN_PARSED_BY_DOXYGEN - /** This is the "real scalar" type; if the \a Scalar type is already real numbers - * (e.g. int, float or double) then \a RealScalar is just the same as \a Scalar. If - * \a Scalar is \a std::complex then RealScalar is \a T. - * - * \sa class NumTraits - */ - typedef typename NumTraits::Real RealScalar; - - /** \internal the return type of coeff() - */ - typedef typename internal::conditional<_HasDirectAccess, const Scalar&, Scalar>::type CoeffReturnType; - - /** \internal Represents a matrix with all coefficients equal to one another*/ - typedef CwiseNullaryOp,Matrix > ConstantReturnType; - - /** type of the equivalent square matrix */ - typedef Matrix SquareMatrixType; - - inline const Derived& derived() const { return *static_cast(this); } - inline Derived& derived() { return *static_cast(this); } - inline Derived& const_cast_derived() const - { return *static_cast(const_cast(this)); } - - typedef internal::special_scalar_op_base > Base; - using Base::operator*; -#endif // not EIGEN_PARSED_BY_DOXYGEN - -#define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::SparseMatrixBase -# include "../plugins/CommonCwiseUnaryOps.h" -# include "../plugins/CommonCwiseBinaryOps.h" -# include "../plugins/MatrixCwiseUnaryOps.h" -# include "../plugins/MatrixCwiseBinaryOps.h" -# include "../plugins/BlockMethods.h" -# ifdef EIGEN_SPARSEMATRIXBASE_PLUGIN -# include EIGEN_SPARSEMATRIXBASE_PLUGIN -# endif -# undef EIGEN_CURRENT_STORAGE_BASE_CLASS -#undef EIGEN_CURRENT_STORAGE_BASE_CLASS - - /** \returns the number of rows. \sa cols() */ - inline Index rows() const { return derived().rows(); } - /** \returns the number of columns. \sa rows() */ - inline Index cols() const { return derived().cols(); } - /** \returns the number of coefficients, which is \a rows()*cols(). - * \sa rows(), cols(). */ - inline Index size() const { return rows() * cols(); } - /** \returns the number of nonzero coefficients which is in practice the number - * of stored coefficients. */ - inline Index nonZeros() const { return derived().nonZeros(); } - /** \returns true if either the number of rows or the number of columns is equal to 1. - * In other words, this function returns - * \code rows()==1 || cols()==1 \endcode - * \sa rows(), cols(), IsVectorAtCompileTime. */ - inline bool isVector() const { return rows()==1 || cols()==1; } - /** \returns the size of the storage major dimension, - * i.e., the number of columns for a columns major matrix, and the number of rows otherwise */ - Index outerSize() const { return (int(Flags)&RowMajorBit) ? this->rows() : this->cols(); } - /** \returns the size of the inner dimension according to the storage order, - * i.e., the number of rows for a columns major matrix, and the number of cols otherwise */ - Index innerSize() const { return (int(Flags)&RowMajorBit) ? this->cols() : this->rows(); } - - bool isRValue() const { return m_isRValue; } - Derived& markAsRValue() { m_isRValue = true; return derived(); } - - SparseMatrixBase() : m_isRValue(false) { /* TODO check flags */ } - - - template - Derived& operator=(const ReturnByValue& other) - { - other.evalTo(derived()); - return derived(); - } - - - template - inline Derived& operator=(const SparseMatrixBase& other) - { - return assign(other.derived()); - } - - inline Derived& operator=(const Derived& other) - { -// if (other.isRValue()) -// derived().swap(other.const_cast_derived()); -// else - return assign(other.derived()); - } - - protected: - - template - inline Derived& assign(const OtherDerived& other) - { - const bool transpose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit); - const Index outerSize = (int(OtherDerived::Flags) & RowMajorBit) ? other.rows() : other.cols(); - if ((!transpose) && other.isRValue()) - { - // eval without temporary - derived().resize(other.rows(), other.cols()); - derived().setZero(); - derived().reserve((std::max)(this->rows(),this->cols())*2); - for (Index j=0; j - inline void assignGeneric(const OtherDerived& other) - { - //const bool transpose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit); - eigen_assert(( ((internal::traits::SupportedAccessPatterns&OuterRandomAccessPattern)==OuterRandomAccessPattern) || - (!((Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit)))) && - "the transpose operation is supposed to be handled in SparseMatrix::operator="); - - enum { Flip = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit) }; - - const Index outerSize = other.outerSize(); - //typedef typename internal::conditional, Derived>::type TempType; - // thanks to shallow copies, we always eval to a tempary - Derived temp(other.rows(), other.cols()); - - temp.reserve((std::max)(this->rows(),this->cols())*2); - for (Index j=0; j - inline Derived& operator=(const SparseSparseProduct& product); - - friend std::ostream & operator << (std::ostream & s, const SparseMatrixBase& m) - { - typedef typename Derived::Nested Nested; - typedef typename internal::remove_all::type NestedCleaned; - - if (Flags&RowMajorBit) - { - const Nested nm(m.derived()); - for (Index row=0; row trans = m; - s << static_cast >&>(trans); - } - } - return s; - } - - template - Derived& operator+=(const SparseMatrixBase& other); - template - Derived& operator-=(const SparseMatrixBase& other); - - Derived& operator*=(const Scalar& other); - Derived& operator/=(const Scalar& other); - - template struct CwiseProductDenseReturnType { - typedef CwiseBinaryOp::Scalar, - typename internal::traits::Scalar - >::ReturnType>, - const Derived, - const OtherDerived - > Type; - }; - - template - EIGEN_STRONG_INLINE const typename CwiseProductDenseReturnType::Type - cwiseProduct(const MatrixBase &other) const; - - // sparse * sparse - template - const typename SparseSparseProductReturnType::Type - operator*(const SparseMatrixBase &other) const; - - // sparse * diagonal - template - const SparseDiagonalProduct - operator*(const DiagonalBase &other) const; - - // diagonal * sparse - template friend - const SparseDiagonalProduct - operator*(const DiagonalBase &lhs, const SparseMatrixBase& rhs) - { return SparseDiagonalProduct(lhs.derived(), rhs.derived()); } - - /** dense * sparse (return a dense object unless it is an outer product) */ - template friend - const typename DenseSparseProductReturnType::Type - operator*(const MatrixBase& lhs, const Derived& rhs) - { return typename DenseSparseProductReturnType::Type(lhs.derived(),rhs); } - - /** sparse * dense (returns a dense object unless it is an outer product) */ - template - const typename SparseDenseProductReturnType::Type - operator*(const MatrixBase &other) const - { return typename SparseDenseProductReturnType::Type(derived(), other.derived()); } - - /** \returns an expression of P H P^-1 where H is the matrix represented by \c *this */ - SparseSymmetricPermutationProduct twistedBy(const PermutationMatrix& perm) const - { - return SparseSymmetricPermutationProduct(derived(), perm); - } - - template - Derived& operator*=(const SparseMatrixBase& other); - - #ifdef EIGEN2_SUPPORT - // deprecated - template - typename internal::plain_matrix_type_column_major::type - solveTriangular(const MatrixBase& other) const; - - // deprecated - template - void solveTriangularInPlace(MatrixBase& other) const; - #endif // EIGEN2_SUPPORT - - template - inline const SparseTriangularView triangularView() const; - - template inline const SparseSelfAdjointView selfadjointView() const; - template inline SparseSelfAdjointView selfadjointView(); - - template Scalar dot(const MatrixBase& other) const; - template Scalar dot(const SparseMatrixBase& other) const; - RealScalar squaredNorm() const; - RealScalar norm() const; - RealScalar blueNorm() const; - - Transpose transpose() { return derived(); } - const Transpose transpose() const { return derived(); } - const AdjointReturnType adjoint() const { return transpose(); } - - // inner-vector - typedef Block InnerVectorReturnType; - typedef Block ConstInnerVectorReturnType; - InnerVectorReturnType innerVector(Index outer); - const ConstInnerVectorReturnType innerVector(Index outer) const; - - // set of inner-vectors - typedef Block InnerVectorsReturnType; - typedef Block ConstInnerVectorsReturnType; - InnerVectorsReturnType innerVectors(Index outerStart, Index outerSize); - const ConstInnerVectorsReturnType innerVectors(Index outerStart, Index outerSize) const; - - /** \internal use operator= */ - template - void evalTo(MatrixBase& dst) const - { - dst.setZero(); - for (Index j=0; j toDense() const - { - return derived(); - } - - template - bool isApprox(const SparseMatrixBase& other, - const RealScalar& prec = NumTraits::dummy_precision()) const - { return toDense().isApprox(other.toDense(),prec); } - - template - bool isApprox(const MatrixBase& other, - const RealScalar& prec = NumTraits::dummy_precision()) const - { return toDense().isApprox(other,prec); } - - /** \returns the matrix or vector obtained by evaluating this expression. - * - * Notice that in the case of a plain matrix or vector (not an expression) this function just returns - * a const reference, in order to avoid a useless copy. - */ - inline const typename internal::eval::type eval() const - { return typename internal::eval::type(derived()); } - - Scalar sum() const; - - protected: - - bool m_isRValue; -}; - -} // end namespace Eigen - -#endif // EIGEN_SPARSEMATRIXBASE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparsePermutation.h b/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparsePermutation.h deleted file mode 100644 index 75e21000..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparsePermutation.h +++ /dev/null @@ -1,148 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2012 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_SPARSE_PERMUTATION_H -#define EIGEN_SPARSE_PERMUTATION_H - -// This file implements sparse * permutation products - -namespace Eigen { - -namespace internal { - -template -struct traits > -{ - typedef typename remove_all::type MatrixTypeNestedCleaned; - typedef typename MatrixTypeNestedCleaned::Scalar Scalar; - typedef typename MatrixTypeNestedCleaned::Index Index; - enum { - SrcStorageOrder = MatrixTypeNestedCleaned::Flags&RowMajorBit ? RowMajor : ColMajor, - MoveOuter = SrcStorageOrder==RowMajor ? Side==OnTheLeft : Side==OnTheRight - }; - - typedef typename internal::conditional, - SparseMatrix >::type ReturnType; -}; - -template -struct permut_sparsematrix_product_retval - : public ReturnByValue > -{ - typedef typename remove_all::type MatrixTypeNestedCleaned; - typedef typename MatrixTypeNestedCleaned::Scalar Scalar; - typedef typename MatrixTypeNestedCleaned::Index Index; - - enum { - SrcStorageOrder = MatrixTypeNestedCleaned::Flags&RowMajorBit ? RowMajor : ColMajor, - MoveOuter = SrcStorageOrder==RowMajor ? Side==OnTheLeft : Side==OnTheRight - }; - - permut_sparsematrix_product_retval(const PermutationType& perm, const MatrixType& matrix) - : m_permutation(perm), m_matrix(matrix) - {} - - inline int rows() const { return m_matrix.rows(); } - inline int cols() const { return m_matrix.cols(); } - - template inline void evalTo(Dest& dst) const - { - if(MoveOuter) - { - SparseMatrix tmp(m_matrix.rows(), m_matrix.cols()); - Matrix sizes(m_matrix.outerSize()); - for(Index j=0; j tmp(m_matrix.rows(), m_matrix.cols()); - Matrix sizes(tmp.outerSize()); - sizes.setZero(); - PermutationMatrix perm; - if((Side==OnTheLeft) ^ Transposed) - perm = m_permutation; - else - perm = m_permutation.transpose(); - - for(Index j=0; j -inline const internal::permut_sparsematrix_product_retval, SparseDerived, OnTheRight, false> -operator*(const SparseMatrixBase& matrix, const PermutationBase& perm) -{ - return internal::permut_sparsematrix_product_retval, SparseDerived, OnTheRight, false>(perm, matrix.derived()); -} - -/** \returns the matrix with the permutation applied to the rows - */ -template -inline const internal::permut_sparsematrix_product_retval, SparseDerived, OnTheLeft, false> -operator*( const PermutationBase& perm, const SparseMatrixBase& matrix) -{ - return internal::permut_sparsematrix_product_retval, SparseDerived, OnTheLeft, false>(perm, matrix.derived()); -} - - - -/** \returns the matrix with the inverse permutation applied to the columns. - */ -template -inline const internal::permut_sparsematrix_product_retval, SparseDerived, OnTheRight, true> -operator*(const SparseMatrixBase& matrix, const Transpose >& tperm) -{ - return internal::permut_sparsematrix_product_retval, SparseDerived, OnTheRight, true>(tperm.nestedPermutation(), matrix.derived()); -} - -/** \returns the matrix with the inverse permutation applied to the rows. - */ -template -inline const internal::permut_sparsematrix_product_retval, SparseDerived, OnTheLeft, true> -operator*(const Transpose >& tperm, const SparseMatrixBase& matrix) -{ - return internal::permut_sparsematrix_product_retval, SparseDerived, OnTheLeft, true>(tperm.nestedPermutation(), matrix.derived()); -} - -} // end namespace Eigen - -#endif // EIGEN_SPARSE_SELFADJOINTVIEW_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseProduct.h b/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseProduct.h deleted file mode 100644 index cf766307..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseProduct.h +++ /dev/null @@ -1,188 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2010 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_SPARSEPRODUCT_H -#define EIGEN_SPARSEPRODUCT_H - -namespace Eigen { - -template -struct SparseSparseProductReturnType -{ - typedef typename internal::traits::Scalar Scalar; - typedef typename internal::traits::Index Index; - enum { - LhsRowMajor = internal::traits::Flags & RowMajorBit, - RhsRowMajor = internal::traits::Flags & RowMajorBit, - TransposeRhs = (!LhsRowMajor) && RhsRowMajor, - TransposeLhs = LhsRowMajor && (!RhsRowMajor) - }; - - typedef typename internal::conditional, - typename internal::nested::type>::type LhsNested; - - typedef typename internal::conditional, - typename internal::nested::type>::type RhsNested; - - typedef SparseSparseProduct Type; -}; - -namespace internal { -template -struct traits > -{ - typedef MatrixXpr XprKind; - // clean the nested types: - typedef typename remove_all::type _LhsNested; - typedef typename remove_all::type _RhsNested; - typedef typename _LhsNested::Scalar Scalar; - typedef typename promote_index_type::Index, - typename traits<_RhsNested>::Index>::type Index; - - enum { - LhsCoeffReadCost = _LhsNested::CoeffReadCost, - RhsCoeffReadCost = _RhsNested::CoeffReadCost, - LhsFlags = _LhsNested::Flags, - RhsFlags = _RhsNested::Flags, - - RowsAtCompileTime = _LhsNested::RowsAtCompileTime, - ColsAtCompileTime = _RhsNested::ColsAtCompileTime, - MaxRowsAtCompileTime = _LhsNested::MaxRowsAtCompileTime, - MaxColsAtCompileTime = _RhsNested::MaxColsAtCompileTime, - - InnerSize = EIGEN_SIZE_MIN_PREFER_FIXED(_LhsNested::ColsAtCompileTime, _RhsNested::RowsAtCompileTime), - - EvalToRowMajor = (RhsFlags & LhsFlags & RowMajorBit), - - RemovedBits = ~(EvalToRowMajor ? 0 : RowMajorBit), - - Flags = (int(LhsFlags | RhsFlags) & HereditaryBits & RemovedBits) - | EvalBeforeAssigningBit - | EvalBeforeNestingBit, - - CoeffReadCost = Dynamic - }; - - typedef Sparse StorageKind; -}; - -} // end namespace internal - -template -class SparseSparseProduct : internal::no_assignment_operator, - public SparseMatrixBase > -{ - public: - - typedef SparseMatrixBase Base; - EIGEN_DENSE_PUBLIC_INTERFACE(SparseSparseProduct) - - private: - - typedef typename internal::traits::_LhsNested _LhsNested; - typedef typename internal::traits::_RhsNested _RhsNested; - - public: - - template - EIGEN_STRONG_INLINE SparseSparseProduct(const Lhs& lhs, const Rhs& rhs) - : m_lhs(lhs), m_rhs(rhs), m_tolerance(0), m_conservative(true) - { - init(); - } - - template - EIGEN_STRONG_INLINE SparseSparseProduct(const Lhs& lhs, const Rhs& rhs, const RealScalar& tolerance) - : m_lhs(lhs), m_rhs(rhs), m_tolerance(tolerance), m_conservative(false) - { - init(); - } - - SparseSparseProduct pruned(const Scalar& reference = 0, const RealScalar& epsilon = NumTraits::dummy_precision()) const - { - using std::abs; - return SparseSparseProduct(m_lhs,m_rhs,abs(reference)*epsilon); - } - - template - void evalTo(Dest& result) const - { - if(m_conservative) - internal::conservative_sparse_sparse_product_selector<_LhsNested, _RhsNested, Dest>::run(lhs(),rhs(),result); - else - internal::sparse_sparse_product_with_pruning_selector<_LhsNested, _RhsNested, Dest>::run(lhs(),rhs(),result,m_tolerance); - } - - EIGEN_STRONG_INLINE Index rows() const { return m_lhs.rows(); } - EIGEN_STRONG_INLINE Index cols() const { return m_rhs.cols(); } - - EIGEN_STRONG_INLINE const _LhsNested& lhs() const { return m_lhs; } - EIGEN_STRONG_INLINE const _RhsNested& rhs() const { return m_rhs; } - - protected: - void init() - { - eigen_assert(m_lhs.cols() == m_rhs.rows()); - - enum { - ProductIsValid = _LhsNested::ColsAtCompileTime==Dynamic - || _RhsNested::RowsAtCompileTime==Dynamic - || int(_LhsNested::ColsAtCompileTime)==int(_RhsNested::RowsAtCompileTime), - AreVectors = _LhsNested::IsVectorAtCompileTime && _RhsNested::IsVectorAtCompileTime, - SameSizes = EIGEN_PREDICATE_SAME_MATRIX_SIZE(_LhsNested,_RhsNested) - }; - // note to the lost user: - // * for a dot product use: v1.dot(v2) - // * for a coeff-wise product use: v1.cwise()*v2 - EIGEN_STATIC_ASSERT(ProductIsValid || !(AreVectors && SameSizes), - INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS) - EIGEN_STATIC_ASSERT(ProductIsValid || !(SameSizes && !AreVectors), - INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION) - EIGEN_STATIC_ASSERT(ProductIsValid || SameSizes, INVALID_MATRIX_PRODUCT) - } - - LhsNested m_lhs; - RhsNested m_rhs; - RealScalar m_tolerance; - bool m_conservative; -}; - -// sparse = sparse * sparse -template -template -inline Derived& SparseMatrixBase::operator=(const SparseSparseProduct& product) -{ - product.evalTo(derived()); - return derived(); -} - -/** \returns an expression of the product of two sparse matrices. - * By default a conservative product preserving the symbolic non zeros is performed. - * The automatic pruning of the small values can be achieved by calling the pruned() function - * in which case a totally different product algorithm is employed: - * \code - * C = (A*B).pruned(); // supress numerical zeros (exact) - * C = (A*B).pruned(ref); - * C = (A*B).pruned(ref,epsilon); - * \endcode - * where \c ref is a meaningful non zero reference value. - * */ -template -template -inline const typename SparseSparseProductReturnType::Type -SparseMatrixBase::operator*(const SparseMatrixBase &other) const -{ - return typename SparseSparseProductReturnType::Type(derived(), other.derived()); -} - -} // end namespace Eigen - -#endif // EIGEN_SPARSEPRODUCT_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseRedux.h b/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseRedux.h deleted file mode 100644 index f3da93a7..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseRedux.h +++ /dev/null @@ -1,45 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_SPARSEREDUX_H -#define EIGEN_SPARSEREDUX_H - -namespace Eigen { - -template -typename internal::traits::Scalar -SparseMatrixBase::sum() const -{ - eigen_assert(rows()>0 && cols()>0 && "you are using a non initialized matrix"); - Scalar res(0); - for (Index j=0; j -typename internal::traits >::Scalar -SparseMatrix<_Scalar,_Options,_Index>::sum() const -{ - eigen_assert(rows()>0 && cols()>0 && "you are using a non initialized matrix"); - return Matrix::Map(&m_data.value(0), m_data.size()).sum(); -} - -template -typename internal::traits >::Scalar -SparseVector<_Scalar,_Options,_Index>::sum() const -{ - eigen_assert(rows()>0 && cols()>0 && "you are using a non initialized matrix"); - return Matrix::Map(&m_data.value(0), m_data.size()).sum(); -} - -} // end namespace Eigen - -#endif // EIGEN_SPARSEREDUX_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseSelfAdjointView.h b/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseSelfAdjointView.h deleted file mode 100644 index 0eda96bc..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseSelfAdjointView.h +++ /dev/null @@ -1,507 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2009 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_SPARSE_SELFADJOINTVIEW_H -#define EIGEN_SPARSE_SELFADJOINTVIEW_H - -namespace Eigen { - -/** \ingroup SparseCore_Module - * \class SparseSelfAdjointView - * - * \brief Pseudo expression to manipulate a triangular sparse matrix as a selfadjoint matrix. - * - * \param MatrixType the type of the dense matrix storing the coefficients - * \param UpLo can be either \c #Lower or \c #Upper - * - * This class is an expression of a sefladjoint matrix from a triangular part of a matrix - * with given dense storage of the coefficients. It is the return type of MatrixBase::selfadjointView() - * and most of the time this is the only way that it is used. - * - * \sa SparseMatrixBase::selfadjointView() - */ -template -class SparseSelfAdjointTimeDenseProduct; - -template -class DenseTimeSparseSelfAdjointProduct; - -namespace internal { - -template -struct traits > : traits { -}; - -template -void permute_symm_to_symm(const MatrixType& mat, SparseMatrix& _dest, const typename MatrixType::Index* perm = 0); - -template -void permute_symm_to_fullsymm(const MatrixType& mat, SparseMatrix& _dest, const typename MatrixType::Index* perm = 0); - -} - -template class SparseSelfAdjointView - : public EigenBase > -{ - public: - - typedef typename MatrixType::Scalar Scalar; - typedef typename MatrixType::Index Index; - typedef Matrix VectorI; - typedef typename MatrixType::Nested MatrixTypeNested; - typedef typename internal::remove_all::type _MatrixTypeNested; - - inline SparseSelfAdjointView(const MatrixType& matrix) : m_matrix(matrix) - { - eigen_assert(rows()==cols() && "SelfAdjointView is only for squared matrices"); - } - - inline Index rows() const { return m_matrix.rows(); } - inline Index cols() const { return m_matrix.cols(); } - - /** \internal \returns a reference to the nested matrix */ - const _MatrixTypeNested& matrix() const { return m_matrix; } - _MatrixTypeNested& matrix() { return m_matrix.const_cast_derived(); } - - /** \returns an expression of the matrix product between a sparse self-adjoint matrix \c *this and a sparse matrix \a rhs. - * - * Note that there is no algorithmic advantage of performing such a product compared to a general sparse-sparse matrix product. - * Indeed, the SparseSelfadjointView operand is first copied into a temporary SparseMatrix before computing the product. - */ - template - SparseSparseProduct - operator*(const SparseMatrixBase& rhs) const - { - return SparseSparseProduct(*this, rhs.derived()); - } - - /** \returns an expression of the matrix product between a sparse matrix \a lhs and a sparse self-adjoint matrix \a rhs. - * - * Note that there is no algorithmic advantage of performing such a product compared to a general sparse-sparse matrix product. - * Indeed, the SparseSelfadjointView operand is first copied into a temporary SparseMatrix before computing the product. - */ - template friend - SparseSparseProduct - operator*(const SparseMatrixBase& lhs, const SparseSelfAdjointView& rhs) - { - return SparseSparseProduct(lhs.derived(), rhs); - } - - /** Efficient sparse self-adjoint matrix times dense vector/matrix product */ - template - SparseSelfAdjointTimeDenseProduct - operator*(const MatrixBase& rhs) const - { - return SparseSelfAdjointTimeDenseProduct(m_matrix, rhs.derived()); - } - - /** Efficient dense vector/matrix times sparse self-adjoint matrix product */ - template friend - DenseTimeSparseSelfAdjointProduct - operator*(const MatrixBase& lhs, const SparseSelfAdjointView& rhs) - { - return DenseTimeSparseSelfAdjointProduct(lhs.derived(), rhs.m_matrix); - } - - /** Perform a symmetric rank K update of the selfadjoint matrix \c *this: - * \f$ this = this + \alpha ( u u^* ) \f$ where \a u is a vector or matrix. - * - * \returns a reference to \c *this - * - * To perform \f$ this = this + \alpha ( u^* u ) \f$ you can simply - * call this function with u.adjoint(). - */ - template - SparseSelfAdjointView& rankUpdate(const SparseMatrixBase& u, const Scalar& alpha = Scalar(1)); - - /** \internal triggered by sparse_matrix = SparseSelfadjointView; */ - template void evalTo(SparseMatrix& _dest) const - { - internal::permute_symm_to_fullsymm(m_matrix, _dest); - } - - template void evalTo(DynamicSparseMatrix& _dest) const - { - // TODO directly evaluate into _dest; - SparseMatrix tmp(_dest.rows(),_dest.cols()); - internal::permute_symm_to_fullsymm(m_matrix, tmp); - _dest = tmp; - } - - /** \returns an expression of P H P^-1 */ - SparseSymmetricPermutationProduct<_MatrixTypeNested,UpLo> twistedBy(const PermutationMatrix& perm) const - { - return SparseSymmetricPermutationProduct<_MatrixTypeNested,UpLo>(m_matrix, perm); - } - - template - SparseSelfAdjointView& operator=(const SparseSymmetricPermutationProduct& permutedMatrix) - { - permutedMatrix.evalTo(*this); - return *this; - } - - - SparseSelfAdjointView& operator=(const SparseSelfAdjointView& src) - { - PermutationMatrix pnull; - return *this = src.twistedBy(pnull); - } - - template - SparseSelfAdjointView& operator=(const SparseSelfAdjointView& src) - { - PermutationMatrix pnull; - return *this = src.twistedBy(pnull); - } - - - // const SparseLLT llt() const; - // const SparseLDLT ldlt() const; - - protected: - - typename MatrixType::Nested m_matrix; - mutable VectorI m_countPerRow; - mutable VectorI m_countPerCol; -}; - -/*************************************************************************** -* Implementation of SparseMatrixBase methods -***************************************************************************/ - -template -template -const SparseSelfAdjointView SparseMatrixBase::selfadjointView() const -{ - return derived(); -} - -template -template -SparseSelfAdjointView SparseMatrixBase::selfadjointView() -{ - return derived(); -} - -/*************************************************************************** -* Implementation of SparseSelfAdjointView methods -***************************************************************************/ - -template -template -SparseSelfAdjointView& -SparseSelfAdjointView::rankUpdate(const SparseMatrixBase& u, const Scalar& alpha) -{ - SparseMatrix tmp = u * u.adjoint(); - if(alpha==Scalar(0)) - m_matrix.const_cast_derived() = tmp.template triangularView(); - else - m_matrix.const_cast_derived() += alpha * tmp.template triangularView(); - - return *this; -} - -/*************************************************************************** -* Implementation of sparse self-adjoint time dense matrix -***************************************************************************/ - -namespace internal { -template -struct traits > - : traits, Lhs, Rhs> > -{ - typedef Dense StorageKind; -}; -} - -template -class SparseSelfAdjointTimeDenseProduct - : public ProductBase, Lhs, Rhs> -{ - public: - EIGEN_PRODUCT_PUBLIC_INTERFACE(SparseSelfAdjointTimeDenseProduct) - - SparseSelfAdjointTimeDenseProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs) - {} - - template void scaleAndAddTo(Dest& dest, const Scalar& alpha) const - { - EIGEN_ONLY_USED_FOR_DEBUG(alpha); - // TODO use alpha - eigen_assert(alpha==Scalar(1) && "alpha != 1 is not implemented yet, sorry"); - typedef typename internal::remove_all::type _Lhs; - typedef typename _Lhs::InnerIterator LhsInnerIterator; - enum { - LhsIsRowMajor = (_Lhs::Flags&RowMajorBit)==RowMajorBit, - ProcessFirstHalf = - ((UpLo&(Upper|Lower))==(Upper|Lower)) - || ( (UpLo&Upper) && !LhsIsRowMajor) - || ( (UpLo&Lower) && LhsIsRowMajor), - ProcessSecondHalf = !ProcessFirstHalf - }; - for (Index j=0; j -struct traits > - : traits, Lhs, Rhs> > -{}; -} - -template -class DenseTimeSparseSelfAdjointProduct - : public ProductBase, Lhs, Rhs> -{ - public: - EIGEN_PRODUCT_PUBLIC_INTERFACE(DenseTimeSparseSelfAdjointProduct) - - DenseTimeSparseSelfAdjointProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs) - {} - - template void scaleAndAddTo(Dest& /*dest*/, const Scalar& /*alpha*/) const - { - // TODO - } - - private: - DenseTimeSparseSelfAdjointProduct& operator=(const DenseTimeSparseSelfAdjointProduct&); -}; - -/*************************************************************************** -* Implementation of symmetric copies and permutations -***************************************************************************/ -namespace internal { - -template -struct traits > : traits { -}; - -template -void permute_symm_to_fullsymm(const MatrixType& mat, SparseMatrix& _dest, const typename MatrixType::Index* perm) -{ - typedef typename MatrixType::Index Index; - typedef typename MatrixType::Scalar Scalar; - typedef SparseMatrix Dest; - typedef Matrix VectorI; - - Dest& dest(_dest.derived()); - enum { - StorageOrderMatch = int(Dest::IsRowMajor) == int(MatrixType::IsRowMajor) - }; - - Index size = mat.rows(); - VectorI count; - count.resize(size); - count.setZero(); - dest.resize(size,size); - for(Index j = 0; jc) || ( UpLo==Upper && rc) || ( (UpLo&Upper)==Upper && r -void permute_symm_to_symm(const MatrixType& mat, SparseMatrix& _dest, const typename MatrixType::Index* perm) -{ - typedef typename MatrixType::Index Index; - typedef typename MatrixType::Scalar Scalar; - SparseMatrix& dest(_dest.derived()); - typedef Matrix VectorI; - enum { - SrcOrder = MatrixType::IsRowMajor ? RowMajor : ColMajor, - StorageOrderMatch = int(SrcOrder) == int(DstOrder), - DstUpLo = DstOrder==RowMajor ? (_DstUpLo==Upper ? Lower : Upper) : _DstUpLo, - SrcUpLo = SrcOrder==RowMajor ? (_SrcUpLo==Upper ? Lower : Upper) : _SrcUpLo - }; - - Index size = mat.rows(); - VectorI count(size); - count.setZero(); - dest.resize(size,size); - for(Index j = 0; jj)) - continue; - - Index ip = perm ? perm[i] : i; - count[int(DstUpLo)==int(Lower) ? (std::min)(ip,jp) : (std::max)(ip,jp)]++; - } - } - dest.outerIndexPtr()[0] = 0; - for(Index j=0; jj)) - continue; - - Index jp = perm ? perm[j] : j; - Index ip = perm? perm[i] : i; - - Index k = count[int(DstUpLo)==int(Lower) ? (std::min)(ip,jp) : (std::max)(ip,jp)]++; - dest.innerIndexPtr()[k] = int(DstUpLo)==int(Lower) ? (std::max)(ip,jp) : (std::min)(ip,jp); - - if(!StorageOrderMatch) std::swap(ip,jp); - if( ((int(DstUpLo)==int(Lower) && ipjp))) - dest.valuePtr()[k] = numext::conj(it.value()); - else - dest.valuePtr()[k] = it.value(); - } - } -} - -} - -template -class SparseSymmetricPermutationProduct - : public EigenBase > -{ - public: - typedef typename MatrixType::Scalar Scalar; - typedef typename MatrixType::Index Index; - protected: - typedef PermutationMatrix Perm; - public: - typedef Matrix VectorI; - typedef typename MatrixType::Nested MatrixTypeNested; - typedef typename internal::remove_all::type _MatrixTypeNested; - - SparseSymmetricPermutationProduct(const MatrixType& mat, const Perm& perm) - : m_matrix(mat), m_perm(perm) - {} - - inline Index rows() const { return m_matrix.rows(); } - inline Index cols() const { return m_matrix.cols(); } - - template - void evalTo(SparseMatrix& _dest) const - { -// internal::permute_symm_to_fullsymm(m_matrix,_dest,m_perm.indices().data()); - SparseMatrix tmp; - internal::permute_symm_to_fullsymm(m_matrix,tmp,m_perm.indices().data()); - _dest = tmp; - } - - template void evalTo(SparseSelfAdjointView& dest) const - { - internal::permute_symm_to_symm(m_matrix,dest.matrix(),m_perm.indices().data()); - } - - protected: - MatrixTypeNested m_matrix; - const Perm& m_perm; - -}; - -} // end namespace Eigen - -#endif // EIGEN_SPARSE_SELFADJOINTVIEW_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseSparseProductWithPruning.h b/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseSparseProductWithPruning.h deleted file mode 100644 index fcc18f5c..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseSparseProductWithPruning.h +++ /dev/null @@ -1,150 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2011 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_SPARSESPARSEPRODUCTWITHPRUNING_H -#define EIGEN_SPARSESPARSEPRODUCTWITHPRUNING_H - -namespace Eigen { - -namespace internal { - - -// perform a pseudo in-place sparse * sparse product assuming all matrices are col major -template -static void sparse_sparse_product_with_pruning_impl(const Lhs& lhs, const Rhs& rhs, ResultType& res, const typename ResultType::RealScalar& tolerance) -{ - // return sparse_sparse_product_with_pruning_impl2(lhs,rhs,res); - - typedef typename remove_all::type::Scalar Scalar; - typedef typename remove_all::type::Index Index; - - // make sure to call innerSize/outerSize since we fake the storage order. - Index rows = lhs.innerSize(); - Index cols = rhs.outerSize(); - //Index size = lhs.outerSize(); - eigen_assert(lhs.outerSize() == rhs.innerSize()); - - // allocate a temporary buffer - AmbiVector tempVector(rows); - - // estimate the number of non zero entries - // given a rhs column containing Y non zeros, we assume that the respective Y columns - // of the lhs differs in average of one non zeros, thus the number of non zeros for - // the product of a rhs column with the lhs is X+Y where X is the average number of non zero - // per column of the lhs. - // Therefore, we have nnz(lhs*rhs) = nnz(lhs) + nnz(rhs) - Index estimated_nnz_prod = lhs.nonZeros() + rhs.nonZeros(); - - // mimics a resizeByInnerOuter: - if(ResultType::IsRowMajor) - res.resize(cols, rows); - else - res.resize(rows, cols); - - res.reserve(estimated_nnz_prod); - double ratioColRes = double(estimated_nnz_prod)/double(lhs.rows()*rhs.cols()); - for (Index j=0; j::Iterator it(tempVector,tolerance); it; ++it) - res.insertBackByOuterInner(j,it.index()) = it.value(); - } - res.finalize(); -} - -template::Flags&RowMajorBit, - int RhsStorageOrder = traits::Flags&RowMajorBit, - int ResStorageOrder = traits::Flags&RowMajorBit> -struct sparse_sparse_product_with_pruning_selector; - -template -struct sparse_sparse_product_with_pruning_selector -{ - typedef typename traits::type>::Scalar Scalar; - typedef typename ResultType::RealScalar RealScalar; - - static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res, const RealScalar& tolerance) - { - typename remove_all::type _res(res.rows(), res.cols()); - internal::sparse_sparse_product_with_pruning_impl(lhs, rhs, _res, tolerance); - res.swap(_res); - } -}; - -template -struct sparse_sparse_product_with_pruning_selector -{ - typedef typename ResultType::RealScalar RealScalar; - static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res, const RealScalar& tolerance) - { - // we need a col-major matrix to hold the result - typedef SparseMatrix SparseTemporaryType; - SparseTemporaryType _res(res.rows(), res.cols()); - internal::sparse_sparse_product_with_pruning_impl(lhs, rhs, _res, tolerance); - res = _res; - } -}; - -template -struct sparse_sparse_product_with_pruning_selector -{ - typedef typename ResultType::RealScalar RealScalar; - static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res, const RealScalar& tolerance) - { - // let's transpose the product to get a column x column product - typename remove_all::type _res(res.rows(), res.cols()); - internal::sparse_sparse_product_with_pruning_impl(rhs, lhs, _res, tolerance); - res.swap(_res); - } -}; - -template -struct sparse_sparse_product_with_pruning_selector -{ - typedef typename ResultType::RealScalar RealScalar; - static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res, const RealScalar& tolerance) - { - typedef SparseMatrix ColMajorMatrixLhs; - typedef SparseMatrix ColMajorMatrixRhs; - ColMajorMatrixLhs colLhs(lhs); - ColMajorMatrixRhs colRhs(rhs); - internal::sparse_sparse_product_with_pruning_impl(colLhs, colRhs, res, tolerance); - - // let's transpose the product to get a column x column product -// typedef SparseMatrix SparseTemporaryType; -// SparseTemporaryType _res(res.cols(), res.rows()); -// sparse_sparse_product_with_pruning_impl(rhs, lhs, _res); -// res = _res.transpose(); - } -}; - -// NOTE the 2 others cases (col row *) must never occur since they are caught -// by ProductReturnType which transforms it to (col col *) by evaluating rhs. - -} // end namespace internal - -} // end namespace Eigen - -#endif // EIGEN_SPARSESPARSEPRODUCTWITHPRUNING_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseTranspose.h b/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseTranspose.h deleted file mode 100644 index 76d031d5..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseTranspose.h +++ /dev/null @@ -1,63 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2009 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_SPARSETRANSPOSE_H -#define EIGEN_SPARSETRANSPOSE_H - -namespace Eigen { - -template class TransposeImpl - : public SparseMatrixBase > -{ - typedef typename internal::remove_all::type _MatrixTypeNested; - public: - - EIGEN_SPARSE_PUBLIC_INTERFACE(Transpose ) - - class InnerIterator; - class ReverseInnerIterator; - - inline Index nonZeros() const { return derived().nestedExpression().nonZeros(); } -}; - -// NOTE: VC10 and VC11 trigger an ICE if don't put typename TransposeImpl:: in front of Index, -// a typedef typename TransposeImpl::Index Index; -// does not fix the issue. -// An alternative is to define the nested class in the parent class itself. -template class TransposeImpl::InnerIterator - : public _MatrixTypeNested::InnerIterator -{ - typedef typename _MatrixTypeNested::InnerIterator Base; - typedef typename TransposeImpl::Index Index; - public: - - EIGEN_STRONG_INLINE InnerIterator(const TransposeImpl& trans, typename TransposeImpl::Index outer) - : Base(trans.derived().nestedExpression(), outer) - {} - typename TransposeImpl::Index row() const { return Base::col(); } - typename TransposeImpl::Index col() const { return Base::row(); } -}; - -template class TransposeImpl::ReverseInnerIterator - : public _MatrixTypeNested::ReverseInnerIterator -{ - typedef typename _MatrixTypeNested::ReverseInnerIterator Base; - typedef typename TransposeImpl::Index Index; - public: - - EIGEN_STRONG_INLINE ReverseInnerIterator(const TransposeImpl& xpr, typename TransposeImpl::Index outer) - : Base(xpr.derived().nestedExpression(), outer) - {} - typename TransposeImpl::Index row() const { return Base::col(); } - typename TransposeImpl::Index col() const { return Base::row(); } -}; - -} // end namespace Eigen - -#endif // EIGEN_SPARSETRANSPOSE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseTriangularView.h b/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseTriangularView.h deleted file mode 100644 index 333127b7..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseTriangularView.h +++ /dev/null @@ -1,179 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2009 Gael Guennebaud -// Copyright (C) 2012 Désiré Nuentsa-Wakam -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_SPARSE_TRIANGULARVIEW_H -#define EIGEN_SPARSE_TRIANGULARVIEW_H - -namespace Eigen { - -namespace internal { - -template -struct traits > -: public traits -{}; - -} // namespace internal - -template class SparseTriangularView - : public SparseMatrixBase > -{ - enum { SkipFirst = ((Mode&Lower) && !(MatrixType::Flags&RowMajorBit)) - || ((Mode&Upper) && (MatrixType::Flags&RowMajorBit)), - SkipLast = !SkipFirst, - SkipDiag = (Mode&ZeroDiag) ? 1 : 0, - HasUnitDiag = (Mode&UnitDiag) ? 1 : 0 - }; - - public: - - EIGEN_SPARSE_PUBLIC_INTERFACE(SparseTriangularView) - - class InnerIterator; - class ReverseInnerIterator; - - inline Index rows() const { return m_matrix.rows(); } - inline Index cols() const { return m_matrix.cols(); } - - typedef typename MatrixType::Nested MatrixTypeNested; - typedef typename internal::remove_reference::type MatrixTypeNestedNonRef; - typedef typename internal::remove_all::type MatrixTypeNestedCleaned; - - inline SparseTriangularView(const MatrixType& matrix) : m_matrix(matrix) {} - - /** \internal */ - inline const MatrixTypeNestedCleaned& nestedExpression() const { return m_matrix; } - - template - typename internal::plain_matrix_type_column_major::type - solve(const MatrixBase& other) const; - - template void solveInPlace(MatrixBase& other) const; - template void solveInPlace(SparseMatrixBase& other) const; - - protected: - MatrixTypeNested m_matrix; -}; - -template -class SparseTriangularView::InnerIterator : public MatrixTypeNestedCleaned::InnerIterator -{ - typedef typename MatrixTypeNestedCleaned::InnerIterator Base; - typedef typename SparseTriangularView::Index Index; - public: - - EIGEN_STRONG_INLINE InnerIterator(const SparseTriangularView& view, Index outer) - : Base(view.nestedExpression(), outer), m_returnOne(false) - { - if(SkipFirst) - { - while((*this) && ((HasUnitDiag||SkipDiag) ? this->index()<=outer : this->index()=Base::outer())) - { - if((!SkipFirst) && Base::operator bool()) - Base::operator++(); - m_returnOne = true; - } - } - - EIGEN_STRONG_INLINE InnerIterator& operator++() - { - if(HasUnitDiag && m_returnOne) - m_returnOne = false; - else - { - Base::operator++(); - if(HasUnitDiag && (!SkipFirst) && ((!Base::operator bool()) || Base::index()>=Base::outer())) - { - if((!SkipFirst) && Base::operator bool()) - Base::operator++(); - m_returnOne = true; - } - } - return *this; - } - - inline Index row() const { return (MatrixType::Flags&RowMajorBit ? Base::outer() : this->index()); } - inline Index col() const { return (MatrixType::Flags&RowMajorBit ? this->index() : Base::outer()); } - inline Index index() const - { - if(HasUnitDiag && m_returnOne) return Base::outer(); - else return Base::index(); - } - inline Scalar value() const - { - if(HasUnitDiag && m_returnOne) return Scalar(1); - else return Base::value(); - } - - EIGEN_STRONG_INLINE operator bool() const - { - if(HasUnitDiag && m_returnOne) - return true; - if(SkipFirst) return Base::operator bool(); - else - { - if (SkipDiag) return (Base::operator bool() && this->index() < this->outer()); - else return (Base::operator bool() && this->index() <= this->outer()); - } - } - protected: - bool m_returnOne; -}; - -template -class SparseTriangularView::ReverseInnerIterator : public MatrixTypeNestedCleaned::ReverseInnerIterator -{ - typedef typename MatrixTypeNestedCleaned::ReverseInnerIterator Base; - typedef typename SparseTriangularView::Index Index; - public: - - EIGEN_STRONG_INLINE ReverseInnerIterator(const SparseTriangularView& view, Index outer) - : Base(view.nestedExpression(), outer) - { - eigen_assert((!HasUnitDiag) && "ReverseInnerIterator does not support yet triangular views with a unit diagonal"); - if(SkipLast) { - while((*this) && (SkipDiag ? this->index()>=outer : this->index()>outer)) - --(*this); - } - } - - EIGEN_STRONG_INLINE ReverseInnerIterator& operator--() - { Base::operator--(); return *this; } - - inline Index row() const { return Base::row(); } - inline Index col() const { return Base::col(); } - - EIGEN_STRONG_INLINE operator bool() const - { - if (SkipLast) return Base::operator bool() ; - else - { - if(SkipDiag) return (Base::operator bool() && this->index() > this->outer()); - else return (Base::operator bool() && this->index() >= this->outer()); - } - } -}; - -template -template -inline const SparseTriangularView -SparseMatrixBase::triangularView() const -{ - return derived(); -} - -} // end namespace Eigen - -#endif // EIGEN_SPARSE_TRIANGULARVIEW_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseUtil.h b/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseUtil.h deleted file mode 100644 index d627546d..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseUtil.h +++ /dev/null @@ -1,172 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_SPARSEUTIL_H -#define EIGEN_SPARSEUTIL_H - -namespace Eigen { - -#ifdef NDEBUG -#define EIGEN_DBG_SPARSE(X) -#else -#define EIGEN_DBG_SPARSE(X) X -#endif - -#define EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(Derived, Op) \ -template \ -EIGEN_STRONG_INLINE Derived& operator Op(const Eigen::SparseMatrixBase& other) \ -{ \ - return Base::operator Op(other.derived()); \ -} \ -EIGEN_STRONG_INLINE Derived& operator Op(const Derived& other) \ -{ \ - return Base::operator Op(other); \ -} - -#define EIGEN_SPARSE_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(Derived, Op) \ -template \ -EIGEN_STRONG_INLINE Derived& operator Op(const Other& scalar) \ -{ \ - return Base::operator Op(scalar); \ -} - -#define EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATORS(Derived) \ -EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(Derived, =) \ -EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(Derived, +=) \ -EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(Derived, -=) \ -EIGEN_SPARSE_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(Derived, *=) \ -EIGEN_SPARSE_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(Derived, /=) - -#define _EIGEN_SPARSE_PUBLIC_INTERFACE(Derived, BaseClass) \ - typedef BaseClass Base; \ - typedef typename Eigen::internal::traits::Scalar Scalar; \ - typedef typename Eigen::NumTraits::Real RealScalar; \ - typedef typename Eigen::internal::nested::type Nested; \ - typedef typename Eigen::internal::traits::StorageKind StorageKind; \ - typedef typename Eigen::internal::traits::Index Index; \ - enum { RowsAtCompileTime = Eigen::internal::traits::RowsAtCompileTime, \ - ColsAtCompileTime = Eigen::internal::traits::ColsAtCompileTime, \ - Flags = Eigen::internal::traits::Flags, \ - CoeffReadCost = Eigen::internal::traits::CoeffReadCost, \ - SizeAtCompileTime = Base::SizeAtCompileTime, \ - IsVectorAtCompileTime = Base::IsVectorAtCompileTime }; \ - using Base::derived; \ - using Base::const_cast_derived; - -#define EIGEN_SPARSE_PUBLIC_INTERFACE(Derived) \ - _EIGEN_SPARSE_PUBLIC_INTERFACE(Derived, Eigen::SparseMatrixBase) - -const int CoherentAccessPattern = 0x1; -const int InnerRandomAccessPattern = 0x2 | CoherentAccessPattern; -const int OuterRandomAccessPattern = 0x4 | CoherentAccessPattern; -const int RandomAccessPattern = 0x8 | OuterRandomAccessPattern | InnerRandomAccessPattern; - -template class SparseMatrix; -template class DynamicSparseMatrix; -template class SparseVector; -template class MappedSparseMatrix; - -template class SparseTriangularView; -template class SparseSelfAdjointView; -template class SparseDiagonalProduct; -template class SparseView; - -template class SparseSparseProduct; -template class SparseTimeDenseProduct; -template class DenseTimeSparseProduct; -template class SparseDenseOuterProduct; - -template struct SparseSparseProductReturnType; -template::ColsAtCompileTime,internal::traits::RowsAtCompileTime)> struct DenseSparseProductReturnType; -template::ColsAtCompileTime,internal::traits::RowsAtCompileTime)> struct SparseDenseProductReturnType; -template class SparseSymmetricPermutationProduct; - -namespace internal { - -template struct sparse_eval; - -template struct eval - : public sparse_eval::RowsAtCompileTime,traits::ColsAtCompileTime> -{}; - -template struct sparse_eval { - typedef typename traits::Scalar _Scalar; - typedef typename traits::Index _Index; - public: - typedef SparseVector<_Scalar, RowMajor, _Index> type; -}; - -template struct sparse_eval { - typedef typename traits::Scalar _Scalar; - typedef typename traits::Index _Index; - public: - typedef SparseVector<_Scalar, ColMajor, _Index> type; -}; - -template struct sparse_eval { - typedef typename traits::Scalar _Scalar; - typedef typename traits::Index _Index; - enum { _Options = ((traits::Flags&RowMajorBit)==RowMajorBit) ? RowMajor : ColMajor }; - public: - typedef SparseMatrix<_Scalar, _Options, _Index> type; -}; - -template struct sparse_eval { - typedef typename traits::Scalar _Scalar; - public: - typedef Matrix<_Scalar, 1, 1> type; -}; - -template struct plain_matrix_type -{ - typedef typename traits::Scalar _Scalar; - typedef typename traits::Index _Index; - enum { _Options = ((traits::Flags&RowMajorBit)==RowMajorBit) ? RowMajor : ColMajor }; - public: - typedef SparseMatrix<_Scalar, _Options, _Index> type; -}; - -} // end namespace internal - -/** \ingroup SparseCore_Module - * - * \class Triplet - * - * \brief A small structure to hold a non zero as a triplet (i,j,value). - * - * \sa SparseMatrix::setFromTriplets() - */ -template::Index > -class Triplet -{ -public: - Triplet() : m_row(0), m_col(0), m_value(0) {} - - Triplet(const Index& i, const Index& j, const Scalar& v = Scalar(0)) - : m_row(i), m_col(j), m_value(v) - {} - - /** \returns the row index of the element */ - const Index& row() const { return m_row; } - - /** \returns the column index of the element */ - const Index& col() const { return m_col; } - - /** \returns the value of the element */ - const Scalar& value() const { return m_value; } -protected: - Index m_row, m_col; - Scalar m_value; -}; - -} // end namespace Eigen - -#endif // EIGEN_SPARSEUTIL_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseVector.h b/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseVector.h deleted file mode 100644 index 49865d0e..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseVector.h +++ /dev/null @@ -1,448 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2009 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_SPARSEVECTOR_H -#define EIGEN_SPARSEVECTOR_H - -namespace Eigen { - -/** \ingroup SparseCore_Module - * \class SparseVector - * - * \brief a sparse vector class - * - * \tparam _Scalar the scalar type, i.e. the type of the coefficients - * - * See http://www.netlib.org/linalg/html_templates/node91.html for details on the storage scheme. - * - * This class can be extended with the help of the plugin mechanism described on the page - * \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_SPARSEVECTOR_PLUGIN. - */ - -namespace internal { -template -struct traits > -{ - typedef _Scalar Scalar; - typedef _Index Index; - typedef Sparse StorageKind; - typedef MatrixXpr XprKind; - enum { - IsColVector = (_Options & RowMajorBit) ? 0 : 1, - - RowsAtCompileTime = IsColVector ? Dynamic : 1, - ColsAtCompileTime = IsColVector ? 1 : Dynamic, - MaxRowsAtCompileTime = RowsAtCompileTime, - MaxColsAtCompileTime = ColsAtCompileTime, - Flags = _Options | NestByRefBit | LvalueBit | (IsColVector ? 0 : RowMajorBit), - CoeffReadCost = NumTraits::ReadCost, - SupportedAccessPatterns = InnerRandomAccessPattern - }; -}; - -// Sparse-Vector-Assignment kinds: -enum { - SVA_RuntimeSwitch, - SVA_Inner, - SVA_Outer -}; - -template< typename Dest, typename Src, - int AssignmentKind = !bool(Src::IsVectorAtCompileTime) ? SVA_RuntimeSwitch - : Src::InnerSizeAtCompileTime==1 ? SVA_Outer - : SVA_Inner> -struct sparse_vector_assign_selector; - -} - -template -class SparseVector - : public SparseMatrixBase > -{ - typedef SparseMatrixBase SparseBase; - - public: - EIGEN_SPARSE_PUBLIC_INTERFACE(SparseVector) - EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(SparseVector, +=) - EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(SparseVector, -=) - - typedef internal::CompressedStorage Storage; - enum { IsColVector = internal::traits::IsColVector }; - - enum { - Options = _Options - }; - - EIGEN_STRONG_INLINE Index rows() const { return IsColVector ? m_size : 1; } - EIGEN_STRONG_INLINE Index cols() const { return IsColVector ? 1 : m_size; } - EIGEN_STRONG_INLINE Index innerSize() const { return m_size; } - EIGEN_STRONG_INLINE Index outerSize() const { return 1; } - - EIGEN_STRONG_INLINE const Scalar* valuePtr() const { return &m_data.value(0); } - EIGEN_STRONG_INLINE Scalar* valuePtr() { return &m_data.value(0); } - - EIGEN_STRONG_INLINE const Index* innerIndexPtr() const { return &m_data.index(0); } - EIGEN_STRONG_INLINE Index* innerIndexPtr() { return &m_data.index(0); } - - /** \internal */ - inline Storage& data() { return m_data; } - /** \internal */ - inline const Storage& data() const { return m_data; } - - inline Scalar coeff(Index row, Index col) const - { - eigen_assert(IsColVector ? (col==0 && row>=0 && row=0 && col=0 && i=0 && row=0 && col=0 && i(m_data.size()); } - - inline void startVec(Index outer) - { - EIGEN_UNUSED_VARIABLE(outer); - eigen_assert(outer==0); - } - - inline Scalar& insertBackByOuterInner(Index outer, Index inner) - { - EIGEN_UNUSED_VARIABLE(outer); - eigen_assert(outer==0); - return insertBack(inner); - } - inline Scalar& insertBack(Index i) - { - m_data.append(0, i); - return m_data.value(m_data.size()-1); - } - - inline Scalar& insert(Index row, Index col) - { - eigen_assert(IsColVector ? (col==0 && row>=0 && row=0 && col=0 && i= startId) && (m_data.index(p) > i) ) - { - m_data.index(p+1) = m_data.index(p); - m_data.value(p+1) = m_data.value(p); - --p; - } - m_data.index(p+1) = i; - m_data.value(p+1) = 0; - return m_data.value(p+1); - } - - /** - */ - inline void reserve(Index reserveSize) { m_data.reserve(reserveSize); } - - - inline void finalize() {} - - void prune(const Scalar& reference, const RealScalar& epsilon = NumTraits::dummy_precision()) - { - m_data.prune(reference,epsilon); - } - - void resize(Index rows, Index cols) - { - eigen_assert(rows==1 || cols==1); - resize(IsColVector ? rows : cols); - } - - void resize(Index newSize) - { - m_size = newSize; - m_data.clear(); - } - - void resizeNonZeros(Index size) { m_data.resize(size); } - - inline SparseVector() : m_size(0) { check_template_parameters(); resize(0); } - - inline SparseVector(Index size) : m_size(0) { check_template_parameters(); resize(size); } - - inline SparseVector(Index rows, Index cols) : m_size(0) { check_template_parameters(); resize(rows,cols); } - - template - inline SparseVector(const SparseMatrixBase& other) - : m_size(0) - { - check_template_parameters(); - *this = other.derived(); - } - - inline SparseVector(const SparseVector& other) - : SparseBase(other), m_size(0) - { - check_template_parameters(); - *this = other.derived(); - } - - /** Swaps the values of \c *this and \a other. - * Overloaded for performance: this version performs a \em shallow swap by swaping pointers and attributes only. - * \sa SparseMatrixBase::swap() - */ - inline void swap(SparseVector& other) - { - std::swap(m_size, other.m_size); - m_data.swap(other.m_data); - } - - inline SparseVector& operator=(const SparseVector& other) - { - if (other.isRValue()) - { - swap(other.const_cast_derived()); - } - else - { - resize(other.size()); - m_data = other.m_data; - } - return *this; - } - - template - inline SparseVector& operator=(const SparseMatrixBase& other) - { - SparseVector tmp(other.size()); - internal::sparse_vector_assign_selector::run(tmp,other.derived()); - this->swap(tmp); - return *this; - } - - #ifndef EIGEN_PARSED_BY_DOXYGEN - template - inline SparseVector& operator=(const SparseSparseProduct& product) - { - return Base::operator=(product); - } - #endif - - friend std::ostream & operator << (std::ostream & s, const SparseVector& m) - { - for (Index i=0; i::IsSigned,THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE); - EIGEN_STATIC_ASSERT((_Options&(ColMajor|RowMajor))==Options,INVALID_MATRIX_TEMPLATE_PARAMETERS); - } - - Storage m_data; - Index m_size; -}; - -template -class SparseVector::InnerIterator -{ - public: - InnerIterator(const SparseVector& vec, Index outer=0) - : m_data(vec.m_data), m_id(0), m_end(static_cast(m_data.size())) - { - EIGEN_UNUSED_VARIABLE(outer); - eigen_assert(outer==0); - } - - InnerIterator(const internal::CompressedStorage& data) - : m_data(data), m_id(0), m_end(static_cast(m_data.size())) - {} - - inline InnerIterator& operator++() { m_id++; return *this; } - - inline Scalar value() const { return m_data.value(m_id); } - inline Scalar& valueRef() { return const_cast(m_data.value(m_id)); } - - inline Index index() const { return m_data.index(m_id); } - inline Index row() const { return IsColVector ? index() : 0; } - inline Index col() const { return IsColVector ? 0 : index(); } - - inline operator bool() const { return (m_id < m_end); } - - protected: - const internal::CompressedStorage& m_data; - Index m_id; - const Index m_end; -}; - -template -class SparseVector::ReverseInnerIterator -{ - public: - ReverseInnerIterator(const SparseVector& vec, Index outer=0) - : m_data(vec.m_data), m_id(static_cast(m_data.size())), m_start(0) - { - EIGEN_UNUSED_VARIABLE(outer); - eigen_assert(outer==0); - } - - ReverseInnerIterator(const internal::CompressedStorage& data) - : m_data(data), m_id(static_cast(m_data.size())), m_start(0) - {} - - inline ReverseInnerIterator& operator--() { m_id--; return *this; } - - inline Scalar value() const { return m_data.value(m_id-1); } - inline Scalar& valueRef() { return const_cast(m_data.value(m_id-1)); } - - inline Index index() const { return m_data.index(m_id-1); } - inline Index row() const { return IsColVector ? index() : 0; } - inline Index col() const { return IsColVector ? 0 : index(); } - - inline operator bool() const { return (m_id > m_start); } - - protected: - const internal::CompressedStorage& m_data; - Index m_id; - const Index m_start; -}; - -namespace internal { - -template< typename Dest, typename Src> -struct sparse_vector_assign_selector { - static void run(Dest& dst, const Src& src) { - eigen_internal_assert(src.innerSize()==src.size()); - for(typename Src::InnerIterator it(src, 0); it; ++it) - dst.insert(it.index()) = it.value(); - } -}; - -template< typename Dest, typename Src> -struct sparse_vector_assign_selector { - static void run(Dest& dst, const Src& src) { - eigen_internal_assert(src.outerSize()==src.size()); - for(typename Dest::Index i=0; i -struct sparse_vector_assign_selector { - static void run(Dest& dst, const Src& src) { - if(src.outerSize()==1) sparse_vector_assign_selector::run(dst, src); - else sparse_vector_assign_selector::run(dst, src); - } -}; - -} - -} // end namespace Eigen - -#endif // EIGEN_SPARSEVECTOR_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseView.h b/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseView.h deleted file mode 100644 index fd845046..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseView.h +++ /dev/null @@ -1,99 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2011 Gael Guennebaud -// Copyright (C) 2010 Daniel Lowengrub -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_SPARSEVIEW_H -#define EIGEN_SPARSEVIEW_H - -namespace Eigen { - -namespace internal { - -template -struct traits > : traits -{ - typedef typename MatrixType::Index Index; - typedef Sparse StorageKind; - enum { - Flags = int(traits::Flags) & (RowMajorBit) - }; -}; - -} // end namespace internal - -template -class SparseView : public SparseMatrixBase > -{ - typedef typename MatrixType::Nested MatrixTypeNested; - typedef typename internal::remove_all::type _MatrixTypeNested; -public: - EIGEN_SPARSE_PUBLIC_INTERFACE(SparseView) - - SparseView(const MatrixType& mat, const Scalar& m_reference = Scalar(0), - typename NumTraits::Real m_epsilon = NumTraits::dummy_precision()) : - m_matrix(mat), m_reference(m_reference), m_epsilon(m_epsilon) {} - - class InnerIterator; - - inline Index rows() const { return m_matrix.rows(); } - inline Index cols() const { return m_matrix.cols(); } - - inline Index innerSize() const { return m_matrix.innerSize(); } - inline Index outerSize() const { return m_matrix.outerSize(); } - -protected: - MatrixTypeNested m_matrix; - Scalar m_reference; - typename NumTraits::Real m_epsilon; -}; - -template -class SparseView::InnerIterator : public _MatrixTypeNested::InnerIterator -{ - typedef typename SparseView::Index Index; -public: - typedef typename _MatrixTypeNested::InnerIterator IterBase; - InnerIterator(const SparseView& view, Index outer) : - IterBase(view.m_matrix, outer), m_view(view) - { - incrementToNonZero(); - } - - EIGEN_STRONG_INLINE InnerIterator& operator++() - { - IterBase::operator++(); - incrementToNonZero(); - return *this; - } - - using IterBase::value; - -protected: - const SparseView& m_view; - -private: - void incrementToNonZero() - { - while((bool(*this)) && internal::isMuchSmallerThan(value(), m_view.m_reference, m_view.m_epsilon)) - { - IterBase::operator++(); - } - } -}; - -template -const SparseView MatrixBase::sparseView(const Scalar& m_reference, - const typename NumTraits::Real& m_epsilon) const -{ - return SparseView(derived(), m_reference, m_epsilon); -} - -} // end namespace Eigen - -#endif diff --git a/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/TriangularSolver.h b/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/TriangularSolver.h deleted file mode 100644 index ccc12af7..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/SparseCore/TriangularSolver.h +++ /dev/null @@ -1,334 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_SPARSETRIANGULARSOLVER_H -#define EIGEN_SPARSETRIANGULARSOLVER_H - -namespace Eigen { - -namespace internal { - -template::Flags) & RowMajorBit> -struct sparse_solve_triangular_selector; - -// forward substitution, row-major -template -struct sparse_solve_triangular_selector -{ - typedef typename Rhs::Scalar Scalar; - static void run(const Lhs& lhs, Rhs& other) - { - for(int col=0 ; col -struct sparse_solve_triangular_selector -{ - typedef typename Rhs::Scalar Scalar; - static void run(const Lhs& lhs, Rhs& other) - { - for(int col=0 ; col=0 ; --i) - { - Scalar tmp = other.coeff(i,col); - Scalar l_ii(0); - typename Lhs::InnerIterator it(lhs, i); - while(it && it.index() -struct sparse_solve_triangular_selector -{ - typedef typename Rhs::Scalar Scalar; - static void run(const Lhs& lhs, Rhs& other) - { - for(int col=0 ; col -struct sparse_solve_triangular_selector -{ - typedef typename Rhs::Scalar Scalar; - static void run(const Lhs& lhs, Rhs& other) - { - for(int col=0 ; col=0; --i) - { - Scalar& tmp = other.coeffRef(i,col); - if (tmp!=Scalar(0)) // optimization when other is actually sparse - { - if(!(Mode & UnitDiag)) - { - // TODO replace this by a binary search. make sure the binary search is safe for partially sorted elements - typename Lhs::ReverseInnerIterator it(lhs, i); - while(it && it.index()!=i) - --it; - eigen_assert(it && it.index()==i); - other.coeffRef(i,col) /= it.value(); - } - typename Lhs::InnerIterator it(lhs, i); - for(; it && it.index() -template -void SparseTriangularView::solveInPlace(MatrixBase& other) const -{ - eigen_assert(m_matrix.cols() == m_matrix.rows() && m_matrix.cols() == other.rows()); - eigen_assert((!(Mode & ZeroDiag)) && bool(Mode & (Upper|Lower))); - - enum { copy = internal::traits::Flags & RowMajorBit }; - - typedef typename internal::conditional::type, OtherDerived&>::type OtherCopy; - OtherCopy otherCopy(other.derived()); - - internal::sparse_solve_triangular_selector::type, Mode>::run(m_matrix, otherCopy); - - if (copy) - other = otherCopy; -} - -template -template -typename internal::plain_matrix_type_column_major::type -SparseTriangularView::solve(const MatrixBase& other) const -{ - typename internal::plain_matrix_type_column_major::type res(other); - solveInPlace(res); - return res; -} - -// pure sparse path - -namespace internal { - -template -struct sparse_solve_triangular_sparse_selector; - -// forward substitution, col-major -template -struct sparse_solve_triangular_sparse_selector -{ - typedef typename Rhs::Scalar Scalar; - typedef typename promote_index_type::Index, - typename traits::Index>::type Index; - static void run(const Lhs& lhs, Rhs& other) - { - const bool IsLower = (UpLo==Lower); - AmbiVector tempVector(other.rows()*2); - tempVector.setBounds(0,other.rows()); - - Rhs res(other.rows(), other.cols()); - res.reserve(other.nonZeros()); - - for(int col=0 ; col=0; - i+=IsLower?1:-1) - { - tempVector.restart(); - Scalar& ci = tempVector.coeffRef(i); - if (ci!=Scalar(0)) - { - // find - typename Lhs::InnerIterator it(lhs, i); - if(!(Mode & UnitDiag)) - { - if (IsLower) - { - eigen_assert(it.index()==i); - ci /= it.value(); - } - else - ci /= lhs.coeff(i,i); - } - tempVector.restart(); - if (IsLower) - { - if (it.index()==i) - ++it; - for(; it; ++it) - tempVector.coeffRef(it.index()) -= ci * it.value(); - } - else - { - for(; it && it.index()::Iterator it(tempVector/*,1e-12*/); it; ++it) - { - ++ count; -// std::cerr << "fill " << it.index() << ", " << col << "\n"; -// std::cout << it.value() << " "; - // FIXME use insertBack - res.insert(it.index(), col) = it.value(); - } -// std::cout << "tempVector.nonZeros() == " << int(count) << " / " << (other.rows()) << "\n"; - } - res.finalize(); - other = res.markAsRValue(); - } -}; - -} // end namespace internal - -template -template -void SparseTriangularView::solveInPlace(SparseMatrixBase& other) const -{ - eigen_assert(m_matrix.cols() == m_matrix.rows() && m_matrix.cols() == other.rows()); - eigen_assert( (!(Mode & ZeroDiag)) && bool(Mode & (Upper|Lower))); - -// enum { copy = internal::traits::Flags & RowMajorBit }; - -// typedef typename internal::conditional::type, OtherDerived&>::type OtherCopy; -// OtherCopy otherCopy(other.derived()); - - internal::sparse_solve_triangular_sparse_selector::run(m_matrix, other.derived()); - -// if (copy) -// other = otherCopy; -} - -#ifdef EIGEN2_SUPPORT - -// deprecated stuff: - -/** \deprecated */ -template -template -void SparseMatrixBase::solveTriangularInPlace(MatrixBase& other) const -{ - this->template triangular().solveInPlace(other); -} - -/** \deprecated */ -template -template -typename internal::plain_matrix_type_column_major::type -SparseMatrixBase::solveTriangular(const MatrixBase& other) const -{ - typename internal::plain_matrix_type_column_major::type res(other); - derived().solveTriangularInPlace(res); - return res; -} -#endif // EIGEN2_SUPPORT - -} // end namespace Eigen - -#endif // EIGEN_SPARSETRIANGULARSOLVER_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU.h b/thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU.h deleted file mode 100644 index bdc4f193..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU.h +++ /dev/null @@ -1,806 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2012 Désiré Nuentsa-Wakam -// Copyright (C) 2012 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - - -#ifndef EIGEN_SPARSE_LU_H -#define EIGEN_SPARSE_LU_H - -namespace Eigen { - -template > class SparseLU; -template struct SparseLUMatrixLReturnType; -template struct SparseLUMatrixUReturnType; - -/** \ingroup SparseLU_Module - * \class SparseLU - * - * \brief Sparse supernodal LU factorization for general matrices - * - * This class implements the supernodal LU factorization for general matrices. - * It uses the main techniques from the sequential SuperLU package - * (http://crd-legacy.lbl.gov/~xiaoye/SuperLU/). It handles transparently real - * and complex arithmetics with single and double precision, depending on the - * scalar type of your input matrix. - * The code has been optimized to provide BLAS-3 operations during supernode-panel updates. - * It benefits directly from the built-in high-performant Eigen BLAS routines. - * Moreover, when the size of a supernode is very small, the BLAS calls are avoided to - * enable a better optimization from the compiler. For best performance, - * you should compile it with NDEBUG flag to avoid the numerous bounds checking on vectors. - * - * An important parameter of this class is the ordering method. It is used to reorder the columns - * (and eventually the rows) of the matrix to reduce the number of new elements that are created during - * numerical factorization. The cheapest method available is COLAMD. - * See \link OrderingMethods_Module the OrderingMethods module \endlink for the list of - * built-in and external ordering methods. - * - * Simple example with key steps - * \code - * VectorXd x(n), b(n); - * SparseMatrix A; - * SparseLU, COLAMDOrdering > solver; - * // fill A and b; - * // Compute the ordering permutation vector from the structural pattern of A - * solver.analyzePattern(A); - * // Compute the numerical factorization - * solver.factorize(A); - * //Use the factors to solve the linear system - * x = solver.solve(b); - * \endcode - * - * \warning The input matrix A should be in a \b compressed and \b column-major form. - * Otherwise an expensive copy will be made. You can call the inexpensive makeCompressed() to get a compressed matrix. - * - * \note Unlike the initial SuperLU implementation, there is no step to equilibrate the matrix. - * For badly scaled matrices, this step can be useful to reduce the pivoting during factorization. - * If this is the case for your matrices, you can try the basic scaling method at - * "unsupported/Eigen/src/IterativeSolvers/Scaling.h" - * - * \tparam _MatrixType The type of the sparse matrix. It must be a column-major SparseMatrix<> - * \tparam _OrderingType The ordering method to use, either AMD, COLAMD or METIS. Default is COLMAD - * - * - * \sa \ref TutorialSparseDirectSolvers - * \sa \ref OrderingMethods_Module - */ -template -class SparseLU : public internal::SparseLUImpl -{ - public: - typedef _MatrixType MatrixType; - typedef _OrderingType OrderingType; - typedef typename MatrixType::Scalar Scalar; - typedef typename MatrixType::RealScalar RealScalar; - typedef typename MatrixType::Index Index; - typedef SparseMatrix NCMatrix; - typedef internal::MappedSuperNodalMatrix SCMatrix; - typedef Matrix ScalarVector; - typedef Matrix IndexVector; - typedef PermutationMatrix PermutationType; - typedef internal::SparseLUImpl Base; - - public: - SparseLU():m_isInitialized(true),m_lastError(""),m_Ustore(0,0,0,0,0,0),m_symmetricmode(false),m_diagpivotthresh(1.0),m_detPermR(1) - { - initperfvalues(); - } - SparseLU(const MatrixType& matrix):m_isInitialized(true),m_lastError(""),m_Ustore(0,0,0,0,0,0),m_symmetricmode(false),m_diagpivotthresh(1.0),m_detPermR(1) - { - initperfvalues(); - compute(matrix); - } - - ~SparseLU() - { - // Free all explicit dynamic pointers - } - - void analyzePattern (const MatrixType& matrix); - void factorize (const MatrixType& matrix); - void simplicialfactorize(const MatrixType& matrix); - - /** - * Compute the symbolic and numeric factorization of the input sparse matrix. - * The input matrix should be in column-major storage. - */ - void compute (const MatrixType& matrix) - { - // Analyze - analyzePattern(matrix); - //Factorize - factorize(matrix); - } - - inline Index rows() const { return m_mat.rows(); } - inline Index cols() const { return m_mat.cols(); } - /** Indicate that the pattern of the input matrix is symmetric */ - void isSymmetric(bool sym) - { - m_symmetricmode = sym; - } - - /** \returns an expression of the matrix L, internally stored as supernodes - * The only operation available with this expression is the triangular solve - * \code - * y = b; matrixL().solveInPlace(y); - * \endcode - */ - SparseLUMatrixLReturnType matrixL() const - { - return SparseLUMatrixLReturnType(m_Lstore); - } - /** \returns an expression of the matrix U, - * The only operation available with this expression is the triangular solve - * \code - * y = b; matrixU().solveInPlace(y); - * \endcode - */ - SparseLUMatrixUReturnType > matrixU() const - { - return SparseLUMatrixUReturnType >(m_Lstore, m_Ustore); - } - - /** - * \returns a reference to the row matrix permutation \f$ P_r \f$ such that \f$P_r A P_c^T = L U\f$ - * \sa colsPermutation() - */ - inline const PermutationType& rowsPermutation() const - { - return m_perm_r; - } - /** - * \returns a reference to the column matrix permutation\f$ P_c^T \f$ such that \f$P_r A P_c^T = L U\f$ - * \sa rowsPermutation() - */ - inline const PermutationType& colsPermutation() const - { - return m_perm_c; - } - /** Set the threshold used for a diagonal entry to be an acceptable pivot. */ - void setPivotThreshold(const RealScalar& thresh) - { - m_diagpivotthresh = thresh; - } - - /** \returns the solution X of \f$ A X = B \f$ using the current decomposition of A. - * - * \warning the destination matrix X in X = this->solve(B) must be colmun-major. - * - * \sa compute() - */ - template - inline const internal::solve_retval solve(const MatrixBase& B) const - { - eigen_assert(m_factorizationIsOk && "SparseLU is not initialized."); - eigen_assert(rows()==B.rows() - && "SparseLU::solve(): invalid number of rows of the right hand side matrix B"); - return internal::solve_retval(*this, B.derived()); - } - - /** \returns the solution X of \f$ A X = B \f$ using the current decomposition of A. - * - * \sa compute() - */ - template - inline const internal::sparse_solve_retval solve(const SparseMatrixBase& B) const - { - eigen_assert(m_factorizationIsOk && "SparseLU is not initialized."); - eigen_assert(rows()==B.rows() - && "SparseLU::solve(): invalid number of rows of the right hand side matrix B"); - return internal::sparse_solve_retval(*this, B.derived()); - } - - /** \brief Reports whether previous computation was successful. - * - * \returns \c Success if computation was succesful, - * \c NumericalIssue if the LU factorization reports a problem, zero diagonal for instance - * \c InvalidInput if the input matrix is invalid - * - * \sa iparm() - */ - ComputationInfo info() const - { - eigen_assert(m_isInitialized && "Decomposition is not initialized."); - return m_info; - } - - /** - * \returns A string describing the type of error - */ - std::string lastErrorMessage() const - { - return m_lastError; - } - - template - bool _solve(const MatrixBase &B, MatrixBase &X_base) const - { - Dest& X(X_base.derived()); - eigen_assert(m_factorizationIsOk && "The matrix should be factorized first"); - EIGEN_STATIC_ASSERT((Dest::Flags&RowMajorBit)==0, - THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES); - - // Permute the right hand side to form X = Pr*B - // on return, X is overwritten by the computed solution - X.resize(B.rows(),B.cols()); - - // this ugly const_cast_derived() helps to detect aliasing when applying the permutations - for(Index j = 0; j < B.cols(); ++j) - X.col(j) = rowsPermutation() * B.const_cast_derived().col(j); - - //Forward substitution with L - this->matrixL().solveInPlace(X); - this->matrixU().solveInPlace(X); - - // Permute back the solution - for (Index j = 0; j < B.cols(); ++j) - X.col(j) = colsPermutation().inverse() * X.col(j); - - return true; - } - - /** - * \returns the absolute value of the determinant of the matrix of which - * *this is the QR decomposition. - * - * \warning a determinant can be very big or small, so for matrices - * of large enough dimension, there is a risk of overflow/underflow. - * One way to work around that is to use logAbsDeterminant() instead. - * - * \sa logAbsDeterminant(), signDeterminant() - */ - Scalar absDeterminant() - { - eigen_assert(m_factorizationIsOk && "The matrix should be factorized first."); - // Initialize with the determinant of the row matrix - Scalar det = Scalar(1.); - // Note that the diagonal blocks of U are stored in supernodes, - // which are available in the L part :) - for (Index j = 0; j < this->cols(); ++j) - { - for (typename SCMatrix::InnerIterator it(m_Lstore, j); it; ++it) - { - if(it.index() == j) - { - using std::abs; - det *= abs(it.value()); - break; - } - } - } - return det; - } - - /** \returns the natural log of the absolute value of the determinant of the matrix - * of which **this is the QR decomposition - * - * \note This method is useful to work around the risk of overflow/underflow that's - * inherent to the determinant computation. - * - * \sa absDeterminant(), signDeterminant() - */ - Scalar logAbsDeterminant() const - { - eigen_assert(m_factorizationIsOk && "The matrix should be factorized first."); - Scalar det = Scalar(0.); - for (Index j = 0; j < this->cols(); ++j) - { - for (typename SCMatrix::InnerIterator it(m_Lstore, j); it; ++it) - { - if(it.row() < j) continue; - if(it.row() == j) - { - using std::log; using std::abs; - det += log(abs(it.value())); - break; - } - } - } - return det; - } - - /** \returns A number representing the sign of the determinant - * - * \sa absDeterminant(), logAbsDeterminant() - */ - Scalar signDeterminant() - { - eigen_assert(m_factorizationIsOk && "The matrix should be factorized first."); - // Initialize with the determinant of the row matrix - Index det = 1; - // Note that the diagonal blocks of U are stored in supernodes, - // which are available in the L part :) - for (Index j = 0; j < this->cols(); ++j) - { - for (typename SCMatrix::InnerIterator it(m_Lstore, j); it; ++it) - { - if(it.index() == j) - { - if(it.value()<0) - det = -det; - else if(it.value()==0) - return 0; - break; - } - } - } - return det * m_detPermR * m_detPermC; - } - - /** \returns The determinant of the matrix. - * - * \sa absDeterminant(), logAbsDeterminant() - */ - Scalar determinant() - { - eigen_assert(m_factorizationIsOk && "The matrix should be factorized first."); - // Initialize with the determinant of the row matrix - Scalar det = Scalar(1.); - // Note that the diagonal blocks of U are stored in supernodes, - // which are available in the L part :) - for (Index j = 0; j < this->cols(); ++j) - { - for (typename SCMatrix::InnerIterator it(m_Lstore, j); it; ++it) - { - if(it.index() == j) - { - det *= it.value(); - break; - } - } - } - return det * Scalar(m_detPermR * m_detPermC); - } - - protected: - // Functions - void initperfvalues() - { - m_perfv.panel_size = 16; - m_perfv.relax = 1; - m_perfv.maxsuper = 128; - m_perfv.rowblk = 16; - m_perfv.colblk = 8; - m_perfv.fillfactor = 20; - } - - // Variables - mutable ComputationInfo m_info; - bool m_isInitialized; - bool m_factorizationIsOk; - bool m_analysisIsOk; - std::string m_lastError; - NCMatrix m_mat; // The input (permuted ) matrix - SCMatrix m_Lstore; // The lower triangular matrix (supernodal) - MappedSparseMatrix m_Ustore; // The upper triangular matrix - PermutationType m_perm_c; // Column permutation - PermutationType m_perm_r ; // Row permutation - IndexVector m_etree; // Column elimination tree - - typename Base::GlobalLU_t m_glu; - - // SparseLU options - bool m_symmetricmode; - // values for performance - internal::perfvalues m_perfv; - RealScalar m_diagpivotthresh; // Specifies the threshold used for a diagonal entry to be an acceptable pivot - Index m_nnzL, m_nnzU; // Nonzeros in L and U factors - Index m_detPermR, m_detPermC; // Determinants of the permutation matrices - private: - // Disable copy constructor - SparseLU (const SparseLU& ); - -}; // End class SparseLU - - - -// Functions needed by the anaysis phase -/** - * Compute the column permutation to minimize the fill-in - * - * - Apply this permutation to the input matrix - - * - * - Compute the column elimination tree on the permuted matrix - * - * - Postorder the elimination tree and the column permutation - * - */ -template -void SparseLU::analyzePattern(const MatrixType& mat) -{ - - //TODO It is possible as in SuperLU to compute row and columns scaling vectors to equilibrate the matrix mat. - - OrderingType ord; - ord(mat,m_perm_c); - - // Apply the permutation to the column of the input matrix - //First copy the whole input matrix. - m_mat = mat; - if (m_perm_c.size()) { - m_mat.uncompress(); //NOTE: The effect of this command is only to create the InnerNonzeros pointers. FIXME : This vector is filled but not subsequently used. - //Then, permute only the column pointers - const Index * outerIndexPtr; - if (mat.isCompressed()) outerIndexPtr = mat.outerIndexPtr(); - else - { - Index *outerIndexPtr_t = new Index[mat.cols()+1]; - for(Index i = 0; i <= mat.cols(); i++) outerIndexPtr_t[i] = m_mat.outerIndexPtr()[i]; - outerIndexPtr = outerIndexPtr_t; - } - for (Index i = 0; i < mat.cols(); i++) - { - m_mat.outerIndexPtr()[m_perm_c.indices()(i)] = outerIndexPtr[i]; - m_mat.innerNonZeroPtr()[m_perm_c.indices()(i)] = outerIndexPtr[i+1] - outerIndexPtr[i]; - } - if(!mat.isCompressed()) delete[] outerIndexPtr; - } - // Compute the column elimination tree of the permuted matrix - IndexVector firstRowElt; - internal::coletree(m_mat, m_etree,firstRowElt); - - // In symmetric mode, do not do postorder here - if (!m_symmetricmode) { - IndexVector post, iwork; - // Post order etree - internal::treePostorder(m_mat.cols(), m_etree, post); - - - // Renumber etree in postorder - Index m = m_mat.cols(); - iwork.resize(m+1); - for (Index i = 0; i < m; ++i) iwork(post(i)) = post(m_etree(i)); - m_etree = iwork; - - // Postmultiply A*Pc by post, i.e reorder the matrix according to the postorder of the etree - PermutationType post_perm(m); - for (Index i = 0; i < m; i++) - post_perm.indices()(i) = post(i); - - // Combine the two permutations : postorder the permutation for future use - if(m_perm_c.size()) { - m_perm_c = post_perm * m_perm_c; - } - - } // end postordering - - m_analysisIsOk = true; -} - -// Functions needed by the numerical factorization phase - - -/** - * - Numerical factorization - * - Interleaved with the symbolic factorization - * On exit, info is - * - * = 0: successful factorization - * - * > 0: if info = i, and i is - * - * <= A->ncol: U(i,i) is exactly zero. The factorization has - * been completed, but the factor U is exactly singular, - * and division by zero will occur if it is used to solve a - * system of equations. - * - * > A->ncol: number of bytes allocated when memory allocation - * failure occurred, plus A->ncol. If lwork = -1, it is - * the estimated amount of space needed, plus A->ncol. - */ -template -void SparseLU::factorize(const MatrixType& matrix) -{ - using internal::emptyIdxLU; - eigen_assert(m_analysisIsOk && "analyzePattern() should be called first"); - eigen_assert((matrix.rows() == matrix.cols()) && "Only for squared matrices"); - - typedef typename IndexVector::Scalar Index; - - - // Apply the column permutation computed in analyzepattern() - // m_mat = matrix * m_perm_c.inverse(); - m_mat = matrix; - if (m_perm_c.size()) - { - m_mat.uncompress(); //NOTE: The effect of this command is only to create the InnerNonzeros pointers. - //Then, permute only the column pointers - const Index * outerIndexPtr; - if (matrix.isCompressed()) outerIndexPtr = matrix.outerIndexPtr(); - else - { - Index* outerIndexPtr_t = new Index[matrix.cols()+1]; - for(Index i = 0; i <= matrix.cols(); i++) outerIndexPtr_t[i] = m_mat.outerIndexPtr()[i]; - outerIndexPtr = outerIndexPtr_t; - } - for (Index i = 0; i < matrix.cols(); i++) - { - m_mat.outerIndexPtr()[m_perm_c.indices()(i)] = outerIndexPtr[i]; - m_mat.innerNonZeroPtr()[m_perm_c.indices()(i)] = outerIndexPtr[i+1] - outerIndexPtr[i]; - } - if(!matrix.isCompressed()) delete[] outerIndexPtr; - } - else - { //FIXME This should not be needed if the empty permutation is handled transparently - m_perm_c.resize(matrix.cols()); - for(Index i = 0; i < matrix.cols(); ++i) m_perm_c.indices()(i) = i; - } - - Index m = m_mat.rows(); - Index n = m_mat.cols(); - Index nnz = m_mat.nonZeros(); - Index maxpanel = m_perfv.panel_size * m; - // Allocate working storage common to the factor routines - Index lwork = 0; - Index info = Base::memInit(m, n, nnz, lwork, m_perfv.fillfactor, m_perfv.panel_size, m_glu); - if (info) - { - m_lastError = "UNABLE TO ALLOCATE WORKING MEMORY\n\n" ; - m_factorizationIsOk = false; - return ; - } - - // Set up pointers for integer working arrays - IndexVector segrep(m); segrep.setZero(); - IndexVector parent(m); parent.setZero(); - IndexVector xplore(m); xplore.setZero(); - IndexVector repfnz(maxpanel); - IndexVector panel_lsub(maxpanel); - IndexVector xprune(n); xprune.setZero(); - IndexVector marker(m*internal::LUNoMarker); marker.setZero(); - - repfnz.setConstant(-1); - panel_lsub.setConstant(-1); - - // Set up pointers for scalar working arrays - ScalarVector dense; - dense.setZero(maxpanel); - ScalarVector tempv; - tempv.setZero(internal::LUnumTempV(m, m_perfv.panel_size, m_perfv.maxsuper, /*m_perfv.rowblk*/m) ); - - // Compute the inverse of perm_c - PermutationType iperm_c(m_perm_c.inverse()); - - // Identify initial relaxed snodes - IndexVector relax_end(n); - if ( m_symmetricmode == true ) - Base::heap_relax_snode(n, m_etree, m_perfv.relax, marker, relax_end); - else - Base::relax_snode(n, m_etree, m_perfv.relax, marker, relax_end); - - - m_perm_r.resize(m); - m_perm_r.indices().setConstant(-1); - marker.setConstant(-1); - m_detPermR = 1; // Record the determinant of the row permutation - - m_glu.supno(0) = emptyIdxLU; m_glu.xsup.setConstant(0); - m_glu.xsup(0) = m_glu.xlsub(0) = m_glu.xusub(0) = m_glu.xlusup(0) = Index(0); - - // Work on one 'panel' at a time. A panel is one of the following : - // (a) a relaxed supernode at the bottom of the etree, or - // (b) panel_size contiguous columns, defined by the user - Index jcol; - IndexVector panel_histo(n); - Index pivrow; // Pivotal row number in the original row matrix - Index nseg1; // Number of segments in U-column above panel row jcol - Index nseg; // Number of segments in each U-column - Index irep; - Index i, k, jj; - for (jcol = 0; jcol < n; ) - { - // Adjust panel size so that a panel won't overlap with the next relaxed snode. - Index panel_size = m_perfv.panel_size; // upper bound on panel width - for (k = jcol + 1; k < (std::min)(jcol+panel_size, n); k++) - { - if (relax_end(k) != emptyIdxLU) - { - panel_size = k - jcol; - break; - } - } - if (k == n) - panel_size = n - jcol; - - // Symbolic outer factorization on a panel of columns - Base::panel_dfs(m, panel_size, jcol, m_mat, m_perm_r.indices(), nseg1, dense, panel_lsub, segrep, repfnz, xprune, marker, parent, xplore, m_glu); - - // Numeric sup-panel updates in topological order - Base::panel_bmod(m, panel_size, jcol, nseg1, dense, tempv, segrep, repfnz, m_glu); - - // Sparse LU within the panel, and below the panel diagonal - for ( jj = jcol; jj< jcol + panel_size; jj++) - { - k = (jj - jcol) * m; // Column index for w-wide arrays - - nseg = nseg1; // begin after all the panel segments - //Depth-first-search for the current column - VectorBlock panel_lsubk(panel_lsub, k, m); - VectorBlock repfnz_k(repfnz, k, m); - info = Base::column_dfs(m, jj, m_perm_r.indices(), m_perfv.maxsuper, nseg, panel_lsubk, segrep, repfnz_k, xprune, marker, parent, xplore, m_glu); - if ( info ) - { - m_lastError = "UNABLE TO EXPAND MEMORY IN COLUMN_DFS() "; - m_info = NumericalIssue; - m_factorizationIsOk = false; - return; - } - // Numeric updates to this column - VectorBlock dense_k(dense, k, m); - VectorBlock segrep_k(segrep, nseg1, m-nseg1); - info = Base::column_bmod(jj, (nseg - nseg1), dense_k, tempv, segrep_k, repfnz_k, jcol, m_glu); - if ( info ) - { - m_lastError = "UNABLE TO EXPAND MEMORY IN COLUMN_BMOD() "; - m_info = NumericalIssue; - m_factorizationIsOk = false; - return; - } - - // Copy the U-segments to ucol(*) - info = Base::copy_to_ucol(jj, nseg, segrep, repfnz_k ,m_perm_r.indices(), dense_k, m_glu); - if ( info ) - { - m_lastError = "UNABLE TO EXPAND MEMORY IN COPY_TO_UCOL() "; - m_info = NumericalIssue; - m_factorizationIsOk = false; - return; - } - - // Form the L-segment - info = Base::pivotL(jj, m_diagpivotthresh, m_perm_r.indices(), iperm_c.indices(), pivrow, m_glu); - if ( info ) - { - m_lastError = "THE MATRIX IS STRUCTURALLY SINGULAR ... ZERO COLUMN AT "; - std::ostringstream returnInfo; - returnInfo << info; - m_lastError += returnInfo.str(); - m_info = NumericalIssue; - m_factorizationIsOk = false; - return; - } - - // Update the determinant of the row permutation matrix - // FIXME: the following test is not correct, we should probably take iperm_c into account and pivrow is not directly the row pivot. - if (pivrow != jj) m_detPermR = -m_detPermR; - - // Prune columns (0:jj-1) using column jj - Base::pruneL(jj, m_perm_r.indices(), pivrow, nseg, segrep, repfnz_k, xprune, m_glu); - - // Reset repfnz for this column - for (i = 0; i < nseg; i++) - { - irep = segrep(i); - repfnz_k(irep) = emptyIdxLU; - } - } // end SparseLU within the panel - jcol += panel_size; // Move to the next panel - } // end for -- end elimination - - m_detPermR = m_perm_r.determinant(); - m_detPermC = m_perm_c.determinant(); - - // Count the number of nonzeros in factors - Base::countnz(n, m_nnzL, m_nnzU, m_glu); - // Apply permutation to the L subscripts - Base::fixupL(n, m_perm_r.indices(), m_glu); - - // Create supernode matrix L - m_Lstore.setInfos(m, n, m_glu.lusup, m_glu.xlusup, m_glu.lsub, m_glu.xlsub, m_glu.supno, m_glu.xsup); - // Create the column major upper sparse matrix U; - new (&m_Ustore) MappedSparseMatrix ( m, n, m_nnzU, m_glu.xusub.data(), m_glu.usub.data(), m_glu.ucol.data() ); - - m_info = Success; - m_factorizationIsOk = true; -} - -template -struct SparseLUMatrixLReturnType : internal::no_assignment_operator -{ - typedef typename MappedSupernodalType::Index Index; - typedef typename MappedSupernodalType::Scalar Scalar; - SparseLUMatrixLReturnType(const MappedSupernodalType& mapL) : m_mapL(mapL) - { } - Index rows() { return m_mapL.rows(); } - Index cols() { return m_mapL.cols(); } - template - void solveInPlace( MatrixBase &X) const - { - m_mapL.solveInPlace(X); - } - const MappedSupernodalType& m_mapL; -}; - -template -struct SparseLUMatrixUReturnType : internal::no_assignment_operator -{ - typedef typename MatrixLType::Index Index; - typedef typename MatrixLType::Scalar Scalar; - SparseLUMatrixUReturnType(const MatrixLType& mapL, const MatrixUType& mapU) - : m_mapL(mapL),m_mapU(mapU) - { } - Index rows() { return m_mapL.rows(); } - Index cols() { return m_mapL.cols(); } - - template void solveInPlace(MatrixBase &X) const - { - Index nrhs = X.cols(); - Index n = X.rows(); - // Backward solve with U - for (Index k = m_mapL.nsuper(); k >= 0; k--) - { - Index fsupc = m_mapL.supToCol()[k]; - Index lda = m_mapL.colIndexPtr()[fsupc+1] - m_mapL.colIndexPtr()[fsupc]; // leading dimension - Index nsupc = m_mapL.supToCol()[k+1] - fsupc; - Index luptr = m_mapL.colIndexPtr()[fsupc]; - - if (nsupc == 1) - { - for (Index j = 0; j < nrhs; j++) - { - X(fsupc, j) /= m_mapL.valuePtr()[luptr]; - } - } - else - { - Map, 0, OuterStride<> > A( &(m_mapL.valuePtr()[luptr]), nsupc, nsupc, OuterStride<>(lda) ); - Map< Matrix, 0, OuterStride<> > U (&(X(fsupc,0)), nsupc, nrhs, OuterStride<>(n) ); - U = A.template triangularView().solve(U); - } - - for (Index j = 0; j < nrhs; ++j) - { - for (Index jcol = fsupc; jcol < fsupc + nsupc; jcol++) - { - typename MatrixUType::InnerIterator it(m_mapU, jcol); - for ( ; it; ++it) - { - Index irow = it.index(); - X(irow, j) -= X(jcol, j) * it.value(); - } - } - } - } // End For U-solve - } - const MatrixLType& m_mapL; - const MatrixUType& m_mapU; -}; - -namespace internal { - -template -struct solve_retval, Rhs> - : solve_retval_base, Rhs> -{ - typedef SparseLU<_MatrixType,Derived> Dec; - EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs) - - template void evalTo(Dest& dst) const - { - dec()._solve(rhs(),dst); - } -}; - -template -struct sparse_solve_retval, Rhs> - : sparse_solve_retval_base, Rhs> -{ - typedef SparseLU<_MatrixType,Derived> Dec; - EIGEN_MAKE_SPARSE_SOLVE_HELPERS(Dec,Rhs) - - template void evalTo(Dest& dst) const - { - this->defaultEvalTo(dst); - } -}; -} // end namespace internal - -} // End namespace Eigen - -#endif diff --git a/thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLUImpl.h b/thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLUImpl.h deleted file mode 100644 index 99d651e4..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLUImpl.h +++ /dev/null @@ -1,66 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2012 Désiré Nuentsa-Wakam -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. -#ifndef SPARSELU_IMPL_H -#define SPARSELU_IMPL_H - -namespace Eigen { -namespace internal { - -/** \ingroup SparseLU_Module - * \class SparseLUImpl - * Base class for sparseLU - */ -template -class SparseLUImpl -{ - public: - typedef Matrix ScalarVector; - typedef Matrix ScalarMatrix; - typedef Map > MappedMatrixBlock; - typedef Matrix IndexVector; - typedef typename ScalarVector::RealScalar RealScalar; - typedef Ref > BlockScalarVector; - typedef Ref > BlockIndexVector; - typedef LU_GlobalLU_t GlobalLU_t; - typedef SparseMatrix MatrixType; - - protected: - template - Index expand(VectorType& vec, Index& length, Index nbElts, Index keep_prev, Index& num_expansions); - Index memInit(Index m, Index n, Index annz, Index lwork, Index fillratio, Index panel_size, GlobalLU_t& glu); - template - Index memXpand(VectorType& vec, Index& maxlen, Index nbElts, MemType memtype, Index& num_expansions); - void heap_relax_snode (const Index n, IndexVector& et, const Index relax_columns, IndexVector& descendants, IndexVector& relax_end); - void relax_snode (const Index n, IndexVector& et, const Index relax_columns, IndexVector& descendants, IndexVector& relax_end); - Index snode_dfs(const Index jcol, const Index kcol,const MatrixType& mat, IndexVector& xprune, IndexVector& marker, GlobalLU_t& glu); - Index snode_bmod (const Index jcol, const Index fsupc, ScalarVector& dense, GlobalLU_t& glu); - Index pivotL(const Index jcol, const RealScalar& diagpivotthresh, IndexVector& perm_r, IndexVector& iperm_c, Index& pivrow, GlobalLU_t& glu); - template - void dfs_kernel(const Index jj, IndexVector& perm_r, - Index& nseg, IndexVector& panel_lsub, IndexVector& segrep, - Ref repfnz_col, IndexVector& xprune, Ref marker, IndexVector& parent, - IndexVector& xplore, GlobalLU_t& glu, Index& nextl_col, Index krow, Traits& traits); - void panel_dfs(const Index m, const Index w, const Index jcol, MatrixType& A, IndexVector& perm_r, Index& nseg, ScalarVector& dense, IndexVector& panel_lsub, IndexVector& segrep, IndexVector& repfnz, IndexVector& xprune, IndexVector& marker, IndexVector& parent, IndexVector& xplore, GlobalLU_t& glu); - - void panel_bmod(const Index m, const Index w, const Index jcol, const Index nseg, ScalarVector& dense, ScalarVector& tempv, IndexVector& segrep, IndexVector& repfnz, GlobalLU_t& glu); - Index column_dfs(const Index m, const Index jcol, IndexVector& perm_r, Index maxsuper, Index& nseg, BlockIndexVector lsub_col, IndexVector& segrep, BlockIndexVector repfnz, IndexVector& xprune, IndexVector& marker, IndexVector& parent, IndexVector& xplore, GlobalLU_t& glu); - Index column_bmod(const Index jcol, const Index nseg, BlockScalarVector dense, ScalarVector& tempv, BlockIndexVector segrep, BlockIndexVector repfnz, Index fpanelc, GlobalLU_t& glu); - Index copy_to_ucol(const Index jcol, const Index nseg, IndexVector& segrep, BlockIndexVector repfnz ,IndexVector& perm_r, BlockScalarVector dense, GlobalLU_t& glu); - void pruneL(const Index jcol, const IndexVector& perm_r, const Index pivrow, const Index nseg, const IndexVector& segrep, BlockIndexVector repfnz, IndexVector& xprune, GlobalLU_t& glu); - void countnz(const Index n, Index& nnzL, Index& nnzU, GlobalLU_t& glu); - void fixupL(const Index n, const IndexVector& perm_r, GlobalLU_t& glu); - - template - friend struct column_dfs_traits; -}; - -} // end namespace internal -} // namespace Eigen - -#endif diff --git a/thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_Memory.h b/thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_Memory.h deleted file mode 100644 index 45f96d16..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_Memory.h +++ /dev/null @@ -1,227 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2012 Désiré Nuentsa-Wakam -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -/* - - * NOTE: This file is the modified version of [s,d,c,z]memory.c files in SuperLU - - * -- SuperLU routine (version 3.1) -- - * Univ. of California Berkeley, Xerox Palo Alto Research Center, - * and Lawrence Berkeley National Lab. - * August 1, 2008 - * - * Copyright (c) 1994 by Xerox Corporation. All rights reserved. - * - * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY - * EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK. - * - * Permission is hereby granted to use or copy this program for any - * purpose, provided the above notices are retained on all copies. - * Permission to modify the code and to distribute modified code is - * granted, provided the above notices are retained, and a notice that - * the code was modified is included with the above copyright notice. - */ - -#ifndef EIGEN_SPARSELU_MEMORY -#define EIGEN_SPARSELU_MEMORY - -namespace Eigen { -namespace internal { - -enum { LUNoMarker = 3 }; -enum {emptyIdxLU = -1}; -template -inline Index LUnumTempV(Index& m, Index& w, Index& t, Index& b) -{ - return (std::max)(m, (t+b)*w); -} - -template< typename Scalar, typename Index> -inline Index LUTempSpace(Index&m, Index& w) -{ - return (2*w + 4 + LUNoMarker) * m * sizeof(Index) + (w + 1) * m * sizeof(Scalar); -} - - - - -/** - * Expand the existing storage to accomodate more fill-ins - * \param vec Valid pointer to the vector to allocate or expand - * \param[in,out] length At input, contain the current length of the vector that is to be increased. At output, length of the newly allocated vector - * \param[in] nbElts Current number of elements in the factors - * \param keep_prev 1: use length and do not expand the vector; 0: compute new_len and expand - * \param[in,out] num_expansions Number of times the memory has been expanded - */ -template -template -Index SparseLUImpl::expand(VectorType& vec, Index& length, Index nbElts, Index keep_prev, Index& num_expansions) -{ - - float alpha = 1.5; // Ratio of the memory increase - Index new_len; // New size of the allocated memory - - if(num_expansions == 0 || keep_prev) - new_len = length ; // First time allocate requested - else - new_len = (std::max)(length+1,Index(alpha * length)); - - VectorType old_vec; // Temporary vector to hold the previous values - if (nbElts > 0 ) - old_vec = vec.segment(0,nbElts); - - //Allocate or expand the current vector -#ifdef EIGEN_EXCEPTIONS - try -#endif - { - vec.resize(new_len); - } -#ifdef EIGEN_EXCEPTIONS - catch(std::bad_alloc& ) -#else - if(!vec.size()) -#endif - { - if (!num_expansions) - { - // First time to allocate from LUMemInit() - // Let LUMemInit() deals with it. - return -1; - } - if (keep_prev) - { - // In this case, the memory length should not not be reduced - return new_len; - } - else - { - // Reduce the size and increase again - Index tries = 0; // Number of attempts - do - { - alpha = (alpha + 1)/2; - new_len = (std::max)(length+1,Index(alpha * length)); -#ifdef EIGEN_EXCEPTIONS - try -#endif - { - vec.resize(new_len); - } -#ifdef EIGEN_EXCEPTIONS - catch(std::bad_alloc& ) -#else - if (!vec.size()) -#endif - { - tries += 1; - if ( tries > 10) return new_len; - } - } while (!vec.size()); - } - } - //Copy the previous values to the newly allocated space - if (nbElts > 0) - vec.segment(0, nbElts) = old_vec; - - - length = new_len; - if(num_expansions) ++num_expansions; - return 0; -} - -/** - * \brief Allocate various working space for the numerical factorization phase. - * \param m number of rows of the input matrix - * \param n number of columns - * \param annz number of initial nonzeros in the matrix - * \param lwork if lwork=-1, this routine returns an estimated size of the required memory - * \param glu persistent data to facilitate multiple factors : will be deleted later ?? - * \param fillratio estimated ratio of fill in the factors - * \param panel_size Size of a panel - * \return an estimated size of the required memory if lwork = -1; otherwise, return the size of actually allocated memory when allocation failed, and 0 on success - * \note Unlike SuperLU, this routine does not support successive factorization with the same pattern and the same row permutation - */ -template -Index SparseLUImpl::memInit(Index m, Index n, Index annz, Index lwork, Index fillratio, Index panel_size, GlobalLU_t& glu) -{ - Index& num_expansions = glu.num_expansions; //No memory expansions so far - num_expansions = 0; - glu.nzumax = glu.nzlumax = (std::min)(fillratio * (annz+1) / n, m) * n; // estimated number of nonzeros in U - glu.nzlmax = (std::max)(Index(4), fillratio) * (annz+1) / 4; // estimated nnz in L factor - // Return the estimated size to the user if necessary - Index tempSpace; - tempSpace = (2*panel_size + 4 + LUNoMarker) * m * sizeof(Index) + (panel_size + 1) * m * sizeof(Scalar); - if (lwork == emptyIdxLU) - { - Index estimated_size; - estimated_size = (5 * n + 5) * sizeof(Index) + tempSpace - + (glu.nzlmax + glu.nzumax) * sizeof(Index) + (glu.nzlumax+glu.nzumax) * sizeof(Scalar) + n; - return estimated_size; - } - - // Setup the required space - - // First allocate Integer pointers for L\U factors - glu.xsup.resize(n+1); - glu.supno.resize(n+1); - glu.xlsub.resize(n+1); - glu.xlusup.resize(n+1); - glu.xusub.resize(n+1); - - // Reserve memory for L/U factors - do - { - if( (expand(glu.lusup, glu.nzlumax, 0, 0, num_expansions)<0) - || (expand(glu.ucol, glu.nzumax, 0, 0, num_expansions)<0) - || (expand (glu.lsub, glu.nzlmax, 0, 0, num_expansions)<0) - || (expand (glu.usub, glu.nzumax, 0, 1, num_expansions)<0) ) - { - //Reduce the estimated size and retry - glu.nzlumax /= 2; - glu.nzumax /= 2; - glu.nzlmax /= 2; - if (glu.nzlumax < annz ) return glu.nzlumax; - } - } while (!glu.lusup.size() || !glu.ucol.size() || !glu.lsub.size() || !glu.usub.size()); - - ++num_expansions; - return 0; - -} // end LuMemInit - -/** - * \brief Expand the existing storage - * \param vec vector to expand - * \param[in,out] maxlen On input, previous size of vec (Number of elements to copy ). on output, new size - * \param nbElts current number of elements in the vector. - * \param memtype Type of the element to expand - * \param num_expansions Number of expansions - * \return 0 on success, > 0 size of the memory allocated so far - */ -template -template -Index SparseLUImpl::memXpand(VectorType& vec, Index& maxlen, Index nbElts, MemType memtype, Index& num_expansions) -{ - Index failed_size; - if (memtype == USUB) - failed_size = this->expand(vec, maxlen, nbElts, 1, num_expansions); - else - failed_size = this->expand(vec, maxlen, nbElts, 0, num_expansions); - - if (failed_size) - return failed_size; - - return 0 ; -} - -} // end namespace internal - -} // end namespace Eigen -#endif // EIGEN_SPARSELU_MEMORY diff --git a/thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_Structs.h b/thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_Structs.h deleted file mode 100644 index 24d6bf17..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_Structs.h +++ /dev/null @@ -1,111 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2012 Désiré Nuentsa-Wakam -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -/* - * NOTE: This file comes from a partly modified version of files slu_[s,d,c,z]defs.h - * -- SuperLU routine (version 4.1) -- - * Univ. of California Berkeley, Xerox Palo Alto Research Center, - * and Lawrence Berkeley National Lab. - * November, 2010 - * - * Global data structures used in LU factorization - - * - * nsuper: #supernodes = nsuper + 1, numbered [0, nsuper]. - * (xsup,supno): supno[i] is the supernode no to which i belongs; - * xsup(s) points to the beginning of the s-th supernode. - * e.g. supno 0 1 2 2 3 3 3 4 4 4 4 4 (n=12) - * xsup 0 1 2 4 7 12 - * Note: dfs will be performed on supernode rep. relative to the new - * row pivoting ordering - * - * (xlsub,lsub): lsub[*] contains the compressed subscript of - * rectangular supernodes; xlsub[j] points to the starting - * location of the j-th column in lsub[*]. Note that xlsub - * is indexed by column. - * Storage: original row subscripts - * - * During the course of sparse LU factorization, we also use - * (xlsub,lsub) for the purpose of symmetric pruning. For each - * supernode {s,s+1,...,t=s+r} with first column s and last - * column t, the subscript set - * lsub[j], j=xlsub[s], .., xlsub[s+1]-1 - * is the structure of column s (i.e. structure of this supernode). - * It is used for the storage of numerical values. - * Furthermore, - * lsub[j], j=xlsub[t], .., xlsub[t+1]-1 - * is the structure of the last column t of this supernode. - * It is for the purpose of symmetric pruning. Therefore, the - * structural subscripts can be rearranged without making physical - * interchanges among the numerical values. - * - * However, if the supernode has only one column, then we - * only keep one set of subscripts. For any subscript interchange - * performed, similar interchange must be done on the numerical - * values. - * - * The last column structures (for pruning) will be removed - * after the numercial LU factorization phase. - * - * (xlusup,lusup): lusup[*] contains the numerical values of the - * rectangular supernodes; xlusup[j] points to the starting - * location of the j-th column in storage vector lusup[*] - * Note: xlusup is indexed by column. - * Each rectangular supernode is stored by column-major - * scheme, consistent with Fortran 2-dim array storage. - * - * (xusub,ucol,usub): ucol[*] stores the numerical values of - * U-columns outside the rectangular supernodes. The row - * subscript of nonzero ucol[k] is stored in usub[k]. - * xusub[i] points to the starting location of column i in ucol. - * Storage: new row subscripts; that is subscripts of PA. - */ - -#ifndef EIGEN_LU_STRUCTS -#define EIGEN_LU_STRUCTS -namespace Eigen { -namespace internal { - -typedef enum {LUSUP, UCOL, LSUB, USUB, LLVL, ULVL} MemType; - -template -struct LU_GlobalLU_t { - typedef typename IndexVector::Scalar Index; - IndexVector xsup; //First supernode column ... xsup(s) points to the beginning of the s-th supernode - IndexVector supno; // Supernode number corresponding to this column (column to supernode mapping) - ScalarVector lusup; // nonzero values of L ordered by columns - IndexVector lsub; // Compressed row indices of L rectangular supernodes. - IndexVector xlusup; // pointers to the beginning of each column in lusup - IndexVector xlsub; // pointers to the beginning of each column in lsub - Index nzlmax; // Current max size of lsub - Index nzlumax; // Current max size of lusup - ScalarVector ucol; // nonzero values of U ordered by columns - IndexVector usub; // row indices of U columns in ucol - IndexVector xusub; // Pointers to the beginning of each column of U in ucol - Index nzumax; // Current max size of ucol - Index n; // Number of columns in the matrix - Index num_expansions; -}; - -// Values to set for performance -template -struct perfvalues { - Index panel_size; // a panel consists of at most consecutive columns - Index relax; // To control degree of relaxing supernodes. If the number of nodes (columns) - // in a subtree of the elimination tree is less than relax, this subtree is considered - // as one supernode regardless of the row structures of those columns - Index maxsuper; // The maximum size for a supernode in complete LU - Index rowblk; // The minimum row dimension for 2-D blocking to be used; - Index colblk; // The minimum column dimension for 2-D blocking to be used; - Index fillfactor; // The estimated fills factors for L and U, compared with A -}; - -} // end namespace internal - -} // end namespace Eigen -#endif // EIGEN_LU_STRUCTS diff --git a/thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h b/thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h deleted file mode 100644 index 54a56940..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h +++ /dev/null @@ -1,298 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2012 Désiré Nuentsa-Wakam -// Copyright (C) 2012 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_SPARSELU_SUPERNODAL_MATRIX_H -#define EIGEN_SPARSELU_SUPERNODAL_MATRIX_H - -namespace Eigen { -namespace internal { - -/** \ingroup SparseLU_Module - * \brief a class to manipulate the L supernodal factor from the SparseLU factorization - * - * This class contain the data to easily store - * and manipulate the supernodes during the factorization and solution phase of Sparse LU. - * Only the lower triangular matrix has supernodes. - * - * NOTE : This class corresponds to the SCformat structure in SuperLU - * - */ -/* TODO - * InnerIterator as for sparsematrix - * SuperInnerIterator to iterate through all supernodes - * Function for triangular solve - */ -template -class MappedSuperNodalMatrix -{ - public: - typedef _Scalar Scalar; - typedef _Index Index; - typedef Matrix IndexVector; - typedef Matrix ScalarVector; - public: - MappedSuperNodalMatrix() - { - - } - MappedSuperNodalMatrix(Index m, Index n, ScalarVector& nzval, IndexVector& nzval_colptr, IndexVector& rowind, - IndexVector& rowind_colptr, IndexVector& col_to_sup, IndexVector& sup_to_col ) - { - setInfos(m, n, nzval, nzval_colptr, rowind, rowind_colptr, col_to_sup, sup_to_col); - } - - ~MappedSuperNodalMatrix() - { - - } - /** - * Set appropriate pointers for the lower triangular supernodal matrix - * These infos are available at the end of the numerical factorization - * FIXME This class will be modified such that it can be use in the course - * of the factorization. - */ - void setInfos(Index m, Index n, ScalarVector& nzval, IndexVector& nzval_colptr, IndexVector& rowind, - IndexVector& rowind_colptr, IndexVector& col_to_sup, IndexVector& sup_to_col ) - { - m_row = m; - m_col = n; - m_nzval = nzval.data(); - m_nzval_colptr = nzval_colptr.data(); - m_rowind = rowind.data(); - m_rowind_colptr = rowind_colptr.data(); - m_nsuper = col_to_sup(n); - m_col_to_sup = col_to_sup.data(); - m_sup_to_col = sup_to_col.data(); - } - - /** - * Number of rows - */ - Index rows() { return m_row; } - - /** - * Number of columns - */ - Index cols() { return m_col; } - - /** - * Return the array of nonzero values packed by column - * - * The size is nnz - */ - Scalar* valuePtr() { return m_nzval; } - - const Scalar* valuePtr() const - { - return m_nzval; - } - /** - * Return the pointers to the beginning of each column in \ref valuePtr() - */ - Index* colIndexPtr() - { - return m_nzval_colptr; - } - - const Index* colIndexPtr() const - { - return m_nzval_colptr; - } - - /** - * Return the array of compressed row indices of all supernodes - */ - Index* rowIndex() { return m_rowind; } - - const Index* rowIndex() const - { - return m_rowind; - } - - /** - * Return the location in \em rowvaluePtr() which starts each column - */ - Index* rowIndexPtr() { return m_rowind_colptr; } - - const Index* rowIndexPtr() const - { - return m_rowind_colptr; - } - - /** - * Return the array of column-to-supernode mapping - */ - Index* colToSup() { return m_col_to_sup; } - - const Index* colToSup() const - { - return m_col_to_sup; - } - /** - * Return the array of supernode-to-column mapping - */ - Index* supToCol() { return m_sup_to_col; } - - const Index* supToCol() const - { - return m_sup_to_col; - } - - /** - * Return the number of supernodes - */ - Index nsuper() const - { - return m_nsuper; - } - - class InnerIterator; - template - void solveInPlace( MatrixBase&X) const; - - - - - protected: - Index m_row; // Number of rows - Index m_col; // Number of columns - Index m_nsuper; // Number of supernodes - Scalar* m_nzval; //array of nonzero values packed by column - Index* m_nzval_colptr; //nzval_colptr[j] Stores the location in nzval[] which starts column j - Index* m_rowind; // Array of compressed row indices of rectangular supernodes - Index* m_rowind_colptr; //rowind_colptr[j] stores the location in rowind[] which starts column j - Index* m_col_to_sup; // col_to_sup[j] is the supernode number to which column j belongs - Index* m_sup_to_col; //sup_to_col[s] points to the starting column of the s-th supernode - - private : -}; - -/** - * \brief InnerIterator class to iterate over nonzero values of the current column in the supernodal matrix L - * - */ -template -class MappedSuperNodalMatrix::InnerIterator -{ - public: - InnerIterator(const MappedSuperNodalMatrix& mat, Index outer) - : m_matrix(mat), - m_outer(outer), - m_supno(mat.colToSup()[outer]), - m_idval(mat.colIndexPtr()[outer]), - m_startidval(m_idval), - m_endidval(mat.colIndexPtr()[outer+1]), - m_idrow(mat.rowIndexPtr()[mat.supToCol()[mat.colToSup()[outer]]]), - m_endidrow(mat.rowIndexPtr()[mat.supToCol()[mat.colToSup()[outer]]+1]) - {} - inline InnerIterator& operator++() - { - m_idval++; - m_idrow++; - return *this; - } - inline Scalar value() const { return m_matrix.valuePtr()[m_idval]; } - - inline Scalar& valueRef() { return const_cast(m_matrix.valuePtr()[m_idval]); } - - inline Index index() const { return m_matrix.rowIndex()[m_idrow]; } - inline Index row() const { return index(); } - inline Index col() const { return m_outer; } - - inline Index supIndex() const { return m_supno; } - - inline operator bool() const - { - return ( (m_idval < m_endidval) && (m_idval >= m_startidval) - && (m_idrow < m_endidrow) ); - } - - protected: - const MappedSuperNodalMatrix& m_matrix; // Supernodal lower triangular matrix - const Index m_outer; // Current column - const Index m_supno; // Current SuperNode number - Index m_idval; // Index to browse the values in the current column - const Index m_startidval; // Start of the column value - const Index m_endidval; // End of the column value - Index m_idrow; // Index to browse the row indices - Index m_endidrow; // End index of row indices of the current column -}; - -/** - * \brief Solve with the supernode triangular matrix - * - */ -template -template -void MappedSuperNodalMatrix::solveInPlace( MatrixBase&X) const -{ - Index n = X.rows(); - Index nrhs = X.cols(); - const Scalar * Lval = valuePtr(); // Nonzero values - Matrix work(n, nrhs); // working vector - work.setZero(); - for (Index k = 0; k <= nsuper(); k ++) - { - Index fsupc = supToCol()[k]; // First column of the current supernode - Index istart = rowIndexPtr()[fsupc]; // Pointer index to the subscript of the current column - Index nsupr = rowIndexPtr()[fsupc+1] - istart; // Number of rows in the current supernode - Index nsupc = supToCol()[k+1] - fsupc; // Number of columns in the current supernode - Index nrow = nsupr - nsupc; // Number of rows in the non-diagonal part of the supernode - Index irow; //Current index row - - if (nsupc == 1 ) - { - for (Index j = 0; j < nrhs; j++) - { - InnerIterator it(*this, fsupc); - ++it; // Skip the diagonal element - for (; it; ++it) - { - irow = it.row(); - X(irow, j) -= X(fsupc, j) * it.value(); - } - } - } - else - { - // The supernode has more than one column - Index luptr = colIndexPtr()[fsupc]; - Index lda = colIndexPtr()[fsupc+1] - luptr; - - // Triangular solve - Map, 0, OuterStride<> > A( &(Lval[luptr]), nsupc, nsupc, OuterStride<>(lda) ); - Map< Matrix, 0, OuterStride<> > U (&(X(fsupc,0)), nsupc, nrhs, OuterStride<>(n) ); - U = A.template triangularView().solve(U); - - // Matrix-vector product - new (&A) Map, 0, OuterStride<> > ( &(Lval[luptr+nsupc]), nrow, nsupc, OuterStride<>(lda) ); - work.block(0, 0, nrow, nrhs) = A * U; - - //Begin Scatter - for (Index j = 0; j < nrhs; j++) - { - Index iptr = istart + nsupc; - for (Index i = 0; i < nrow; i++) - { - irow = rowIndex()[iptr]; - X(irow, j) -= work(i, j); // Scatter operation - work(i, j) = Scalar(0); - iptr++; - } - } - } - } -} - -} // end namespace internal - -} // end namespace Eigen - -#endif // EIGEN_SPARSELU_MATRIX_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_Utils.h b/thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_Utils.h deleted file mode 100644 index 15352ac3..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_Utils.h +++ /dev/null @@ -1,80 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2012 Désiré Nuentsa-Wakam -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - - -#ifndef EIGEN_SPARSELU_UTILS_H -#define EIGEN_SPARSELU_UTILS_H - -namespace Eigen { -namespace internal { - -/** - * \brief Count Nonzero elements in the factors - */ -template -void SparseLUImpl::countnz(const Index n, Index& nnzL, Index& nnzU, GlobalLU_t& glu) -{ - nnzL = 0; - nnzU = (glu.xusub)(n); - Index nsuper = (glu.supno)(n); - Index jlen; - Index i, j, fsupc; - if (n <= 0 ) return; - // For each supernode - for (i = 0; i <= nsuper; i++) - { - fsupc = glu.xsup(i); - jlen = glu.xlsub(fsupc+1) - glu.xlsub(fsupc); - - for (j = fsupc; j < glu.xsup(i+1); j++) - { - nnzL += jlen; - nnzU += j - fsupc + 1; - jlen--; - } - } -} - -/** - * \brief Fix up the data storage lsub for L-subscripts. - * - * It removes the subscripts sets for structural pruning, - * and applies permutation to the remaining subscripts - * - */ -template -void SparseLUImpl::fixupL(const Index n, const IndexVector& perm_r, GlobalLU_t& glu) -{ - Index fsupc, i, j, k, jstart; - - Index nextl = 0; - Index nsuper = (glu.supno)(n); - - // For each supernode - for (i = 0; i <= nsuper; i++) - { - fsupc = glu.xsup(i); - jstart = glu.xlsub(fsupc); - glu.xlsub(fsupc) = nextl; - for (j = jstart; j < glu.xlsub(fsupc + 1); j++) - { - glu.lsub(nextl) = perm_r(glu.lsub(j)); // Now indexed into P*A - nextl++; - } - for (k = fsupc+1; k < glu.xsup(i+1); k++) - glu.xlsub(k) = nextl; // other columns in supernode i - } - - glu.xlsub(n) = nextl; -} - -} // end namespace internal - -} // end namespace Eigen -#endif // EIGEN_SPARSELU_UTILS_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_column_bmod.h b/thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_column_bmod.h deleted file mode 100644 index cacc7e98..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_column_bmod.h +++ /dev/null @@ -1,180 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2012 Désiré Nuentsa-Wakam -// Copyright (C) 2012 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -/* - - * NOTE: This file is the modified version of xcolumn_bmod.c file in SuperLU - - * -- SuperLU routine (version 3.0) -- - * Univ. of California Berkeley, Xerox Palo Alto Research Center, - * and Lawrence Berkeley National Lab. - * October 15, 2003 - * - * Copyright (c) 1994 by Xerox Corporation. All rights reserved. - * - * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY - * EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK. - * - * Permission is hereby granted to use or copy this program for any - * purpose, provided the above notices are retained on all copies. - * Permission to modify the code and to distribute modified code is - * granted, provided the above notices are retained, and a notice that - * the code was modified is included with the above copyright notice. - */ -#ifndef SPARSELU_COLUMN_BMOD_H -#define SPARSELU_COLUMN_BMOD_H - -namespace Eigen { - -namespace internal { -/** - * \brief Performs numeric block updates (sup-col) in topological order - * - * \param jcol current column to update - * \param nseg Number of segments in the U part - * \param dense Store the full representation of the column - * \param tempv working array - * \param segrep segment representative ... - * \param repfnz ??? First nonzero column in each row ??? ... - * \param fpanelc First column in the current panel - * \param glu Global LU data. - * \return 0 - successful return - * > 0 - number of bytes allocated when run out of space - * - */ -template -Index SparseLUImpl::column_bmod(const Index jcol, const Index nseg, BlockScalarVector dense, ScalarVector& tempv, BlockIndexVector segrep, BlockIndexVector repfnz, Index fpanelc, GlobalLU_t& glu) -{ - Index jsupno, k, ksub, krep, ksupno; - Index lptr, nrow, isub, irow, nextlu, new_next, ufirst; - Index fsupc, nsupc, nsupr, luptr, kfnz, no_zeros; - /* krep = representative of current k-th supernode - * fsupc = first supernodal column - * nsupc = number of columns in a supernode - * nsupr = number of rows in a supernode - * luptr = location of supernodal LU-block in storage - * kfnz = first nonz in the k-th supernodal segment - * no_zeros = no lf leading zeros in a supernodal U-segment - */ - - jsupno = glu.supno(jcol); - // For each nonzero supernode segment of U[*,j] in topological order - k = nseg - 1; - Index d_fsupc; // distance between the first column of the current panel and the - // first column of the current snode - Index fst_col; // First column within small LU update - Index segsize; - for (ksub = 0; ksub < nseg; ksub++) - { - krep = segrep(k); k--; - ksupno = glu.supno(krep); - if (jsupno != ksupno ) - { - // outside the rectangular supernode - fsupc = glu.xsup(ksupno); - fst_col = (std::max)(fsupc, fpanelc); - - // Distance from the current supernode to the current panel; - // d_fsupc = 0 if fsupc > fpanelc - d_fsupc = fst_col - fsupc; - - luptr = glu.xlusup(fst_col) + d_fsupc; - lptr = glu.xlsub(fsupc) + d_fsupc; - - kfnz = repfnz(krep); - kfnz = (std::max)(kfnz, fpanelc); - - segsize = krep - kfnz + 1; - nsupc = krep - fst_col + 1; - nsupr = glu.xlsub(fsupc+1) - glu.xlsub(fsupc); - nrow = nsupr - d_fsupc - nsupc; - Index lda = glu.xlusup(fst_col+1) - glu.xlusup(fst_col); - - - // Perform a triangular solver and block update, - // then scatter the result of sup-col update to dense - no_zeros = kfnz - fst_col; - if(segsize==1) - LU_kernel_bmod<1>::run(segsize, dense, tempv, glu.lusup, luptr, lda, nrow, glu.lsub, lptr, no_zeros); - else - LU_kernel_bmod::run(segsize, dense, tempv, glu.lusup, luptr, lda, nrow, glu.lsub, lptr, no_zeros); - } // end if jsupno - } // end for each segment - - // Process the supernodal portion of L\U[*,j] - nextlu = glu.xlusup(jcol); - fsupc = glu.xsup(jsupno); - - // copy the SPA dense into L\U[*,j] - Index mem; - new_next = nextlu + glu.xlsub(fsupc + 1) - glu.xlsub(fsupc); - Index offset = internal::first_multiple(new_next, internal::packet_traits::size) - new_next; - if(offset) - new_next += offset; - while (new_next > glu.nzlumax ) - { - mem = memXpand(glu.lusup, glu.nzlumax, nextlu, LUSUP, glu.num_expansions); - if (mem) return mem; - } - - for (isub = glu.xlsub(fsupc); isub < glu.xlsub(fsupc+1); isub++) - { - irow = glu.lsub(isub); - glu.lusup(nextlu) = dense(irow); - dense(irow) = Scalar(0.0); - ++nextlu; - } - - if(offset) - { - glu.lusup.segment(nextlu,offset).setZero(); - nextlu += offset; - } - glu.xlusup(jcol + 1) = nextlu; // close L\U(*,jcol); - - /* For more updates within the panel (also within the current supernode), - * should start from the first column of the panel, or the first column - * of the supernode, whichever is bigger. There are two cases: - * 1) fsupc < fpanelc, then fst_col <-- fpanelc - * 2) fsupc >= fpanelc, then fst_col <-- fsupc - */ - fst_col = (std::max)(fsupc, fpanelc); - - if (fst_col < jcol) - { - // Distance between the current supernode and the current panel - // d_fsupc = 0 if fsupc >= fpanelc - d_fsupc = fst_col - fsupc; - - lptr = glu.xlsub(fsupc) + d_fsupc; - luptr = glu.xlusup(fst_col) + d_fsupc; - nsupr = glu.xlsub(fsupc+1) - glu.xlsub(fsupc); // leading dimension - nsupc = jcol - fst_col; // excluding jcol - nrow = nsupr - d_fsupc - nsupc; - - // points to the beginning of jcol in snode L\U(jsupno) - ufirst = glu.xlusup(jcol) + d_fsupc; - Index lda = glu.xlusup(jcol+1) - glu.xlusup(jcol); - MappedMatrixBlock A( &(glu.lusup.data()[luptr]), nsupc, nsupc, OuterStride<>(lda) ); - VectorBlock u(glu.lusup, ufirst, nsupc); - u = A.template triangularView().solve(u); - - new (&A) MappedMatrixBlock ( &(glu.lusup.data()[luptr+nsupc]), nrow, nsupc, OuterStride<>(lda) ); - VectorBlock l(glu.lusup, ufirst+nsupc, nrow); - l.noalias() -= A * u; - - } // End if fst_col - return 0; -} - -} // end namespace internal -} // end namespace Eigen - -#endif // SPARSELU_COLUMN_BMOD_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_column_dfs.h b/thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_column_dfs.h deleted file mode 100644 index 4c04b0e4..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_column_dfs.h +++ /dev/null @@ -1,177 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2012 Désiré Nuentsa-Wakam -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -/* - - * NOTE: This file is the modified version of [s,d,c,z]column_dfs.c file in SuperLU - - * -- SuperLU routine (version 2.0) -- - * Univ. of California Berkeley, Xerox Palo Alto Research Center, - * and Lawrence Berkeley National Lab. - * November 15, 1997 - * - * Copyright (c) 1994 by Xerox Corporation. All rights reserved. - * - * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY - * EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK. - * - * Permission is hereby granted to use or copy this program for any - * purpose, provided the above notices are retained on all copies. - * Permission to modify the code and to distribute modified code is - * granted, provided the above notices are retained, and a notice that - * the code was modified is included with the above copyright notice. - */ -#ifndef SPARSELU_COLUMN_DFS_H -#define SPARSELU_COLUMN_DFS_H - -template class SparseLUImpl; -namespace Eigen { - -namespace internal { - -template -struct column_dfs_traits : no_assignment_operator -{ - typedef typename ScalarVector::Scalar Scalar; - typedef typename IndexVector::Scalar Index; - column_dfs_traits(Index jcol, Index& jsuper, typename SparseLUImpl::GlobalLU_t& glu, SparseLUImpl& luImpl) - : m_jcol(jcol), m_jsuper_ref(jsuper), m_glu(glu), m_luImpl(luImpl) - {} - bool update_segrep(Index /*krep*/, Index /*jj*/) - { - return true; - } - void mem_expand(IndexVector& lsub, Index& nextl, Index chmark) - { - if (nextl >= m_glu.nzlmax) - m_luImpl.memXpand(lsub, m_glu.nzlmax, nextl, LSUB, m_glu.num_expansions); - if (chmark != (m_jcol-1)) m_jsuper_ref = emptyIdxLU; - } - enum { ExpandMem = true }; - - Index m_jcol; - Index& m_jsuper_ref; - typename SparseLUImpl::GlobalLU_t& m_glu; - SparseLUImpl& m_luImpl; -}; - - -/** - * \brief Performs a symbolic factorization on column jcol and decide the supernode boundary - * - * A supernode representative is the last column of a supernode. - * The nonzeros in U[*,j] are segments that end at supernodes representatives. - * The routine returns a list of the supernodal representatives - * in topological order of the dfs that generates them. - * The location of the first nonzero in each supernodal segment - * (supernodal entry location) is also returned. - * - * \param m number of rows in the matrix - * \param jcol Current column - * \param perm_r Row permutation - * \param maxsuper Maximum number of column allowed in a supernode - * \param [in,out] nseg Number of segments in current U[*,j] - new segments appended - * \param lsub_col defines the rhs vector to start the dfs - * \param [in,out] segrep Segment representatives - new segments appended - * \param repfnz First nonzero location in each row - * \param xprune - * \param marker marker[i] == jj, if i was visited during dfs of current column jj; - * \param parent - * \param xplore working array - * \param glu global LU data - * \return 0 success - * > 0 number of bytes allocated when run out of space - * - */ -template -Index SparseLUImpl::column_dfs(const Index m, const Index jcol, IndexVector& perm_r, Index maxsuper, Index& nseg, BlockIndexVector lsub_col, IndexVector& segrep, BlockIndexVector repfnz, IndexVector& xprune, IndexVector& marker, IndexVector& parent, IndexVector& xplore, GlobalLU_t& glu) -{ - - Index jsuper = glu.supno(jcol); - Index nextl = glu.xlsub(jcol); - VectorBlock marker2(marker, 2*m, m); - - - column_dfs_traits traits(jcol, jsuper, glu, *this); - - // For each nonzero in A(*,jcol) do dfs - for (Index k = 0; ((k < m) ? lsub_col[k] != emptyIdxLU : false) ; k++) - { - Index krow = lsub_col(k); - lsub_col(k) = emptyIdxLU; - Index kmark = marker2(krow); - - // krow was visited before, go to the next nonz; - if (kmark == jcol) continue; - - dfs_kernel(jcol, perm_r, nseg, glu.lsub, segrep, repfnz, xprune, marker2, parent, - xplore, glu, nextl, krow, traits); - } // for each nonzero ... - - Index fsupc, jptr, jm1ptr, ito, ifrom, istop; - Index nsuper = glu.supno(jcol); - Index jcolp1 = jcol + 1; - Index jcolm1 = jcol - 1; - - // check to see if j belongs in the same supernode as j-1 - if ( jcol == 0 ) - { // Do nothing for column 0 - nsuper = glu.supno(0) = 0 ; - } - else - { - fsupc = glu.xsup(nsuper); - jptr = glu.xlsub(jcol); // Not yet compressed - jm1ptr = glu.xlsub(jcolm1); - - // Use supernodes of type T2 : see SuperLU paper - if ( (nextl-jptr != jptr-jm1ptr-1) ) jsuper = emptyIdxLU; - - // Make sure the number of columns in a supernode doesn't - // exceed threshold - if ( (jcol - fsupc) >= maxsuper) jsuper = emptyIdxLU; - - /* If jcol starts a new supernode, reclaim storage space in - * glu.lsub from previous supernode. Note we only store - * the subscript set of the first and last columns of - * a supernode. (first for num values, last for pruning) - */ - if (jsuper == emptyIdxLU) - { // starts a new supernode - if ( (fsupc < jcolm1-1) ) - { // >= 3 columns in nsuper - ito = glu.xlsub(fsupc+1); - glu.xlsub(jcolm1) = ito; - istop = ito + jptr - jm1ptr; - xprune(jcolm1) = istop; // intialize xprune(jcol-1) - glu.xlsub(jcol) = istop; - - for (ifrom = jm1ptr; ifrom < nextl; ++ifrom, ++ito) - glu.lsub(ito) = glu.lsub(ifrom); - nextl = ito; // = istop + length(jcol) - } - nsuper++; - glu.supno(jcol) = nsuper; - } // if a new supernode - } // end else: jcol > 0 - - // Tidy up the pointers before exit - glu.xsup(nsuper+1) = jcolp1; - glu.supno(jcolp1) = nsuper; - xprune(jcol) = nextl; // Intialize upper bound for pruning - glu.xlsub(jcolp1) = nextl; - - return 0; -} - -} // end namespace internal - -} // end namespace Eigen - -#endif diff --git a/thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_copy_to_ucol.h b/thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_copy_to_ucol.h deleted file mode 100644 index 170610d9..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_copy_to_ucol.h +++ /dev/null @@ -1,106 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2012 Désiré Nuentsa-Wakam -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. -/* - - * NOTE: This file is the modified version of [s,d,c,z]copy_to_ucol.c file in SuperLU - - * -- SuperLU routine (version 2.0) -- - * Univ. of California Berkeley, Xerox Palo Alto Research Center, - * and Lawrence Berkeley National Lab. - * November 15, 1997 - * - * Copyright (c) 1994 by Xerox Corporation. All rights reserved. - * - * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY - * EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK. - * - * Permission is hereby granted to use or copy this program for any - * purpose, provided the above notices are retained on all copies. - * Permission to modify the code and to distribute modified code is - * granted, provided the above notices are retained, and a notice that - * the code was modified is included with the above copyright notice. - */ -#ifndef SPARSELU_COPY_TO_UCOL_H -#define SPARSELU_COPY_TO_UCOL_H - -namespace Eigen { -namespace internal { - -/** - * \brief Performs numeric block updates (sup-col) in topological order - * - * \param jcol current column to update - * \param nseg Number of segments in the U part - * \param segrep segment representative ... - * \param repfnz First nonzero column in each row ... - * \param perm_r Row permutation - * \param dense Store the full representation of the column - * \param glu Global LU data. - * \return 0 - successful return - * > 0 - number of bytes allocated when run out of space - * - */ -template -Index SparseLUImpl::copy_to_ucol(const Index jcol, const Index nseg, IndexVector& segrep, BlockIndexVector repfnz ,IndexVector& perm_r, BlockScalarVector dense, GlobalLU_t& glu) -{ - Index ksub, krep, ksupno; - - Index jsupno = glu.supno(jcol); - - // For each nonzero supernode segment of U[*,j] in topological order - Index k = nseg - 1, i; - Index nextu = glu.xusub(jcol); - Index kfnz, isub, segsize; - Index new_next,irow; - Index fsupc, mem; - for (ksub = 0; ksub < nseg; ksub++) - { - krep = segrep(k); k--; - ksupno = glu.supno(krep); - if (jsupno != ksupno ) // should go into ucol(); - { - kfnz = repfnz(krep); - if (kfnz != emptyIdxLU) - { // Nonzero U-segment - fsupc = glu.xsup(ksupno); - isub = glu.xlsub(fsupc) + kfnz - fsupc; - segsize = krep - kfnz + 1; - new_next = nextu + segsize; - while (new_next > glu.nzumax) - { - mem = memXpand(glu.ucol, glu.nzumax, nextu, UCOL, glu.num_expansions); - if (mem) return mem; - mem = memXpand(glu.usub, glu.nzumax, nextu, USUB, glu.num_expansions); - if (mem) return mem; - - } - - for (i = 0; i < segsize; i++) - { - irow = glu.lsub(isub); - glu.usub(nextu) = perm_r(irow); // Unlike the L part, the U part is stored in its final order - glu.ucol(nextu) = dense(irow); - dense(irow) = Scalar(0.0); - nextu++; - isub++; - } - - } // end nonzero U-segment - - } // end if jsupno - - } // end for each segment - glu.xusub(jcol + 1) = nextu; // close U(*,jcol) - return 0; -} - -} // namespace internal -} // end namespace Eigen - -#endif // SPARSELU_COPY_TO_UCOL_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_gemm_kernel.h b/thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_gemm_kernel.h deleted file mode 100644 index 9e4e3e72..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_gemm_kernel.h +++ /dev/null @@ -1,279 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2012 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_SPARSELU_GEMM_KERNEL_H -#define EIGEN_SPARSELU_GEMM_KERNEL_H - -namespace Eigen { - -namespace internal { - - -/** \internal - * A general matrix-matrix product kernel optimized for the SparseLU factorization. - * - A, B, and C must be column major - * - lda and ldc must be multiples of the respective packet size - * - C must have the same alignment as A - */ -template -EIGEN_DONT_INLINE -void sparselu_gemm(Index m, Index n, Index d, const Scalar* A, Index lda, const Scalar* B, Index ldb, Scalar* C, Index ldc) -{ - using namespace Eigen::internal; - - typedef typename packet_traits::type Packet; - enum { - NumberOfRegisters = EIGEN_ARCH_DEFAULT_NUMBER_OF_REGISTERS, - PacketSize = packet_traits::size, - PM = 8, // peeling in M - RN = 2, // register blocking - RK = NumberOfRegisters>=16 ? 4 : 2, // register blocking - BM = 4096/sizeof(Scalar), // number of rows of A-C per chunk - SM = PM*PacketSize // step along M - }; - Index d_end = (d/RK)*RK; // number of columns of A (rows of B) suitable for full register blocking - Index n_end = (n/RN)*RN; // number of columns of B-C suitable for processing RN columns at once - Index i0 = internal::first_aligned(A,m); - - eigen_internal_assert(((lda%PacketSize)==0) && ((ldc%PacketSize)==0) && (i0==internal::first_aligned(C,m))); - - // handle the non aligned rows of A and C without any optimization: - for(Index i=0; i(BM, m-ib); // actual number of rows - Index actual_b_end1 = (actual_b/SM)*SM; // actual number of rows suitable for peeling - Index actual_b_end2 = (actual_b/PacketSize)*PacketSize; // actual number of rows suitable for vectorization - - // Let's process two columns of B-C at once - for(Index j=0; j(Bc0[0]); - b10 = pset1(Bc0[1]); - if(RK==4) b20 = pset1(Bc0[2]); - if(RK==4) b30 = pset1(Bc0[3]); - b01 = pset1(Bc1[0]); - b11 = pset1(Bc1[1]); - if(RK==4) b21 = pset1(Bc1[2]); - if(RK==4) b31 = pset1(Bc1[3]); - - Packet a0, a1, a2, a3, c0, c1, t0, t1; - - const Scalar* A0 = A+ib+(k+0)*lda; - const Scalar* A1 = A+ib+(k+1)*lda; - const Scalar* A2 = A+ib+(k+2)*lda; - const Scalar* A3 = A+ib+(k+3)*lda; - - Scalar* C0 = C+ib+(j+0)*ldc; - Scalar* C1 = C+ib+(j+1)*ldc; - - a0 = pload(A0); - a1 = pload(A1); - if(RK==4) - { - a2 = pload(A2); - a3 = pload(A3); - } - else - { - // workaround "may be used uninitialized in this function" warning - a2 = a3 = a0; - } - -#define KMADD(c, a, b, tmp) {tmp = b; tmp = pmul(a,tmp); c = padd(c,tmp);} -#define WORK(I) \ - c0 = pload(C0+i+(I)*PacketSize); \ - c1 = pload(C1+i+(I)*PacketSize); \ - KMADD(c0, a0, b00, t0) \ - KMADD(c1, a0, b01, t1) \ - a0 = pload(A0+i+(I+1)*PacketSize); \ - KMADD(c0, a1, b10, t0) \ - KMADD(c1, a1, b11, t1) \ - a1 = pload(A1+i+(I+1)*PacketSize); \ - if(RK==4) KMADD(c0, a2, b20, t0) \ - if(RK==4) KMADD(c1, a2, b21, t1) \ - if(RK==4) a2 = pload(A2+i+(I+1)*PacketSize); \ - if(RK==4) KMADD(c0, a3, b30, t0) \ - if(RK==4) KMADD(c1, a3, b31, t1) \ - if(RK==4) a3 = pload(A3+i+(I+1)*PacketSize); \ - pstore(C0+i+(I)*PacketSize, c0); \ - pstore(C1+i+(I)*PacketSize, c1) - - // process rows of A' - C' with aggressive vectorization and peeling - for(Index i=0; i0) - { - const Scalar* Bc0 = B+(n-1)*ldb; - - for(Index k=0; k(Bc0[0]); - b10 = pset1(Bc0[1]); - if(RK==4) b20 = pset1(Bc0[2]); - if(RK==4) b30 = pset1(Bc0[3]); - - Packet a0, a1, a2, a3, c0, t0/*, t1*/; - - const Scalar* A0 = A+ib+(k+0)*lda; - const Scalar* A1 = A+ib+(k+1)*lda; - const Scalar* A2 = A+ib+(k+2)*lda; - const Scalar* A3 = A+ib+(k+3)*lda; - - Scalar* C0 = C+ib+(n_end)*ldc; - - a0 = pload(A0); - a1 = pload(A1); - if(RK==4) - { - a2 = pload(A2); - a3 = pload(A3); - } - else - { - // workaround "may be used uninitialized in this function" warning - a2 = a3 = a0; - } - -#define WORK(I) \ - c0 = pload(C0+i+(I)*PacketSize); \ - KMADD(c0, a0, b00, t0) \ - a0 = pload(A0+i+(I+1)*PacketSize); \ - KMADD(c0, a1, b10, t0) \ - a1 = pload(A1+i+(I+1)*PacketSize); \ - if(RK==4) KMADD(c0, a2, b20, t0) \ - if(RK==4) a2 = pload(A2+i+(I+1)*PacketSize); \ - if(RK==4) KMADD(c0, a3, b30, t0) \ - if(RK==4) a3 = pload(A3+i+(I+1)*PacketSize); \ - pstore(C0+i+(I)*PacketSize, c0); - - // agressive vectorization and peeling - for(Index i=0; i0) - { - for(Index j=0; j1 ? Aligned : 0 - }; - typedef Map, Alignment > MapVector; - typedef Map, Alignment > ConstMapVector; - if(rd==1) MapVector(C+j*ldc+ib,actual_b) += B[0+d_end+j*ldb] * ConstMapVector(A+(d_end+0)*lda+ib, actual_b); - - else if(rd==2) MapVector(C+j*ldc+ib,actual_b) += B[0+d_end+j*ldb] * ConstMapVector(A+(d_end+0)*lda+ib, actual_b) - + B[1+d_end+j*ldb] * ConstMapVector(A+(d_end+1)*lda+ib, actual_b); - - else MapVector(C+j*ldc+ib,actual_b) += B[0+d_end+j*ldb] * ConstMapVector(A+(d_end+0)*lda+ib, actual_b) - + B[1+d_end+j*ldb] * ConstMapVector(A+(d_end+1)*lda+ib, actual_b) - + B[2+d_end+j*ldb] * ConstMapVector(A+(d_end+2)*lda+ib, actual_b); - } - } - - } // blocking on the rows of A and C -} -#undef KMADD - -} // namespace internal - -} // namespace Eigen - -#endif // EIGEN_SPARSELU_GEMM_KERNEL_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_heap_relax_snode.h b/thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_heap_relax_snode.h deleted file mode 100644 index 7a4e4305..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_heap_relax_snode.h +++ /dev/null @@ -1,127 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2012 Désiré Nuentsa-Wakam -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -/* This file is a modified version of heap_relax_snode.c file in SuperLU - * -- SuperLU routine (version 3.0) -- - * Univ. of California Berkeley, Xerox Palo Alto Research Center, - * and Lawrence Berkeley National Lab. - * October 15, 2003 - * - * Copyright (c) 1994 by Xerox Corporation. All rights reserved. - * - * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY - * EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK. - * - * Permission is hereby granted to use or copy this program for any - * purpose, provided the above notices are retained on all copies. - * Permission to modify the code and to distribute modified code is - * granted, provided the above notices are retained, and a notice that - * the code was modified is included with the above copyright notice. - */ - -#ifndef SPARSELU_HEAP_RELAX_SNODE_H -#define SPARSELU_HEAP_RELAX_SNODE_H - -namespace Eigen { -namespace internal { - -/** - * \brief Identify the initial relaxed supernodes - * - * This routine applied to a symmetric elimination tree. - * It assumes that the matrix has been reordered according to the postorder of the etree - * \param n The number of columns - * \param et elimination tree - * \param relax_columns Maximum number of columns allowed in a relaxed snode - * \param descendants Number of descendants of each node in the etree - * \param relax_end last column in a supernode - */ -template -void SparseLUImpl::heap_relax_snode (const Index n, IndexVector& et, const Index relax_columns, IndexVector& descendants, IndexVector& relax_end) -{ - - // The etree may not be postordered, but its heap ordered - IndexVector post; - internal::treePostorder(n, et, post); // Post order etree - IndexVector inv_post(n+1); - Index i; - for (i = 0; i < n+1; ++i) inv_post(post(i)) = i; // inv_post = post.inverse()??? - - // Renumber etree in postorder - IndexVector iwork(n); - IndexVector et_save(n+1); - for (i = 0; i < n; ++i) - { - iwork(post(i)) = post(et(i)); - } - et_save = et; // Save the original etree - et = iwork; - - // compute the number of descendants of each node in the etree - relax_end.setConstant(emptyIdxLU); - Index j, parent; - descendants.setZero(); - for (j = 0; j < n; j++) - { - parent = et(j); - if (parent != n) // not the dummy root - descendants(parent) += descendants(j) + 1; - } - // Identify the relaxed supernodes by postorder traversal of the etree - Index snode_start; // beginning of a snode - Index k; - Index nsuper_et_post = 0; // Number of relaxed snodes in postordered etree - Index nsuper_et = 0; // Number of relaxed snodes in the original etree - Index l; - for (j = 0; j < n; ) - { - parent = et(j); - snode_start = j; - while ( parent != n && descendants(parent) < relax_columns ) - { - j = parent; - parent = et(j); - } - // Found a supernode in postordered etree, j is the last column - ++nsuper_et_post; - k = n; - for (i = snode_start; i <= j; ++i) - k = (std::min)(k, inv_post(i)); - l = inv_post(j); - if ( (l - k) == (j - snode_start) ) // Same number of columns in the snode - { - // This is also a supernode in the original etree - relax_end(k) = l; // Record last column - ++nsuper_et; - } - else - { - for (i = snode_start; i <= j; ++i) - { - l = inv_post(i); - if (descendants(i) == 0) - { - relax_end(l) = l; - ++nsuper_et; - } - } - } - j++; - // Search for a new leaf - while (descendants(j) != 0 && j < n) j++; - } // End postorder traversal of the etree - - // Recover the original etree - et = et_save; -} - -} // end namespace internal - -} // end namespace Eigen -#endif // SPARSELU_HEAP_RELAX_SNODE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_kernel_bmod.h b/thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_kernel_bmod.h deleted file mode 100644 index 6af02675..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_kernel_bmod.h +++ /dev/null @@ -1,130 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2012 Désiré Nuentsa-Wakam -// Copyright (C) 2012 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef SPARSELU_KERNEL_BMOD_H -#define SPARSELU_KERNEL_BMOD_H - -namespace Eigen { -namespace internal { - -/** - * \brief Performs numeric block updates from a given supernode to a single column - * - * \param segsize Size of the segment (and blocks ) to use for updates - * \param[in,out] dense Packed values of the original matrix - * \param tempv temporary vector to use for updates - * \param lusup array containing the supernodes - * \param lda Leading dimension in the supernode - * \param nrow Number of rows in the rectangular part of the supernode - * \param lsub compressed row subscripts of supernodes - * \param lptr pointer to the first column of the current supernode in lsub - * \param no_zeros Number of nonzeros elements before the diagonal part of the supernode - * \return 0 on success - */ -template struct LU_kernel_bmod -{ - template - static EIGEN_DONT_INLINE void run(const int segsize, BlockScalarVector& dense, ScalarVector& tempv, ScalarVector& lusup, Index& luptr, const Index lda, - const Index nrow, IndexVector& lsub, const Index lptr, const Index no_zeros); -}; - -template -template -EIGEN_DONT_INLINE void LU_kernel_bmod::run(const int segsize, BlockScalarVector& dense, ScalarVector& tempv, ScalarVector& lusup, Index& luptr, const Index lda, - const Index nrow, IndexVector& lsub, const Index lptr, const Index no_zeros) -{ - typedef typename ScalarVector::Scalar Scalar; - // First, copy U[*,j] segment from dense(*) to tempv(*) - // The result of triangular solve is in tempv[*]; - // The result of matric-vector update is in dense[*] - Index isub = lptr + no_zeros; - int i; - Index irow; - for (i = 0; i < ((SegSizeAtCompileTime==Dynamic)?segsize:SegSizeAtCompileTime); i++) - { - irow = lsub(isub); - tempv(i) = dense(irow); - ++isub; - } - // Dense triangular solve -- start effective triangle - luptr += lda * no_zeros + no_zeros; - // Form Eigen matrix and vector - Map, 0, OuterStride<> > A( &(lusup.data()[luptr]), segsize, segsize, OuterStride<>(lda) ); - Map > u(tempv.data(), segsize); - - u = A.template triangularView().solve(u); - - // Dense matrix-vector product y <-- B*x - luptr += segsize; - const Index PacketSize = internal::packet_traits::size; - Index ldl = internal::first_multiple(nrow, PacketSize); - Map, 0, OuterStride<> > B( &(lusup.data()[luptr]), nrow, segsize, OuterStride<>(lda) ); - Index aligned_offset = internal::first_aligned(tempv.data()+segsize, PacketSize); - Index aligned_with_B_offset = (PacketSize-internal::first_aligned(B.data(), PacketSize))%PacketSize; - Map, 0, OuterStride<> > l(tempv.data()+segsize+aligned_offset+aligned_with_B_offset, nrow, OuterStride<>(ldl) ); - - l.setZero(); - internal::sparselu_gemm(l.rows(), l.cols(), B.cols(), B.data(), B.outerStride(), u.data(), u.outerStride(), l.data(), l.outerStride()); - - // Scatter tempv[] into SPA dense[] as a temporary storage - isub = lptr + no_zeros; - for (i = 0; i < ((SegSizeAtCompileTime==Dynamic)?segsize:SegSizeAtCompileTime); i++) - { - irow = lsub(isub++); - dense(irow) = tempv(i); - } - - // Scatter l into SPA dense[] - for (i = 0; i < nrow; i++) - { - irow = lsub(isub++); - dense(irow) -= l(i); - } -} - -template <> struct LU_kernel_bmod<1> -{ - template - static EIGEN_DONT_INLINE void run(const int /*segsize*/, BlockScalarVector& dense, ScalarVector& /*tempv*/, ScalarVector& lusup, Index& luptr, - const Index lda, const Index nrow, IndexVector& lsub, const Index lptr, const Index no_zeros); -}; - - -template -EIGEN_DONT_INLINE void LU_kernel_bmod<1>::run(const int /*segsize*/, BlockScalarVector& dense, ScalarVector& /*tempv*/, ScalarVector& lusup, Index& luptr, - const Index lda, const Index nrow, IndexVector& lsub, const Index lptr, const Index no_zeros) -{ - typedef typename ScalarVector::Scalar Scalar; - Scalar f = dense(lsub(lptr + no_zeros)); - luptr += lda * no_zeros + no_zeros + 1; - const Scalar* a(lusup.data() + luptr); - const /*typename IndexVector::Scalar*/Index* irow(lsub.data()+lptr + no_zeros + 1); - Index i = 0; - for (; i+1 < nrow; i+=2) - { - Index i0 = *(irow++); - Index i1 = *(irow++); - Scalar a0 = *(a++); - Scalar a1 = *(a++); - Scalar d0 = dense.coeff(i0); - Scalar d1 = dense.coeff(i1); - d0 -= f*a0; - d1 -= f*a1; - dense.coeffRef(i0) = d0; - dense.coeffRef(i1) = d1; - } - if(i -// Copyright (C) 2012 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -/* - - * NOTE: This file is the modified version of [s,d,c,z]panel_bmod.c file in SuperLU - - * -- SuperLU routine (version 3.0) -- - * Univ. of California Berkeley, Xerox Palo Alto Research Center, - * and Lawrence Berkeley National Lab. - * October 15, 2003 - * - * Copyright (c) 1994 by Xerox Corporation. All rights reserved. - * - * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY - * EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK. - * - * Permission is hereby granted to use or copy this program for any - * purpose, provided the above notices are retained on all copies. - * Permission to modify the code and to distribute modified code is - * granted, provided the above notices are retained, and a notice that - * the code was modified is included with the above copyright notice. - */ -#ifndef SPARSELU_PANEL_BMOD_H -#define SPARSELU_PANEL_BMOD_H - -namespace Eigen { -namespace internal { - -/** - * \brief Performs numeric block updates (sup-panel) in topological order. - * - * Before entering this routine, the original nonzeros in the panel - * were already copied i nto the spa[m,w] - * - * \param m number of rows in the matrix - * \param w Panel size - * \param jcol Starting column of the panel - * \param nseg Number of segments in the U part - * \param dense Store the full representation of the panel - * \param tempv working array - * \param segrep segment representative... first row in the segment - * \param repfnz First nonzero rows - * \param glu Global LU data. - * - * - */ -template -void SparseLUImpl::panel_bmod(const Index m, const Index w, const Index jcol, - const Index nseg, ScalarVector& dense, ScalarVector& tempv, - IndexVector& segrep, IndexVector& repfnz, GlobalLU_t& glu) -{ - - Index ksub,jj,nextl_col; - Index fsupc, nsupc, nsupr, nrow; - Index krep, kfnz; - Index lptr; // points to the row subscripts of a supernode - Index luptr; // ... - Index segsize,no_zeros ; - // For each nonz supernode segment of U[*,j] in topological order - Index k = nseg - 1; - const Index PacketSize = internal::packet_traits::size; - - for (ksub = 0; ksub < nseg; ksub++) - { // For each updating supernode - /* krep = representative of current k-th supernode - * fsupc = first supernodal column - * nsupc = number of columns in a supernode - * nsupr = number of rows in a supernode - */ - krep = segrep(k); k--; - fsupc = glu.xsup(glu.supno(krep)); - nsupc = krep - fsupc + 1; - nsupr = glu.xlsub(fsupc+1) - glu.xlsub(fsupc); - nrow = nsupr - nsupc; - lptr = glu.xlsub(fsupc); - - // loop over the panel columns to detect the actual number of columns and rows - Index u_rows = 0; - Index u_cols = 0; - for (jj = jcol; jj < jcol + w; jj++) - { - nextl_col = (jj-jcol) * m; - VectorBlock repfnz_col(repfnz, nextl_col, m); // First nonzero column index for each row - - kfnz = repfnz_col(krep); - if ( kfnz == emptyIdxLU ) - continue; // skip any zero segment - - segsize = krep - kfnz + 1; - u_cols++; - u_rows = (std::max)(segsize,u_rows); - } - - if(nsupc >= 2) - { - Index ldu = internal::first_multiple(u_rows, PacketSize); - Map > U(tempv.data(), u_rows, u_cols, OuterStride<>(ldu)); - - // gather U - Index u_col = 0; - for (jj = jcol; jj < jcol + w; jj++) - { - nextl_col = (jj-jcol) * m; - VectorBlock repfnz_col(repfnz, nextl_col, m); // First nonzero column index for each row - VectorBlock dense_col(dense, nextl_col, m); // Scatter/gather entire matrix column from/to here - - kfnz = repfnz_col(krep); - if ( kfnz == emptyIdxLU ) - continue; // skip any zero segment - - segsize = krep - kfnz + 1; - luptr = glu.xlusup(fsupc); - no_zeros = kfnz - fsupc; - - Index isub = lptr + no_zeros; - Index off = u_rows-segsize; - for (Index i = 0; i < off; i++) U(i,u_col) = 0; - for (Index i = 0; i < segsize; i++) - { - Index irow = glu.lsub(isub); - U(i+off,u_col) = dense_col(irow); - ++isub; - } - u_col++; - } - // solve U = A^-1 U - luptr = glu.xlusup(fsupc); - Index lda = glu.xlusup(fsupc+1) - glu.xlusup(fsupc); - no_zeros = (krep - u_rows + 1) - fsupc; - luptr += lda * no_zeros + no_zeros; - MappedMatrixBlock A(glu.lusup.data()+luptr, u_rows, u_rows, OuterStride<>(lda) ); - U = A.template triangularView().solve(U); - - // update - luptr += u_rows; - MappedMatrixBlock B(glu.lusup.data()+luptr, nrow, u_rows, OuterStride<>(lda) ); - eigen_assert(tempv.size()>w*ldu + nrow*w + 1); - - Index ldl = internal::first_multiple(nrow, PacketSize); - Index offset = (PacketSize-internal::first_aligned(B.data(), PacketSize)) % PacketSize; - MappedMatrixBlock L(tempv.data()+w*ldu+offset, nrow, u_cols, OuterStride<>(ldl)); - - L.setZero(); - internal::sparselu_gemm(L.rows(), L.cols(), B.cols(), B.data(), B.outerStride(), U.data(), U.outerStride(), L.data(), L.outerStride()); - - // scatter U and L - u_col = 0; - for (jj = jcol; jj < jcol + w; jj++) - { - nextl_col = (jj-jcol) * m; - VectorBlock repfnz_col(repfnz, nextl_col, m); // First nonzero column index for each row - VectorBlock dense_col(dense, nextl_col, m); // Scatter/gather entire matrix column from/to here - - kfnz = repfnz_col(krep); - if ( kfnz == emptyIdxLU ) - continue; // skip any zero segment - - segsize = krep - kfnz + 1; - no_zeros = kfnz - fsupc; - Index isub = lptr + no_zeros; - - Index off = u_rows-segsize; - for (Index i = 0; i < segsize; i++) - { - Index irow = glu.lsub(isub++); - dense_col(irow) = U.coeff(i+off,u_col); - U.coeffRef(i+off,u_col) = 0; - } - - // Scatter l into SPA dense[] - for (Index i = 0; i < nrow; i++) - { - Index irow = glu.lsub(isub++); - dense_col(irow) -= L.coeff(i,u_col); - L.coeffRef(i,u_col) = 0; - } - u_col++; - } - } - else // level 2 only - { - // Sequence through each column in the panel - for (jj = jcol; jj < jcol + w; jj++) - { - nextl_col = (jj-jcol) * m; - VectorBlock repfnz_col(repfnz, nextl_col, m); // First nonzero column index for each row - VectorBlock dense_col(dense, nextl_col, m); // Scatter/gather entire matrix column from/to here - - kfnz = repfnz_col(krep); - if ( kfnz == emptyIdxLU ) - continue; // skip any zero segment - - segsize = krep - kfnz + 1; - luptr = glu.xlusup(fsupc); - - Index lda = glu.xlusup(fsupc+1)-glu.xlusup(fsupc);// nsupr - - // Perform a trianglar solve and block update, - // then scatter the result of sup-col update to dense[] - no_zeros = kfnz - fsupc; - if(segsize==1) LU_kernel_bmod<1>::run(segsize, dense_col, tempv, glu.lusup, luptr, lda, nrow, glu.lsub, lptr, no_zeros); - else if(segsize==2) LU_kernel_bmod<2>::run(segsize, dense_col, tempv, glu.lusup, luptr, lda, nrow, glu.lsub, lptr, no_zeros); - else if(segsize==3) LU_kernel_bmod<3>::run(segsize, dense_col, tempv, glu.lusup, luptr, lda, nrow, glu.lsub, lptr, no_zeros); - else LU_kernel_bmod::run(segsize, dense_col, tempv, glu.lusup, luptr, lda, nrow, glu.lsub, lptr, no_zeros); - } // End for each column in the panel - } - - } // End for each updating supernode -} // end panel bmod - -} // end namespace internal - -} // end namespace Eigen - -#endif // SPARSELU_PANEL_BMOD_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_panel_dfs.h b/thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_panel_dfs.h deleted file mode 100644 index dc0054ef..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_panel_dfs.h +++ /dev/null @@ -1,258 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2012 Désiré Nuentsa-Wakam -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -/* - - * NOTE: This file is the modified version of [s,d,c,z]panel_dfs.c file in SuperLU - - * -- SuperLU routine (version 2.0) -- - * Univ. of California Berkeley, Xerox Palo Alto Research Center, - * and Lawrence Berkeley National Lab. - * November 15, 1997 - * - * Copyright (c) 1994 by Xerox Corporation. All rights reserved. - * - * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY - * EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK. - * - * Permission is hereby granted to use or copy this program for any - * purpose, provided the above notices are retained on all copies. - * Permission to modify the code and to distribute modified code is - * granted, provided the above notices are retained, and a notice that - * the code was modified is included with the above copyright notice. - */ -#ifndef SPARSELU_PANEL_DFS_H -#define SPARSELU_PANEL_DFS_H - -namespace Eigen { - -namespace internal { - -template -struct panel_dfs_traits -{ - typedef typename IndexVector::Scalar Index; - panel_dfs_traits(Index jcol, Index* marker) - : m_jcol(jcol), m_marker(marker) - {} - bool update_segrep(Index krep, Index jj) - { - if(m_marker[krep] -template -void SparseLUImpl::dfs_kernel(const Index jj, IndexVector& perm_r, - Index& nseg, IndexVector& panel_lsub, IndexVector& segrep, - Ref repfnz_col, IndexVector& xprune, Ref marker, IndexVector& parent, - IndexVector& xplore, GlobalLU_t& glu, - Index& nextl_col, Index krow, Traits& traits - ) -{ - - Index kmark = marker(krow); - - // For each unmarked krow of jj - marker(krow) = jj; - Index kperm = perm_r(krow); - if (kperm == emptyIdxLU ) { - // krow is in L : place it in structure of L(*, jj) - panel_lsub(nextl_col++) = krow; // krow is indexed into A - - traits.mem_expand(panel_lsub, nextl_col, kmark); - } - else - { - // krow is in U : if its supernode-representative krep - // has been explored, update repfnz(*) - // krep = supernode representative of the current row - Index krep = glu.xsup(glu.supno(kperm)+1) - 1; - // First nonzero element in the current column: - Index myfnz = repfnz_col(krep); - - if (myfnz != emptyIdxLU ) - { - // Representative visited before - if (myfnz > kperm ) repfnz_col(krep) = kperm; - - } - else - { - // Otherwise, perform dfs starting at krep - Index oldrep = emptyIdxLU; - parent(krep) = oldrep; - repfnz_col(krep) = kperm; - Index xdfs = glu.xlsub(krep); - Index maxdfs = xprune(krep); - - Index kpar; - do - { - // For each unmarked kchild of krep - while (xdfs < maxdfs) - { - Index kchild = glu.lsub(xdfs); - xdfs++; - Index chmark = marker(kchild); - - if (chmark != jj ) - { - marker(kchild) = jj; - Index chperm = perm_r(kchild); - - if (chperm == emptyIdxLU) - { - // case kchild is in L: place it in L(*, j) - panel_lsub(nextl_col++) = kchild; - traits.mem_expand(panel_lsub, nextl_col, chmark); - } - else - { - // case kchild is in U : - // chrep = its supernode-rep. If its rep has been explored, - // update its repfnz(*) - Index chrep = glu.xsup(glu.supno(chperm)+1) - 1; - myfnz = repfnz_col(chrep); - - if (myfnz != emptyIdxLU) - { // Visited before - if (myfnz > chperm) - repfnz_col(chrep) = chperm; - } - else - { // Cont. dfs at snode-rep of kchild - xplore(krep) = xdfs; - oldrep = krep; - krep = chrep; // Go deeper down G(L) - parent(krep) = oldrep; - repfnz_col(krep) = chperm; - xdfs = glu.xlsub(krep); - maxdfs = xprune(krep); - - } // end if myfnz != -1 - } // end if chperm == -1 - - } // end if chmark !=jj - } // end while xdfs < maxdfs - - // krow has no more unexplored nbrs : - // Place snode-rep krep in postorder DFS, if this - // segment is seen for the first time. (Note that - // "repfnz(krep)" may change later.) - // Baktrack dfs to its parent - if(traits.update_segrep(krep,jj)) - //if (marker1(krep) < jcol ) - { - segrep(nseg) = krep; - ++nseg; - //marker1(krep) = jj; - } - - kpar = parent(krep); // Pop recursion, mimic recursion - if (kpar == emptyIdxLU) - break; // dfs done - krep = kpar; - xdfs = xplore(krep); - maxdfs = xprune(krep); - - } while (kpar != emptyIdxLU); // Do until empty stack - - } // end if (myfnz = -1) - - } // end if (kperm == -1) -} - -/** - * \brief Performs a symbolic factorization on a panel of columns [jcol, jcol+w) - * - * A supernode representative is the last column of a supernode. - * The nonzeros in U[*,j] are segments that end at supernodes representatives - * - * The routine returns a list of the supernodal representatives - * in topological order of the dfs that generates them. This list is - * a superset of the topological order of each individual column within - * the panel. - * The location of the first nonzero in each supernodal segment - * (supernodal entry location) is also returned. Each column has - * a separate list for this purpose. - * - * Two markers arrays are used for dfs : - * marker[i] == jj, if i was visited during dfs of current column jj; - * marker1[i] >= jcol, if i was visited by earlier columns in this panel; - * - * \param[in] m number of rows in the matrix - * \param[in] w Panel size - * \param[in] jcol Starting column of the panel - * \param[in] A Input matrix in column-major storage - * \param[in] perm_r Row permutation - * \param[out] nseg Number of U segments - * \param[out] dense Accumulate the column vectors of the panel - * \param[out] panel_lsub Subscripts of the row in the panel - * \param[out] segrep Segment representative i.e first nonzero row of each segment - * \param[out] repfnz First nonzero location in each row - * \param[out] xprune The pruned elimination tree - * \param[out] marker work vector - * \param parent The elimination tree - * \param xplore work vector - * \param glu The global data structure - * - */ - -template -void SparseLUImpl::panel_dfs(const Index m, const Index w, const Index jcol, MatrixType& A, IndexVector& perm_r, Index& nseg, ScalarVector& dense, IndexVector& panel_lsub, IndexVector& segrep, IndexVector& repfnz, IndexVector& xprune, IndexVector& marker, IndexVector& parent, IndexVector& xplore, GlobalLU_t& glu) -{ - Index nextl_col; // Next available position in panel_lsub[*,jj] - - // Initialize pointers - VectorBlock marker1(marker, m, m); - nseg = 0; - - panel_dfs_traits traits(jcol, marker1.data()); - - // For each column in the panel - for (Index jj = jcol; jj < jcol + w; jj++) - { - nextl_col = (jj - jcol) * m; - - VectorBlock repfnz_col(repfnz, nextl_col, m); // First nonzero location in each row - VectorBlock dense_col(dense,nextl_col, m); // Accumulate a column vector here - - - // For each nnz in A[*, jj] do depth first search - for (typename MatrixType::InnerIterator it(A, jj); it; ++it) - { - Index krow = it.row(); - dense_col(krow) = it.value(); - - Index kmark = marker(krow); - if (kmark == jj) - continue; // krow visited before, go to the next nonzero - - dfs_kernel(jj, perm_r, nseg, panel_lsub, segrep, repfnz_col, xprune, marker, parent, - xplore, glu, nextl_col, krow, traits); - }// end for nonzeros in column jj - - } // end for column jj -} - -} // end namespace internal -} // end namespace Eigen - -#endif // SPARSELU_PANEL_DFS_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_pivotL.h b/thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_pivotL.h deleted file mode 100644 index 2e49ef66..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_pivotL.h +++ /dev/null @@ -1,137 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2012 Désiré Nuentsa-Wakam -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -/* - - * NOTE: This file is the modified version of xpivotL.c file in SuperLU - - * -- SuperLU routine (version 3.0) -- - * Univ. of California Berkeley, Xerox Palo Alto Research Center, - * and Lawrence Berkeley National Lab. - * October 15, 2003 - * - * Copyright (c) 1994 by Xerox Corporation. All rights reserved. - * - * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY - * EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK. - * - * Permission is hereby granted to use or copy this program for any - * purpose, provided the above notices are retained on all copies. - * Permission to modify the code and to distribute modified code is - * granted, provided the above notices are retained, and a notice that - * the code was modified is included with the above copyright notice. - */ -#ifndef SPARSELU_PIVOTL_H -#define SPARSELU_PIVOTL_H - -namespace Eigen { -namespace internal { - -/** - * \brief Performs the numerical pivotin on the current column of L, and the CDIV operation. - * - * Pivot policy : - * (1) Compute thresh = u * max_(i>=j) abs(A_ij); - * (2) IF user specifies pivot row k and abs(A_kj) >= thresh THEN - * pivot row = k; - * ELSE IF abs(A_jj) >= thresh THEN - * pivot row = j; - * ELSE - * pivot row = m; - * - * Note: If you absolutely want to use a given pivot order, then set u=0.0. - * - * \param jcol The current column of L - * \param diagpivotthresh diagonal pivoting threshold - * \param[in,out] perm_r Row permutation (threshold pivoting) - * \param[in] iperm_c column permutation - used to finf diagonal of Pc*A*Pc' - * \param[out] pivrow The pivot row - * \param glu Global LU data - * \return 0 if success, i > 0 if U(i,i) is exactly zero - * - */ -template -Index SparseLUImpl::pivotL(const Index jcol, const RealScalar& diagpivotthresh, IndexVector& perm_r, IndexVector& iperm_c, Index& pivrow, GlobalLU_t& glu) -{ - - Index fsupc = (glu.xsup)((glu.supno)(jcol)); // First column in the supernode containing the column jcol - Index nsupc = jcol - fsupc; // Number of columns in the supernode portion, excluding jcol; nsupc >=0 - Index lptr = glu.xlsub(fsupc); // pointer to the starting location of the row subscripts for this supernode portion - Index nsupr = glu.xlsub(fsupc+1) - lptr; // Number of rows in the supernode - Index lda = glu.xlusup(fsupc+1) - glu.xlusup(fsupc); // leading dimension - Scalar* lu_sup_ptr = &(glu.lusup.data()[glu.xlusup(fsupc)]); // Start of the current supernode - Scalar* lu_col_ptr = &(glu.lusup.data()[glu.xlusup(jcol)]); // Start of jcol in the supernode - Index* lsub_ptr = &(glu.lsub.data()[lptr]); // Start of row indices of the supernode - - // Determine the largest abs numerical value for partial pivoting - Index diagind = iperm_c(jcol); // diagonal index - RealScalar pivmax(-1.0); - Index pivptr = nsupc; - Index diag = emptyIdxLU; - RealScalar rtemp; - Index isub, icol, itemp, k; - for (isub = nsupc; isub < nsupr; ++isub) { - using std::abs; - rtemp = abs(lu_col_ptr[isub]); - if (rtemp > pivmax) { - pivmax = rtemp; - pivptr = isub; - } - if (lsub_ptr[isub] == diagind) diag = isub; - } - - // Test for singularity - if ( pivmax <= RealScalar(0.0) ) { - // if pivmax == -1, the column is structurally empty, otherwise it is only numerically zero - pivrow = pivmax < RealScalar(0.0) ? diagind : lsub_ptr[pivptr]; - perm_r(pivrow) = jcol; - return (jcol+1); - } - - RealScalar thresh = diagpivotthresh * pivmax; - - // Choose appropriate pivotal element - - { - // Test if the diagonal element can be used as a pivot (given the threshold value) - if (diag >= 0 ) - { - // Diagonal element exists - using std::abs; - rtemp = abs(lu_col_ptr[diag]); - if (rtemp != 0.0 && rtemp >= thresh) pivptr = diag; - } - pivrow = lsub_ptr[pivptr]; - } - - // Record pivot row - perm_r(pivrow) = jcol; - // Interchange row subscripts - if (pivptr != nsupc ) - { - std::swap( lsub_ptr[pivptr], lsub_ptr[nsupc] ); - // Interchange numerical values as well, for the two rows in the whole snode - // such that L is indexed the same way as A - for (icol = 0; icol <= nsupc; icol++) - { - itemp = pivptr + icol * lda; - std::swap(lu_sup_ptr[itemp], lu_sup_ptr[nsupc + icol * lda]); - } - } - // cdiv operations - Scalar temp = Scalar(1.0) / lu_col_ptr[nsupc]; - for (k = nsupc+1; k < nsupr; k++) - lu_col_ptr[k] *= temp; - return 0; -} - -} // end namespace internal -} // end namespace Eigen - -#endif // SPARSELU_PIVOTL_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_pruneL.h b/thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_pruneL.h deleted file mode 100644 index 66460d16..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_pruneL.h +++ /dev/null @@ -1,135 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2012 Désiré Nuentsa-Wakam -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -/* - - * NOTE: This file is the modified version of [s,d,c,z]pruneL.c file in SuperLU - - * -- SuperLU routine (version 2.0) -- - * Univ. of California Berkeley, Xerox Palo Alto Research Center, - * and Lawrence Berkeley National Lab. - * November 15, 1997 - * - * Copyright (c) 1994 by Xerox Corporation. All rights reserved. - * - * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY - * EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK. - * - * Permission is hereby granted to use or copy this program for any - * purpose, provided the above notices are retained on all copies. - * Permission to modify the code and to distribute modified code is - * granted, provided the above notices are retained, and a notice that - * the code was modified is included with the above copyright notice. - */ -#ifndef SPARSELU_PRUNEL_H -#define SPARSELU_PRUNEL_H - -namespace Eigen { -namespace internal { - -/** - * \brief Prunes the L-structure. - * - * It prunes the L-structure of supernodes whose L-structure contains the current pivot row "pivrow" - * - * - * \param jcol The current column of L - * \param[in] perm_r Row permutation - * \param[out] pivrow The pivot row - * \param nseg Number of segments - * \param segrep - * \param repfnz - * \param[out] xprune - * \param glu Global LU data - * - */ -template -void SparseLUImpl::pruneL(const Index jcol, const IndexVector& perm_r, const Index pivrow, const Index nseg, const IndexVector& segrep, BlockIndexVector repfnz, IndexVector& xprune, GlobalLU_t& glu) -{ - // For each supernode-rep irep in U(*,j] - Index jsupno = glu.supno(jcol); - Index i,irep,irep1; - bool movnum, do_prune = false; - Index kmin = 0, kmax = 0, minloc, maxloc,krow; - for (i = 0; i < nseg; i++) - { - irep = segrep(i); - irep1 = irep + 1; - do_prune = false; - - // Don't prune with a zero U-segment - if (repfnz(irep) == emptyIdxLU) continue; - - // If a snode overlaps with the next panel, then the U-segment - // is fragmented into two parts -- irep and irep1. We should let - // pruning occur at the rep-column in irep1s snode. - if (glu.supno(irep) == glu.supno(irep1) ) continue; // don't prune - - // If it has not been pruned & it has a nonz in row L(pivrow,i) - if (glu.supno(irep) != jsupno ) - { - if ( xprune (irep) >= glu.xlsub(irep1) ) - { - kmin = glu.xlsub(irep); - kmax = glu.xlsub(irep1) - 1; - for (krow = kmin; krow <= kmax; krow++) - { - if (glu.lsub(krow) == pivrow) - { - do_prune = true; - break; - } - } - } - - if (do_prune) - { - // do a quicksort-type partition - // movnum=true means that the num values have to be exchanged - movnum = false; - if (irep == glu.xsup(glu.supno(irep)) ) // Snode of size 1 - movnum = true; - - while (kmin <= kmax) - { - if (perm_r(glu.lsub(kmax)) == emptyIdxLU) - kmax--; - else if ( perm_r(glu.lsub(kmin)) != emptyIdxLU) - kmin++; - else - { - // kmin below pivrow (not yet pivoted), and kmax - // above pivrow: interchange the two suscripts - std::swap(glu.lsub(kmin), glu.lsub(kmax)); - - // If the supernode has only one column, then we - // only keep one set of subscripts. For any subscript - // intercnahge performed, similar interchange must be - // done on the numerical values. - if (movnum) - { - minloc = glu.xlusup(irep) + ( kmin - glu.xlsub(irep) ); - maxloc = glu.xlusup(irep) + ( kmax - glu.xlsub(irep) ); - std::swap(glu.lusup(minloc), glu.lusup(maxloc)); - } - kmin++; - kmax--; - } - } // end while - - xprune(irep) = kmin; //Pruning - } // end if do_prune - } // end pruning - } // End for each U-segment -} - -} // end namespace internal -} // end namespace Eigen - -#endif // SPARSELU_PRUNEL_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_relax_snode.h b/thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_relax_snode.h deleted file mode 100644 index 58ec32e2..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_relax_snode.h +++ /dev/null @@ -1,83 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2012 Désiré Nuentsa-Wakam -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -/* This file is a modified version of heap_relax_snode.c file in SuperLU - * -- SuperLU routine (version 3.0) -- - * Univ. of California Berkeley, Xerox Palo Alto Research Center, - * and Lawrence Berkeley National Lab. - * October 15, 2003 - * - * Copyright (c) 1994 by Xerox Corporation. All rights reserved. - * - * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY - * EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK. - * - * Permission is hereby granted to use or copy this program for any - * purpose, provided the above notices are retained on all copies. - * Permission to modify the code and to distribute modified code is - * granted, provided the above notices are retained, and a notice that - * the code was modified is included with the above copyright notice. - */ - -#ifndef SPARSELU_RELAX_SNODE_H -#define SPARSELU_RELAX_SNODE_H - -namespace Eigen { - -namespace internal { - -/** - * \brief Identify the initial relaxed supernodes - * - * This routine is applied to a column elimination tree. - * It assumes that the matrix has been reordered according to the postorder of the etree - * \param n the number of columns - * \param et elimination tree - * \param relax_columns Maximum number of columns allowed in a relaxed snode - * \param descendants Number of descendants of each node in the etree - * \param relax_end last column in a supernode - */ -template -void SparseLUImpl::relax_snode (const Index n, IndexVector& et, const Index relax_columns, IndexVector& descendants, IndexVector& relax_end) -{ - - // compute the number of descendants of each node in the etree - Index j, parent; - relax_end.setConstant(emptyIdxLU); - descendants.setZero(); - for (j = 0; j < n; j++) - { - parent = et(j); - if (parent != n) // not the dummy root - descendants(parent) += descendants(j) + 1; - } - // Identify the relaxed supernodes by postorder traversal of the etree - Index snode_start; // beginning of a snode - for (j = 0; j < n; ) - { - parent = et(j); - snode_start = j; - while ( parent != n && descendants(parent) < relax_columns ) - { - j = parent; - parent = et(j); - } - // Found a supernode in postordered etree, j is the last column - relax_end(snode_start) = j; // Record last column - j++; - // Search for a new leaf - while (descendants(j) != 0 && j < n) j++; - } // End postorder traversal of the etree - -} - -} // end namespace internal - -} // end namespace Eigen -#endif diff --git a/thirdparty/eigen-3.2.7/Eigen/src/SparseQR/SparseQR.h b/thirdparty/eigen-3.2.7/Eigen/src/SparseQR/SparseQR.h deleted file mode 100644 index a00bd5db..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/SparseQR/SparseQR.h +++ /dev/null @@ -1,714 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2012-2013 Desire Nuentsa -// Copyright (C) 2012-2014 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_SPARSE_QR_H -#define EIGEN_SPARSE_QR_H - -namespace Eigen { - -template class SparseQR; -template struct SparseQRMatrixQReturnType; -template struct SparseQRMatrixQTransposeReturnType; -template struct SparseQR_QProduct; -namespace internal { - template struct traits > - { - typedef typename SparseQRType::MatrixType ReturnType; - typedef typename ReturnType::Index Index; - typedef typename ReturnType::StorageKind StorageKind; - }; - template struct traits > - { - typedef typename SparseQRType::MatrixType ReturnType; - }; - template struct traits > - { - typedef typename Derived::PlainObject ReturnType; - }; -} // End namespace internal - -/** - * \ingroup SparseQR_Module - * \class SparseQR - * \brief Sparse left-looking rank-revealing QR factorization - * - * This class implements a left-looking rank-revealing QR decomposition - * of sparse matrices. When a column has a norm less than a given tolerance - * it is implicitly permuted to the end. The QR factorization thus obtained is - * given by A*P = Q*R where R is upper triangular or trapezoidal. - * - * P is the column permutation which is the product of the fill-reducing and the - * rank-revealing permutations. Use colsPermutation() to get it. - * - * Q is the orthogonal matrix represented as products of Householder reflectors. - * Use matrixQ() to get an expression and matrixQ().transpose() to get the transpose. - * You can then apply it to a vector. - * - * R is the sparse triangular or trapezoidal matrix. The later occurs when A is rank-deficient. - * matrixR().topLeftCorner(rank(), rank()) always returns a triangular factor of full rank. - * - * \tparam _MatrixType The type of the sparse matrix A, must be a column-major SparseMatrix<> - * \tparam _OrderingType The fill-reducing ordering method. See the \link OrderingMethods_Module - * OrderingMethods \endlink module for the list of built-in and external ordering methods. - * - * \warning The input sparse matrix A must be in compressed mode (see SparseMatrix::makeCompressed()). - * - */ -template -class SparseQR -{ - public: - typedef _MatrixType MatrixType; - typedef _OrderingType OrderingType; - typedef typename MatrixType::Scalar Scalar; - typedef typename MatrixType::RealScalar RealScalar; - typedef typename MatrixType::Index Index; - typedef SparseMatrix QRMatrixType; - typedef Matrix IndexVector; - typedef Matrix ScalarVector; - typedef PermutationMatrix PermutationType; - public: - SparseQR () : m_isInitialized(false), m_analysisIsok(false), m_lastError(""), m_useDefaultThreshold(true),m_isQSorted(false),m_isEtreeOk(false) - { } - - /** Construct a QR factorization of the matrix \a mat. - * - * \warning The matrix \a mat must be in compressed mode (see SparseMatrix::makeCompressed()). - * - * \sa compute() - */ - SparseQR(const MatrixType& mat) : m_isInitialized(false), m_analysisIsok(false), m_lastError(""), m_useDefaultThreshold(true),m_isQSorted(false),m_isEtreeOk(false) - { - compute(mat); - } - - /** Computes the QR factorization of the sparse matrix \a mat. - * - * \warning The matrix \a mat must be in compressed mode (see SparseMatrix::makeCompressed()). - * - * \sa analyzePattern(), factorize() - */ - void compute(const MatrixType& mat) - { - analyzePattern(mat); - factorize(mat); - } - void analyzePattern(const MatrixType& mat); - void factorize(const MatrixType& mat); - - /** \returns the number of rows of the represented matrix. - */ - inline Index rows() const { return m_pmat.rows(); } - - /** \returns the number of columns of the represented matrix. - */ - inline Index cols() const { return m_pmat.cols();} - - /** \returns a const reference to the \b sparse upper triangular matrix R of the QR factorization. - */ - const QRMatrixType& matrixR() const { return m_R; } - - /** \returns the number of non linearly dependent columns as determined by the pivoting threshold. - * - * \sa setPivotThreshold() - */ - Index rank() const - { - eigen_assert(m_isInitialized && "The factorization should be called first, use compute()"); - return m_nonzeropivots; - } - - /** \returns an expression of the matrix Q as products of sparse Householder reflectors. - * The common usage of this function is to apply it to a dense matrix or vector - * \code - * VectorXd B1, B2; - * // Initialize B1 - * B2 = matrixQ() * B1; - * \endcode - * - * To get a plain SparseMatrix representation of Q: - * \code - * SparseMatrix Q; - * Q = SparseQR >(A).matrixQ(); - * \endcode - * Internally, this call simply performs a sparse product between the matrix Q - * and a sparse identity matrix. However, due to the fact that the sparse - * reflectors are stored unsorted, two transpositions are needed to sort - * them before performing the product. - */ - SparseQRMatrixQReturnType matrixQ() const - { return SparseQRMatrixQReturnType(*this); } - - /** \returns a const reference to the column permutation P that was applied to A such that A*P = Q*R - * It is the combination of the fill-in reducing permutation and numerical column pivoting. - */ - const PermutationType& colsPermutation() const - { - eigen_assert(m_isInitialized && "Decomposition is not initialized."); - return m_outputPerm_c; - } - - /** \returns A string describing the type of error. - * This method is provided to ease debugging, not to handle errors. - */ - std::string lastErrorMessage() const { return m_lastError; } - - /** \internal */ - template - bool _solve(const MatrixBase &B, MatrixBase &dest) const - { - eigen_assert(m_isInitialized && "The factorization should be called first, use compute()"); - eigen_assert(this->rows() == B.rows() && "SparseQR::solve() : invalid number of rows in the right hand side matrix"); - - Index rank = this->rank(); - - // Compute Q^T * b; - typename Dest::PlainObject y, b; - y = this->matrixQ().transpose() * B; - b = y; - - // Solve with the triangular matrix R - y.resize((std::max)(cols(),Index(y.rows())),y.cols()); - y.topRows(rank) = this->matrixR().topLeftCorner(rank, rank).template triangularView().solve(b.topRows(rank)); - y.bottomRows(y.rows()-rank).setZero(); - - // Apply the column permutation - if (m_perm_c.size()) dest = colsPermutation() * y.topRows(cols()); - else dest = y.topRows(cols()); - - m_info = Success; - return true; - } - - - /** Sets the threshold that is used to determine linearly dependent columns during the factorization. - * - * In practice, if during the factorization the norm of the column that has to be eliminated is below - * this threshold, then the entire column is treated as zero, and it is moved at the end. - */ - void setPivotThreshold(const RealScalar& threshold) - { - m_useDefaultThreshold = false; - m_threshold = threshold; - } - - /** \returns the solution X of \f$ A X = B \f$ using the current decomposition of A. - * - * \sa compute() - */ - template - inline const internal::solve_retval solve(const MatrixBase& B) const - { - eigen_assert(m_isInitialized && "The factorization should be called first, use compute()"); - eigen_assert(this->rows() == B.rows() && "SparseQR::solve() : invalid number of rows in the right hand side matrix"); - return internal::solve_retval(*this, B.derived()); - } - template - inline const internal::sparse_solve_retval solve(const SparseMatrixBase& B) const - { - eigen_assert(m_isInitialized && "The factorization should be called first, use compute()"); - eigen_assert(this->rows() == B.rows() && "SparseQR::solve() : invalid number of rows in the right hand side matrix"); - return internal::sparse_solve_retval(*this, B.derived()); - } - - /** \brief Reports whether previous computation was successful. - * - * \returns \c Success if computation was successful, - * \c NumericalIssue if the QR factorization reports a numerical problem - * \c InvalidInput if the input matrix is invalid - * - * \sa iparm() - */ - ComputationInfo info() const - { - eigen_assert(m_isInitialized && "Decomposition is not initialized."); - return m_info; - } - - protected: - inline void sort_matrix_Q() - { - if(this->m_isQSorted) return; - // The matrix Q is sorted during the transposition - SparseMatrix mQrm(this->m_Q); - this->m_Q = mQrm; - this->m_isQSorted = true; - } - - - protected: - bool m_isInitialized; - bool m_analysisIsok; - bool m_factorizationIsok; - mutable ComputationInfo m_info; - std::string m_lastError; - QRMatrixType m_pmat; // Temporary matrix - QRMatrixType m_R; // The triangular factor matrix - QRMatrixType m_Q; // The orthogonal reflectors - ScalarVector m_hcoeffs; // The Householder coefficients - PermutationType m_perm_c; // Fill-reducing Column permutation - PermutationType m_pivotperm; // The permutation for rank revealing - PermutationType m_outputPerm_c; // The final column permutation - RealScalar m_threshold; // Threshold to determine null Householder reflections - bool m_useDefaultThreshold; // Use default threshold - Index m_nonzeropivots; // Number of non zero pivots found - IndexVector m_etree; // Column elimination tree - IndexVector m_firstRowElt; // First element in each row - bool m_isQSorted; // whether Q is sorted or not - bool m_isEtreeOk; // whether the elimination tree match the initial input matrix - - template friend struct SparseQR_QProduct; - template friend struct SparseQRMatrixQReturnType; - -}; - -/** \brief Preprocessing step of a QR factorization - * - * \warning The matrix \a mat must be in compressed mode (see SparseMatrix::makeCompressed()). - * - * In this step, the fill-reducing permutation is computed and applied to the columns of A - * and the column elimination tree is computed as well. Only the sparsity pattern of \a mat is exploited. - * - * \note In this step it is assumed that there is no empty row in the matrix \a mat. - */ -template -void SparseQR::analyzePattern(const MatrixType& mat) -{ - eigen_assert(mat.isCompressed() && "SparseQR requires a sparse matrix in compressed mode. Call .makeCompressed() before passing it to SparseQR"); - // Copy to a column major matrix if the input is rowmajor - typename internal::conditional::type matCpy(mat); - // Compute the column fill reducing ordering - OrderingType ord; - ord(matCpy, m_perm_c); - Index n = mat.cols(); - Index m = mat.rows(); - Index diagSize = (std::min)(m,n); - - if (!m_perm_c.size()) - { - m_perm_c.resize(n); - m_perm_c.indices().setLinSpaced(n, 0,n-1); - } - - // Compute the column elimination tree of the permuted matrix - m_outputPerm_c = m_perm_c.inverse(); - internal::coletree(matCpy, m_etree, m_firstRowElt, m_outputPerm_c.indices().data()); - m_isEtreeOk = true; - - m_R.resize(m, n); - m_Q.resize(m, diagSize); - - // Allocate space for nonzero elements : rough estimation - m_R.reserve(2*mat.nonZeros()); //FIXME Get a more accurate estimation through symbolic factorization with the etree - m_Q.reserve(2*mat.nonZeros()); - m_hcoeffs.resize(diagSize); - m_analysisIsok = true; -} - -/** \brief Performs the numerical QR factorization of the input matrix - * - * The function SparseQR::analyzePattern(const MatrixType&) must have been called beforehand with - * a matrix having the same sparsity pattern than \a mat. - * - * \param mat The sparse column-major matrix - */ -template -void SparseQR::factorize(const MatrixType& mat) -{ - using std::abs; - using std::max; - - eigen_assert(m_analysisIsok && "analyzePattern() should be called before this step"); - Index m = mat.rows(); - Index n = mat.cols(); - Index diagSize = (std::min)(m,n); - IndexVector mark((std::max)(m,n)); mark.setConstant(-1); // Record the visited nodes - IndexVector Ridx(n), Qidx(m); // Store temporarily the row indexes for the current column of R and Q - Index nzcolR, nzcolQ; // Number of nonzero for the current column of R and Q - ScalarVector tval(m); // The dense vector used to compute the current column - RealScalar pivotThreshold = m_threshold; - - m_R.setZero(); - m_Q.setZero(); - m_pmat = mat; - if(!m_isEtreeOk) - { - m_outputPerm_c = m_perm_c.inverse(); - internal::coletree(m_pmat, m_etree, m_firstRowElt, m_outputPerm_c.indices().data()); - m_isEtreeOk = true; - } - - m_pmat.uncompress(); // To have the innerNonZeroPtr allocated - - // Apply the fill-in reducing permutation lazily: - { - // If the input is row major, copy the original column indices, - // otherwise directly use the input matrix - // - IndexVector originalOuterIndicesCpy; - const Index *originalOuterIndices = mat.outerIndexPtr(); - if(MatrixType::IsRowMajor) - { - originalOuterIndicesCpy = IndexVector::Map(m_pmat.outerIndexPtr(),n+1); - originalOuterIndices = originalOuterIndicesCpy.data(); - } - - for (int i = 0; i < n; i++) - { - Index p = m_perm_c.size() ? m_perm_c.indices()(i) : i; - m_pmat.outerIndexPtr()[p] = originalOuterIndices[i]; - m_pmat.innerNonZeroPtr()[p] = originalOuterIndices[i+1] - originalOuterIndices[i]; - } - } - - /* Compute the default threshold as in MatLab, see: - * Tim Davis, "Algorithm 915, SuiteSparseQR: Multifrontal Multithreaded Rank-Revealing - * Sparse QR Factorization, ACM Trans. on Math. Soft. 38(1), 2011, Page 8:3 - */ - if(m_useDefaultThreshold) - { - RealScalar max2Norm = 0.0; - for (int j = 0; j < n; j++) max2Norm = (max)(max2Norm, m_pmat.col(j).norm()); - if(max2Norm==RealScalar(0)) - max2Norm = RealScalar(1); - pivotThreshold = 20 * (m + n) * max2Norm * NumTraits::epsilon(); - } - - // Initialize the numerical permutation - m_pivotperm.setIdentity(n); - - Index nonzeroCol = 0; // Record the number of valid pivots - m_Q.startVec(0); - - // Left looking rank-revealing QR factorization: compute a column of R and Q at a time - for (Index col = 0; col < n; ++col) - { - mark.setConstant(-1); - m_R.startVec(col); - mark(nonzeroCol) = col; - Qidx(0) = nonzeroCol; - nzcolR = 0; nzcolQ = 1; - bool found_diag = nonzeroCol>=m; - tval.setZero(); - - // Symbolic factorization: find the nonzero locations of the column k of the factors R and Q, i.e., - // all the nodes (with indexes lower than rank) reachable through the column elimination tree (etree) rooted at node k. - // Note: if the diagonal entry does not exist, then its contribution must be explicitly added, - // thus the trick with found_diag that permits to do one more iteration on the diagonal element if this one has not been found. - for (typename QRMatrixType::InnerIterator itp(m_pmat, col); itp || !found_diag; ++itp) - { - Index curIdx = nonzeroCol; - if(itp) curIdx = itp.row(); - if(curIdx == nonzeroCol) found_diag = true; - - // Get the nonzeros indexes of the current column of R - Index st = m_firstRowElt(curIdx); // The traversal of the etree starts here - if (st < 0 ) - { - m_lastError = "Empty row found during numerical factorization"; - m_info = InvalidInput; - return; - } - - // Traverse the etree - Index bi = nzcolR; - for (; mark(st) != col; st = m_etree(st)) - { - Ridx(nzcolR) = st; // Add this row to the list, - mark(st) = col; // and mark this row as visited - nzcolR++; - } - - // Reverse the list to get the topological ordering - Index nt = nzcolR-bi; - for(Index i = 0; i < nt/2; i++) std::swap(Ridx(bi+i), Ridx(nzcolR-i-1)); - - // Copy the current (curIdx,pcol) value of the input matrix - if(itp) tval(curIdx) = itp.value(); - else tval(curIdx) = Scalar(0); - - // Compute the pattern of Q(:,k) - if(curIdx > nonzeroCol && mark(curIdx) != col ) - { - Qidx(nzcolQ) = curIdx; // Add this row to the pattern of Q, - mark(curIdx) = col; // and mark it as visited - nzcolQ++; - } - } - - // Browse all the indexes of R(:,col) in reverse order - for (Index i = nzcolR-1; i >= 0; i--) - { - Index curIdx = Ridx(i); - - // Apply the curIdx-th householder vector to the current column (temporarily stored into tval) - Scalar tdot(0); - - // First compute q' * tval - tdot = m_Q.col(curIdx).dot(tval); - - tdot *= m_hcoeffs(curIdx); - - // Then update tval = tval - q * tau - // FIXME: tval -= tdot * m_Q.col(curIdx) should amount to the same (need to check/add support for efficient "dense ?= sparse") - for (typename QRMatrixType::InnerIterator itq(m_Q, curIdx); itq; ++itq) - tval(itq.row()) -= itq.value() * tdot; - - // Detect fill-in for the current column of Q - if(m_etree(Ridx(i)) == nonzeroCol) - { - for (typename QRMatrixType::InnerIterator itq(m_Q, curIdx); itq; ++itq) - { - Index iQ = itq.row(); - if (mark(iQ) != col) - { - Qidx(nzcolQ++) = iQ; // Add this row to the pattern of Q, - mark(iQ) = col; // and mark it as visited - } - } - } - } // End update current column - - Scalar tau = 0; - RealScalar beta = 0; - - if(nonzeroCol < diagSize) - { - // Compute the Householder reflection that eliminate the current column - // FIXME this step should call the Householder module. - Scalar c0 = nzcolQ ? tval(Qidx(0)) : Scalar(0); - - // First, the squared norm of Q((col+1):m, col) - RealScalar sqrNorm = 0.; - for (Index itq = 1; itq < nzcolQ; ++itq) sqrNorm += numext::abs2(tval(Qidx(itq))); - if(sqrNorm == RealScalar(0) && numext::imag(c0) == RealScalar(0)) - { - beta = numext::real(c0); - tval(Qidx(0)) = 1; - } - else - { - using std::sqrt; - beta = sqrt(numext::abs2(c0) + sqrNorm); - if(numext::real(c0) >= RealScalar(0)) - beta = -beta; - tval(Qidx(0)) = 1; - for (Index itq = 1; itq < nzcolQ; ++itq) - tval(Qidx(itq)) /= (c0 - beta); - tau = numext::conj((beta-c0) / beta); - - } - } - - // Insert values in R - for (Index i = nzcolR-1; i >= 0; i--) - { - Index curIdx = Ridx(i); - if(curIdx < nonzeroCol) - { - m_R.insertBackByOuterInnerUnordered(col, curIdx) = tval(curIdx); - tval(curIdx) = Scalar(0.); - } - } - - if(nonzeroCol < diagSize && abs(beta) >= pivotThreshold) - { - m_R.insertBackByOuterInner(col, nonzeroCol) = beta; - // The householder coefficient - m_hcoeffs(nonzeroCol) = tau; - // Record the householder reflections - for (Index itq = 0; itq < nzcolQ; ++itq) - { - Index iQ = Qidx(itq); - m_Q.insertBackByOuterInnerUnordered(nonzeroCol,iQ) = tval(iQ); - tval(iQ) = Scalar(0.); - } - nonzeroCol++; - if(nonzeroCol -struct solve_retval, Rhs> - : solve_retval_base, Rhs> -{ - typedef SparseQR<_MatrixType,OrderingType> Dec; - EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs) - - template void evalTo(Dest& dst) const - { - dec()._solve(rhs(),dst); - } -}; -template -struct sparse_solve_retval, Rhs> - : sparse_solve_retval_base, Rhs> -{ - typedef SparseQR<_MatrixType, OrderingType> Dec; - EIGEN_MAKE_SPARSE_SOLVE_HELPERS(Dec, Rhs) - - template void evalTo(Dest& dst) const - { - this->defaultEvalTo(dst); - } -}; -} // end namespace internal - -template -struct SparseQR_QProduct : ReturnByValue > -{ - typedef typename SparseQRType::QRMatrixType MatrixType; - typedef typename SparseQRType::Scalar Scalar; - typedef typename SparseQRType::Index Index; - // Get the references - SparseQR_QProduct(const SparseQRType& qr, const Derived& other, bool transpose) : - m_qr(qr),m_other(other),m_transpose(transpose) {} - inline Index rows() const { return m_transpose ? m_qr.rows() : m_qr.cols(); } - inline Index cols() const { return m_other.cols(); } - - // Assign to a vector - template - void evalTo(DesType& res) const - { - Index m = m_qr.rows(); - Index n = m_qr.cols(); - Index diagSize = (std::min)(m,n); - res = m_other; - if (m_transpose) - { - eigen_assert(m_qr.m_Q.rows() == m_other.rows() && "Non conforming object sizes"); - //Compute res = Q' * other column by column - for(Index j = 0; j < res.cols(); j++){ - for (Index k = 0; k < diagSize; k++) - { - Scalar tau = Scalar(0); - tau = m_qr.m_Q.col(k).dot(res.col(j)); - if(tau==Scalar(0)) continue; - tau = tau * m_qr.m_hcoeffs(k); - res.col(j) -= tau * m_qr.m_Q.col(k); - } - } - } - else - { - eigen_assert(m_qr.m_Q.rows() == m_other.rows() && "Non conforming object sizes"); - // Compute res = Q * other column by column - for(Index j = 0; j < res.cols(); j++) - { - for (Index k = diagSize-1; k >=0; k--) - { - Scalar tau = Scalar(0); - tau = m_qr.m_Q.col(k).dot(res.col(j)); - if(tau==Scalar(0)) continue; - tau = tau * m_qr.m_hcoeffs(k); - res.col(j) -= tau * m_qr.m_Q.col(k); - } - } - } - } - - const SparseQRType& m_qr; - const Derived& m_other; - bool m_transpose; -}; - -template -struct SparseQRMatrixQReturnType : public EigenBase > -{ - typedef typename SparseQRType::Index Index; - typedef typename SparseQRType::Scalar Scalar; - typedef Matrix DenseMatrix; - SparseQRMatrixQReturnType(const SparseQRType& qr) : m_qr(qr) {} - template - SparseQR_QProduct operator*(const MatrixBase& other) - { - return SparseQR_QProduct(m_qr,other.derived(),false); - } - SparseQRMatrixQTransposeReturnType adjoint() const - { - return SparseQRMatrixQTransposeReturnType(m_qr); - } - inline Index rows() const { return m_qr.rows(); } - inline Index cols() const { return (std::min)(m_qr.rows(),m_qr.cols()); } - // To use for operations with the transpose of Q - SparseQRMatrixQTransposeReturnType transpose() const - { - return SparseQRMatrixQTransposeReturnType(m_qr); - } - template void evalTo(MatrixBase& dest) const - { - dest.derived() = m_qr.matrixQ() * Dest::Identity(m_qr.rows(), m_qr.rows()); - } - template void evalTo(SparseMatrixBase& dest) const - { - Dest idMat(m_qr.rows(), m_qr.rows()); - idMat.setIdentity(); - // Sort the sparse householder reflectors if needed - const_cast(&m_qr)->sort_matrix_Q(); - dest.derived() = SparseQR_QProduct(m_qr, idMat, false); - } - - const SparseQRType& m_qr; -}; - -template -struct SparseQRMatrixQTransposeReturnType -{ - SparseQRMatrixQTransposeReturnType(const SparseQRType& qr) : m_qr(qr) {} - template - SparseQR_QProduct operator*(const MatrixBase& other) - { - return SparseQR_QProduct(m_qr,other.derived(), true); - } - const SparseQRType& m_qr; -}; - -} // end namespace Eigen - -#endif diff --git a/thirdparty/eigen-3.2.7/Eigen/src/StlSupport/StdDeque.h b/thirdparty/eigen-3.2.7/Eigen/src/StlSupport/StdDeque.h deleted file mode 100644 index aaf66330..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/StlSupport/StdDeque.h +++ /dev/null @@ -1,134 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2009 Gael Guennebaud -// Copyright (C) 2009 Hauke Heibel -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_STDDEQUE_H -#define EIGEN_STDDEQUE_H - -#include "details.h" - -// Define the explicit instantiation (e.g. necessary for the Intel compiler) -#if defined(__INTEL_COMPILER) || defined(__GNUC__) - #define EIGEN_EXPLICIT_STL_DEQUE_INSTANTIATION(...) template class std::deque<__VA_ARGS__, EIGEN_ALIGNED_ALLOCATOR<__VA_ARGS__> >; -#else - #define EIGEN_EXPLICIT_STL_DEQUE_INSTANTIATION(...) -#endif - -/** - * This section contains a convenience MACRO which allows an easy specialization of - * std::deque such that for data types with alignment issues the correct allocator - * is used automatically. - */ -#define EIGEN_DEFINE_STL_DEQUE_SPECIALIZATION(...) \ -EIGEN_EXPLICIT_STL_DEQUE_INSTANTIATION(__VA_ARGS__) \ -namespace std \ -{ \ - template \ - class deque<__VA_ARGS__, _Ay> \ - : public deque<__VA_ARGS__, EIGEN_ALIGNED_ALLOCATOR<__VA_ARGS__> > \ - { \ - typedef deque<__VA_ARGS__, EIGEN_ALIGNED_ALLOCATOR<__VA_ARGS__> > deque_base; \ - public: \ - typedef __VA_ARGS__ value_type; \ - typedef typename deque_base::allocator_type allocator_type; \ - typedef typename deque_base::size_type size_type; \ - typedef typename deque_base::iterator iterator; \ - explicit deque(const allocator_type& a = allocator_type()) : deque_base(a) {} \ - template \ - deque(InputIterator first, InputIterator last, const allocator_type& a = allocator_type()) : deque_base(first, last, a) {} \ - deque(const deque& c) : deque_base(c) {} \ - explicit deque(size_type num, const value_type& val = value_type()) : deque_base(num, val) {} \ - deque(iterator start, iterator end) : deque_base(start, end) {} \ - deque& operator=(const deque& x) { \ - deque_base::operator=(x); \ - return *this; \ - } \ - }; \ -} - -// check whether we really need the std::deque specialization -#if !(defined(_GLIBCXX_DEQUE) && (!EIGEN_GNUC_AT_LEAST(4,1))) /* Note that before gcc-4.1 we already have: std::deque::resize(size_type,const T&). */ - -namespace std { - -#define EIGEN_STD_DEQUE_SPECIALIZATION_BODY \ - public: \ - typedef T value_type; \ - typedef typename deque_base::allocator_type allocator_type; \ - typedef typename deque_base::size_type size_type; \ - typedef typename deque_base::iterator iterator; \ - typedef typename deque_base::const_iterator const_iterator; \ - explicit deque(const allocator_type& a = allocator_type()) : deque_base(a) {} \ - template \ - deque(InputIterator first, InputIterator last, const allocator_type& a = allocator_type()) \ - : deque_base(first, last, a) {} \ - deque(const deque& c) : deque_base(c) {} \ - explicit deque(size_type num, const value_type& val = value_type()) : deque_base(num, val) {} \ - deque(iterator start, iterator end) : deque_base(start, end) {} \ - deque& operator=(const deque& x) { \ - deque_base::operator=(x); \ - return *this; \ - } - - template - class deque > - : public deque > -{ - typedef deque > deque_base; - EIGEN_STD_DEQUE_SPECIALIZATION_BODY - - void resize(size_type new_size) - { resize(new_size, T()); } - -#if defined(_DEQUE_) - // workaround MSVC std::deque implementation - void resize(size_type new_size, const value_type& x) - { - if (deque_base::size() < new_size) - deque_base::_Insert_n(deque_base::end(), new_size - deque_base::size(), x); - else if (new_size < deque_base::size()) - deque_base::erase(deque_base::begin() + new_size, deque_base::end()); - } - void push_back(const value_type& x) - { deque_base::push_back(x); } - void push_front(const value_type& x) - { deque_base::push_front(x); } - using deque_base::insert; - iterator insert(const_iterator position, const value_type& x) - { return deque_base::insert(position,x); } - void insert(const_iterator position, size_type new_size, const value_type& x) - { deque_base::insert(position, new_size, x); } -#elif defined(_GLIBCXX_DEQUE) && EIGEN_GNUC_AT_LEAST(4,2) - // workaround GCC std::deque implementation - void resize(size_type new_size, const value_type& x) - { - if (new_size < deque_base::size()) - deque_base::_M_erase_at_end(this->_M_impl._M_start + new_size); - else - deque_base::insert(deque_base::end(), new_size - deque_base::size(), x); - } -#else - // either GCC 4.1 or non-GCC - // default implementation which should always work. - void resize(size_type new_size, const value_type& x) - { - if (new_size < deque_base::size()) - deque_base::erase(deque_base::begin() + new_size, deque_base::end()); - else if (new_size > deque_base::size()) - deque_base::insert(deque_base::end(), new_size - deque_base::size(), x); - } -#endif - }; -} - -#endif // check whether specialization is actually required - -#endif // EIGEN_STDDEQUE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/StlSupport/StdList.h b/thirdparty/eigen-3.2.7/Eigen/src/StlSupport/StdList.h deleted file mode 100644 index 3c742430..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/StlSupport/StdList.h +++ /dev/null @@ -1,114 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2009 Hauke Heibel -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_STDLIST_H -#define EIGEN_STDLIST_H - -#include "details.h" - -// Define the explicit instantiation (e.g. necessary for the Intel compiler) -#if defined(__INTEL_COMPILER) || defined(__GNUC__) - #define EIGEN_EXPLICIT_STL_LIST_INSTANTIATION(...) template class std::list<__VA_ARGS__, EIGEN_ALIGNED_ALLOCATOR<__VA_ARGS__> >; -#else - #define EIGEN_EXPLICIT_STL_LIST_INSTANTIATION(...) -#endif - -/** - * This section contains a convenience MACRO which allows an easy specialization of - * std::list such that for data types with alignment issues the correct allocator - * is used automatically. - */ -#define EIGEN_DEFINE_STL_LIST_SPECIALIZATION(...) \ -EIGEN_EXPLICIT_STL_LIST_INSTANTIATION(__VA_ARGS__) \ -namespace std \ -{ \ - template \ - class list<__VA_ARGS__, _Ay> \ - : public list<__VA_ARGS__, EIGEN_ALIGNED_ALLOCATOR<__VA_ARGS__> > \ - { \ - typedef list<__VA_ARGS__, EIGEN_ALIGNED_ALLOCATOR<__VA_ARGS__> > list_base; \ - public: \ - typedef __VA_ARGS__ value_type; \ - typedef typename list_base::allocator_type allocator_type; \ - typedef typename list_base::size_type size_type; \ - typedef typename list_base::iterator iterator; \ - explicit list(const allocator_type& a = allocator_type()) : list_base(a) {} \ - template \ - list(InputIterator first, InputIterator last, const allocator_type& a = allocator_type()) : list_base(first, last, a) {} \ - list(const list& c) : list_base(c) {} \ - explicit list(size_type num, const value_type& val = value_type()) : list_base(num, val) {} \ - list(iterator start, iterator end) : list_base(start, end) {} \ - list& operator=(const list& x) { \ - list_base::operator=(x); \ - return *this; \ - } \ - }; \ -} - -// check whether we really need the std::vector specialization -#if !(defined(_GLIBCXX_VECTOR) && (!EIGEN_GNUC_AT_LEAST(4,1))) /* Note that before gcc-4.1 we already have: std::list::resize(size_type,const T&). */ - -namespace std -{ - -#define EIGEN_STD_LIST_SPECIALIZATION_BODY \ - public: \ - typedef T value_type; \ - typedef typename list_base::allocator_type allocator_type; \ - typedef typename list_base::size_type size_type; \ - typedef typename list_base::iterator iterator; \ - typedef typename list_base::const_iterator const_iterator; \ - explicit list(const allocator_type& a = allocator_type()) : list_base(a) {} \ - template \ - list(InputIterator first, InputIterator last, const allocator_type& a = allocator_type()) \ - : list_base(first, last, a) {} \ - list(const list& c) : list_base(c) {} \ - explicit list(size_type num, const value_type& val = value_type()) : list_base(num, val) {} \ - list(iterator start, iterator end) : list_base(start, end) {} \ - list& operator=(const list& x) { \ - list_base::operator=(x); \ - return *this; \ - } - - template - class list > - : public list > - { - typedef list > list_base; - EIGEN_STD_LIST_SPECIALIZATION_BODY - - void resize(size_type new_size) - { resize(new_size, T()); } - - void resize(size_type new_size, const value_type& x) - { - if (list_base::size() < new_size) - list_base::insert(list_base::end(), new_size - list_base::size(), x); - else - while (new_size < list_base::size()) list_base::pop_back(); - } - -#if defined(_LIST_) - // workaround MSVC std::list implementation - void push_back(const value_type& x) - { list_base::push_back(x); } - using list_base::insert; - iterator insert(const_iterator position, const value_type& x) - { return list_base::insert(position,x); } - void insert(const_iterator position, size_type new_size, const value_type& x) - { list_base::insert(position, new_size, x); } -#endif - }; -} - -#endif // check whether specialization is actually required - -#endif // EIGEN_STDLIST_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/StlSupport/StdVector.h b/thirdparty/eigen-3.2.7/Eigen/src/StlSupport/StdVector.h deleted file mode 100644 index 611664a2..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/StlSupport/StdVector.h +++ /dev/null @@ -1,126 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2009 Gael Guennebaud -// Copyright (C) 2009 Hauke Heibel -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_STDVECTOR_H -#define EIGEN_STDVECTOR_H - -#include "details.h" - -/** - * This section contains a convenience MACRO which allows an easy specialization of - * std::vector such that for data types with alignment issues the correct allocator - * is used automatically. - */ -#define EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(...) \ -namespace std \ -{ \ - template<> \ - class vector<__VA_ARGS__, std::allocator<__VA_ARGS__> > \ - : public vector<__VA_ARGS__, EIGEN_ALIGNED_ALLOCATOR<__VA_ARGS__> > \ - { \ - typedef vector<__VA_ARGS__, EIGEN_ALIGNED_ALLOCATOR<__VA_ARGS__> > vector_base; \ - public: \ - typedef __VA_ARGS__ value_type; \ - typedef vector_base::allocator_type allocator_type; \ - typedef vector_base::size_type size_type; \ - typedef vector_base::iterator iterator; \ - explicit vector(const allocator_type& a = allocator_type()) : vector_base(a) {} \ - template \ - vector(InputIterator first, InputIterator last, const allocator_type& a = allocator_type()) : vector_base(first, last, a) {} \ - vector(const vector& c) : vector_base(c) {} \ - explicit vector(size_type num, const value_type& val = value_type()) : vector_base(num, val) {} \ - vector(iterator start, iterator end) : vector_base(start, end) {} \ - vector& operator=(const vector& x) { \ - vector_base::operator=(x); \ - return *this; \ - } \ - }; \ -} - -namespace std { - -#define EIGEN_STD_VECTOR_SPECIALIZATION_BODY \ - public: \ - typedef T value_type; \ - typedef typename vector_base::allocator_type allocator_type; \ - typedef typename vector_base::size_type size_type; \ - typedef typename vector_base::iterator iterator; \ - typedef typename vector_base::const_iterator const_iterator; \ - explicit vector(const allocator_type& a = allocator_type()) : vector_base(a) {} \ - template \ - vector(InputIterator first, InputIterator last, const allocator_type& a = allocator_type()) \ - : vector_base(first, last, a) {} \ - vector(const vector& c) : vector_base(c) {} \ - explicit vector(size_type num, const value_type& val = value_type()) : vector_base(num, val) {} \ - vector(iterator start, iterator end) : vector_base(start, end) {} \ - vector& operator=(const vector& x) { \ - vector_base::operator=(x); \ - return *this; \ - } - - template - class vector > - : public vector > -{ - typedef vector > vector_base; - EIGEN_STD_VECTOR_SPECIALIZATION_BODY - - void resize(size_type new_size) - { resize(new_size, T()); } - -#if defined(_VECTOR_) - // workaround MSVC std::vector implementation - void resize(size_type new_size, const value_type& x) - { - if (vector_base::size() < new_size) - vector_base::_Insert_n(vector_base::end(), new_size - vector_base::size(), x); - else if (new_size < vector_base::size()) - vector_base::erase(vector_base::begin() + new_size, vector_base::end()); - } - void push_back(const value_type& x) - { vector_base::push_back(x); } - using vector_base::insert; - iterator insert(const_iterator position, const value_type& x) - { return vector_base::insert(position,x); } - void insert(const_iterator position, size_type new_size, const value_type& x) - { vector_base::insert(position, new_size, x); } -#elif defined(_GLIBCXX_VECTOR) && (!(EIGEN_GNUC_AT_LEAST(4,1))) - /* Note that before gcc-4.1 we already have: std::vector::resize(size_type,const T&). - * However, this specialization is still needed to make the above EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION trick to work. */ - void resize(size_type new_size, const value_type& x) - { - vector_base::resize(new_size,x); - } -#elif defined(_GLIBCXX_VECTOR) && EIGEN_GNUC_AT_LEAST(4,2) - // workaround GCC std::vector implementation - void resize(size_type new_size, const value_type& x) - { - if (new_size < vector_base::size()) - vector_base::_M_erase_at_end(this->_M_impl._M_start + new_size); - else - vector_base::insert(vector_base::end(), new_size - vector_base::size(), x); - } -#else - // either GCC 4.1 or non-GCC - // default implementation which should always work. - void resize(size_type new_size, const value_type& x) - { - if (new_size < vector_base::size()) - vector_base::erase(vector_base::begin() + new_size, vector_base::end()); - else if (new_size > vector_base::size()) - vector_base::insert(vector_base::end(), new_size - vector_base::size(), x); - } -#endif - }; -} - -#endif // EIGEN_STDVECTOR_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/StlSupport/details.h b/thirdparty/eigen-3.2.7/Eigen/src/StlSupport/details.h deleted file mode 100644 index d8debc7c..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/StlSupport/details.h +++ /dev/null @@ -1,84 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2009 Gael Guennebaud -// Copyright (C) 2009 Hauke Heibel -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_STL_DETAILS_H -#define EIGEN_STL_DETAILS_H - -#ifndef EIGEN_ALIGNED_ALLOCATOR - #define EIGEN_ALIGNED_ALLOCATOR Eigen::aligned_allocator -#endif - -namespace Eigen { - - // This one is needed to prevent reimplementing the whole std::vector. - template - class aligned_allocator_indirection : public EIGEN_ALIGNED_ALLOCATOR - { - public: - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef T* pointer; - typedef const T* const_pointer; - typedef T& reference; - typedef const T& const_reference; - typedef T value_type; - - template - struct rebind - { - typedef aligned_allocator_indirection other; - }; - - aligned_allocator_indirection() {} - aligned_allocator_indirection(const aligned_allocator_indirection& ) : EIGEN_ALIGNED_ALLOCATOR() {} - aligned_allocator_indirection(const EIGEN_ALIGNED_ALLOCATOR& ) {} - template - aligned_allocator_indirection(const aligned_allocator_indirection& ) {} - template - aligned_allocator_indirection(const EIGEN_ALIGNED_ALLOCATOR& ) {} - ~aligned_allocator_indirection() {} - }; - -#ifdef _MSC_VER - - // sometimes, MSVC detects, at compile time, that the argument x - // in std::vector::resize(size_t s,T x) won't be aligned and generate an error - // even if this function is never called. Whence this little wrapper. -#define EIGEN_WORKAROUND_MSVC_STL_SUPPORT(T) \ - typename Eigen::internal::conditional< \ - Eigen::internal::is_arithmetic::value, \ - T, \ - Eigen::internal::workaround_msvc_stl_support \ - >::type - - namespace internal { - template struct workaround_msvc_stl_support : public T - { - inline workaround_msvc_stl_support() : T() {} - inline workaround_msvc_stl_support(const T& other) : T(other) {} - inline operator T& () { return *static_cast(this); } - inline operator const T& () const { return *static_cast(this); } - template - inline T& operator=(const OtherT& other) - { T::operator=(other); return *this; } - inline workaround_msvc_stl_support& operator=(const workaround_msvc_stl_support& other) - { T::operator=(other); return *this; } - }; - } - -#else - -#define EIGEN_WORKAROUND_MSVC_STL_SUPPORT(T) T - -#endif - -} - -#endif // EIGEN_STL_DETAILS_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/SuperLUSupport/SuperLUSupport.h b/thirdparty/eigen-3.2.7/Eigen/src/SuperLUSupport/SuperLUSupport.h deleted file mode 100644 index bcb35576..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/SuperLUSupport/SuperLUSupport.h +++ /dev/null @@ -1,1026 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2011 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_SUPERLUSUPPORT_H -#define EIGEN_SUPERLUSUPPORT_H - -namespace Eigen { - -#define DECL_GSSVX(PREFIX,FLOATTYPE,KEYTYPE) \ - extern "C" { \ - typedef struct { FLOATTYPE for_lu; FLOATTYPE total_needed; int expansions; } PREFIX##mem_usage_t; \ - extern void PREFIX##gssvx(superlu_options_t *, SuperMatrix *, int *, int *, int *, \ - char *, FLOATTYPE *, FLOATTYPE *, SuperMatrix *, SuperMatrix *, \ - void *, int, SuperMatrix *, SuperMatrix *, \ - FLOATTYPE *, FLOATTYPE *, FLOATTYPE *, FLOATTYPE *, \ - PREFIX##mem_usage_t *, SuperLUStat_t *, int *); \ - } \ - inline float SuperLU_gssvx(superlu_options_t *options, SuperMatrix *A, \ - int *perm_c, int *perm_r, int *etree, char *equed, \ - FLOATTYPE *R, FLOATTYPE *C, SuperMatrix *L, \ - SuperMatrix *U, void *work, int lwork, \ - SuperMatrix *B, SuperMatrix *X, \ - FLOATTYPE *recip_pivot_growth, \ - FLOATTYPE *rcond, FLOATTYPE *ferr, FLOATTYPE *berr, \ - SuperLUStat_t *stats, int *info, KEYTYPE) { \ - PREFIX##mem_usage_t mem_usage; \ - PREFIX##gssvx(options, A, perm_c, perm_r, etree, equed, R, C, L, \ - U, work, lwork, B, X, recip_pivot_growth, rcond, \ - ferr, berr, &mem_usage, stats, info); \ - return mem_usage.for_lu; /* bytes used by the factor storage */ \ - } - -DECL_GSSVX(s,float,float) -DECL_GSSVX(c,float,std::complex) -DECL_GSSVX(d,double,double) -DECL_GSSVX(z,double,std::complex) - -#ifdef MILU_ALPHA -#define EIGEN_SUPERLU_HAS_ILU -#endif - -#ifdef EIGEN_SUPERLU_HAS_ILU - -// similarly for the incomplete factorization using gsisx -#define DECL_GSISX(PREFIX,FLOATTYPE,KEYTYPE) \ - extern "C" { \ - extern void PREFIX##gsisx(superlu_options_t *, SuperMatrix *, int *, int *, int *, \ - char *, FLOATTYPE *, FLOATTYPE *, SuperMatrix *, SuperMatrix *, \ - void *, int, SuperMatrix *, SuperMatrix *, FLOATTYPE *, FLOATTYPE *, \ - PREFIX##mem_usage_t *, SuperLUStat_t *, int *); \ - } \ - inline float SuperLU_gsisx(superlu_options_t *options, SuperMatrix *A, \ - int *perm_c, int *perm_r, int *etree, char *equed, \ - FLOATTYPE *R, FLOATTYPE *C, SuperMatrix *L, \ - SuperMatrix *U, void *work, int lwork, \ - SuperMatrix *B, SuperMatrix *X, \ - FLOATTYPE *recip_pivot_growth, \ - FLOATTYPE *rcond, \ - SuperLUStat_t *stats, int *info, KEYTYPE) { \ - PREFIX##mem_usage_t mem_usage; \ - PREFIX##gsisx(options, A, perm_c, perm_r, etree, equed, R, C, L, \ - U, work, lwork, B, X, recip_pivot_growth, rcond, \ - &mem_usage, stats, info); \ - return mem_usage.for_lu; /* bytes used by the factor storage */ \ - } - -DECL_GSISX(s,float,float) -DECL_GSISX(c,float,std::complex) -DECL_GSISX(d,double,double) -DECL_GSISX(z,double,std::complex) - -#endif - -template -struct SluMatrixMapHelper; - -/** \internal - * - * A wrapper class for SuperLU matrices. It supports only compressed sparse matrices - * and dense matrices. Supernodal and other fancy format are not supported by this wrapper. - * - * This wrapper class mainly aims to avoids the need of dynamic allocation of the storage structure. - */ -struct SluMatrix : SuperMatrix -{ - SluMatrix() - { - Store = &storage; - } - - SluMatrix(const SluMatrix& other) - : SuperMatrix(other) - { - Store = &storage; - storage = other.storage; - } - - SluMatrix& operator=(const SluMatrix& other) - { - SuperMatrix::operator=(static_cast(other)); - Store = &storage; - storage = other.storage; - return *this; - } - - struct - { - union {int nnz;int lda;}; - void *values; - int *innerInd; - int *outerInd; - } storage; - - void setStorageType(Stype_t t) - { - Stype = t; - if (t==SLU_NC || t==SLU_NR || t==SLU_DN) - Store = &storage; - else - { - eigen_assert(false && "storage type not supported"); - Store = 0; - } - } - - template - void setScalarType() - { - if (internal::is_same::value) - Dtype = SLU_S; - else if (internal::is_same::value) - Dtype = SLU_D; - else if (internal::is_same >::value) - Dtype = SLU_C; - else if (internal::is_same >::value) - Dtype = SLU_Z; - else - { - eigen_assert(false && "Scalar type not supported by SuperLU"); - } - } - - template - static SluMatrix Map(MatrixBase& _mat) - { - MatrixType& mat(_mat.derived()); - eigen_assert( ((MatrixType::Flags&RowMajorBit)!=RowMajorBit) && "row-major dense matrices are not supported by SuperLU"); - SluMatrix res; - res.setStorageType(SLU_DN); - res.setScalarType(); - res.Mtype = SLU_GE; - - res.nrow = mat.rows(); - res.ncol = mat.cols(); - - res.storage.lda = MatrixType::IsVectorAtCompileTime ? mat.size() : mat.outerStride(); - res.storage.values = (void*)(mat.data()); - return res; - } - - template - static SluMatrix Map(SparseMatrixBase& mat) - { - SluMatrix res; - if ((MatrixType::Flags&RowMajorBit)==RowMajorBit) - { - res.setStorageType(SLU_NR); - res.nrow = mat.cols(); - res.ncol = mat.rows(); - } - else - { - res.setStorageType(SLU_NC); - res.nrow = mat.rows(); - res.ncol = mat.cols(); - } - - res.Mtype = SLU_GE; - - res.storage.nnz = mat.nonZeros(); - res.storage.values = mat.derived().valuePtr(); - res.storage.innerInd = mat.derived().innerIndexPtr(); - res.storage.outerInd = mat.derived().outerIndexPtr(); - - res.setScalarType(); - - // FIXME the following is not very accurate - if (MatrixType::Flags & Upper) - res.Mtype = SLU_TRU; - if (MatrixType::Flags & Lower) - res.Mtype = SLU_TRL; - - eigen_assert(((MatrixType::Flags & SelfAdjoint)==0) && "SelfAdjoint matrix shape not supported by SuperLU"); - - return res; - } -}; - -template -struct SluMatrixMapHelper > -{ - typedef Matrix MatrixType; - static void run(MatrixType& mat, SluMatrix& res) - { - eigen_assert( ((Options&RowMajor)!=RowMajor) && "row-major dense matrices is not supported by SuperLU"); - res.setStorageType(SLU_DN); - res.setScalarType(); - res.Mtype = SLU_GE; - - res.nrow = mat.rows(); - res.ncol = mat.cols(); - - res.storage.lda = mat.outerStride(); - res.storage.values = mat.data(); - } -}; - -template -struct SluMatrixMapHelper > -{ - typedef Derived MatrixType; - static void run(MatrixType& mat, SluMatrix& res) - { - if ((MatrixType::Flags&RowMajorBit)==RowMajorBit) - { - res.setStorageType(SLU_NR); - res.nrow = mat.cols(); - res.ncol = mat.rows(); - } - else - { - res.setStorageType(SLU_NC); - res.nrow = mat.rows(); - res.ncol = mat.cols(); - } - - res.Mtype = SLU_GE; - - res.storage.nnz = mat.nonZeros(); - res.storage.values = mat.valuePtr(); - res.storage.innerInd = mat.innerIndexPtr(); - res.storage.outerInd = mat.outerIndexPtr(); - - res.setScalarType(); - - // FIXME the following is not very accurate - if (MatrixType::Flags & Upper) - res.Mtype = SLU_TRU; - if (MatrixType::Flags & Lower) - res.Mtype = SLU_TRL; - - eigen_assert(((MatrixType::Flags & SelfAdjoint)==0) && "SelfAdjoint matrix shape not supported by SuperLU"); - } -}; - -namespace internal { - -template -SluMatrix asSluMatrix(MatrixType& mat) -{ - return SluMatrix::Map(mat); -} - -/** View a Super LU matrix as an Eigen expression */ -template -MappedSparseMatrix map_superlu(SluMatrix& sluMat) -{ - eigen_assert((Flags&RowMajor)==RowMajor && sluMat.Stype == SLU_NR - || (Flags&ColMajor)==ColMajor && sluMat.Stype == SLU_NC); - - Index outerSize = (Flags&RowMajor)==RowMajor ? sluMat.ncol : sluMat.nrow; - - return MappedSparseMatrix( - sluMat.nrow, sluMat.ncol, sluMat.storage.outerInd[outerSize], - sluMat.storage.outerInd, sluMat.storage.innerInd, reinterpret_cast(sluMat.storage.values) ); -} - -} // end namespace internal - -/** \ingroup SuperLUSupport_Module - * \class SuperLUBase - * \brief The base class for the direct and incomplete LU factorization of SuperLU - */ -template -class SuperLUBase : internal::noncopyable -{ - public: - typedef _MatrixType MatrixType; - typedef typename MatrixType::Scalar Scalar; - typedef typename MatrixType::RealScalar RealScalar; - typedef typename MatrixType::Index Index; - typedef Matrix Vector; - typedef Matrix IntRowVectorType; - typedef Matrix IntColVectorType; - typedef SparseMatrix LUMatrixType; - - public: - - SuperLUBase() {} - - ~SuperLUBase() - { - clearFactors(); - } - - Derived& derived() { return *static_cast(this); } - const Derived& derived() const { return *static_cast(this); } - - inline Index rows() const { return m_matrix.rows(); } - inline Index cols() const { return m_matrix.cols(); } - - /** \returns a reference to the Super LU option object to configure the Super LU algorithms. */ - inline superlu_options_t& options() { return m_sluOptions; } - - /** \brief Reports whether previous computation was successful. - * - * \returns \c Success if computation was succesful, - * \c NumericalIssue if the matrix.appears to be negative. - */ - ComputationInfo info() const - { - eigen_assert(m_isInitialized && "Decomposition is not initialized."); - return m_info; - } - - /** Computes the sparse Cholesky decomposition of \a matrix */ - void compute(const MatrixType& matrix) - { - derived().analyzePattern(matrix); - derived().factorize(matrix); - } - - /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. - * - * \sa compute() - */ - template - inline const internal::solve_retval solve(const MatrixBase& b) const - { - eigen_assert(m_isInitialized && "SuperLU is not initialized."); - eigen_assert(rows()==b.rows() - && "SuperLU::solve(): invalid number of rows of the right hand side matrix b"); - return internal::solve_retval(*this, b.derived()); - } - - /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. - * - * \sa compute() - */ - template - inline const internal::sparse_solve_retval solve(const SparseMatrixBase& b) const - { - eigen_assert(m_isInitialized && "SuperLU is not initialized."); - eigen_assert(rows()==b.rows() - && "SuperLU::solve(): invalid number of rows of the right hand side matrix b"); - return internal::sparse_solve_retval(*this, b.derived()); - } - - /** Performs a symbolic decomposition on the sparcity of \a matrix. - * - * This function is particularly useful when solving for several problems having the same structure. - * - * \sa factorize() - */ - void analyzePattern(const MatrixType& /*matrix*/) - { - m_isInitialized = true; - m_info = Success; - m_analysisIsOk = true; - m_factorizationIsOk = false; - } - - template - void dumpMemory(Stream& /*s*/) - {} - - protected: - - void initFactorization(const MatrixType& a) - { - set_default_options(&this->m_sluOptions); - - const int size = a.rows(); - m_matrix = a; - - m_sluA = internal::asSluMatrix(m_matrix); - clearFactors(); - - m_p.resize(size); - m_q.resize(size); - m_sluRscale.resize(size); - m_sluCscale.resize(size); - m_sluEtree.resize(size); - - // set empty B and X - m_sluB.setStorageType(SLU_DN); - m_sluB.setScalarType(); - m_sluB.Mtype = SLU_GE; - m_sluB.storage.values = 0; - m_sluB.nrow = 0; - m_sluB.ncol = 0; - m_sluB.storage.lda = size; - m_sluX = m_sluB; - - m_extractedDataAreDirty = true; - } - - void init() - { - m_info = InvalidInput; - m_isInitialized = false; - m_sluL.Store = 0; - m_sluU.Store = 0; - } - - void extractData() const; - - void clearFactors() - { - if(m_sluL.Store) - Destroy_SuperNode_Matrix(&m_sluL); - if(m_sluU.Store) - Destroy_CompCol_Matrix(&m_sluU); - - m_sluL.Store = 0; - m_sluU.Store = 0; - - memset(&m_sluL,0,sizeof m_sluL); - memset(&m_sluU,0,sizeof m_sluU); - } - - // cached data to reduce reallocation, etc. - mutable LUMatrixType m_l; - mutable LUMatrixType m_u; - mutable IntColVectorType m_p; - mutable IntRowVectorType m_q; - - mutable LUMatrixType m_matrix; // copy of the factorized matrix - mutable SluMatrix m_sluA; - mutable SuperMatrix m_sluL, m_sluU; - mutable SluMatrix m_sluB, m_sluX; - mutable SuperLUStat_t m_sluStat; - mutable superlu_options_t m_sluOptions; - mutable std::vector m_sluEtree; - mutable Matrix m_sluRscale, m_sluCscale; - mutable Matrix m_sluFerr, m_sluBerr; - mutable char m_sluEqued; - - mutable ComputationInfo m_info; - bool m_isInitialized; - int m_factorizationIsOk; - int m_analysisIsOk; - mutable bool m_extractedDataAreDirty; - - private: - SuperLUBase(SuperLUBase& ) { } -}; - - -/** \ingroup SuperLUSupport_Module - * \class SuperLU - * \brief A sparse direct LU factorization and solver based on the SuperLU library - * - * This class allows to solve for A.X = B sparse linear problems via a direct LU factorization - * using the SuperLU library. The sparse matrix A must be squared and invertible. The vectors or matrices - * X and B can be either dense or sparse. - * - * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> - * - * \sa \ref TutorialSparseDirectSolvers - */ -template -class SuperLU : public SuperLUBase<_MatrixType,SuperLU<_MatrixType> > -{ - public: - typedef SuperLUBase<_MatrixType,SuperLU> Base; - typedef _MatrixType MatrixType; - typedef typename Base::Scalar Scalar; - typedef typename Base::RealScalar RealScalar; - typedef typename Base::Index Index; - typedef typename Base::IntRowVectorType IntRowVectorType; - typedef typename Base::IntColVectorType IntColVectorType; - typedef typename Base::LUMatrixType LUMatrixType; - typedef TriangularView LMatrixType; - typedef TriangularView UMatrixType; - - public: - - SuperLU() : Base() { init(); } - - SuperLU(const MatrixType& matrix) : Base() - { - init(); - Base::compute(matrix); - } - - ~SuperLU() - { - } - - /** Performs a symbolic decomposition on the sparcity of \a matrix. - * - * This function is particularly useful when solving for several problems having the same structure. - * - * \sa factorize() - */ - void analyzePattern(const MatrixType& matrix) - { - m_info = InvalidInput; - m_isInitialized = false; - Base::analyzePattern(matrix); - } - - /** Performs a numeric decomposition of \a matrix - * - * The given matrix must has the same sparcity than the matrix on which the symbolic decomposition has been performed. - * - * \sa analyzePattern() - */ - void factorize(const MatrixType& matrix); - - #ifndef EIGEN_PARSED_BY_DOXYGEN - /** \internal */ - template - void _solve(const MatrixBase &b, MatrixBase &dest) const; - #endif // EIGEN_PARSED_BY_DOXYGEN - - inline const LMatrixType& matrixL() const - { - if (m_extractedDataAreDirty) this->extractData(); - return m_l; - } - - inline const UMatrixType& matrixU() const - { - if (m_extractedDataAreDirty) this->extractData(); - return m_u; - } - - inline const IntColVectorType& permutationP() const - { - if (m_extractedDataAreDirty) this->extractData(); - return m_p; - } - - inline const IntRowVectorType& permutationQ() const - { - if (m_extractedDataAreDirty) this->extractData(); - return m_q; - } - - Scalar determinant() const; - - protected: - - using Base::m_matrix; - using Base::m_sluOptions; - using Base::m_sluA; - using Base::m_sluB; - using Base::m_sluX; - using Base::m_p; - using Base::m_q; - using Base::m_sluEtree; - using Base::m_sluEqued; - using Base::m_sluRscale; - using Base::m_sluCscale; - using Base::m_sluL; - using Base::m_sluU; - using Base::m_sluStat; - using Base::m_sluFerr; - using Base::m_sluBerr; - using Base::m_l; - using Base::m_u; - - using Base::m_analysisIsOk; - using Base::m_factorizationIsOk; - using Base::m_extractedDataAreDirty; - using Base::m_isInitialized; - using Base::m_info; - - void init() - { - Base::init(); - - set_default_options(&this->m_sluOptions); - m_sluOptions.PrintStat = NO; - m_sluOptions.ConditionNumber = NO; - m_sluOptions.Trans = NOTRANS; - m_sluOptions.ColPerm = COLAMD; - } - - - private: - SuperLU(SuperLU& ) { } -}; - -template -void SuperLU::factorize(const MatrixType& a) -{ - eigen_assert(m_analysisIsOk && "You must first call analyzePattern()"); - if(!m_analysisIsOk) - { - m_info = InvalidInput; - return; - } - - this->initFactorization(a); - - m_sluOptions.ColPerm = COLAMD; - int info = 0; - RealScalar recip_pivot_growth, rcond; - RealScalar ferr, berr; - - StatInit(&m_sluStat); - SuperLU_gssvx(&m_sluOptions, &m_sluA, m_q.data(), m_p.data(), &m_sluEtree[0], - &m_sluEqued, &m_sluRscale[0], &m_sluCscale[0], - &m_sluL, &m_sluU, - NULL, 0, - &m_sluB, &m_sluX, - &recip_pivot_growth, &rcond, - &ferr, &berr, - &m_sluStat, &info, Scalar()); - StatFree(&m_sluStat); - - m_extractedDataAreDirty = true; - - // FIXME how to better check for errors ??? - m_info = info == 0 ? Success : NumericalIssue; - m_factorizationIsOk = true; -} - -template -template -void SuperLU::_solve(const MatrixBase &b, MatrixBase& x) const -{ - eigen_assert(m_factorizationIsOk && "The decomposition is not in a valid state for solving, you must first call either compute() or analyzePattern()/factorize()"); - - const int size = m_matrix.rows(); - const int rhsCols = b.cols(); - eigen_assert(size==b.rows()); - - m_sluOptions.Trans = NOTRANS; - m_sluOptions.Fact = FACTORED; - m_sluOptions.IterRefine = NOREFINE; - - - m_sluFerr.resize(rhsCols); - m_sluBerr.resize(rhsCols); - m_sluB = SluMatrix::Map(b.const_cast_derived()); - m_sluX = SluMatrix::Map(x.derived()); - - typename Rhs::PlainObject b_cpy; - if(m_sluEqued!='N') - { - b_cpy = b; - m_sluB = SluMatrix::Map(b_cpy.const_cast_derived()); - } - - StatInit(&m_sluStat); - int info = 0; - RealScalar recip_pivot_growth, rcond; - SuperLU_gssvx(&m_sluOptions, &m_sluA, - m_q.data(), m_p.data(), - &m_sluEtree[0], &m_sluEqued, - &m_sluRscale[0], &m_sluCscale[0], - &m_sluL, &m_sluU, - NULL, 0, - &m_sluB, &m_sluX, - &recip_pivot_growth, &rcond, - &m_sluFerr[0], &m_sluBerr[0], - &m_sluStat, &info, Scalar()); - StatFree(&m_sluStat); - m_info = info==0 ? Success : NumericalIssue; -} - -// the code of this extractData() function has been adapted from the SuperLU's Matlab support code, -// -// Copyright (c) 1994 by Xerox Corporation. All rights reserved. -// -// THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY -// EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK. -// -template -void SuperLUBase::extractData() const -{ - eigen_assert(m_factorizationIsOk && "The decomposition is not in a valid state for extracting factors, you must first call either compute() or analyzePattern()/factorize()"); - if (m_extractedDataAreDirty) - { - int upper; - int fsupc, istart, nsupr; - int lastl = 0, lastu = 0; - SCformat *Lstore = static_cast(m_sluL.Store); - NCformat *Ustore = static_cast(m_sluU.Store); - Scalar *SNptr; - - const int size = m_matrix.rows(); - m_l.resize(size,size); - m_l.resizeNonZeros(Lstore->nnz); - m_u.resize(size,size); - m_u.resizeNonZeros(Ustore->nnz); - - int* Lcol = m_l.outerIndexPtr(); - int* Lrow = m_l.innerIndexPtr(); - Scalar* Lval = m_l.valuePtr(); - - int* Ucol = m_u.outerIndexPtr(); - int* Urow = m_u.innerIndexPtr(); - Scalar* Uval = m_u.valuePtr(); - - Ucol[0] = 0; - Ucol[0] = 0; - - /* for each supernode */ - for (int k = 0; k <= Lstore->nsuper; ++k) - { - fsupc = L_FST_SUPC(k); - istart = L_SUB_START(fsupc); - nsupr = L_SUB_START(fsupc+1) - istart; - upper = 1; - - /* for each column in the supernode */ - for (int j = fsupc; j < L_FST_SUPC(k+1); ++j) - { - SNptr = &((Scalar*)Lstore->nzval)[L_NZ_START(j)]; - - /* Extract U */ - for (int i = U_NZ_START(j); i < U_NZ_START(j+1); ++i) - { - Uval[lastu] = ((Scalar*)Ustore->nzval)[i]; - /* Matlab doesn't like explicit zero. */ - if (Uval[lastu] != 0.0) - Urow[lastu++] = U_SUB(i); - } - for (int i = 0; i < upper; ++i) - { - /* upper triangle in the supernode */ - Uval[lastu] = SNptr[i]; - /* Matlab doesn't like explicit zero. */ - if (Uval[lastu] != 0.0) - Urow[lastu++] = L_SUB(istart+i); - } - Ucol[j+1] = lastu; - - /* Extract L */ - Lval[lastl] = 1.0; /* unit diagonal */ - Lrow[lastl++] = L_SUB(istart + upper - 1); - for (int i = upper; i < nsupr; ++i) - { - Lval[lastl] = SNptr[i]; - /* Matlab doesn't like explicit zero. */ - if (Lval[lastl] != 0.0) - Lrow[lastl++] = L_SUB(istart+i); - } - Lcol[j+1] = lastl; - - ++upper; - } /* for j ... */ - - } /* for k ... */ - - // squeeze the matrices : - m_l.resizeNonZeros(lastl); - m_u.resizeNonZeros(lastu); - - m_extractedDataAreDirty = false; - } -} - -template -typename SuperLU::Scalar SuperLU::determinant() const -{ - eigen_assert(m_factorizationIsOk && "The decomposition is not in a valid state for computing the determinant, you must first call either compute() or analyzePattern()/factorize()"); - - if (m_extractedDataAreDirty) - this->extractData(); - - Scalar det = Scalar(1); - for (int j=0; j 0) - { - int lastId = m_u.outerIndexPtr()[j+1]-1; - eigen_assert(m_u.innerIndexPtr()[lastId]<=j); - if (m_u.innerIndexPtr()[lastId]==j) - det *= m_u.valuePtr()[lastId]; - } - } - if(m_sluEqued!='N') - return det/m_sluRscale.prod()/m_sluCscale.prod(); - else - return det; -} - -#ifdef EIGEN_PARSED_BY_DOXYGEN -#define EIGEN_SUPERLU_HAS_ILU -#endif - -#ifdef EIGEN_SUPERLU_HAS_ILU - -/** \ingroup SuperLUSupport_Module - * \class SuperILU - * \brief A sparse direct \b incomplete LU factorization and solver based on the SuperLU library - * - * This class allows to solve for an approximate solution of A.X = B sparse linear problems via an incomplete LU factorization - * using the SuperLU library. This class is aimed to be used as a preconditioner of the iterative linear solvers. - * - * \warning This class requires SuperLU 4 or later. - * - * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> - * - * \sa \ref TutorialSparseDirectSolvers, class ConjugateGradient, class BiCGSTAB - */ - -template -class SuperILU : public SuperLUBase<_MatrixType,SuperILU<_MatrixType> > -{ - public: - typedef SuperLUBase<_MatrixType,SuperILU> Base; - typedef _MatrixType MatrixType; - typedef typename Base::Scalar Scalar; - typedef typename Base::RealScalar RealScalar; - typedef typename Base::Index Index; - - public: - - SuperILU() : Base() { init(); } - - SuperILU(const MatrixType& matrix) : Base() - { - init(); - Base::compute(matrix); - } - - ~SuperILU() - { - } - - /** Performs a symbolic decomposition on the sparcity of \a matrix. - * - * This function is particularly useful when solving for several problems having the same structure. - * - * \sa factorize() - */ - void analyzePattern(const MatrixType& matrix) - { - Base::analyzePattern(matrix); - } - - /** Performs a numeric decomposition of \a matrix - * - * The given matrix must has the same sparcity than the matrix on which the symbolic decomposition has been performed. - * - * \sa analyzePattern() - */ - void factorize(const MatrixType& matrix); - - #ifndef EIGEN_PARSED_BY_DOXYGEN - /** \internal */ - template - void _solve(const MatrixBase &b, MatrixBase &dest) const; - #endif // EIGEN_PARSED_BY_DOXYGEN - - protected: - - using Base::m_matrix; - using Base::m_sluOptions; - using Base::m_sluA; - using Base::m_sluB; - using Base::m_sluX; - using Base::m_p; - using Base::m_q; - using Base::m_sluEtree; - using Base::m_sluEqued; - using Base::m_sluRscale; - using Base::m_sluCscale; - using Base::m_sluL; - using Base::m_sluU; - using Base::m_sluStat; - using Base::m_sluFerr; - using Base::m_sluBerr; - using Base::m_l; - using Base::m_u; - - using Base::m_analysisIsOk; - using Base::m_factorizationIsOk; - using Base::m_extractedDataAreDirty; - using Base::m_isInitialized; - using Base::m_info; - - void init() - { - Base::init(); - - ilu_set_default_options(&m_sluOptions); - m_sluOptions.PrintStat = NO; - m_sluOptions.ConditionNumber = NO; - m_sluOptions.Trans = NOTRANS; - m_sluOptions.ColPerm = MMD_AT_PLUS_A; - - // no attempt to preserve column sum - m_sluOptions.ILU_MILU = SILU; - // only basic ILU(k) support -- no direct control over memory consumption - // better to use ILU_DropRule = DROP_BASIC | DROP_AREA - // and set ILU_FillFactor to max memory growth - m_sluOptions.ILU_DropRule = DROP_BASIC; - m_sluOptions.ILU_DropTol = NumTraits::dummy_precision()*10; - } - - private: - SuperILU(SuperILU& ) { } -}; - -template -void SuperILU::factorize(const MatrixType& a) -{ - eigen_assert(m_analysisIsOk && "You must first call analyzePattern()"); - if(!m_analysisIsOk) - { - m_info = InvalidInput; - return; - } - - this->initFactorization(a); - - int info = 0; - RealScalar recip_pivot_growth, rcond; - - StatInit(&m_sluStat); - SuperLU_gsisx(&m_sluOptions, &m_sluA, m_q.data(), m_p.data(), &m_sluEtree[0], - &m_sluEqued, &m_sluRscale[0], &m_sluCscale[0], - &m_sluL, &m_sluU, - NULL, 0, - &m_sluB, &m_sluX, - &recip_pivot_growth, &rcond, - &m_sluStat, &info, Scalar()); - StatFree(&m_sluStat); - - // FIXME how to better check for errors ??? - m_info = info == 0 ? Success : NumericalIssue; - m_factorizationIsOk = true; -} - -template -template -void SuperILU::_solve(const MatrixBase &b, MatrixBase& x) const -{ - eigen_assert(m_factorizationIsOk && "The decomposition is not in a valid state for solving, you must first call either compute() or analyzePattern()/factorize()"); - - const int size = m_matrix.rows(); - const int rhsCols = b.cols(); - eigen_assert(size==b.rows()); - - m_sluOptions.Trans = NOTRANS; - m_sluOptions.Fact = FACTORED; - m_sluOptions.IterRefine = NOREFINE; - - m_sluFerr.resize(rhsCols); - m_sluBerr.resize(rhsCols); - m_sluB = SluMatrix::Map(b.const_cast_derived()); - m_sluX = SluMatrix::Map(x.derived()); - - typename Rhs::PlainObject b_cpy; - if(m_sluEqued!='N') - { - b_cpy = b; - m_sluB = SluMatrix::Map(b_cpy.const_cast_derived()); - } - - int info = 0; - RealScalar recip_pivot_growth, rcond; - - StatInit(&m_sluStat); - SuperLU_gsisx(&m_sluOptions, &m_sluA, - m_q.data(), m_p.data(), - &m_sluEtree[0], &m_sluEqued, - &m_sluRscale[0], &m_sluCscale[0], - &m_sluL, &m_sluU, - NULL, 0, - &m_sluB, &m_sluX, - &recip_pivot_growth, &rcond, - &m_sluStat, &info, Scalar()); - StatFree(&m_sluStat); - - m_info = info==0 ? Success : NumericalIssue; -} -#endif - -namespace internal { - -template -struct solve_retval, Rhs> - : solve_retval_base, Rhs> -{ - typedef SuperLUBase<_MatrixType,Derived> Dec; - EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs) - - template void evalTo(Dest& dst) const - { - dec().derived()._solve(rhs(),dst); - } -}; - -template -struct sparse_solve_retval, Rhs> - : sparse_solve_retval_base, Rhs> -{ - typedef SuperLUBase<_MatrixType,Derived> Dec; - EIGEN_MAKE_SPARSE_SOLVE_HELPERS(Dec,Rhs) - - template void evalTo(Dest& dst) const - { - this->defaultEvalTo(dst); - } -}; - -} // end namespace internal - -} // end namespace Eigen - -#endif // EIGEN_SUPERLUSUPPORT_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/UmfPackSupport/UmfPackSupport.h b/thirdparty/eigen-3.2.7/Eigen/src/UmfPackSupport/UmfPackSupport.h deleted file mode 100644 index 29c60c37..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/UmfPackSupport/UmfPackSupport.h +++ /dev/null @@ -1,474 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2011 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_UMFPACKSUPPORT_H -#define EIGEN_UMFPACKSUPPORT_H - -namespace Eigen { - -/* TODO extract L, extract U, compute det, etc... */ - -// generic double/complex wrapper functions: - -inline void umfpack_free_numeric(void **Numeric, double) -{ umfpack_di_free_numeric(Numeric); *Numeric = 0; } - -inline void umfpack_free_numeric(void **Numeric, std::complex) -{ umfpack_zi_free_numeric(Numeric); *Numeric = 0; } - -inline void umfpack_free_symbolic(void **Symbolic, double) -{ umfpack_di_free_symbolic(Symbolic); *Symbolic = 0; } - -inline void umfpack_free_symbolic(void **Symbolic, std::complex) -{ umfpack_zi_free_symbolic(Symbolic); *Symbolic = 0; } - -inline int umfpack_symbolic(int n_row,int n_col, - const int Ap[], const int Ai[], const double Ax[], void **Symbolic, - const double Control [UMFPACK_CONTROL], double Info [UMFPACK_INFO]) -{ - return umfpack_di_symbolic(n_row,n_col,Ap,Ai,Ax,Symbolic,Control,Info); -} - -inline int umfpack_symbolic(int n_row,int n_col, - const int Ap[], const int Ai[], const std::complex Ax[], void **Symbolic, - const double Control [UMFPACK_CONTROL], double Info [UMFPACK_INFO]) -{ - return umfpack_zi_symbolic(n_row,n_col,Ap,Ai,&numext::real_ref(Ax[0]),0,Symbolic,Control,Info); -} - -inline int umfpack_numeric( const int Ap[], const int Ai[], const double Ax[], - void *Symbolic, void **Numeric, - const double Control[UMFPACK_CONTROL],double Info [UMFPACK_INFO]) -{ - return umfpack_di_numeric(Ap,Ai,Ax,Symbolic,Numeric,Control,Info); -} - -inline int umfpack_numeric( const int Ap[], const int Ai[], const std::complex Ax[], - void *Symbolic, void **Numeric, - const double Control[UMFPACK_CONTROL],double Info [UMFPACK_INFO]) -{ - return umfpack_zi_numeric(Ap,Ai,&numext::real_ref(Ax[0]),0,Symbolic,Numeric,Control,Info); -} - -inline int umfpack_solve( int sys, const int Ap[], const int Ai[], const double Ax[], - double X[], const double B[], void *Numeric, - const double Control[UMFPACK_CONTROL], double Info[UMFPACK_INFO]) -{ - return umfpack_di_solve(sys,Ap,Ai,Ax,X,B,Numeric,Control,Info); -} - -inline int umfpack_solve( int sys, const int Ap[], const int Ai[], const std::complex Ax[], - std::complex X[], const std::complex B[], void *Numeric, - const double Control[UMFPACK_CONTROL], double Info[UMFPACK_INFO]) -{ - return umfpack_zi_solve(sys,Ap,Ai,&numext::real_ref(Ax[0]),0,&numext::real_ref(X[0]),0,&numext::real_ref(B[0]),0,Numeric,Control,Info); -} - -inline int umfpack_get_lunz(int *lnz, int *unz, int *n_row, int *n_col, int *nz_udiag, void *Numeric, double) -{ - return umfpack_di_get_lunz(lnz,unz,n_row,n_col,nz_udiag,Numeric); -} - -inline int umfpack_get_lunz(int *lnz, int *unz, int *n_row, int *n_col, int *nz_udiag, void *Numeric, std::complex) -{ - return umfpack_zi_get_lunz(lnz,unz,n_row,n_col,nz_udiag,Numeric); -} - -inline int umfpack_get_numeric(int Lp[], int Lj[], double Lx[], int Up[], int Ui[], double Ux[], - int P[], int Q[], double Dx[], int *do_recip, double Rs[], void *Numeric) -{ - return umfpack_di_get_numeric(Lp,Lj,Lx,Up,Ui,Ux,P,Q,Dx,do_recip,Rs,Numeric); -} - -inline int umfpack_get_numeric(int Lp[], int Lj[], std::complex Lx[], int Up[], int Ui[], std::complex Ux[], - int P[], int Q[], std::complex Dx[], int *do_recip, double Rs[], void *Numeric) -{ - double& lx0_real = numext::real_ref(Lx[0]); - double& ux0_real = numext::real_ref(Ux[0]); - double& dx0_real = numext::real_ref(Dx[0]); - return umfpack_zi_get_numeric(Lp,Lj,Lx?&lx0_real:0,0,Up,Ui,Ux?&ux0_real:0,0,P,Q, - Dx?&dx0_real:0,0,do_recip,Rs,Numeric); -} - -inline int umfpack_get_determinant(double *Mx, double *Ex, void *NumericHandle, double User_Info [UMFPACK_INFO]) -{ - return umfpack_di_get_determinant(Mx,Ex,NumericHandle,User_Info); -} - -inline int umfpack_get_determinant(std::complex *Mx, double *Ex, void *NumericHandle, double User_Info [UMFPACK_INFO]) -{ - double& mx_real = numext::real_ref(*Mx); - return umfpack_zi_get_determinant(&mx_real,0,Ex,NumericHandle,User_Info); -} - -namespace internal { - template struct umfpack_helper_is_sparse_plain : false_type {}; - template - struct umfpack_helper_is_sparse_plain > - : true_type {}; - template - struct umfpack_helper_is_sparse_plain > - : true_type {}; -} - -/** \ingroup UmfPackSupport_Module - * \brief A sparse LU factorization and solver based on UmfPack - * - * This class allows to solve for A.X = B sparse linear problems via a LU factorization - * using the UmfPack library. The sparse matrix A must be squared and full rank. - * The vectors or matrices X and B can be either dense or sparse. - * - * \warning The input matrix A should be in a \b compressed and \b column-major form. - * Otherwise an expensive copy will be made. You can call the inexpensive makeCompressed() to get a compressed matrix. - * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> - * - * \sa \ref TutorialSparseDirectSolvers - */ -template -class UmfPackLU : internal::noncopyable -{ - public: - typedef _MatrixType MatrixType; - typedef typename MatrixType::Scalar Scalar; - typedef typename MatrixType::RealScalar RealScalar; - typedef typename MatrixType::Index Index; - typedef Matrix Vector; - typedef Matrix IntRowVectorType; - typedef Matrix IntColVectorType; - typedef SparseMatrix LUMatrixType; - typedef SparseMatrix UmfpackMatrixType; - - public: - - UmfPackLU() { init(); } - - UmfPackLU(const MatrixType& matrix) - { - init(); - compute(matrix); - } - - ~UmfPackLU() - { - if(m_symbolic) umfpack_free_symbolic(&m_symbolic,Scalar()); - if(m_numeric) umfpack_free_numeric(&m_numeric,Scalar()); - } - - inline Index rows() const { return m_copyMatrix.rows(); } - inline Index cols() const { return m_copyMatrix.cols(); } - - /** \brief Reports whether previous computation was successful. - * - * \returns \c Success if computation was succesful, - * \c NumericalIssue if the matrix.appears to be negative. - */ - ComputationInfo info() const - { - eigen_assert(m_isInitialized && "Decomposition is not initialized."); - return m_info; - } - - inline const LUMatrixType& matrixL() const - { - if (m_extractedDataAreDirty) extractData(); - return m_l; - } - - inline const LUMatrixType& matrixU() const - { - if (m_extractedDataAreDirty) extractData(); - return m_u; - } - - inline const IntColVectorType& permutationP() const - { - if (m_extractedDataAreDirty) extractData(); - return m_p; - } - - inline const IntRowVectorType& permutationQ() const - { - if (m_extractedDataAreDirty) extractData(); - return m_q; - } - - /** Computes the sparse Cholesky decomposition of \a matrix - * Note that the matrix should be column-major, and in compressed format for best performance. - * \sa SparseMatrix::makeCompressed(). - */ - template - void compute(const InputMatrixType& matrix) - { - if(m_symbolic) umfpack_free_symbolic(&m_symbolic,Scalar()); - if(m_numeric) umfpack_free_numeric(&m_numeric,Scalar()); - grapInput(matrix.derived()); - analyzePattern_impl(); - factorize_impl(); - } - - /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. - * - * \sa compute() - */ - template - inline const internal::solve_retval solve(const MatrixBase& b) const - { - eigen_assert(m_isInitialized && "UmfPackLU is not initialized."); - eigen_assert(rows()==b.rows() - && "UmfPackLU::solve(): invalid number of rows of the right hand side matrix b"); - return internal::solve_retval(*this, b.derived()); - } - - /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. - * - * \sa compute() - */ - template - inline const internal::sparse_solve_retval solve(const SparseMatrixBase& b) const - { - eigen_assert(m_isInitialized && "UmfPackLU is not initialized."); - eigen_assert(rows()==b.rows() - && "UmfPackLU::solve(): invalid number of rows of the right hand side matrix b"); - return internal::sparse_solve_retval(*this, b.derived()); - } - - /** Performs a symbolic decomposition on the sparcity of \a matrix. - * - * This function is particularly useful when solving for several problems having the same structure. - * - * \sa factorize(), compute() - */ - template - void analyzePattern(const InputMatrixType& matrix) - { - if(m_symbolic) umfpack_free_symbolic(&m_symbolic,Scalar()); - if(m_numeric) umfpack_free_numeric(&m_numeric,Scalar()); - - grapInput(matrix.derived()); - - analyzePattern_impl(); - } - - /** Performs a numeric decomposition of \a matrix - * - * The given matrix must has the same sparcity than the matrix on which the pattern anylysis has been performed. - * - * \sa analyzePattern(), compute() - */ - template - void factorize(const InputMatrixType& matrix) - { - eigen_assert(m_analysisIsOk && "UmfPackLU: you must first call analyzePattern()"); - if(m_numeric) - umfpack_free_numeric(&m_numeric,Scalar()); - - grapInput(matrix.derived()); - - factorize_impl(); - } - - #ifndef EIGEN_PARSED_BY_DOXYGEN - /** \internal */ - template - bool _solve(const MatrixBase &b, MatrixBase &x) const; - #endif - - Scalar determinant() const; - - void extractData() const; - - protected: - - void init() - { - m_info = InvalidInput; - m_isInitialized = false; - m_numeric = 0; - m_symbolic = 0; - m_outerIndexPtr = 0; - m_innerIndexPtr = 0; - m_valuePtr = 0; - m_extractedDataAreDirty = true; - } - - template - void grapInput_impl(const InputMatrixType& mat, internal::true_type) - { - m_copyMatrix.resize(mat.rows(), mat.cols()); - if( ((MatrixType::Flags&RowMajorBit)==RowMajorBit) || sizeof(typename MatrixType::Index)!=sizeof(int) || !mat.isCompressed() ) - { - // non supported input -> copy - m_copyMatrix = mat; - m_outerIndexPtr = m_copyMatrix.outerIndexPtr(); - m_innerIndexPtr = m_copyMatrix.innerIndexPtr(); - m_valuePtr = m_copyMatrix.valuePtr(); - } - else - { - m_outerIndexPtr = mat.outerIndexPtr(); - m_innerIndexPtr = mat.innerIndexPtr(); - m_valuePtr = mat.valuePtr(); - } - } - - template - void grapInput_impl(const InputMatrixType& mat, internal::false_type) - { - m_copyMatrix = mat; - m_outerIndexPtr = m_copyMatrix.outerIndexPtr(); - m_innerIndexPtr = m_copyMatrix.innerIndexPtr(); - m_valuePtr = m_copyMatrix.valuePtr(); - } - - template - void grapInput(const InputMatrixType& mat) - { - grapInput_impl(mat, internal::umfpack_helper_is_sparse_plain()); - } - - void analyzePattern_impl() - { - int errorCode = 0; - errorCode = umfpack_symbolic(m_copyMatrix.rows(), m_copyMatrix.cols(), m_outerIndexPtr, m_innerIndexPtr, m_valuePtr, - &m_symbolic, 0, 0); - - m_isInitialized = true; - m_info = errorCode ? InvalidInput : Success; - m_analysisIsOk = true; - m_factorizationIsOk = false; - m_extractedDataAreDirty = true; - } - - void factorize_impl() - { - int errorCode; - errorCode = umfpack_numeric(m_outerIndexPtr, m_innerIndexPtr, m_valuePtr, - m_symbolic, &m_numeric, 0, 0); - - m_info = errorCode ? NumericalIssue : Success; - m_factorizationIsOk = true; - m_extractedDataAreDirty = true; - } - - // cached data to reduce reallocation, etc. - mutable LUMatrixType m_l; - mutable LUMatrixType m_u; - mutable IntColVectorType m_p; - mutable IntRowVectorType m_q; - - UmfpackMatrixType m_copyMatrix; - const Scalar* m_valuePtr; - const int* m_outerIndexPtr; - const int* m_innerIndexPtr; - void* m_numeric; - void* m_symbolic; - - mutable ComputationInfo m_info; - bool m_isInitialized; - int m_factorizationIsOk; - int m_analysisIsOk; - mutable bool m_extractedDataAreDirty; - - private: - UmfPackLU(UmfPackLU& ) { } -}; - - -template -void UmfPackLU::extractData() const -{ - if (m_extractedDataAreDirty) - { - // get size of the data - int lnz, unz, rows, cols, nz_udiag; - umfpack_get_lunz(&lnz, &unz, &rows, &cols, &nz_udiag, m_numeric, Scalar()); - - // allocate data - m_l.resize(rows,(std::min)(rows,cols)); - m_l.resizeNonZeros(lnz); - - m_u.resize((std::min)(rows,cols),cols); - m_u.resizeNonZeros(unz); - - m_p.resize(rows); - m_q.resize(cols); - - // extract - umfpack_get_numeric(m_l.outerIndexPtr(), m_l.innerIndexPtr(), m_l.valuePtr(), - m_u.outerIndexPtr(), m_u.innerIndexPtr(), m_u.valuePtr(), - m_p.data(), m_q.data(), 0, 0, 0, m_numeric); - - m_extractedDataAreDirty = false; - } -} - -template -typename UmfPackLU::Scalar UmfPackLU::determinant() const -{ - Scalar det; - umfpack_get_determinant(&det, 0, m_numeric, 0); - return det; -} - -template -template -bool UmfPackLU::_solve(const MatrixBase &b, MatrixBase &x) const -{ - const int rhsCols = b.cols(); - eigen_assert((BDerived::Flags&RowMajorBit)==0 && "UmfPackLU backend does not support non col-major rhs yet"); - eigen_assert((XDerived::Flags&RowMajorBit)==0 && "UmfPackLU backend does not support non col-major result yet"); - eigen_assert(b.derived().data() != x.derived().data() && " Umfpack does not support inplace solve"); - - int errorCode; - for (int j=0; j -struct solve_retval, Rhs> - : solve_retval_base, Rhs> -{ - typedef UmfPackLU<_MatrixType> Dec; - EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs) - - template void evalTo(Dest& dst) const - { - dec()._solve(rhs(),dst); - } -}; - -template -struct sparse_solve_retval, Rhs> - : sparse_solve_retval_base, Rhs> -{ - typedef UmfPackLU<_MatrixType> Dec; - EIGEN_MAKE_SPARSE_SOLVE_HELPERS(Dec,Rhs) - - template void evalTo(Dest& dst) const - { - this->defaultEvalTo(dst); - } -}; - -} // end namespace internal - -} // end namespace Eigen - -#endif // EIGEN_UMFPACKSUPPORT_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/misc/Image.h b/thirdparty/eigen-3.2.7/Eigen/src/misc/Image.h deleted file mode 100644 index 75c5f433..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/misc/Image.h +++ /dev/null @@ -1,84 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2009 Benoit Jacob -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_MISC_IMAGE_H -#define EIGEN_MISC_IMAGE_H - -namespace Eigen { - -namespace internal { - -/** \class image_retval_base - * - */ -template -struct traits > -{ - typedef typename DecompositionType::MatrixType MatrixType; - typedef Matrix< - typename MatrixType::Scalar, - MatrixType::RowsAtCompileTime, // the image is a subspace of the destination space, whose - // dimension is the number of rows of the original matrix - Dynamic, // we don't know at compile time the dimension of the image (the rank) - MatrixType::Options, - MatrixType::MaxRowsAtCompileTime, // the image matrix will consist of columns from the original matrix, - MatrixType::MaxColsAtCompileTime // so it has the same number of rows and at most as many columns. - > ReturnType; -}; - -template struct image_retval_base - : public ReturnByValue > -{ - typedef _DecompositionType DecompositionType; - typedef typename DecompositionType::MatrixType MatrixType; - typedef ReturnByValue Base; - typedef typename Base::Index Index; - - image_retval_base(const DecompositionType& dec, const MatrixType& originalMatrix) - : m_dec(dec), m_rank(dec.rank()), - m_cols(m_rank == 0 ? 1 : m_rank), - m_originalMatrix(originalMatrix) - {} - - inline Index rows() const { return m_dec.rows(); } - inline Index cols() const { return m_cols; } - inline Index rank() const { return m_rank; } - inline const DecompositionType& dec() const { return m_dec; } - inline const MatrixType& originalMatrix() const { return m_originalMatrix; } - - template inline void evalTo(Dest& dst) const - { - static_cast*>(this)->evalTo(dst); - } - - protected: - const DecompositionType& m_dec; - Index m_rank, m_cols; - const MatrixType& m_originalMatrix; -}; - -} // end namespace internal - -#define EIGEN_MAKE_IMAGE_HELPERS(DecompositionType) \ - typedef typename DecompositionType::MatrixType MatrixType; \ - typedef typename MatrixType::Scalar Scalar; \ - typedef typename MatrixType::RealScalar RealScalar; \ - typedef typename MatrixType::Index Index; \ - typedef Eigen::internal::image_retval_base Base; \ - using Base::dec; \ - using Base::originalMatrix; \ - using Base::rank; \ - using Base::rows; \ - using Base::cols; \ - image_retval(const DecompositionType& dec, const MatrixType& originalMatrix) \ - : Base(dec, originalMatrix) {} - -} // end namespace Eigen - -#endif // EIGEN_MISC_IMAGE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/misc/Kernel.h b/thirdparty/eigen-3.2.7/Eigen/src/misc/Kernel.h deleted file mode 100644 index b9e1518f..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/misc/Kernel.h +++ /dev/null @@ -1,81 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2009 Benoit Jacob -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_MISC_KERNEL_H -#define EIGEN_MISC_KERNEL_H - -namespace Eigen { - -namespace internal { - -/** \class kernel_retval_base - * - */ -template -struct traits > -{ - typedef typename DecompositionType::MatrixType MatrixType; - typedef Matrix< - typename MatrixType::Scalar, - MatrixType::ColsAtCompileTime, // the number of rows in the "kernel matrix" - // is the number of cols of the original matrix - // so that the product "matrix * kernel = zero" makes sense - Dynamic, // we don't know at compile-time the dimension of the kernel - MatrixType::Options, - MatrixType::MaxColsAtCompileTime, // see explanation for 2nd template parameter - MatrixType::MaxColsAtCompileTime // the kernel is a subspace of the domain space, - // whose dimension is the number of columns of the original matrix - > ReturnType; -}; - -template struct kernel_retval_base - : public ReturnByValue > -{ - typedef _DecompositionType DecompositionType; - typedef ReturnByValue Base; - typedef typename Base::Index Index; - - kernel_retval_base(const DecompositionType& dec) - : m_dec(dec), - m_rank(dec.rank()), - m_cols(m_rank==dec.cols() ? 1 : dec.cols() - m_rank) - {} - - inline Index rows() const { return m_dec.cols(); } - inline Index cols() const { return m_cols; } - inline Index rank() const { return m_rank; } - inline const DecompositionType& dec() const { return m_dec; } - - template inline void evalTo(Dest& dst) const - { - static_cast*>(this)->evalTo(dst); - } - - protected: - const DecompositionType& m_dec; - Index m_rank, m_cols; -}; - -} // end namespace internal - -#define EIGEN_MAKE_KERNEL_HELPERS(DecompositionType) \ - typedef typename DecompositionType::MatrixType MatrixType; \ - typedef typename MatrixType::Scalar Scalar; \ - typedef typename MatrixType::RealScalar RealScalar; \ - typedef typename MatrixType::Index Index; \ - typedef Eigen::internal::kernel_retval_base Base; \ - using Base::dec; \ - using Base::rank; \ - using Base::rows; \ - using Base::cols; \ - kernel_retval(const DecompositionType& dec) : Base(dec) {} - -} // end namespace Eigen - -#endif // EIGEN_MISC_KERNEL_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/misc/Solve.h b/thirdparty/eigen-3.2.7/Eigen/src/misc/Solve.h deleted file mode 100644 index 7f70d60a..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/misc/Solve.h +++ /dev/null @@ -1,76 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2009 Benoit Jacob -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_MISC_SOLVE_H -#define EIGEN_MISC_SOLVE_H - -namespace Eigen { - -namespace internal { - -/** \class solve_retval_base - * - */ -template -struct traits > -{ - typedef typename DecompositionType::MatrixType MatrixType; - typedef Matrix ReturnType; -}; - -template struct solve_retval_base - : public ReturnByValue > -{ - typedef typename remove_all::type RhsNestedCleaned; - typedef _DecompositionType DecompositionType; - typedef ReturnByValue Base; - typedef typename Base::Index Index; - - solve_retval_base(const DecompositionType& dec, const Rhs& rhs) - : m_dec(dec), m_rhs(rhs) - {} - - inline Index rows() const { return m_dec.cols(); } - inline Index cols() const { return m_rhs.cols(); } - inline const DecompositionType& dec() const { return m_dec; } - inline const RhsNestedCleaned& rhs() const { return m_rhs; } - - template inline void evalTo(Dest& dst) const - { - static_cast*>(this)->evalTo(dst); - } - - protected: - const DecompositionType& m_dec; - typename Rhs::Nested m_rhs; -}; - -} // end namespace internal - -#define EIGEN_MAKE_SOLVE_HELPERS(DecompositionType,Rhs) \ - typedef typename DecompositionType::MatrixType MatrixType; \ - typedef typename MatrixType::Scalar Scalar; \ - typedef typename MatrixType::RealScalar RealScalar; \ - typedef typename MatrixType::Index Index; \ - typedef Eigen::internal::solve_retval_base Base; \ - using Base::dec; \ - using Base::rhs; \ - using Base::rows; \ - using Base::cols; \ - solve_retval(const DecompositionType& dec, const Rhs& rhs) \ - : Base(dec, rhs) {} - -} // end namespace Eigen - -#endif // EIGEN_MISC_SOLVE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/misc/SparseSolve.h b/thirdparty/eigen-3.2.7/Eigen/src/misc/SparseSolve.h deleted file mode 100644 index 244bb8ec..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/misc/SparseSolve.h +++ /dev/null @@ -1,128 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2010 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_SPARSE_SOLVE_H -#define EIGEN_SPARSE_SOLVE_H - -namespace Eigen { - -namespace internal { - -template struct sparse_solve_retval_base; -template struct sparse_solve_retval; - -template -struct traits > -{ - typedef typename DecompositionType::MatrixType MatrixType; - typedef SparseMatrix ReturnType; -}; - -template struct sparse_solve_retval_base - : public ReturnByValue > -{ - typedef typename remove_all::type RhsNestedCleaned; - typedef _DecompositionType DecompositionType; - typedef ReturnByValue Base; - typedef typename Base::Index Index; - - sparse_solve_retval_base(const DecompositionType& dec, const Rhs& rhs) - : m_dec(dec), m_rhs(rhs) - {} - - inline Index rows() const { return m_dec.cols(); } - inline Index cols() const { return m_rhs.cols(); } - inline const DecompositionType& dec() const { return m_dec; } - inline const RhsNestedCleaned& rhs() const { return m_rhs; } - - template inline void evalTo(Dest& dst) const - { - static_cast*>(this)->evalTo(dst); - } - - protected: - template - inline void defaultEvalTo(SparseMatrix& dst) const - { - // we process the sparse rhs per block of NbColsAtOnce columns temporarily stored into a dense matrix. - static const int NbColsAtOnce = 4; - int rhsCols = m_rhs.cols(); - int size = m_rhs.rows(); - Eigen::Matrix tmp(size,rhsCols); - Eigen::Matrix tmpX(size,rhsCols); - for(int k=0; k(rhsCols-k, NbColsAtOnce); - tmp.leftCols(actualCols) = m_rhs.middleCols(k,actualCols); - tmpX.leftCols(actualCols) = m_dec.solve(tmp.leftCols(actualCols)); - dst.middleCols(k,actualCols) = tmpX.leftCols(actualCols).sparseView(); - } - } - const DecompositionType& m_dec; - typename Rhs::Nested m_rhs; -}; - -#define EIGEN_MAKE_SPARSE_SOLVE_HELPERS(DecompositionType,Rhs) \ - typedef typename DecompositionType::MatrixType MatrixType; \ - typedef typename MatrixType::Scalar Scalar; \ - typedef typename MatrixType::RealScalar RealScalar; \ - typedef typename MatrixType::Index Index; \ - typedef Eigen::internal::sparse_solve_retval_base Base; \ - using Base::dec; \ - using Base::rhs; \ - using Base::rows; \ - using Base::cols; \ - sparse_solve_retval(const DecompositionType& dec, const Rhs& rhs) \ - : Base(dec, rhs) {} - - - -template struct solve_retval_with_guess; - -template -struct traits > -{ - typedef typename DecompositionType::MatrixType MatrixType; - typedef Matrix ReturnType; -}; - -template struct solve_retval_with_guess - : public ReturnByValue > -{ - typedef typename DecompositionType::Index Index; - - solve_retval_with_guess(const DecompositionType& dec, const Rhs& rhs, const Guess& guess) - : m_dec(dec), m_rhs(rhs), m_guess(guess) - {} - - inline Index rows() const { return m_dec.cols(); } - inline Index cols() const { return m_rhs.cols(); } - - template inline void evalTo(Dest& dst) const - { - dst = m_guess; - m_dec._solveWithGuess(m_rhs,dst); - } - - protected: - const DecompositionType& m_dec; - const typename Rhs::Nested m_rhs; - const typename Guess::Nested m_guess; -}; - -} // namepsace internal - -} // end namespace Eigen - -#endif // EIGEN_SPARSE_SOLVE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/misc/blas.h b/thirdparty/eigen-3.2.7/Eigen/src/misc/blas.h deleted file mode 100644 index 6fce99ed..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/misc/blas.h +++ /dev/null @@ -1,658 +0,0 @@ -#ifndef BLAS_H -#define BLAS_H - -#ifdef __cplusplus -extern "C" -{ -#endif - -#define BLASFUNC(FUNC) FUNC##_ - -#ifdef __WIN64__ -typedef long long BLASLONG; -typedef unsigned long long BLASULONG; -#else -typedef long BLASLONG; -typedef unsigned long BLASULONG; -#endif - -int BLASFUNC(xerbla)(const char *, int *info, int); - -float BLASFUNC(sdot) (int *, float *, int *, float *, int *); -float BLASFUNC(sdsdot)(int *, float *, float *, int *, float *, int *); - -double BLASFUNC(dsdot) (int *, float *, int *, float *, int *); -double BLASFUNC(ddot) (int *, double *, int *, double *, int *); -double BLASFUNC(qdot) (int *, double *, int *, double *, int *); - -int BLASFUNC(cdotuw) (int *, float *, int *, float *, int *, float*); -int BLASFUNC(cdotcw) (int *, float *, int *, float *, int *, float*); -int BLASFUNC(zdotuw) (int *, double *, int *, double *, int *, double*); -int BLASFUNC(zdotcw) (int *, double *, int *, double *, int *, double*); - -int BLASFUNC(saxpy) (int *, float *, float *, int *, float *, int *); -int BLASFUNC(daxpy) (int *, double *, double *, int *, double *, int *); -int BLASFUNC(qaxpy) (int *, double *, double *, int *, double *, int *); -int BLASFUNC(caxpy) (int *, float *, float *, int *, float *, int *); -int BLASFUNC(zaxpy) (int *, double *, double *, int *, double *, int *); -int BLASFUNC(xaxpy) (int *, double *, double *, int *, double *, int *); -int BLASFUNC(caxpyc)(int *, float *, float *, int *, float *, int *); -int BLASFUNC(zaxpyc)(int *, double *, double *, int *, double *, int *); -int BLASFUNC(xaxpyc)(int *, double *, double *, int *, double *, int *); - -int BLASFUNC(scopy) (int *, float *, int *, float *, int *); -int BLASFUNC(dcopy) (int *, double *, int *, double *, int *); -int BLASFUNC(qcopy) (int *, double *, int *, double *, int *); -int BLASFUNC(ccopy) (int *, float *, int *, float *, int *); -int BLASFUNC(zcopy) (int *, double *, int *, double *, int *); -int BLASFUNC(xcopy) (int *, double *, int *, double *, int *); - -int BLASFUNC(sswap) (int *, float *, int *, float *, int *); -int BLASFUNC(dswap) (int *, double *, int *, double *, int *); -int BLASFUNC(qswap) (int *, double *, int *, double *, int *); -int BLASFUNC(cswap) (int *, float *, int *, float *, int *); -int BLASFUNC(zswap) (int *, double *, int *, double *, int *); -int BLASFUNC(xswap) (int *, double *, int *, double *, int *); - -float BLASFUNC(sasum) (int *, float *, int *); -float BLASFUNC(scasum)(int *, float *, int *); -double BLASFUNC(dasum) (int *, double *, int *); -double BLASFUNC(qasum) (int *, double *, int *); -double BLASFUNC(dzasum)(int *, double *, int *); -double BLASFUNC(qxasum)(int *, double *, int *); - -int BLASFUNC(isamax)(int *, float *, int *); -int BLASFUNC(idamax)(int *, double *, int *); -int BLASFUNC(iqamax)(int *, double *, int *); -int BLASFUNC(icamax)(int *, float *, int *); -int BLASFUNC(izamax)(int *, double *, int *); -int BLASFUNC(ixamax)(int *, double *, int *); - -int BLASFUNC(ismax) (int *, float *, int *); -int BLASFUNC(idmax) (int *, double *, int *); -int BLASFUNC(iqmax) (int *, double *, int *); -int BLASFUNC(icmax) (int *, float *, int *); -int BLASFUNC(izmax) (int *, double *, int *); -int BLASFUNC(ixmax) (int *, double *, int *); - -int BLASFUNC(isamin)(int *, float *, int *); -int BLASFUNC(idamin)(int *, double *, int *); -int BLASFUNC(iqamin)(int *, double *, int *); -int BLASFUNC(icamin)(int *, float *, int *); -int BLASFUNC(izamin)(int *, double *, int *); -int BLASFUNC(ixamin)(int *, double *, int *); - -int BLASFUNC(ismin)(int *, float *, int *); -int BLASFUNC(idmin)(int *, double *, int *); -int BLASFUNC(iqmin)(int *, double *, int *); -int BLASFUNC(icmin)(int *, float *, int *); -int BLASFUNC(izmin)(int *, double *, int *); -int BLASFUNC(ixmin)(int *, double *, int *); - -float BLASFUNC(samax) (int *, float *, int *); -double BLASFUNC(damax) (int *, double *, int *); -double BLASFUNC(qamax) (int *, double *, int *); -float BLASFUNC(scamax)(int *, float *, int *); -double BLASFUNC(dzamax)(int *, double *, int *); -double BLASFUNC(qxamax)(int *, double *, int *); - -float BLASFUNC(samin) (int *, float *, int *); -double BLASFUNC(damin) (int *, double *, int *); -double BLASFUNC(qamin) (int *, double *, int *); -float BLASFUNC(scamin)(int *, float *, int *); -double BLASFUNC(dzamin)(int *, double *, int *); -double BLASFUNC(qxamin)(int *, double *, int *); - -float BLASFUNC(smax) (int *, float *, int *); -double BLASFUNC(dmax) (int *, double *, int *); -double BLASFUNC(qmax) (int *, double *, int *); -float BLASFUNC(scmax) (int *, float *, int *); -double BLASFUNC(dzmax) (int *, double *, int *); -double BLASFUNC(qxmax) (int *, double *, int *); - -float BLASFUNC(smin) (int *, float *, int *); -double BLASFUNC(dmin) (int *, double *, int *); -double BLASFUNC(qmin) (int *, double *, int *); -float BLASFUNC(scmin) (int *, float *, int *); -double BLASFUNC(dzmin) (int *, double *, int *); -double BLASFUNC(qxmin) (int *, double *, int *); - -int BLASFUNC(sscal) (int *, float *, float *, int *); -int BLASFUNC(dscal) (int *, double *, double *, int *); -int BLASFUNC(qscal) (int *, double *, double *, int *); -int BLASFUNC(cscal) (int *, float *, float *, int *); -int BLASFUNC(zscal) (int *, double *, double *, int *); -int BLASFUNC(xscal) (int *, double *, double *, int *); -int BLASFUNC(csscal)(int *, float *, float *, int *); -int BLASFUNC(zdscal)(int *, double *, double *, int *); -int BLASFUNC(xqscal)(int *, double *, double *, int *); - -float BLASFUNC(snrm2) (int *, float *, int *); -float BLASFUNC(scnrm2)(int *, float *, int *); - -double BLASFUNC(dnrm2) (int *, double *, int *); -double BLASFUNC(qnrm2) (int *, double *, int *); -double BLASFUNC(dznrm2)(int *, double *, int *); -double BLASFUNC(qxnrm2)(int *, double *, int *); - -int BLASFUNC(srot) (int *, float *, int *, float *, int *, float *, float *); -int BLASFUNC(drot) (int *, double *, int *, double *, int *, double *, double *); -int BLASFUNC(qrot) (int *, double *, int *, double *, int *, double *, double *); -int BLASFUNC(csrot) (int *, float *, int *, float *, int *, float *, float *); -int BLASFUNC(zdrot) (int *, double *, int *, double *, int *, double *, double *); -int BLASFUNC(xqrot) (int *, double *, int *, double *, int *, double *, double *); - -int BLASFUNC(srotg) (float *, float *, float *, float *); -int BLASFUNC(drotg) (double *, double *, double *, double *); -int BLASFUNC(qrotg) (double *, double *, double *, double *); -int BLASFUNC(crotg) (float *, float *, float *, float *); -int BLASFUNC(zrotg) (double *, double *, double *, double *); -int BLASFUNC(xrotg) (double *, double *, double *, double *); - -int BLASFUNC(srotmg)(float *, float *, float *, float *, float *); -int BLASFUNC(drotmg)(double *, double *, double *, double *, double *); - -int BLASFUNC(srotm) (int *, float *, int *, float *, int *, float *); -int BLASFUNC(drotm) (int *, double *, int *, double *, int *, double *); -int BLASFUNC(qrotm) (int *, double *, int *, double *, int *, double *); - -/* Level 2 routines */ - -int BLASFUNC(sger)(int *, int *, float *, float *, int *, - float *, int *, float *, int *); -int BLASFUNC(dger)(int *, int *, double *, double *, int *, - double *, int *, double *, int *); -int BLASFUNC(qger)(int *, int *, double *, double *, int *, - double *, int *, double *, int *); -int BLASFUNC(cgeru)(int *, int *, float *, float *, int *, - float *, int *, float *, int *); -int BLASFUNC(cgerc)(int *, int *, float *, float *, int *, - float *, int *, float *, int *); -int BLASFUNC(zgeru)(int *, int *, double *, double *, int *, - double *, int *, double *, int *); -int BLASFUNC(zgerc)(int *, int *, double *, double *, int *, - double *, int *, double *, int *); -int BLASFUNC(xgeru)(int *, int *, double *, double *, int *, - double *, int *, double *, int *); -int BLASFUNC(xgerc)(int *, int *, double *, double *, int *, - double *, int *, double *, int *); - -int BLASFUNC(sgemv)(char *, int *, int *, float *, float *, int *, - float *, int *, float *, float *, int *); -int BLASFUNC(dgemv)(char *, int *, int *, double *, double *, int *, - double *, int *, double *, double *, int *); -int BLASFUNC(qgemv)(char *, int *, int *, double *, double *, int *, - double *, int *, double *, double *, int *); -int BLASFUNC(cgemv)(char *, int *, int *, float *, float *, int *, - float *, int *, float *, float *, int *); -int BLASFUNC(zgemv)(char *, int *, int *, double *, double *, int *, - double *, int *, double *, double *, int *); -int BLASFUNC(xgemv)(char *, int *, int *, double *, double *, int *, - double *, int *, double *, double *, int *); - -int BLASFUNC(strsv) (char *, char *, char *, int *, float *, int *, - float *, int *); -int BLASFUNC(dtrsv) (char *, char *, char *, int *, double *, int *, - double *, int *); -int BLASFUNC(qtrsv) (char *, char *, char *, int *, double *, int *, - double *, int *); -int BLASFUNC(ctrsv) (char *, char *, char *, int *, float *, int *, - float *, int *); -int BLASFUNC(ztrsv) (char *, char *, char *, int *, double *, int *, - double *, int *); -int BLASFUNC(xtrsv) (char *, char *, char *, int *, double *, int *, - double *, int *); - -int BLASFUNC(stpsv) (char *, char *, char *, int *, float *, float *, int *); -int BLASFUNC(dtpsv) (char *, char *, char *, int *, double *, double *, int *); -int BLASFUNC(qtpsv) (char *, char *, char *, int *, double *, double *, int *); -int BLASFUNC(ctpsv) (char *, char *, char *, int *, float *, float *, int *); -int BLASFUNC(ztpsv) (char *, char *, char *, int *, double *, double *, int *); -int BLASFUNC(xtpsv) (char *, char *, char *, int *, double *, double *, int *); - -int BLASFUNC(strmv) (char *, char *, char *, int *, float *, int *, - float *, int *); -int BLASFUNC(dtrmv) (char *, char *, char *, int *, double *, int *, - double *, int *); -int BLASFUNC(qtrmv) (char *, char *, char *, int *, double *, int *, - double *, int *); -int BLASFUNC(ctrmv) (char *, char *, char *, int *, float *, int *, - float *, int *); -int BLASFUNC(ztrmv) (char *, char *, char *, int *, double *, int *, - double *, int *); -int BLASFUNC(xtrmv) (char *, char *, char *, int *, double *, int *, - double *, int *); - -int BLASFUNC(stpmv) (char *, char *, char *, int *, float *, float *, int *); -int BLASFUNC(dtpmv) (char *, char *, char *, int *, double *, double *, int *); -int BLASFUNC(qtpmv) (char *, char *, char *, int *, double *, double *, int *); -int BLASFUNC(ctpmv) (char *, char *, char *, int *, float *, float *, int *); -int BLASFUNC(ztpmv) (char *, char *, char *, int *, double *, double *, int *); -int BLASFUNC(xtpmv) (char *, char *, char *, int *, double *, double *, int *); - -int BLASFUNC(stbmv) (char *, char *, char *, int *, int *, float *, int *, float *, int *); -int BLASFUNC(dtbmv) (char *, char *, char *, int *, int *, double *, int *, double *, int *); -int BLASFUNC(qtbmv) (char *, char *, char *, int *, int *, double *, int *, double *, int *); -int BLASFUNC(ctbmv) (char *, char *, char *, int *, int *, float *, int *, float *, int *); -int BLASFUNC(ztbmv) (char *, char *, char *, int *, int *, double *, int *, double *, int *); -int BLASFUNC(xtbmv) (char *, char *, char *, int *, int *, double *, int *, double *, int *); - -int BLASFUNC(stbsv) (char *, char *, char *, int *, int *, float *, int *, float *, int *); -int BLASFUNC(dtbsv) (char *, char *, char *, int *, int *, double *, int *, double *, int *); -int BLASFUNC(qtbsv) (char *, char *, char *, int *, int *, double *, int *, double *, int *); -int BLASFUNC(ctbsv) (char *, char *, char *, int *, int *, float *, int *, float *, int *); -int BLASFUNC(ztbsv) (char *, char *, char *, int *, int *, double *, int *, double *, int *); -int BLASFUNC(xtbsv) (char *, char *, char *, int *, int *, double *, int *, double *, int *); - -int BLASFUNC(ssymv) (char *, int *, float *, float *, int *, - float *, int *, float *, float *, int *); -int BLASFUNC(dsymv) (char *, int *, double *, double *, int *, - double *, int *, double *, double *, int *); -int BLASFUNC(qsymv) (char *, int *, double *, double *, int *, - double *, int *, double *, double *, int *); -int BLASFUNC(csymv) (char *, int *, float *, float *, int *, - float *, int *, float *, float *, int *); -int BLASFUNC(zsymv) (char *, int *, double *, double *, int *, - double *, int *, double *, double *, int *); -int BLASFUNC(xsymv) (char *, int *, double *, double *, int *, - double *, int *, double *, double *, int *); - -int BLASFUNC(sspmv) (char *, int *, float *, float *, - float *, int *, float *, float *, int *); -int BLASFUNC(dspmv) (char *, int *, double *, double *, - double *, int *, double *, double *, int *); -int BLASFUNC(qspmv) (char *, int *, double *, double *, - double *, int *, double *, double *, int *); -int BLASFUNC(cspmv) (char *, int *, float *, float *, - float *, int *, float *, float *, int *); -int BLASFUNC(zspmv) (char *, int *, double *, double *, - double *, int *, double *, double *, int *); -int BLASFUNC(xspmv) (char *, int *, double *, double *, - double *, int *, double *, double *, int *); - -int BLASFUNC(ssyr) (char *, int *, float *, float *, int *, - float *, int *); -int BLASFUNC(dsyr) (char *, int *, double *, double *, int *, - double *, int *); -int BLASFUNC(qsyr) (char *, int *, double *, double *, int *, - double *, int *); -int BLASFUNC(csyr) (char *, int *, float *, float *, int *, - float *, int *); -int BLASFUNC(zsyr) (char *, int *, double *, double *, int *, - double *, int *); -int BLASFUNC(xsyr) (char *, int *, double *, double *, int *, - double *, int *); - -int BLASFUNC(ssyr2) (char *, int *, float *, - float *, int *, float *, int *, float *, int *); -int BLASFUNC(dsyr2) (char *, int *, double *, - double *, int *, double *, int *, double *, int *); -int BLASFUNC(qsyr2) (char *, int *, double *, - double *, int *, double *, int *, double *, int *); -int BLASFUNC(csyr2) (char *, int *, float *, - float *, int *, float *, int *, float *, int *); -int BLASFUNC(zsyr2) (char *, int *, double *, - double *, int *, double *, int *, double *, int *); -int BLASFUNC(xsyr2) (char *, int *, double *, - double *, int *, double *, int *, double *, int *); - -int BLASFUNC(sspr) (char *, int *, float *, float *, int *, - float *); -int BLASFUNC(dspr) (char *, int *, double *, double *, int *, - double *); -int BLASFUNC(qspr) (char *, int *, double *, double *, int *, - double *); -int BLASFUNC(cspr) (char *, int *, float *, float *, int *, - float *); -int BLASFUNC(zspr) (char *, int *, double *, double *, int *, - double *); -int BLASFUNC(xspr) (char *, int *, double *, double *, int *, - double *); - -int BLASFUNC(sspr2) (char *, int *, float *, - float *, int *, float *, int *, float *); -int BLASFUNC(dspr2) (char *, int *, double *, - double *, int *, double *, int *, double *); -int BLASFUNC(qspr2) (char *, int *, double *, - double *, int *, double *, int *, double *); -int BLASFUNC(cspr2) (char *, int *, float *, - float *, int *, float *, int *, float *); -int BLASFUNC(zspr2) (char *, int *, double *, - double *, int *, double *, int *, double *); -int BLASFUNC(xspr2) (char *, int *, double *, - double *, int *, double *, int *, double *); - -int BLASFUNC(cher) (char *, int *, float *, float *, int *, - float *, int *); -int BLASFUNC(zher) (char *, int *, double *, double *, int *, - double *, int *); -int BLASFUNC(xher) (char *, int *, double *, double *, int *, - double *, int *); - -int BLASFUNC(chpr) (char *, int *, float *, float *, int *, float *); -int BLASFUNC(zhpr) (char *, int *, double *, double *, int *, double *); -int BLASFUNC(xhpr) (char *, int *, double *, double *, int *, double *); - -int BLASFUNC(cher2) (char *, int *, float *, - float *, int *, float *, int *, float *, int *); -int BLASFUNC(zher2) (char *, int *, double *, - double *, int *, double *, int *, double *, int *); -int BLASFUNC(xher2) (char *, int *, double *, - double *, int *, double *, int *, double *, int *); - -int BLASFUNC(chpr2) (char *, int *, float *, - float *, int *, float *, int *, float *); -int BLASFUNC(zhpr2) (char *, int *, double *, - double *, int *, double *, int *, double *); -int BLASFUNC(xhpr2) (char *, int *, double *, - double *, int *, double *, int *, double *); - -int BLASFUNC(chemv) (char *, int *, float *, float *, int *, - float *, int *, float *, float *, int *); -int BLASFUNC(zhemv) (char *, int *, double *, double *, int *, - double *, int *, double *, double *, int *); -int BLASFUNC(xhemv) (char *, int *, double *, double *, int *, - double *, int *, double *, double *, int *); - -int BLASFUNC(chpmv) (char *, int *, float *, float *, - float *, int *, float *, float *, int *); -int BLASFUNC(zhpmv) (char *, int *, double *, double *, - double *, int *, double *, double *, int *); -int BLASFUNC(xhpmv) (char *, int *, double *, double *, - double *, int *, double *, double *, int *); - -int BLASFUNC(snorm)(char *, int *, int *, float *, int *); -int BLASFUNC(dnorm)(char *, int *, int *, double *, int *); -int BLASFUNC(cnorm)(char *, int *, int *, float *, int *); -int BLASFUNC(znorm)(char *, int *, int *, double *, int *); - -int BLASFUNC(sgbmv)(char *, int *, int *, int *, int *, float *, float *, int *, - float *, int *, float *, float *, int *); -int BLASFUNC(dgbmv)(char *, int *, int *, int *, int *, double *, double *, int *, - double *, int *, double *, double *, int *); -int BLASFUNC(qgbmv)(char *, int *, int *, int *, int *, double *, double *, int *, - double *, int *, double *, double *, int *); -int BLASFUNC(cgbmv)(char *, int *, int *, int *, int *, float *, float *, int *, - float *, int *, float *, float *, int *); -int BLASFUNC(zgbmv)(char *, int *, int *, int *, int *, double *, double *, int *, - double *, int *, double *, double *, int *); -int BLASFUNC(xgbmv)(char *, int *, int *, int *, int *, double *, double *, int *, - double *, int *, double *, double *, int *); - -int BLASFUNC(ssbmv)(char *, int *, int *, float *, float *, int *, - float *, int *, float *, float *, int *); -int BLASFUNC(dsbmv)(char *, int *, int *, double *, double *, int *, - double *, int *, double *, double *, int *); -int BLASFUNC(qsbmv)(char *, int *, int *, double *, double *, int *, - double *, int *, double *, double *, int *); -int BLASFUNC(csbmv)(char *, int *, int *, float *, float *, int *, - float *, int *, float *, float *, int *); -int BLASFUNC(zsbmv)(char *, int *, int *, double *, double *, int *, - double *, int *, double *, double *, int *); -int BLASFUNC(xsbmv)(char *, int *, int *, double *, double *, int *, - double *, int *, double *, double *, int *); - -int BLASFUNC(chbmv)(char *, int *, int *, float *, float *, int *, - float *, int *, float *, float *, int *); -int BLASFUNC(zhbmv)(char *, int *, int *, double *, double *, int *, - double *, int *, double *, double *, int *); -int BLASFUNC(xhbmv)(char *, int *, int *, double *, double *, int *, - double *, int *, double *, double *, int *); - -/* Level 3 routines */ - -int BLASFUNC(sgemm)(char *, char *, int *, int *, int *, float *, - float *, int *, float *, int *, float *, float *, int *); -int BLASFUNC(dgemm)(char *, char *, int *, int *, int *, double *, - double *, int *, double *, int *, double *, double *, int *); -int BLASFUNC(qgemm)(char *, char *, int *, int *, int *, double *, - double *, int *, double *, int *, double *, double *, int *); -int BLASFUNC(cgemm)(char *, char *, int *, int *, int *, float *, - float *, int *, float *, int *, float *, float *, int *); -int BLASFUNC(zgemm)(char *, char *, int *, int *, int *, double *, - double *, int *, double *, int *, double *, double *, int *); -int BLASFUNC(xgemm)(char *, char *, int *, int *, int *, double *, - double *, int *, double *, int *, double *, double *, int *); - -int BLASFUNC(cgemm3m)(char *, char *, int *, int *, int *, float *, - float *, int *, float *, int *, float *, float *, int *); -int BLASFUNC(zgemm3m)(char *, char *, int *, int *, int *, double *, - double *, int *, double *, int *, double *, double *, int *); -int BLASFUNC(xgemm3m)(char *, char *, int *, int *, int *, double *, - double *, int *, double *, int *, double *, double *, int *); - -int BLASFUNC(sge2mm)(char *, char *, char *, int *, int *, - float *, float *, int *, float *, int *, - float *, float *, int *); -int BLASFUNC(dge2mm)(char *, char *, char *, int *, int *, - double *, double *, int *, double *, int *, - double *, double *, int *); -int BLASFUNC(cge2mm)(char *, char *, char *, int *, int *, - float *, float *, int *, float *, int *, - float *, float *, int *); -int BLASFUNC(zge2mm)(char *, char *, char *, int *, int *, - double *, double *, int *, double *, int *, - double *, double *, int *); - -int BLASFUNC(strsm)(char *, char *, char *, char *, int *, int *, - float *, float *, int *, float *, int *); -int BLASFUNC(dtrsm)(char *, char *, char *, char *, int *, int *, - double *, double *, int *, double *, int *); -int BLASFUNC(qtrsm)(char *, char *, char *, char *, int *, int *, - double *, double *, int *, double *, int *); -int BLASFUNC(ctrsm)(char *, char *, char *, char *, int *, int *, - float *, float *, int *, float *, int *); -int BLASFUNC(ztrsm)(char *, char *, char *, char *, int *, int *, - double *, double *, int *, double *, int *); -int BLASFUNC(xtrsm)(char *, char *, char *, char *, int *, int *, - double *, double *, int *, double *, int *); - -int BLASFUNC(strmm)(char *, char *, char *, char *, int *, int *, - float *, float *, int *, float *, int *); -int BLASFUNC(dtrmm)(char *, char *, char *, char *, int *, int *, - double *, double *, int *, double *, int *); -int BLASFUNC(qtrmm)(char *, char *, char *, char *, int *, int *, - double *, double *, int *, double *, int *); -int BLASFUNC(ctrmm)(char *, char *, char *, char *, int *, int *, - float *, float *, int *, float *, int *); -int BLASFUNC(ztrmm)(char *, char *, char *, char *, int *, int *, - double *, double *, int *, double *, int *); -int BLASFUNC(xtrmm)(char *, char *, char *, char *, int *, int *, - double *, double *, int *, double *, int *); - -int BLASFUNC(ssymm)(char *, char *, int *, int *, float *, float *, int *, - float *, int *, float *, float *, int *); -int BLASFUNC(dsymm)(char *, char *, int *, int *, double *, double *, int *, - double *, int *, double *, double *, int *); -int BLASFUNC(qsymm)(char *, char *, int *, int *, double *, double *, int *, - double *, int *, double *, double *, int *); -int BLASFUNC(csymm)(char *, char *, int *, int *, float *, float *, int *, - float *, int *, float *, float *, int *); -int BLASFUNC(zsymm)(char *, char *, int *, int *, double *, double *, int *, - double *, int *, double *, double *, int *); -int BLASFUNC(xsymm)(char *, char *, int *, int *, double *, double *, int *, - double *, int *, double *, double *, int *); - -int BLASFUNC(csymm3m)(char *, char *, int *, int *, float *, float *, int *, - float *, int *, float *, float *, int *); -int BLASFUNC(zsymm3m)(char *, char *, int *, int *, double *, double *, int *, - double *, int *, double *, double *, int *); -int BLASFUNC(xsymm3m)(char *, char *, int *, int *, double *, double *, int *, - double *, int *, double *, double *, int *); - -int BLASFUNC(ssyrk)(char *, char *, int *, int *, float *, float *, int *, - float *, float *, int *); -int BLASFUNC(dsyrk)(char *, char *, int *, int *, double *, double *, int *, - double *, double *, int *); -int BLASFUNC(qsyrk)(char *, char *, int *, int *, double *, double *, int *, - double *, double *, int *); -int BLASFUNC(csyrk)(char *, char *, int *, int *, float *, float *, int *, - float *, float *, int *); -int BLASFUNC(zsyrk)(char *, char *, int *, int *, double *, double *, int *, - double *, double *, int *); -int BLASFUNC(xsyrk)(char *, char *, int *, int *, double *, double *, int *, - double *, double *, int *); - -int BLASFUNC(ssyr2k)(char *, char *, int *, int *, float *, float *, int *, - float *, int *, float *, float *, int *); -int BLASFUNC(dsyr2k)(char *, char *, int *, int *, double *, double *, int *, - double*, int *, double *, double *, int *); -int BLASFUNC(qsyr2k)(char *, char *, int *, int *, double *, double *, int *, - double*, int *, double *, double *, int *); -int BLASFUNC(csyr2k)(char *, char *, int *, int *, float *, float *, int *, - float *, int *, float *, float *, int *); -int BLASFUNC(zsyr2k)(char *, char *, int *, int *, double *, double *, int *, - double*, int *, double *, double *, int *); -int BLASFUNC(xsyr2k)(char *, char *, int *, int *, double *, double *, int *, - double*, int *, double *, double *, int *); - -int BLASFUNC(chemm)(char *, char *, int *, int *, float *, float *, int *, - float *, int *, float *, float *, int *); -int BLASFUNC(zhemm)(char *, char *, int *, int *, double *, double *, int *, - double *, int *, double *, double *, int *); -int BLASFUNC(xhemm)(char *, char *, int *, int *, double *, double *, int *, - double *, int *, double *, double *, int *); - -int BLASFUNC(chemm3m)(char *, char *, int *, int *, float *, float *, int *, - float *, int *, float *, float *, int *); -int BLASFUNC(zhemm3m)(char *, char *, int *, int *, double *, double *, int *, - double *, int *, double *, double *, int *); -int BLASFUNC(xhemm3m)(char *, char *, int *, int *, double *, double *, int *, - double *, int *, double *, double *, int *); - -int BLASFUNC(cherk)(char *, char *, int *, int *, float *, float *, int *, - float *, float *, int *); -int BLASFUNC(zherk)(char *, char *, int *, int *, double *, double *, int *, - double *, double *, int *); -int BLASFUNC(xherk)(char *, char *, int *, int *, double *, double *, int *, - double *, double *, int *); - -int BLASFUNC(cher2k)(char *, char *, int *, int *, float *, float *, int *, - float *, int *, float *, float *, int *); -int BLASFUNC(zher2k)(char *, char *, int *, int *, double *, double *, int *, - double*, int *, double *, double *, int *); -int BLASFUNC(xher2k)(char *, char *, int *, int *, double *, double *, int *, - double*, int *, double *, double *, int *); -int BLASFUNC(cher2m)(char *, char *, char *, int *, int *, float *, float *, int *, - float *, int *, float *, float *, int *); -int BLASFUNC(zher2m)(char *, char *, char *, int *, int *, double *, double *, int *, - double*, int *, double *, double *, int *); -int BLASFUNC(xher2m)(char *, char *, char *, int *, int *, double *, double *, int *, - double*, int *, double *, double *, int *); - -int BLASFUNC(sgemt)(char *, int *, int *, float *, float *, int *, - float *, int *); -int BLASFUNC(dgemt)(char *, int *, int *, double *, double *, int *, - double *, int *); -int BLASFUNC(cgemt)(char *, int *, int *, float *, float *, int *, - float *, int *); -int BLASFUNC(zgemt)(char *, int *, int *, double *, double *, int *, - double *, int *); - -int BLASFUNC(sgema)(char *, char *, int *, int *, float *, - float *, int *, float *, float *, int *, float *, int *); -int BLASFUNC(dgema)(char *, char *, int *, int *, double *, - double *, int *, double*, double *, int *, double*, int *); -int BLASFUNC(cgema)(char *, char *, int *, int *, float *, - float *, int *, float *, float *, int *, float *, int *); -int BLASFUNC(zgema)(char *, char *, int *, int *, double *, - double *, int *, double*, double *, int *, double*, int *); - -int BLASFUNC(sgems)(char *, char *, int *, int *, float *, - float *, int *, float *, float *, int *, float *, int *); -int BLASFUNC(dgems)(char *, char *, int *, int *, double *, - double *, int *, double*, double *, int *, double*, int *); -int BLASFUNC(cgems)(char *, char *, int *, int *, float *, - float *, int *, float *, float *, int *, float *, int *); -int BLASFUNC(zgems)(char *, char *, int *, int *, double *, - double *, int *, double*, double *, int *, double*, int *); - -int BLASFUNC(sgetf2)(int *, int *, float *, int *, int *, int *); -int BLASFUNC(dgetf2)(int *, int *, double *, int *, int *, int *); -int BLASFUNC(qgetf2)(int *, int *, double *, int *, int *, int *); -int BLASFUNC(cgetf2)(int *, int *, float *, int *, int *, int *); -int BLASFUNC(zgetf2)(int *, int *, double *, int *, int *, int *); -int BLASFUNC(xgetf2)(int *, int *, double *, int *, int *, int *); - -int BLASFUNC(sgetrf)(int *, int *, float *, int *, int *, int *); -int BLASFUNC(dgetrf)(int *, int *, double *, int *, int *, int *); -int BLASFUNC(qgetrf)(int *, int *, double *, int *, int *, int *); -int BLASFUNC(cgetrf)(int *, int *, float *, int *, int *, int *); -int BLASFUNC(zgetrf)(int *, int *, double *, int *, int *, int *); -int BLASFUNC(xgetrf)(int *, int *, double *, int *, int *, int *); - -int BLASFUNC(slaswp)(int *, float *, int *, int *, int *, int *, int *); -int BLASFUNC(dlaswp)(int *, double *, int *, int *, int *, int *, int *); -int BLASFUNC(qlaswp)(int *, double *, int *, int *, int *, int *, int *); -int BLASFUNC(claswp)(int *, float *, int *, int *, int *, int *, int *); -int BLASFUNC(zlaswp)(int *, double *, int *, int *, int *, int *, int *); -int BLASFUNC(xlaswp)(int *, double *, int *, int *, int *, int *, int *); - -int BLASFUNC(sgetrs)(char *, int *, int *, float *, int *, int *, float *, int *, int *); -int BLASFUNC(dgetrs)(char *, int *, int *, double *, int *, int *, double *, int *, int *); -int BLASFUNC(qgetrs)(char *, int *, int *, double *, int *, int *, double *, int *, int *); -int BLASFUNC(cgetrs)(char *, int *, int *, float *, int *, int *, float *, int *, int *); -int BLASFUNC(zgetrs)(char *, int *, int *, double *, int *, int *, double *, int *, int *); -int BLASFUNC(xgetrs)(char *, int *, int *, double *, int *, int *, double *, int *, int *); - -int BLASFUNC(sgesv)(int *, int *, float *, int *, int *, float *, int *, int *); -int BLASFUNC(dgesv)(int *, int *, double *, int *, int *, double*, int *, int *); -int BLASFUNC(qgesv)(int *, int *, double *, int *, int *, double*, int *, int *); -int BLASFUNC(cgesv)(int *, int *, float *, int *, int *, float *, int *, int *); -int BLASFUNC(zgesv)(int *, int *, double *, int *, int *, double*, int *, int *); -int BLASFUNC(xgesv)(int *, int *, double *, int *, int *, double*, int *, int *); - -int BLASFUNC(spotf2)(char *, int *, float *, int *, int *); -int BLASFUNC(dpotf2)(char *, int *, double *, int *, int *); -int BLASFUNC(qpotf2)(char *, int *, double *, int *, int *); -int BLASFUNC(cpotf2)(char *, int *, float *, int *, int *); -int BLASFUNC(zpotf2)(char *, int *, double *, int *, int *); -int BLASFUNC(xpotf2)(char *, int *, double *, int *, int *); - -int BLASFUNC(spotrf)(char *, int *, float *, int *, int *); -int BLASFUNC(dpotrf)(char *, int *, double *, int *, int *); -int BLASFUNC(qpotrf)(char *, int *, double *, int *, int *); -int BLASFUNC(cpotrf)(char *, int *, float *, int *, int *); -int BLASFUNC(zpotrf)(char *, int *, double *, int *, int *); -int BLASFUNC(xpotrf)(char *, int *, double *, int *, int *); - -int BLASFUNC(slauu2)(char *, int *, float *, int *, int *); -int BLASFUNC(dlauu2)(char *, int *, double *, int *, int *); -int BLASFUNC(qlauu2)(char *, int *, double *, int *, int *); -int BLASFUNC(clauu2)(char *, int *, float *, int *, int *); -int BLASFUNC(zlauu2)(char *, int *, double *, int *, int *); -int BLASFUNC(xlauu2)(char *, int *, double *, int *, int *); - -int BLASFUNC(slauum)(char *, int *, float *, int *, int *); -int BLASFUNC(dlauum)(char *, int *, double *, int *, int *); -int BLASFUNC(qlauum)(char *, int *, double *, int *, int *); -int BLASFUNC(clauum)(char *, int *, float *, int *, int *); -int BLASFUNC(zlauum)(char *, int *, double *, int *, int *); -int BLASFUNC(xlauum)(char *, int *, double *, int *, int *); - -int BLASFUNC(strti2)(char *, char *, int *, float *, int *, int *); -int BLASFUNC(dtrti2)(char *, char *, int *, double *, int *, int *); -int BLASFUNC(qtrti2)(char *, char *, int *, double *, int *, int *); -int BLASFUNC(ctrti2)(char *, char *, int *, float *, int *, int *); -int BLASFUNC(ztrti2)(char *, char *, int *, double *, int *, int *); -int BLASFUNC(xtrti2)(char *, char *, int *, double *, int *, int *); - -int BLASFUNC(strtri)(char *, char *, int *, float *, int *, int *); -int BLASFUNC(dtrtri)(char *, char *, int *, double *, int *, int *); -int BLASFUNC(qtrtri)(char *, char *, int *, double *, int *, int *); -int BLASFUNC(ctrtri)(char *, char *, int *, float *, int *, int *); -int BLASFUNC(ztrtri)(char *, char *, int *, double *, int *, int *); -int BLASFUNC(xtrtri)(char *, char *, int *, double *, int *, int *); - -int BLASFUNC(spotri)(char *, int *, float *, int *, int *); -int BLASFUNC(dpotri)(char *, int *, double *, int *, int *); -int BLASFUNC(qpotri)(char *, int *, double *, int *, int *); -int BLASFUNC(cpotri)(char *, int *, float *, int *, int *); -int BLASFUNC(zpotri)(char *, int *, double *, int *, int *); -int BLASFUNC(xpotri)(char *, int *, double *, int *, int *); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/thirdparty/eigen-3.2.7/Eigen/src/plugins/ArrayCwiseBinaryOps.h b/thirdparty/eigen-3.2.7/Eigen/src/plugins/ArrayCwiseBinaryOps.h deleted file mode 100644 index 1951286f..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/plugins/ArrayCwiseBinaryOps.h +++ /dev/null @@ -1,253 +0,0 @@ -/** \returns an expression of the coefficient wise product of \c *this and \a other - * - * \sa MatrixBase::cwiseProduct - */ -template -EIGEN_STRONG_INLINE const EIGEN_CWISE_PRODUCT_RETURN_TYPE(Derived,OtherDerived) -operator*(const EIGEN_CURRENT_STORAGE_BASE_CLASS &other) const -{ - return EIGEN_CWISE_PRODUCT_RETURN_TYPE(Derived,OtherDerived)(derived(), other.derived()); -} - -/** \returns an expression of the coefficient wise quotient of \c *this and \a other - * - * \sa MatrixBase::cwiseQuotient - */ -template -EIGEN_STRONG_INLINE const CwiseBinaryOp, const Derived, const OtherDerived> -operator/(const EIGEN_CURRENT_STORAGE_BASE_CLASS &other) const -{ - return CwiseBinaryOp, const Derived, const OtherDerived>(derived(), other.derived()); -} - -/** \returns an expression of the coefficient-wise min of \c *this and \a other - * - * Example: \include Cwise_min.cpp - * Output: \verbinclude Cwise_min.out - * - * \sa max() - */ -EIGEN_MAKE_CWISE_BINARY_OP(min,internal::scalar_min_op) - -/** \returns an expression of the coefficient-wise min of \c *this and scalar \a other - * - * \sa max() - */ -EIGEN_STRONG_INLINE const CwiseBinaryOp, const Derived, - const CwiseNullaryOp, PlainObject> > -#ifdef EIGEN_PARSED_BY_DOXYGEN -min -#else -(min) -#endif -(const Scalar &other) const -{ - return (min)(Derived::PlainObject::Constant(rows(), cols(), other)); -} - -/** \returns an expression of the coefficient-wise max of \c *this and \a other - * - * Example: \include Cwise_max.cpp - * Output: \verbinclude Cwise_max.out - * - * \sa min() - */ -EIGEN_MAKE_CWISE_BINARY_OP(max,internal::scalar_max_op) - -/** \returns an expression of the coefficient-wise max of \c *this and scalar \a other - * - * \sa min() - */ -EIGEN_STRONG_INLINE const CwiseBinaryOp, const Derived, - const CwiseNullaryOp, PlainObject> > -#ifdef EIGEN_PARSED_BY_DOXYGEN -max -#else -(max) -#endif -(const Scalar &other) const -{ - return (max)(Derived::PlainObject::Constant(rows(), cols(), other)); -} - - -#define EIGEN_MAKE_CWISE_COMP_OP(OP, COMPARATOR) \ -template \ -EIGEN_STRONG_INLINE const CwiseBinaryOp, const Derived, const OtherDerived> \ -OP(const EIGEN_CURRENT_STORAGE_BASE_CLASS &other) const \ -{ \ - return CwiseBinaryOp, const Derived, const OtherDerived>(derived(), other.derived()); \ -}\ -typedef CwiseBinaryOp, const Derived, const CwiseNullaryOp, PlainObject> > Cmp ## COMPARATOR ## ReturnType; \ -typedef CwiseBinaryOp, const CwiseNullaryOp, PlainObject>, const Derived > RCmp ## COMPARATOR ## ReturnType; \ -EIGEN_STRONG_INLINE const Cmp ## COMPARATOR ## ReturnType \ -OP(const Scalar& s) const { \ - return this->OP(Derived::PlainObject::Constant(rows(), cols(), s)); \ -} \ -friend EIGEN_STRONG_INLINE const RCmp ## COMPARATOR ## ReturnType \ -OP(const Scalar& s, const Derived& d) { \ - return Derived::PlainObject::Constant(d.rows(), d.cols(), s).OP(d); \ -} - -#define EIGEN_MAKE_CWISE_COMP_R_OP(OP, R_OP, RCOMPARATOR) \ -template \ -EIGEN_STRONG_INLINE const CwiseBinaryOp, const OtherDerived, const Derived> \ -OP(const EIGEN_CURRENT_STORAGE_BASE_CLASS &other) const \ -{ \ - return CwiseBinaryOp, const OtherDerived, const Derived>(other.derived(), derived()); \ -} \ -\ -inline const RCmp ## RCOMPARATOR ## ReturnType \ -OP(const Scalar& s) const { \ - return Derived::PlainObject::Constant(rows(), cols(), s).R_OP(*this); \ -} \ -friend inline const Cmp ## RCOMPARATOR ## ReturnType \ -OP(const Scalar& s, const Derived& d) { \ - return d.R_OP(Derived::PlainObject::Constant(d.rows(), d.cols(), s)); \ -} - - -/** \returns an expression of the coefficient-wise \< operator of *this and \a other - * - * Example: \include Cwise_less.cpp - * Output: \verbinclude Cwise_less.out - * - * \sa all(), any(), operator>(), operator<=() - */ -EIGEN_MAKE_CWISE_COMP_OP(operator<, LT) - -/** \returns an expression of the coefficient-wise \<= operator of *this and \a other - * - * Example: \include Cwise_less_equal.cpp - * Output: \verbinclude Cwise_less_equal.out - * - * \sa all(), any(), operator>=(), operator<() - */ -EIGEN_MAKE_CWISE_COMP_OP(operator<=, LE) - -/** \returns an expression of the coefficient-wise \> operator of *this and \a other - * - * Example: \include Cwise_greater.cpp - * Output: \verbinclude Cwise_greater.out - * - * \sa all(), any(), operator>=(), operator<() - */ -EIGEN_MAKE_CWISE_COMP_R_OP(operator>, operator<, LT) - -/** \returns an expression of the coefficient-wise \>= operator of *this and \a other - * - * Example: \include Cwise_greater_equal.cpp - * Output: \verbinclude Cwise_greater_equal.out - * - * \sa all(), any(), operator>(), operator<=() - */ -EIGEN_MAKE_CWISE_COMP_R_OP(operator>=, operator<=, LE) - -/** \returns an expression of the coefficient-wise == operator of *this and \a other - * - * \warning this performs an exact comparison, which is generally a bad idea with floating-point types. - * In order to check for equality between two vectors or matrices with floating-point coefficients, it is - * generally a far better idea to use a fuzzy comparison as provided by isApprox() and - * isMuchSmallerThan(). - * - * Example: \include Cwise_equal_equal.cpp - * Output: \verbinclude Cwise_equal_equal.out - * - * \sa all(), any(), isApprox(), isMuchSmallerThan() - */ -EIGEN_MAKE_CWISE_COMP_OP(operator==, EQ) - -/** \returns an expression of the coefficient-wise != operator of *this and \a other - * - * \warning this performs an exact comparison, which is generally a bad idea with floating-point types. - * In order to check for equality between two vectors or matrices with floating-point coefficients, it is - * generally a far better idea to use a fuzzy comparison as provided by isApprox() and - * isMuchSmallerThan(). - * - * Example: \include Cwise_not_equal.cpp - * Output: \verbinclude Cwise_not_equal.out - * - * \sa all(), any(), isApprox(), isMuchSmallerThan() - */ -EIGEN_MAKE_CWISE_COMP_OP(operator!=, NEQ) - -#undef EIGEN_MAKE_CWISE_COMP_OP -#undef EIGEN_MAKE_CWISE_COMP_R_OP - -// scalar addition - -/** \returns an expression of \c *this with each coeff incremented by the constant \a scalar - * - * Example: \include Cwise_plus.cpp - * Output: \verbinclude Cwise_plus.out - * - * \sa operator+=(), operator-() - */ -inline const CwiseUnaryOp, const Derived> -operator+(const Scalar& scalar) const -{ - return CwiseUnaryOp, const Derived>(derived(), internal::scalar_add_op(scalar)); -} - -friend inline const CwiseUnaryOp, const Derived> -operator+(const Scalar& scalar,const EIGEN_CURRENT_STORAGE_BASE_CLASS& other) -{ - return other + scalar; -} - -/** \returns an expression of \c *this with each coeff decremented by the constant \a scalar - * - * Example: \include Cwise_minus.cpp - * Output: \verbinclude Cwise_minus.out - * - * \sa operator+(), operator-=() - */ -inline const CwiseUnaryOp, const Derived> -operator-(const Scalar& scalar) const -{ - return *this + (-scalar); -} - -friend inline const CwiseUnaryOp, const CwiseUnaryOp, const Derived> > -operator-(const Scalar& scalar,const EIGEN_CURRENT_STORAGE_BASE_CLASS& other) -{ - return (-other) + scalar; -} - -/** \returns an expression of the coefficient-wise && operator of *this and \a other - * - * \warning this operator is for expression of bool only. - * - * Example: \include Cwise_boolean_and.cpp - * Output: \verbinclude Cwise_boolean_and.out - * - * \sa operator||(), select() - */ -template -inline const CwiseBinaryOp -operator&&(const EIGEN_CURRENT_STORAGE_BASE_CLASS &other) const -{ - EIGEN_STATIC_ASSERT((internal::is_same::value && internal::is_same::value), - THIS_METHOD_IS_ONLY_FOR_EXPRESSIONS_OF_BOOL); - return CwiseBinaryOp(derived(),other.derived()); -} - -/** \returns an expression of the coefficient-wise || operator of *this and \a other - * - * \warning this operator is for expression of bool only. - * - * Example: \include Cwise_boolean_or.cpp - * Output: \verbinclude Cwise_boolean_or.out - * - * \sa operator&&(), select() - */ -template -inline const CwiseBinaryOp -operator||(const EIGEN_CURRENT_STORAGE_BASE_CLASS &other) const -{ - EIGEN_STATIC_ASSERT((internal::is_same::value && internal::is_same::value), - THIS_METHOD_IS_ONLY_FOR_EXPRESSIONS_OF_BOOL); - return CwiseBinaryOp(derived(),other.derived()); -} - - diff --git a/thirdparty/eigen-3.2.7/Eigen/src/plugins/ArrayCwiseUnaryOps.h b/thirdparty/eigen-3.2.7/Eigen/src/plugins/ArrayCwiseUnaryOps.h deleted file mode 100644 index 1c3ed3fc..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/plugins/ArrayCwiseUnaryOps.h +++ /dev/null @@ -1,187 +0,0 @@ - - -/** \returns an expression of the coefficient-wise absolute value of \c *this - * - * Example: \include Cwise_abs.cpp - * Output: \verbinclude Cwise_abs.out - * - * \sa abs2() - */ -EIGEN_STRONG_INLINE const CwiseUnaryOp, const Derived> -abs() const -{ - return derived(); -} - -/** \returns an expression of the coefficient-wise squared absolute value of \c *this - * - * Example: \include Cwise_abs2.cpp - * Output: \verbinclude Cwise_abs2.out - * - * \sa abs(), square() - */ -EIGEN_STRONG_INLINE const CwiseUnaryOp, const Derived> -abs2() const -{ - return derived(); -} - -/** \returns an expression of the coefficient-wise exponential of *this. - * - * Example: \include Cwise_exp.cpp - * Output: \verbinclude Cwise_exp.out - * - * \sa pow(), log(), sin(), cos() - */ -inline const CwiseUnaryOp, const Derived> -exp() const -{ - return derived(); -} - -/** \returns an expression of the coefficient-wise logarithm of *this. - * - * Example: \include Cwise_log.cpp - * Output: \verbinclude Cwise_log.out - * - * \sa exp() - */ -inline const CwiseUnaryOp, const Derived> -log() const -{ - return derived(); -} - -/** \returns an expression of the coefficient-wise square root of *this. - * - * Example: \include Cwise_sqrt.cpp - * Output: \verbinclude Cwise_sqrt.out - * - * \sa pow(), square() - */ -inline const CwiseUnaryOp, const Derived> -sqrt() const -{ - return derived(); -} - -/** \returns an expression of the coefficient-wise cosine of *this. - * - * Example: \include Cwise_cos.cpp - * Output: \verbinclude Cwise_cos.out - * - * \sa sin(), acos() - */ -inline const CwiseUnaryOp, const Derived> -cos() const -{ - return derived(); -} - - -/** \returns an expression of the coefficient-wise sine of *this. - * - * Example: \include Cwise_sin.cpp - * Output: \verbinclude Cwise_sin.out - * - * \sa cos(), asin() - */ -inline const CwiseUnaryOp, const Derived> -sin() const -{ - return derived(); -} - -/** \returns an expression of the coefficient-wise arc cosine of *this. - * - * Example: \include Cwise_acos.cpp - * Output: \verbinclude Cwise_acos.out - * - * \sa cos(), asin() - */ -inline const CwiseUnaryOp, const Derived> -acos() const -{ - return derived(); -} - -/** \returns an expression of the coefficient-wise arc sine of *this. - * - * Example: \include Cwise_asin.cpp - * Output: \verbinclude Cwise_asin.out - * - * \sa sin(), acos() - */ -inline const CwiseUnaryOp, const Derived> -asin() const -{ - return derived(); -} - -/** \returns an expression of the coefficient-wise tan of *this. - * - * Example: \include Cwise_tan.cpp - * Output: \verbinclude Cwise_tan.out - * - * \sa cos(), sin() - */ -inline const CwiseUnaryOp, Derived> -tan() const -{ - return derived(); -} - - -/** \returns an expression of the coefficient-wise power of *this to the given exponent. - * - * Example: \include Cwise_pow.cpp - * Output: \verbinclude Cwise_pow.out - * - * \sa exp(), log() - */ -inline const CwiseUnaryOp, const Derived> -pow(const Scalar& exponent) const -{ - return CwiseUnaryOp, const Derived> - (derived(), internal::scalar_pow_op(exponent)); -} - - -/** \returns an expression of the coefficient-wise inverse of *this. - * - * Example: \include Cwise_inverse.cpp - * Output: \verbinclude Cwise_inverse.out - * - * \sa operator/(), operator*() - */ -inline const CwiseUnaryOp, const Derived> -inverse() const -{ - return derived(); -} - -/** \returns an expression of the coefficient-wise square of *this. - * - * Example: \include Cwise_square.cpp - * Output: \verbinclude Cwise_square.out - * - * \sa operator/(), operator*(), abs2() - */ -inline const CwiseUnaryOp, const Derived> -square() const -{ - return derived(); -} - -/** \returns an expression of the coefficient-wise cube of *this. - * - * Example: \include Cwise_cube.cpp - * Output: \verbinclude Cwise_cube.out - * - * \sa square(), pow() - */ -inline const CwiseUnaryOp, const Derived> -cube() const -{ - return derived(); -} diff --git a/thirdparty/eigen-3.2.7/Eigen/src/plugins/BlockMethods.h b/thirdparty/eigen-3.2.7/Eigen/src/plugins/BlockMethods.h deleted file mode 100644 index 2788251e..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/plugins/BlockMethods.h +++ /dev/null @@ -1,935 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2010 Gael Guennebaud -// Copyright (C) 2006-2010 Benoit Jacob -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - - -#ifndef EIGEN_PARSED_BY_DOXYGEN - -/** \internal expression type of a column */ -typedef Block::RowsAtCompileTime, 1, !IsRowMajor> ColXpr; -typedef const Block::RowsAtCompileTime, 1, !IsRowMajor> ConstColXpr; -/** \internal expression type of a row */ -typedef Block::ColsAtCompileTime, IsRowMajor> RowXpr; -typedef const Block::ColsAtCompileTime, IsRowMajor> ConstRowXpr; -/** \internal expression type of a block of whole columns */ -typedef Block::RowsAtCompileTime, Dynamic, !IsRowMajor> ColsBlockXpr; -typedef const Block::RowsAtCompileTime, Dynamic, !IsRowMajor> ConstColsBlockXpr; -/** \internal expression type of a block of whole rows */ -typedef Block::ColsAtCompileTime, IsRowMajor> RowsBlockXpr; -typedef const Block::ColsAtCompileTime, IsRowMajor> ConstRowsBlockXpr; -/** \internal expression type of a block of whole columns */ -template struct NColsBlockXpr { typedef Block::RowsAtCompileTime, N, !IsRowMajor> Type; }; -template struct ConstNColsBlockXpr { typedef const Block::RowsAtCompileTime, N, !IsRowMajor> Type; }; -/** \internal expression type of a block of whole rows */ -template struct NRowsBlockXpr { typedef Block::ColsAtCompileTime, IsRowMajor> Type; }; -template struct ConstNRowsBlockXpr { typedef const Block::ColsAtCompileTime, IsRowMajor> Type; }; - -typedef VectorBlock SegmentReturnType; -typedef const VectorBlock ConstSegmentReturnType; -template struct FixedSegmentReturnType { typedef VectorBlock Type; }; -template struct ConstFixedSegmentReturnType { typedef const VectorBlock Type; }; - -#endif // not EIGEN_PARSED_BY_DOXYGEN - -/** \returns a dynamic-size expression of a block in *this. - * - * \param startRow the first row in the block - * \param startCol the first column in the block - * \param blockRows the number of rows in the block - * \param blockCols the number of columns in the block - * - * Example: \include MatrixBase_block_int_int_int_int.cpp - * Output: \verbinclude MatrixBase_block_int_int_int_int.out - * - * \note Even though the returned expression has dynamic size, in the case - * when it is applied to a fixed-size matrix, it inherits a fixed maximal size, - * which means that evaluating it does not cause a dynamic memory allocation. - * - * \sa class Block, block(Index,Index) - */ -inline Block block(Index startRow, Index startCol, Index blockRows, Index blockCols) -{ - return Block(derived(), startRow, startCol, blockRows, blockCols); -} - -/** This is the const version of block(Index,Index,Index,Index). */ -inline const Block block(Index startRow, Index startCol, Index blockRows, Index blockCols) const -{ - return Block(derived(), startRow, startCol, blockRows, blockCols); -} - - - - -/** \returns a dynamic-size expression of a top-right corner of *this. - * - * \param cRows the number of rows in the corner - * \param cCols the number of columns in the corner - * - * Example: \include MatrixBase_topRightCorner_int_int.cpp - * Output: \verbinclude MatrixBase_topRightCorner_int_int.out - * - * \sa class Block, block(Index,Index,Index,Index) - */ -inline Block topRightCorner(Index cRows, Index cCols) -{ - return Block(derived(), 0, cols() - cCols, cRows, cCols); -} - -/** This is the const version of topRightCorner(Index, Index).*/ -inline const Block topRightCorner(Index cRows, Index cCols) const -{ - return Block(derived(), 0, cols() - cCols, cRows, cCols); -} - -/** \returns an expression of a fixed-size top-right corner of *this. - * - * \tparam CRows the number of rows in the corner - * \tparam CCols the number of columns in the corner - * - * Example: \include MatrixBase_template_int_int_topRightCorner.cpp - * Output: \verbinclude MatrixBase_template_int_int_topRightCorner.out - * - * \sa class Block, block(Index,Index) - */ -template -inline Block topRightCorner() -{ - return Block(derived(), 0, cols() - CCols); -} - -/** This is the const version of topRightCorner().*/ -template -inline const Block topRightCorner() const -{ - return Block(derived(), 0, cols() - CCols); -} - -/** \returns an expression of a top-right corner of *this. - * - * \tparam CRows number of rows in corner as specified at compile-time - * \tparam CCols number of columns in corner as specified at compile-time - * \param cRows number of rows in corner as specified at run-time - * \param cCols number of columns in corner as specified at run-time - * - * This function is mainly useful for corners where the number of rows is specified at compile-time - * and the number of columns is specified at run-time, or vice versa. The compile-time and run-time - * information should not contradict. In other words, \a cRows should equal \a CRows unless - * \a CRows is \a Dynamic, and the same for the number of columns. - * - * Example: \include MatrixBase_template_int_int_topRightCorner_int_int.cpp - * Output: \verbinclude MatrixBase_template_int_int_topRightCorner_int_int.out - * - * \sa class Block - */ -template -inline Block topRightCorner(Index cRows, Index cCols) -{ - return Block(derived(), 0, cols() - cCols, cRows, cCols); -} - -/** This is the const version of topRightCorner(Index, Index).*/ -template -inline const Block topRightCorner(Index cRows, Index cCols) const -{ - return Block(derived(), 0, cols() - cCols, cRows, cCols); -} - - - -/** \returns a dynamic-size expression of a top-left corner of *this. - * - * \param cRows the number of rows in the corner - * \param cCols the number of columns in the corner - * - * Example: \include MatrixBase_topLeftCorner_int_int.cpp - * Output: \verbinclude MatrixBase_topLeftCorner_int_int.out - * - * \sa class Block, block(Index,Index,Index,Index) - */ -inline Block topLeftCorner(Index cRows, Index cCols) -{ - return Block(derived(), 0, 0, cRows, cCols); -} - -/** This is the const version of topLeftCorner(Index, Index).*/ -inline const Block topLeftCorner(Index cRows, Index cCols) const -{ - return Block(derived(), 0, 0, cRows, cCols); -} - -/** \returns an expression of a fixed-size top-left corner of *this. - * - * The template parameters CRows and CCols are the number of rows and columns in the corner. - * - * Example: \include MatrixBase_template_int_int_topLeftCorner.cpp - * Output: \verbinclude MatrixBase_template_int_int_topLeftCorner.out - * - * \sa class Block, block(Index,Index,Index,Index) - */ -template -inline Block topLeftCorner() -{ - return Block(derived(), 0, 0); -} - -/** This is the const version of topLeftCorner().*/ -template -inline const Block topLeftCorner() const -{ - return Block(derived(), 0, 0); -} - -/** \returns an expression of a top-left corner of *this. - * - * \tparam CRows number of rows in corner as specified at compile-time - * \tparam CCols number of columns in corner as specified at compile-time - * \param cRows number of rows in corner as specified at run-time - * \param cCols number of columns in corner as specified at run-time - * - * This function is mainly useful for corners where the number of rows is specified at compile-time - * and the number of columns is specified at run-time, or vice versa. The compile-time and run-time - * information should not contradict. In other words, \a cRows should equal \a CRows unless - * \a CRows is \a Dynamic, and the same for the number of columns. - * - * Example: \include MatrixBase_template_int_int_topLeftCorner_int_int.cpp - * Output: \verbinclude MatrixBase_template_int_int_topLeftCorner_int_int.out - * - * \sa class Block - */ -template -inline Block topLeftCorner(Index cRows, Index cCols) -{ - return Block(derived(), 0, 0, cRows, cCols); -} - -/** This is the const version of topLeftCorner(Index, Index).*/ -template -inline const Block topLeftCorner(Index cRows, Index cCols) const -{ - return Block(derived(), 0, 0, cRows, cCols); -} - - - -/** \returns a dynamic-size expression of a bottom-right corner of *this. - * - * \param cRows the number of rows in the corner - * \param cCols the number of columns in the corner - * - * Example: \include MatrixBase_bottomRightCorner_int_int.cpp - * Output: \verbinclude MatrixBase_bottomRightCorner_int_int.out - * - * \sa class Block, block(Index,Index,Index,Index) - */ -inline Block bottomRightCorner(Index cRows, Index cCols) -{ - return Block(derived(), rows() - cRows, cols() - cCols, cRows, cCols); -} - -/** This is the const version of bottomRightCorner(Index, Index).*/ -inline const Block bottomRightCorner(Index cRows, Index cCols) const -{ - return Block(derived(), rows() - cRows, cols() - cCols, cRows, cCols); -} - -/** \returns an expression of a fixed-size bottom-right corner of *this. - * - * The template parameters CRows and CCols are the number of rows and columns in the corner. - * - * Example: \include MatrixBase_template_int_int_bottomRightCorner.cpp - * Output: \verbinclude MatrixBase_template_int_int_bottomRightCorner.out - * - * \sa class Block, block(Index,Index,Index,Index) - */ -template -inline Block bottomRightCorner() -{ - return Block(derived(), rows() - CRows, cols() - CCols); -} - -/** This is the const version of bottomRightCorner().*/ -template -inline const Block bottomRightCorner() const -{ - return Block(derived(), rows() - CRows, cols() - CCols); -} - -/** \returns an expression of a bottom-right corner of *this. - * - * \tparam CRows number of rows in corner as specified at compile-time - * \tparam CCols number of columns in corner as specified at compile-time - * \param cRows number of rows in corner as specified at run-time - * \param cCols number of columns in corner as specified at run-time - * - * This function is mainly useful for corners where the number of rows is specified at compile-time - * and the number of columns is specified at run-time, or vice versa. The compile-time and run-time - * information should not contradict. In other words, \a cRows should equal \a CRows unless - * \a CRows is \a Dynamic, and the same for the number of columns. - * - * Example: \include MatrixBase_template_int_int_bottomRightCorner_int_int.cpp - * Output: \verbinclude MatrixBase_template_int_int_bottomRightCorner_int_int.out - * - * \sa class Block - */ -template -inline Block bottomRightCorner(Index cRows, Index cCols) -{ - return Block(derived(), rows() - cRows, cols() - cCols, cRows, cCols); -} - -/** This is the const version of bottomRightCorner(Index, Index).*/ -template -inline const Block bottomRightCorner(Index cRows, Index cCols) const -{ - return Block(derived(), rows() - cRows, cols() - cCols, cRows, cCols); -} - - - -/** \returns a dynamic-size expression of a bottom-left corner of *this. - * - * \param cRows the number of rows in the corner - * \param cCols the number of columns in the corner - * - * Example: \include MatrixBase_bottomLeftCorner_int_int.cpp - * Output: \verbinclude MatrixBase_bottomLeftCorner_int_int.out - * - * \sa class Block, block(Index,Index,Index,Index) - */ -inline Block bottomLeftCorner(Index cRows, Index cCols) -{ - return Block(derived(), rows() - cRows, 0, cRows, cCols); -} - -/** This is the const version of bottomLeftCorner(Index, Index).*/ -inline const Block bottomLeftCorner(Index cRows, Index cCols) const -{ - return Block(derived(), rows() - cRows, 0, cRows, cCols); -} - -/** \returns an expression of a fixed-size bottom-left corner of *this. - * - * The template parameters CRows and CCols are the number of rows and columns in the corner. - * - * Example: \include MatrixBase_template_int_int_bottomLeftCorner.cpp - * Output: \verbinclude MatrixBase_template_int_int_bottomLeftCorner.out - * - * \sa class Block, block(Index,Index,Index,Index) - */ -template -inline Block bottomLeftCorner() -{ - return Block(derived(), rows() - CRows, 0); -} - -/** This is the const version of bottomLeftCorner().*/ -template -inline const Block bottomLeftCorner() const -{ - return Block(derived(), rows() - CRows, 0); -} - -/** \returns an expression of a bottom-left corner of *this. - * - * \tparam CRows number of rows in corner as specified at compile-time - * \tparam CCols number of columns in corner as specified at compile-time - * \param cRows number of rows in corner as specified at run-time - * \param cCols number of columns in corner as specified at run-time - * - * This function is mainly useful for corners where the number of rows is specified at compile-time - * and the number of columns is specified at run-time, or vice versa. The compile-time and run-time - * information should not contradict. In other words, \a cRows should equal \a CRows unless - * \a CRows is \a Dynamic, and the same for the number of columns. - * - * Example: \include MatrixBase_template_int_int_bottomLeftCorner_int_int.cpp - * Output: \verbinclude MatrixBase_template_int_int_bottomLeftCorner_int_int.out - * - * \sa class Block - */ -template -inline Block bottomLeftCorner(Index cRows, Index cCols) -{ - return Block(derived(), rows() - cRows, 0, cRows, cCols); -} - -/** This is the const version of bottomLeftCorner(Index, Index).*/ -template -inline const Block bottomLeftCorner(Index cRows, Index cCols) const -{ - return Block(derived(), rows() - cRows, 0, cRows, cCols); -} - - - -/** \returns a block consisting of the top rows of *this. - * - * \param n the number of rows in the block - * - * Example: \include MatrixBase_topRows_int.cpp - * Output: \verbinclude MatrixBase_topRows_int.out - * - * \sa class Block, block(Index,Index,Index,Index) - */ -inline RowsBlockXpr topRows(Index n) -{ - return RowsBlockXpr(derived(), 0, 0, n, cols()); -} - -/** This is the const version of topRows(Index).*/ -inline ConstRowsBlockXpr topRows(Index n) const -{ - return ConstRowsBlockXpr(derived(), 0, 0, n, cols()); -} - -/** \returns a block consisting of the top rows of *this. - * - * \tparam N the number of rows in the block as specified at compile-time - * \param n the number of rows in the block as specified at run-time - * - * The compile-time and run-time information should not contradict. In other words, - * \a n should equal \a N unless \a N is \a Dynamic. - * - * Example: \include MatrixBase_template_int_topRows.cpp - * Output: \verbinclude MatrixBase_template_int_topRows.out - * - * \sa class Block, block(Index,Index,Index,Index) - */ -template -inline typename NRowsBlockXpr::Type topRows(Index n = N) -{ - return typename NRowsBlockXpr::Type(derived(), 0, 0, n, cols()); -} - -/** This is the const version of topRows().*/ -template -inline typename ConstNRowsBlockXpr::Type topRows(Index n = N) const -{ - return typename ConstNRowsBlockXpr::Type(derived(), 0, 0, n, cols()); -} - - - -/** \returns a block consisting of the bottom rows of *this. - * - * \param n the number of rows in the block - * - * Example: \include MatrixBase_bottomRows_int.cpp - * Output: \verbinclude MatrixBase_bottomRows_int.out - * - * \sa class Block, block(Index,Index,Index,Index) - */ -inline RowsBlockXpr bottomRows(Index n) -{ - return RowsBlockXpr(derived(), rows() - n, 0, n, cols()); -} - -/** This is the const version of bottomRows(Index).*/ -inline ConstRowsBlockXpr bottomRows(Index n) const -{ - return ConstRowsBlockXpr(derived(), rows() - n, 0, n, cols()); -} - -/** \returns a block consisting of the bottom rows of *this. - * - * \tparam N the number of rows in the block as specified at compile-time - * \param n the number of rows in the block as specified at run-time - * - * The compile-time and run-time information should not contradict. In other words, - * \a n should equal \a N unless \a N is \a Dynamic. - * - * Example: \include MatrixBase_template_int_bottomRows.cpp - * Output: \verbinclude MatrixBase_template_int_bottomRows.out - * - * \sa class Block, block(Index,Index,Index,Index) - */ -template -inline typename NRowsBlockXpr::Type bottomRows(Index n = N) -{ - return typename NRowsBlockXpr::Type(derived(), rows() - n, 0, n, cols()); -} - -/** This is the const version of bottomRows().*/ -template -inline typename ConstNRowsBlockXpr::Type bottomRows(Index n = N) const -{ - return typename ConstNRowsBlockXpr::Type(derived(), rows() - n, 0, n, cols()); -} - - - -/** \returns a block consisting of a range of rows of *this. - * - * \param startRow the index of the first row in the block - * \param n the number of rows in the block - * - * Example: \include DenseBase_middleRows_int.cpp - * Output: \verbinclude DenseBase_middleRows_int.out - * - * \sa class Block, block(Index,Index,Index,Index) - */ -inline RowsBlockXpr middleRows(Index startRow, Index n) -{ - return RowsBlockXpr(derived(), startRow, 0, n, cols()); -} - -/** This is the const version of middleRows(Index,Index).*/ -inline ConstRowsBlockXpr middleRows(Index startRow, Index n) const -{ - return ConstRowsBlockXpr(derived(), startRow, 0, n, cols()); -} - -/** \returns a block consisting of a range of rows of *this. - * - * \tparam N the number of rows in the block as specified at compile-time - * \param startRow the index of the first row in the block - * \param n the number of rows in the block as specified at run-time - * - * The compile-time and run-time information should not contradict. In other words, - * \a n should equal \a N unless \a N is \a Dynamic. - * - * Example: \include DenseBase_template_int_middleRows.cpp - * Output: \verbinclude DenseBase_template_int_middleRows.out - * - * \sa class Block, block(Index,Index,Index,Index) - */ -template -inline typename NRowsBlockXpr::Type middleRows(Index startRow, Index n = N) -{ - return typename NRowsBlockXpr::Type(derived(), startRow, 0, n, cols()); -} - -/** This is the const version of middleRows().*/ -template -inline typename ConstNRowsBlockXpr::Type middleRows(Index startRow, Index n = N) const -{ - return typename ConstNRowsBlockXpr::Type(derived(), startRow, 0, n, cols()); -} - - - -/** \returns a block consisting of the left columns of *this. - * - * \param n the number of columns in the block - * - * Example: \include MatrixBase_leftCols_int.cpp - * Output: \verbinclude MatrixBase_leftCols_int.out - * - * \sa class Block, block(Index,Index,Index,Index) - */ -inline ColsBlockXpr leftCols(Index n) -{ - return ColsBlockXpr(derived(), 0, 0, rows(), n); -} - -/** This is the const version of leftCols(Index).*/ -inline ConstColsBlockXpr leftCols(Index n) const -{ - return ConstColsBlockXpr(derived(), 0, 0, rows(), n); -} - -/** \returns a block consisting of the left columns of *this. - * - * \tparam N the number of columns in the block as specified at compile-time - * \param n the number of columns in the block as specified at run-time - * - * The compile-time and run-time information should not contradict. In other words, - * \a n should equal \a N unless \a N is \a Dynamic. - * - * Example: \include MatrixBase_template_int_leftCols.cpp - * Output: \verbinclude MatrixBase_template_int_leftCols.out - * - * \sa class Block, block(Index,Index,Index,Index) - */ -template -inline typename NColsBlockXpr::Type leftCols(Index n = N) -{ - return typename NColsBlockXpr::Type(derived(), 0, 0, rows(), n); -} - -/** This is the const version of leftCols().*/ -template -inline typename ConstNColsBlockXpr::Type leftCols(Index n = N) const -{ - return typename ConstNColsBlockXpr::Type(derived(), 0, 0, rows(), n); -} - - - -/** \returns a block consisting of the right columns of *this. - * - * \param n the number of columns in the block - * - * Example: \include MatrixBase_rightCols_int.cpp - * Output: \verbinclude MatrixBase_rightCols_int.out - * - * \sa class Block, block(Index,Index,Index,Index) - */ -inline ColsBlockXpr rightCols(Index n) -{ - return ColsBlockXpr(derived(), 0, cols() - n, rows(), n); -} - -/** This is the const version of rightCols(Index).*/ -inline ConstColsBlockXpr rightCols(Index n) const -{ - return ConstColsBlockXpr(derived(), 0, cols() - n, rows(), n); -} - -/** \returns a block consisting of the right columns of *this. - * - * \tparam N the number of columns in the block as specified at compile-time - * \param n the number of columns in the block as specified at run-time - * - * The compile-time and run-time information should not contradict. In other words, - * \a n should equal \a N unless \a N is \a Dynamic. - * - * Example: \include MatrixBase_template_int_rightCols.cpp - * Output: \verbinclude MatrixBase_template_int_rightCols.out - * - * \sa class Block, block(Index,Index,Index,Index) - */ -template -inline typename NColsBlockXpr::Type rightCols(Index n = N) -{ - return typename NColsBlockXpr::Type(derived(), 0, cols() - n, rows(), n); -} - -/** This is the const version of rightCols().*/ -template -inline typename ConstNColsBlockXpr::Type rightCols(Index n = N) const -{ - return typename ConstNColsBlockXpr::Type(derived(), 0, cols() - n, rows(), n); -} - - - -/** \returns a block consisting of a range of columns of *this. - * - * \param startCol the index of the first column in the block - * \param numCols the number of columns in the block - * - * Example: \include DenseBase_middleCols_int.cpp - * Output: \verbinclude DenseBase_middleCols_int.out - * - * \sa class Block, block(Index,Index,Index,Index) - */ -inline ColsBlockXpr middleCols(Index startCol, Index numCols) -{ - return ColsBlockXpr(derived(), 0, startCol, rows(), numCols); -} - -/** This is the const version of middleCols(Index,Index).*/ -inline ConstColsBlockXpr middleCols(Index startCol, Index numCols) const -{ - return ConstColsBlockXpr(derived(), 0, startCol, rows(), numCols); -} - -/** \returns a block consisting of a range of columns of *this. - * - * \tparam N the number of columns in the block as specified at compile-time - * \param startCol the index of the first column in the block - * \param n the number of columns in the block as specified at run-time - * - * The compile-time and run-time information should not contradict. In other words, - * \a n should equal \a N unless \a N is \a Dynamic. - * - * Example: \include DenseBase_template_int_middleCols.cpp - * Output: \verbinclude DenseBase_template_int_middleCols.out - * - * \sa class Block, block(Index,Index,Index,Index) - */ -template -inline typename NColsBlockXpr::Type middleCols(Index startCol, Index n = N) -{ - return typename NColsBlockXpr::Type(derived(), 0, startCol, rows(), n); -} - -/** This is the const version of middleCols().*/ -template -inline typename ConstNColsBlockXpr::Type middleCols(Index startCol, Index n = N) const -{ - return typename ConstNColsBlockXpr::Type(derived(), 0, startCol, rows(), n); -} - - - -/** \returns a fixed-size expression of a block in *this. - * - * The template parameters \a BlockRows and \a BlockCols are the number of - * rows and columns in the block. - * - * \param startRow the first row in the block - * \param startCol the first column in the block - * - * Example: \include MatrixBase_block_int_int.cpp - * Output: \verbinclude MatrixBase_block_int_int.out - * - * \note since block is a templated member, the keyword template has to be used - * if the matrix type is also a template parameter: \code m.template block<3,3>(1,1); \endcode - * - * \sa class Block, block(Index,Index,Index,Index) - */ -template -inline Block block(Index startRow, Index startCol) -{ - return Block(derived(), startRow, startCol); -} - -/** This is the const version of block<>(Index, Index). */ -template -inline const Block block(Index startRow, Index startCol) const -{ - return Block(derived(), startRow, startCol); -} - -/** \returns an expression of a block in *this. - * - * \tparam BlockRows number of rows in block as specified at compile-time - * \tparam BlockCols number of columns in block as specified at compile-time - * \param startRow the first row in the block - * \param startCol the first column in the block - * \param blockRows number of rows in block as specified at run-time - * \param blockCols number of columns in block as specified at run-time - * - * This function is mainly useful for blocks where the number of rows is specified at compile-time - * and the number of columns is specified at run-time, or vice versa. The compile-time and run-time - * information should not contradict. In other words, \a blockRows should equal \a BlockRows unless - * \a BlockRows is \a Dynamic, and the same for the number of columns. - * - * Example: \include MatrixBase_template_int_int_block_int_int_int_int.cpp - * Output: \verbinclude MatrixBase_template_int_int_block_int_int_int_int.cpp - * - * \sa class Block, block(Index,Index,Index,Index) - */ -template -inline Block block(Index startRow, Index startCol, - Index blockRows, Index blockCols) -{ - return Block(derived(), startRow, startCol, blockRows, blockCols); -} - -/** This is the const version of block<>(Index, Index, Index, Index). */ -template -inline const Block block(Index startRow, Index startCol, - Index blockRows, Index blockCols) const -{ - return Block(derived(), startRow, startCol, blockRows, blockCols); -} - -/** \returns an expression of the \a i-th column of *this. Note that the numbering starts at 0. - * - * Example: \include MatrixBase_col.cpp - * Output: \verbinclude MatrixBase_col.out - * - * \sa row(), class Block */ -inline ColXpr col(Index i) -{ - return ColXpr(derived(), i); -} - -/** This is the const version of col(). */ -inline ConstColXpr col(Index i) const -{ - return ConstColXpr(derived(), i); -} - -/** \returns an expression of the \a i-th row of *this. Note that the numbering starts at 0. - * - * Example: \include MatrixBase_row.cpp - * Output: \verbinclude MatrixBase_row.out - * - * \sa col(), class Block */ -inline RowXpr row(Index i) -{ - return RowXpr(derived(), i); -} - -/** This is the const version of row(). */ -inline ConstRowXpr row(Index i) const -{ - return ConstRowXpr(derived(), i); -} - -/** \returns a dynamic-size expression of a segment (i.e. a vector block) in *this. - * - * \only_for_vectors - * - * \param start the first coefficient in the segment - * \param n the number of coefficients in the segment - * - * Example: \include MatrixBase_segment_int_int.cpp - * Output: \verbinclude MatrixBase_segment_int_int.out - * - * \note Even though the returned expression has dynamic size, in the case - * when it is applied to a fixed-size vector, it inherits a fixed maximal size, - * which means that evaluating it does not cause a dynamic memory allocation. - * - * \sa class Block, segment(Index) - */ -inline SegmentReturnType segment(Index start, Index n) -{ - EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) - return SegmentReturnType(derived(), start, n); -} - - -/** This is the const version of segment(Index,Index).*/ -inline ConstSegmentReturnType segment(Index start, Index n) const -{ - EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) - return ConstSegmentReturnType(derived(), start, n); -} - -/** \returns a dynamic-size expression of the first coefficients of *this. - * - * \only_for_vectors - * - * \param n the number of coefficients in the segment - * - * Example: \include MatrixBase_start_int.cpp - * Output: \verbinclude MatrixBase_start_int.out - * - * \note Even though the returned expression has dynamic size, in the case - * when it is applied to a fixed-size vector, it inherits a fixed maximal size, - * which means that evaluating it does not cause a dynamic memory allocation. - * - * \sa class Block, block(Index,Index) - */ -inline SegmentReturnType head(Index n) -{ - EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) - return SegmentReturnType(derived(), 0, n); -} - -/** This is the const version of head(Index).*/ -inline ConstSegmentReturnType head(Index n) const -{ - EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) - return ConstSegmentReturnType(derived(), 0, n); -} - -/** \returns a dynamic-size expression of the last coefficients of *this. - * - * \only_for_vectors - * - * \param n the number of coefficients in the segment - * - * Example: \include MatrixBase_end_int.cpp - * Output: \verbinclude MatrixBase_end_int.out - * - * \note Even though the returned expression has dynamic size, in the case - * when it is applied to a fixed-size vector, it inherits a fixed maximal size, - * which means that evaluating it does not cause a dynamic memory allocation. - * - * \sa class Block, block(Index,Index) - */ -inline SegmentReturnType tail(Index n) -{ - EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) - return SegmentReturnType(derived(), this->size() - n, n); -} - -/** This is the const version of tail(Index).*/ -inline ConstSegmentReturnType tail(Index n) const -{ - EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) - return ConstSegmentReturnType(derived(), this->size() - n, n); -} - -/** \returns a fixed-size expression of a segment (i.e. a vector block) in \c *this - * - * \only_for_vectors - * - * \tparam N the number of coefficients in the segment as specified at compile-time - * \param start the index of the first element in the segment - * \param n the number of coefficients in the segment as specified at compile-time - * - * The compile-time and run-time information should not contradict. In other words, - * \a n should equal \a N unless \a N is \a Dynamic. - * - * Example: \include MatrixBase_template_int_segment.cpp - * Output: \verbinclude MatrixBase_template_int_segment.out - * - * \sa class Block - */ -template -inline typename FixedSegmentReturnType::Type segment(Index start, Index n = N) -{ - EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) - return typename FixedSegmentReturnType::Type(derived(), start, n); -} - -/** This is the const version of segment(Index).*/ -template -inline typename ConstFixedSegmentReturnType::Type segment(Index start, Index n = N) const -{ - EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) - return typename ConstFixedSegmentReturnType::Type(derived(), start, n); -} - -/** \returns a fixed-size expression of the first coefficients of *this. - * - * \only_for_vectors - * - * \tparam N the number of coefficients in the segment as specified at compile-time - * \param n the number of coefficients in the segment as specified at run-time - * - * The compile-time and run-time information should not contradict. In other words, - * \a n should equal \a N unless \a N is \a Dynamic. - * - * Example: \include MatrixBase_template_int_start.cpp - * Output: \verbinclude MatrixBase_template_int_start.out - * - * \sa class Block - */ -template -inline typename FixedSegmentReturnType::Type head(Index n = N) -{ - EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) - return typename FixedSegmentReturnType::Type(derived(), 0, n); -} - -/** This is the const version of head().*/ -template -inline typename ConstFixedSegmentReturnType::Type head(Index n = N) const -{ - EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) - return typename ConstFixedSegmentReturnType::Type(derived(), 0, n); -} - -/** \returns a fixed-size expression of the last coefficients of *this. - * - * \only_for_vectors - * - * \tparam N the number of coefficients in the segment as specified at compile-time - * \param n the number of coefficients in the segment as specified at run-time - * - * The compile-time and run-time information should not contradict. In other words, - * \a n should equal \a N unless \a N is \a Dynamic. - * - * Example: \include MatrixBase_template_int_end.cpp - * Output: \verbinclude MatrixBase_template_int_end.out - * - * \sa class Block - */ -template -inline typename FixedSegmentReturnType::Type tail(Index n = N) -{ - EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) - return typename FixedSegmentReturnType::Type(derived(), size() - n); -} - -/** This is the const version of tail.*/ -template -inline typename ConstFixedSegmentReturnType::Type tail(Index n = N) const -{ - EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) - return typename ConstFixedSegmentReturnType::Type(derived(), size() - n); -} diff --git a/thirdparty/eigen-3.2.7/Eigen/src/plugins/CommonCwiseBinaryOps.h b/thirdparty/eigen-3.2.7/Eigen/src/plugins/CommonCwiseBinaryOps.h deleted file mode 100644 index 688d2244..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/plugins/CommonCwiseBinaryOps.h +++ /dev/null @@ -1,46 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2009 Gael Guennebaud -// Copyright (C) 2006-2008 Benoit Jacob -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -// This file is a base class plugin containing common coefficient wise functions. - -/** \returns an expression of the difference of \c *this and \a other - * - * \note If you want to substract a given scalar from all coefficients, see Cwise::operator-(). - * - * \sa class CwiseBinaryOp, operator-=() - */ -EIGEN_MAKE_CWISE_BINARY_OP(operator-,internal::scalar_difference_op) - -/** \returns an expression of the sum of \c *this and \a other - * - * \note If you want to add a given scalar to all coefficients, see Cwise::operator+(). - * - * \sa class CwiseBinaryOp, operator+=() - */ -EIGEN_MAKE_CWISE_BINARY_OP(operator+,internal::scalar_sum_op) - -/** \returns an expression of a custom coefficient-wise operator \a func of *this and \a other - * - * The template parameter \a CustomBinaryOp is the type of the functor - * of the custom operator (see class CwiseBinaryOp for an example) - * - * Here is an example illustrating the use of custom functors: - * \include class_CwiseBinaryOp.cpp - * Output: \verbinclude class_CwiseBinaryOp.out - * - * \sa class CwiseBinaryOp, operator+(), operator-(), cwiseProduct() - */ -template -EIGEN_STRONG_INLINE const CwiseBinaryOp -binaryExpr(const EIGEN_CURRENT_STORAGE_BASE_CLASS &other, const CustomBinaryOp& func = CustomBinaryOp()) const -{ - return CwiseBinaryOp(derived(), other.derived(), func); -} - diff --git a/thirdparty/eigen-3.2.7/Eigen/src/plugins/CommonCwiseUnaryOps.h b/thirdparty/eigen-3.2.7/Eigen/src/plugins/CommonCwiseUnaryOps.h deleted file mode 100644 index 08e931aa..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/plugins/CommonCwiseUnaryOps.h +++ /dev/null @@ -1,172 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2009 Gael Guennebaud -// Copyright (C) 2006-2008 Benoit Jacob -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -// This file is a base class plugin containing common coefficient wise functions. - -#ifndef EIGEN_PARSED_BY_DOXYGEN - -/** \internal Represents a scalar multiple of an expression */ -typedef CwiseUnaryOp, const Derived> ScalarMultipleReturnType; -/** \internal Represents a quotient of an expression by a scalar*/ -typedef CwiseUnaryOp, const Derived> ScalarQuotient1ReturnType; -/** \internal the return type of conjugate() */ -typedef typename internal::conditional::IsComplex, - const CwiseUnaryOp, const Derived>, - const Derived& - >::type ConjugateReturnType; -/** \internal the return type of real() const */ -typedef typename internal::conditional::IsComplex, - const CwiseUnaryOp, const Derived>, - const Derived& - >::type RealReturnType; -/** \internal the return type of real() */ -typedef typename internal::conditional::IsComplex, - CwiseUnaryView, Derived>, - Derived& - >::type NonConstRealReturnType; -/** \internal the return type of imag() const */ -typedef CwiseUnaryOp, const Derived> ImagReturnType; -/** \internal the return type of imag() */ -typedef CwiseUnaryView, Derived> NonConstImagReturnType; - -#endif // not EIGEN_PARSED_BY_DOXYGEN - -/** \returns an expression of the opposite of \c *this - */ -inline const CwiseUnaryOp::Scalar>, const Derived> -operator-() const { return derived(); } - - -/** \returns an expression of \c *this scaled by the scalar factor \a scalar */ -inline const ScalarMultipleReturnType -operator*(const Scalar& scalar) const -{ - return CwiseUnaryOp, const Derived> - (derived(), internal::scalar_multiple_op(scalar)); -} - -#ifdef EIGEN_PARSED_BY_DOXYGEN -const ScalarMultipleReturnType operator*(const RealScalar& scalar) const; -#endif - -/** \returns an expression of \c *this divided by the scalar value \a scalar */ -inline const CwiseUnaryOp::Scalar>, const Derived> -operator/(const Scalar& scalar) const -{ - return CwiseUnaryOp, const Derived> - (derived(), internal::scalar_quotient1_op(scalar)); -} - -/** Overloaded for efficient real matrix times complex scalar value */ -inline const CwiseUnaryOp >, const Derived> -operator*(const std::complex& scalar) const -{ - return CwiseUnaryOp >, const Derived> - (*static_cast(this), internal::scalar_multiple2_op >(scalar)); -} - -inline friend const ScalarMultipleReturnType -operator*(const Scalar& scalar, const StorageBaseType& matrix) -{ return matrix*scalar; } - -inline friend const CwiseUnaryOp >, const Derived> -operator*(const std::complex& scalar, const StorageBaseType& matrix) -{ return matrix*scalar; } - -/** \returns an expression of *this with the \a Scalar type casted to - * \a NewScalar. - * - * The template parameter \a NewScalar is the type we are casting the scalars to. - * - * \sa class CwiseUnaryOp - */ -template -typename internal::cast_return_type::Scalar, NewType>, const Derived> >::type -cast() const -{ - return derived(); -} - -/** \returns an expression of the complex conjugate of \c *this. - * - * \sa adjoint() */ -inline ConjugateReturnType -conjugate() const -{ - return ConjugateReturnType(derived()); -} - -/** \returns a read-only expression of the real part of \c *this. - * - * \sa imag() */ -inline RealReturnType -real() const { return derived(); } - -/** \returns an read-only expression of the imaginary part of \c *this. - * - * \sa real() */ -inline const ImagReturnType -imag() const { return derived(); } - -/** \brief Apply a unary operator coefficient-wise - * \param[in] func Functor implementing the unary operator - * \tparam CustomUnaryOp Type of \a func - * \returns An expression of a custom coefficient-wise unary operator \a func of *this - * - * The function \c ptr_fun() from the C++ standard library can be used to make functors out of normal functions. - * - * Example: - * \include class_CwiseUnaryOp_ptrfun.cpp - * Output: \verbinclude class_CwiseUnaryOp_ptrfun.out - * - * Genuine functors allow for more possibilities, for instance it may contain a state. - * - * Example: - * \include class_CwiseUnaryOp.cpp - * Output: \verbinclude class_CwiseUnaryOp.out - * - * \sa class CwiseUnaryOp, class CwiseBinaryOp - */ -template -inline const CwiseUnaryOp -unaryExpr(const CustomUnaryOp& func = CustomUnaryOp()) const -{ - return CwiseUnaryOp(derived(), func); -} - -/** \returns an expression of a custom coefficient-wise unary operator \a func of *this - * - * The template parameter \a CustomUnaryOp is the type of the functor - * of the custom unary operator. - * - * Example: - * \include class_CwiseUnaryOp.cpp - * Output: \verbinclude class_CwiseUnaryOp.out - * - * \sa class CwiseUnaryOp, class CwiseBinaryOp - */ -template -inline const CwiseUnaryView -unaryViewExpr(const CustomViewOp& func = CustomViewOp()) const -{ - return CwiseUnaryView(derived(), func); -} - -/** \returns a non const expression of the real part of \c *this. - * - * \sa imag() */ -inline NonConstRealReturnType -real() { return derived(); } - -/** \returns a non const expression of the imaginary part of \c *this. - * - * \sa real() */ -inline NonConstImagReturnType -imag() { return derived(); } diff --git a/thirdparty/eigen-3.2.7/Eigen/src/plugins/MatrixCwiseBinaryOps.h b/thirdparty/eigen-3.2.7/Eigen/src/plugins/MatrixCwiseBinaryOps.h deleted file mode 100644 index c4a042b7..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/plugins/MatrixCwiseBinaryOps.h +++ /dev/null @@ -1,143 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2009 Gael Guennebaud -// Copyright (C) 2006-2008 Benoit Jacob -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -// This file is a base class plugin containing matrix specifics coefficient wise functions. - -/** \returns an expression of the Schur product (coefficient wise product) of *this and \a other - * - * Example: \include MatrixBase_cwiseProduct.cpp - * Output: \verbinclude MatrixBase_cwiseProduct.out - * - * \sa class CwiseBinaryOp, cwiseAbs2 - */ -template -EIGEN_STRONG_INLINE const EIGEN_CWISE_PRODUCT_RETURN_TYPE(Derived,OtherDerived) -cwiseProduct(const EIGEN_CURRENT_STORAGE_BASE_CLASS &other) const -{ - return EIGEN_CWISE_PRODUCT_RETURN_TYPE(Derived,OtherDerived)(derived(), other.derived()); -} - -/** \returns an expression of the coefficient-wise == operator of *this and \a other - * - * \warning this performs an exact comparison, which is generally a bad idea with floating-point types. - * In order to check for equality between two vectors or matrices with floating-point coefficients, it is - * generally a far better idea to use a fuzzy comparison as provided by isApprox() and - * isMuchSmallerThan(). - * - * Example: \include MatrixBase_cwiseEqual.cpp - * Output: \verbinclude MatrixBase_cwiseEqual.out - * - * \sa cwiseNotEqual(), isApprox(), isMuchSmallerThan() - */ -template -inline const CwiseBinaryOp, const Derived, const OtherDerived> -cwiseEqual(const EIGEN_CURRENT_STORAGE_BASE_CLASS &other) const -{ - return CwiseBinaryOp, const Derived, const OtherDerived>(derived(), other.derived()); -} - -/** \returns an expression of the coefficient-wise != operator of *this and \a other - * - * \warning this performs an exact comparison, which is generally a bad idea with floating-point types. - * In order to check for equality between two vectors or matrices with floating-point coefficients, it is - * generally a far better idea to use a fuzzy comparison as provided by isApprox() and - * isMuchSmallerThan(). - * - * Example: \include MatrixBase_cwiseNotEqual.cpp - * Output: \verbinclude MatrixBase_cwiseNotEqual.out - * - * \sa cwiseEqual(), isApprox(), isMuchSmallerThan() - */ -template -inline const CwiseBinaryOp, const Derived, const OtherDerived> -cwiseNotEqual(const EIGEN_CURRENT_STORAGE_BASE_CLASS &other) const -{ - return CwiseBinaryOp, const Derived, const OtherDerived>(derived(), other.derived()); -} - -/** \returns an expression of the coefficient-wise min of *this and \a other - * - * Example: \include MatrixBase_cwiseMin.cpp - * Output: \verbinclude MatrixBase_cwiseMin.out - * - * \sa class CwiseBinaryOp, max() - */ -template -EIGEN_STRONG_INLINE const CwiseBinaryOp, const Derived, const OtherDerived> -cwiseMin(const EIGEN_CURRENT_STORAGE_BASE_CLASS &other) const -{ - return CwiseBinaryOp, const Derived, const OtherDerived>(derived(), other.derived()); -} - -/** \returns an expression of the coefficient-wise min of *this and scalar \a other - * - * \sa class CwiseBinaryOp, min() - */ -EIGEN_STRONG_INLINE const CwiseBinaryOp, const Derived, const ConstantReturnType> -cwiseMin(const Scalar &other) const -{ - return cwiseMin(Derived::Constant(rows(), cols(), other)); -} - -/** \returns an expression of the coefficient-wise max of *this and \a other - * - * Example: \include MatrixBase_cwiseMax.cpp - * Output: \verbinclude MatrixBase_cwiseMax.out - * - * \sa class CwiseBinaryOp, min() - */ -template -EIGEN_STRONG_INLINE const CwiseBinaryOp, const Derived, const OtherDerived> -cwiseMax(const EIGEN_CURRENT_STORAGE_BASE_CLASS &other) const -{ - return CwiseBinaryOp, const Derived, const OtherDerived>(derived(), other.derived()); -} - -/** \returns an expression of the coefficient-wise max of *this and scalar \a other - * - * \sa class CwiseBinaryOp, min() - */ -EIGEN_STRONG_INLINE const CwiseBinaryOp, const Derived, const ConstantReturnType> -cwiseMax(const Scalar &other) const -{ - return cwiseMax(Derived::Constant(rows(), cols(), other)); -} - - -/** \returns an expression of the coefficient-wise quotient of *this and \a other - * - * Example: \include MatrixBase_cwiseQuotient.cpp - * Output: \verbinclude MatrixBase_cwiseQuotient.out - * - * \sa class CwiseBinaryOp, cwiseProduct(), cwiseInverse() - */ -template -EIGEN_STRONG_INLINE const CwiseBinaryOp, const Derived, const OtherDerived> -cwiseQuotient(const EIGEN_CURRENT_STORAGE_BASE_CLASS &other) const -{ - return CwiseBinaryOp, const Derived, const OtherDerived>(derived(), other.derived()); -} - -typedef CwiseBinaryOp, const Derived, const ConstantReturnType> CwiseScalarEqualReturnType; - -/** \returns an expression of the coefficient-wise == operator of \c *this and a scalar \a s - * - * \warning this performs an exact comparison, which is generally a bad idea with floating-point types. - * In order to check for equality between two vectors or matrices with floating-point coefficients, it is - * generally a far better idea to use a fuzzy comparison as provided by isApprox() and - * isMuchSmallerThan(). - * - * \sa cwiseEqual(const MatrixBase &) const - */ -inline const CwiseScalarEqualReturnType -cwiseEqual(const Scalar& s) const -{ - return CwiseScalarEqualReturnType(derived(), Derived::Constant(rows(), cols(), s), internal::scalar_cmp_op()); -} diff --git a/thirdparty/eigen-3.2.7/Eigen/src/plugins/MatrixCwiseUnaryOps.h b/thirdparty/eigen-3.2.7/Eigen/src/plugins/MatrixCwiseUnaryOps.h deleted file mode 100644 index 8de10935..00000000 --- a/thirdparty/eigen-3.2.7/Eigen/src/plugins/MatrixCwiseUnaryOps.h +++ /dev/null @@ -1,52 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2009 Gael Guennebaud -// Copyright (C) 2006-2008 Benoit Jacob -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -// This file is a base class plugin containing matrix specifics coefficient wise functions. - -/** \returns an expression of the coefficient-wise absolute value of \c *this - * - * Example: \include MatrixBase_cwiseAbs.cpp - * Output: \verbinclude MatrixBase_cwiseAbs.out - * - * \sa cwiseAbs2() - */ -EIGEN_STRONG_INLINE const CwiseUnaryOp, const Derived> -cwiseAbs() const { return derived(); } - -/** \returns an expression of the coefficient-wise squared absolute value of \c *this - * - * Example: \include MatrixBase_cwiseAbs2.cpp - * Output: \verbinclude MatrixBase_cwiseAbs2.out - * - * \sa cwiseAbs() - */ -EIGEN_STRONG_INLINE const CwiseUnaryOp, const Derived> -cwiseAbs2() const { return derived(); } - -/** \returns an expression of the coefficient-wise square root of *this. - * - * Example: \include MatrixBase_cwiseSqrt.cpp - * Output: \verbinclude MatrixBase_cwiseSqrt.out - * - * \sa cwisePow(), cwiseSquare() - */ -inline const CwiseUnaryOp, const Derived> -cwiseSqrt() const { return derived(); } - -/** \returns an expression of the coefficient-wise inverse of *this. - * - * Example: \include MatrixBase_cwiseInverse.cpp - * Output: \verbinclude MatrixBase_cwiseInverse.out - * - * \sa cwiseProduct() - */ -inline const CwiseUnaryOp, const Derived> -cwiseInverse() const { return derived(); } - From 82614a9f193f44374232fab5975db52af84b858b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Schmitt?= Date: Fri, 20 Nov 2015 15:35:13 +0100 Subject: [PATCH 109/185] added a .gitignore for Eigen MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Étienne Schmitt --- thirdparty/eigen-3.2.7/.gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 thirdparty/eigen-3.2.7/.gitignore diff --git a/thirdparty/eigen-3.2.7/.gitignore b/thirdparty/eigen-3.2.7/.gitignore new file mode 100644 index 00000000..18c09451 --- /dev/null +++ b/thirdparty/eigen-3.2.7/.gitignore @@ -0,0 +1 @@ +Eigen/ From eb1a30acf739b88141b15b7cf79c64306f30daa5 Mon Sep 17 00:00:00 2001 From: Etienne Schmitt Date: Fri, 20 Nov 2015 15:09:20 +0100 Subject: [PATCH 110/185] fixed download and extraction of eigen on Windows Signed-off-by: Etienne Schmitt --- thirdparty/eigen-3.2.7/CMakeLists.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/thirdparty/eigen-3.2.7/CMakeLists.txt b/thirdparty/eigen-3.2.7/CMakeLists.txt index e9c16744..984afcb1 100644 --- a/thirdparty/eigen-3.2.7/CMakeLists.txt +++ b/thirdparty/eigen-3.2.7/CMakeLists.txt @@ -7,16 +7,19 @@ if (CGOGN_PROVIDE_EIGEN) set(CGOGN_OLD_EIGEN_DIRECTORY "eigen-eigen-b30b87236a1b") if(NOT EXISTS ${PROJECT_BINARY_DIR}/eigen${CGOGN_EIGEN_VERSION_STR}.tar.gz) file(DOWNLOAD http://bitbucket.org/eigen/eigen/get/${CGOGN_EIGEN_VERSION_STR}.tar.gz ${PROJECT_BINARY_DIR}/eigen${CGOGN_EIGEN_VERSION_STR}.tar.gz + TIMEOUT 180 SHOW_PROGRESS EXPECTED_MD5 ${CGOGN_EIGEN_MD5} ) execute_process( - COMMAND ${CMAKE_COMMAND} -E tar xzf ${PROJECT_BINARY_DIR}/eigen${CGOGN_EIGEN_VERSION_STR}.tar.gz + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E tar xzf eigen${CGOGN_EIGEN_VERSION_STR}.tar.gz ) endif() if(NOT EXISTS ${EIGEN_ROOT}/Eigen) execute_process( + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} COMMAND ${CMAKE_COMMAND} -E copy_directory ${CGOGN_OLD_EIGEN_DIRECTORY}/Eigen ${EIGEN_ROOT}/Eigen ) file( From 1fcc6220bb324d7a54bf92756f3100d453a5eed6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Schmitt?= Date: Mon, 23 Nov 2015 17:13:53 +0100 Subject: [PATCH 111/185] initialize ChunkArrayFactory::map_CA_ static array when the first map is created so we can again use a map as a global variable. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Étienne Schmitt --- cgogn/core/container/chunk_array_factory.h | 7 +++++++ cgogn/core/map/map_base_data.h | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/cgogn/core/container/chunk_array_factory.h b/cgogn/core/container/chunk_array_factory.h index c2fc5284..efac53d4 100644 --- a/cgogn/core/container/chunk_array_factory.h +++ b/cgogn/core/container/chunk_array_factory.h @@ -38,6 +38,8 @@ namespace cgogn template class ChunkArrayFactory { + static_assert(CHUNKSIZE >= 1u,"ChunkSize must be at least 1"); + static_assert((CHUNKSIZE >= 1u) & !(CHUNKSIZE & (CHUNKSIZE - 1)),"CHUNKSIZE must be a power of 2"); public: typedef std::integral_constant chunksize_type; typedef std::unique_ptr< ChunkArrayGen > ChunkArrayGenPtr; @@ -77,6 +79,11 @@ class ChunkArrayFactory return tmp; } + + static void reset() + { + ChunkArrayFactory::map_CA_ = NamePtrMap(); + } }; template diff --git a/cgogn/core/map/map_base_data.h b/cgogn/core/map/map_base_data.h index 6780d6ac..f2252740 100644 --- a/cgogn/core/map/map_base_data.h +++ b/cgogn/core/map/map_base_data.h @@ -112,6 +112,12 @@ class MapBaseData : public MapGen MapBaseData() : Inherit() { + static bool initCAFactory = true; + if (initCAFactory) + { + ChunkArrayFactory::reset(); + initCAFactory = false; + } for (unsigned int i = 0; i < NB_ORBITS; ++i) { embeddings_[i] = nullptr; From 361b3963f360cd646e96132c5d9cd00c09432356 Mon Sep 17 00:00:00 2001 From: Etienne Schmitt Date: Wed, 25 Nov 2015 14:15:52 +0100 Subject: [PATCH 112/185] Revert "removed Eigen3." This reverts commit cbc903910eb2d1c551b9fda2ba00bc8acba8d866. # Conflicts: # thirdparty/eigen-3.2.7/CMakeLists.txt Signed-off-by: Etienne Schmitt --- thirdparty/CMakeLists.txt | 4 +- thirdparty/eigen-3.2.7/.gitignore | 1 - thirdparty/eigen-3.2.7/CMakeLists.txt | 32 +- thirdparty/eigen-3.2.7/Eigen/Array | 11 + thirdparty/eigen-3.2.7/Eigen/Cholesky | 32 + thirdparty/eigen-3.2.7/Eigen/CholmodSupport | 45 + thirdparty/eigen-3.2.7/Eigen/Core | 376 ++++ thirdparty/eigen-3.2.7/Eigen/Dense | 7 + thirdparty/eigen-3.2.7/Eigen/Eigen | 2 + thirdparty/eigen-3.2.7/Eigen/Eigen2Support | 95 + thirdparty/eigen-3.2.7/Eigen/Eigenvalues | 48 + thirdparty/eigen-3.2.7/Eigen/Geometry | 63 + thirdparty/eigen-3.2.7/Eigen/Householder | 23 + .../eigen-3.2.7/Eigen/IterativeLinearSolvers | 40 + thirdparty/eigen-3.2.7/Eigen/Jacobi | 26 + thirdparty/eigen-3.2.7/Eigen/LU | 41 + thirdparty/eigen-3.2.7/Eigen/LeastSquares | 32 + thirdparty/eigen-3.2.7/Eigen/MetisSupport | 28 + thirdparty/eigen-3.2.7/Eigen/OrderingMethods | 66 + thirdparty/eigen-3.2.7/Eigen/PaStiXSupport | 46 + thirdparty/eigen-3.2.7/Eigen/PardisoSupport | 30 + thirdparty/eigen-3.2.7/Eigen/QR | 45 + thirdparty/eigen-3.2.7/Eigen/QtAlignedMalloc | 34 + thirdparty/eigen-3.2.7/Eigen/SPQRSupport | 29 + thirdparty/eigen-3.2.7/Eigen/SVD | 37 + thirdparty/eigen-3.2.7/Eigen/Sparse | 27 + thirdparty/eigen-3.2.7/Eigen/SparseCholesky | 47 + thirdparty/eigen-3.2.7/Eigen/SparseCore | 64 + thirdparty/eigen-3.2.7/Eigen/SparseLU | 49 + thirdparty/eigen-3.2.7/Eigen/SparseQR | 33 + thirdparty/eigen-3.2.7/Eigen/StdDeque | 27 + thirdparty/eigen-3.2.7/Eigen/StdList | 26 + thirdparty/eigen-3.2.7/Eigen/StdVector | 27 + thirdparty/eigen-3.2.7/Eigen/SuperLUSupport | 59 + thirdparty/eigen-3.2.7/Eigen/UmfPackSupport | 36 + .../eigen-3.2.7/Eigen/src/Cholesky/LDLT.h | 611 ++++++ .../eigen-3.2.7/Eigen/src/Cholesky/LLT.h | 498 +++++ .../eigen-3.2.7/Eigen/src/Cholesky/LLT_MKL.h | 102 + .../Eigen/src/CholmodSupport/CholmodSupport.h | 607 ++++++ thirdparty/eigen-3.2.7/Eigen/src/Core/Array.h | 323 +++ .../eigen-3.2.7/Eigen/src/Core/ArrayBase.h | 226 ++ .../eigen-3.2.7/Eigen/src/Core/ArrayWrapper.h | 264 +++ .../eigen-3.2.7/Eigen/src/Core/Assign.h | 590 ++++++ .../eigen-3.2.7/Eigen/src/Core/Assign_MKL.h | 224 ++ .../eigen-3.2.7/Eigen/src/Core/BandMatrix.h | 334 +++ thirdparty/eigen-3.2.7/Eigen/src/Core/Block.h | 406 ++++ .../eigen-3.2.7/Eigen/src/Core/BooleanRedux.h | 154 ++ .../Eigen/src/Core/CommaInitializer.h | 154 ++ .../Eigen/src/Core/CoreIterators.h | 61 + .../Eigen/src/Core/CwiseBinaryOp.h | 230 ++ .../Eigen/src/Core/CwiseNullaryOp.h | 864 ++++++++ .../eigen-3.2.7/Eigen/src/Core/CwiseUnaryOp.h | 126 ++ .../Eigen/src/Core/CwiseUnaryView.h | 139 ++ .../eigen-3.2.7/Eigen/src/Core/DenseBase.h | 521 +++++ .../Eigen/src/Core/DenseCoeffsBase.h | 754 +++++++ .../eigen-3.2.7/Eigen/src/Core/DenseStorage.h | 434 ++++ .../eigen-3.2.7/Eigen/src/Core/Diagonal.h | 237 +++ .../Eigen/src/Core/DiagonalMatrix.h | 313 +++ .../Eigen/src/Core/DiagonalProduct.h | 131 ++ thirdparty/eigen-3.2.7/Eigen/src/Core/Dot.h | 263 +++ .../eigen-3.2.7/Eigen/src/Core/EigenBase.h | 131 ++ .../eigen-3.2.7/Eigen/src/Core/Flagged.h | 140 ++ .../Eigen/src/Core/ForceAlignedAccess.h | 146 ++ .../eigen-3.2.7/Eigen/src/Core/Functors.h | 1026 +++++++++ thirdparty/eigen-3.2.7/Eigen/src/Core/Fuzzy.h | 150 ++ .../Eigen/src/Core/GeneralProduct.h | 635 ++++++ .../Eigen/src/Core/GenericPacketMath.h | 350 ++++ .../Eigen/src/Core/GlobalFunctions.h | 92 + thirdparty/eigen-3.2.7/Eigen/src/Core/IO.h | 250 +++ thirdparty/eigen-3.2.7/Eigen/src/Core/Map.h | 192 ++ .../eigen-3.2.7/Eigen/src/Core/MapBase.h | 247 +++ .../Eigen/src/Core/MathFunctions.h | 768 +++++++ .../eigen-3.2.7/Eigen/src/Core/Matrix.h | 420 ++++ .../eigen-3.2.7/Eigen/src/Core/MatrixBase.h | 563 +++++ .../eigen-3.2.7/Eigen/src/Core/NestByValue.h | 111 + .../eigen-3.2.7/Eigen/src/Core/NoAlias.h | 134 ++ .../eigen-3.2.7/Eigen/src/Core/NumTraits.h | 150 ++ .../Eigen/src/Core/PermutationMatrix.h | 721 +++++++ .../Eigen/src/Core/PlainObjectBase.h | 822 ++++++++ .../eigen-3.2.7/Eigen/src/Core/ProductBase.h | 290 +++ .../eigen-3.2.7/Eigen/src/Core/Random.h | 152 ++ thirdparty/eigen-3.2.7/Eigen/src/Core/Redux.h | 409 ++++ thirdparty/eigen-3.2.7/Eigen/src/Core/Ref.h | 278 +++ .../eigen-3.2.7/Eigen/src/Core/Replicate.h | 177 ++ .../Eigen/src/Core/ReturnByValue.h | 99 + .../eigen-3.2.7/Eigen/src/Core/Reverse.h | 224 ++ .../eigen-3.2.7/Eigen/src/Core/Select.h | 162 ++ .../Eigen/src/Core/SelfAdjointView.h | 314 +++ .../Eigen/src/Core/SelfCwiseBinaryOp.h | 191 ++ .../Eigen/src/Core/SolveTriangular.h | 260 +++ .../eigen-3.2.7/Eigen/src/Core/StableNorm.h | 203 ++ .../eigen-3.2.7/Eigen/src/Core/Stride.h | 108 + thirdparty/eigen-3.2.7/Eigen/src/Core/Swap.h | 126 ++ .../eigen-3.2.7/Eigen/src/Core/Transpose.h | 419 ++++ .../Eigen/src/Core/Transpositions.h | 436 ++++ .../Eigen/src/Core/TriangularMatrix.h | 839 ++++++++ .../eigen-3.2.7/Eigen/src/Core/VectorBlock.h | 95 + .../eigen-3.2.7/Eigen/src/Core/VectorwiseOp.h | 642 ++++++ .../eigen-3.2.7/Eigen/src/Core/Visitor.h | 237 +++ .../Eigen/src/Core/arch/AltiVec/Complex.h | 217 ++ .../Eigen/src/Core/arch/AltiVec/PacketMath.h | 501 +++++ .../Eigen/src/Core/arch/Default/Settings.h | 49 + .../Eigen/src/Core/arch/NEON/Complex.h | 253 +++ .../Eigen/src/Core/arch/NEON/PacketMath.h | 420 ++++ .../Eigen/src/Core/arch/SSE/Complex.h | 442 ++++ .../Eigen/src/Core/arch/SSE/MathFunctions.h | 475 +++++ .../Eigen/src/Core/arch/SSE/PacketMath.h | 649 ++++++ .../src/Core/products/CoeffBasedProduct.h | 476 +++++ .../Core/products/GeneralBlockPanelKernel.h | 1341 ++++++++++++ .../src/Core/products/GeneralMatrixMatrix.h | 427 ++++ .../products/GeneralMatrixMatrixTriangular.h | 278 +++ .../GeneralMatrixMatrixTriangular_MKL.h | 146 ++ .../Core/products/GeneralMatrixMatrix_MKL.h | 118 ++ .../src/Core/products/GeneralMatrixVector.h | 566 +++++ .../Core/products/GeneralMatrixVector_MKL.h | 131 ++ .../Eigen/src/Core/products/Parallelizer.h | 162 ++ .../Core/products/SelfadjointMatrixMatrix.h | 436 ++++ .../products/SelfadjointMatrixMatrix_MKL.h | 295 +++ .../Core/products/SelfadjointMatrixVector.h | 281 +++ .../products/SelfadjointMatrixVector_MKL.h | 114 + .../src/Core/products/SelfadjointProduct.h | 123 ++ .../Core/products/SelfadjointRank2Update.h | 93 + .../Core/products/TriangularMatrixMatrix.h | 427 ++++ .../products/TriangularMatrixMatrix_MKL.h | 309 +++ .../Core/products/TriangularMatrixVector.h | 348 ++++ .../products/TriangularMatrixVector_MKL.h | 247 +++ .../Core/products/TriangularSolverMatrix.h | 332 +++ .../products/TriangularSolverMatrix_MKL.h | 155 ++ .../Core/products/TriangularSolverVector.h | 139 ++ .../Eigen/src/Core/util/BlasUtil.h | 264 +++ .../Eigen/src/Core/util/Constants.h | 451 ++++ .../src/Core/util/DisableStupidWarnings.h | 40 + .../Eigen/src/Core/util/ForwardDeclarations.h | 302 +++ .../Eigen/src/Core/util/MKL_support.h | 158 ++ .../eigen-3.2.7/Eigen/src/Core/util/Macros.h | 451 ++++ .../eigen-3.2.7/Eigen/src/Core/util/Memory.h | 977 +++++++++ .../eigen-3.2.7/Eigen/src/Core/util/Meta.h | 243 +++ .../eigen-3.2.7/Eigen/src/Core/util/NonMPL2.h | 3 + .../src/Core/util/ReenableStupidWarnings.h | 14 + .../Eigen/src/Core/util/StaticAssert.h | 208 ++ .../Eigen/src/Core/util/XprHelper.h | 469 +++++ .../Eigen/src/Eigen2Support/Block.h | 126 ++ .../Eigen/src/Eigen2Support/Cwise.h | 192 ++ .../Eigen/src/Eigen2Support/CwiseOperators.h | 298 +++ .../src/Eigen2Support/Geometry/AlignedBox.h | 159 ++ .../Eigen/src/Eigen2Support/Geometry/All.h | 115 + .../src/Eigen2Support/Geometry/AngleAxis.h | 214 ++ .../src/Eigen2Support/Geometry/Hyperplane.h | 254 +++ .../Eigen2Support/Geometry/ParametrizedLine.h | 141 ++ .../src/Eigen2Support/Geometry/Quaternion.h | 495 +++++ .../src/Eigen2Support/Geometry/Rotation2D.h | 145 ++ .../src/Eigen2Support/Geometry/RotationBase.h | 123 ++ .../src/Eigen2Support/Geometry/Scaling.h | 167 ++ .../src/Eigen2Support/Geometry/Transform.h | 786 +++++++ .../src/Eigen2Support/Geometry/Translation.h | 184 ++ .../eigen-3.2.7/Eigen/src/Eigen2Support/LU.h | 120 ++ .../Eigen/src/Eigen2Support/Lazy.h | 71 + .../Eigen/src/Eigen2Support/LeastSquares.h | 169 ++ .../Eigen/src/Eigen2Support/Macros.h | 20 + .../Eigen/src/Eigen2Support/MathFunctions.h | 57 + .../Eigen/src/Eigen2Support/Memory.h | 45 + .../Eigen/src/Eigen2Support/Meta.h | 75 + .../Eigen/src/Eigen2Support/Minor.h | 117 ++ .../eigen-3.2.7/Eigen/src/Eigen2Support/QR.h | 67 + .../eigen-3.2.7/Eigen/src/Eigen2Support/SVD.h | 637 ++++++ .../src/Eigen2Support/TriangularSolver.h | 42 + .../Eigen/src/Eigen2Support/VectorBlock.h | 94 + .../src/Eigenvalues/ComplexEigenSolver.h | 341 +++ .../Eigen/src/Eigenvalues/ComplexSchur.h | 456 ++++ .../Eigen/src/Eigenvalues/ComplexSchur_MKL.h | 94 + .../Eigen/src/Eigenvalues/EigenSolver.h | 607 ++++++ .../src/Eigenvalues/GeneralizedEigenSolver.h | 350 ++++ .../GeneralizedSelfAdjointEigenSolver.h | 227 ++ .../src/Eigenvalues/HessenbergDecomposition.h | 373 ++++ .../src/Eigenvalues/MatrixBaseEigenvalues.h | 160 ++ .../Eigen/src/Eigenvalues/RealQZ.h | 624 ++++++ .../Eigen/src/Eigenvalues/RealSchur.h | 525 +++++ .../Eigen/src/Eigenvalues/RealSchur_MKL.h | 83 + .../src/Eigenvalues/SelfAdjointEigenSolver.h | 801 +++++++ .../Eigenvalues/SelfAdjointEigenSolver_MKL.h | 92 + .../src/Eigenvalues/Tridiagonalization.h | 557 +++++ .../Eigen/src/Geometry/AlignedBox.h | 392 ++++ .../Eigen/src/Geometry/AngleAxis.h | 233 +++ .../Eigen/src/Geometry/EulerAngles.h | 104 + .../Eigen/src/Geometry/Homogeneous.h | 307 +++ .../Eigen/src/Geometry/Hyperplane.h | 280 +++ .../Eigen/src/Geometry/OrthoMethods.h | 218 ++ .../Eigen/src/Geometry/ParametrizedLine.h | 195 ++ .../Eigen/src/Geometry/Quaternion.h | 776 +++++++ .../Eigen/src/Geometry/Rotation2D.h | 160 ++ .../Eigen/src/Geometry/RotationBase.h | 206 ++ .../eigen-3.2.7/Eigen/src/Geometry/Scaling.h | 166 ++ .../Eigen/src/Geometry/Transform.h | 1455 +++++++++++++ .../Eigen/src/Geometry/Translation.h | 206 ++ .../eigen-3.2.7/Eigen/src/Geometry/Umeyama.h | 177 ++ .../Eigen/src/Geometry/arch/Geometry_SSE.h | 115 + .../Eigen/src/Householder/BlockHouseholder.h | 68 + .../Eigen/src/Householder/Householder.h | 171 ++ .../src/Householder/HouseholderSequence.h | 441 ++++ .../BasicPreconditioners.h | 149 ++ .../src/IterativeLinearSolvers/BiCGSTAB.h | 263 +++ .../ConjugateGradient.h | 256 +++ .../IterativeLinearSolvers/IncompleteLUT.h | 478 +++++ .../IterativeSolverBase.h | 282 +++ .../eigen-3.2.7/Eigen/src/Jacobi/Jacobi.h | 433 ++++ .../eigen-3.2.7/Eigen/src/LU/Determinant.h | 101 + .../eigen-3.2.7/Eigen/src/LU/FullPivLU.h | 751 +++++++ thirdparty/eigen-3.2.7/Eigen/src/LU/Inverse.h | 400 ++++ .../eigen-3.2.7/Eigen/src/LU/PartialPivLU.h | 509 +++++ .../Eigen/src/LU/PartialPivLU_MKL.h | 85 + .../Eigen/src/LU/arch/Inverse_SSE.h | 329 +++ .../Eigen/src/MetisSupport/MetisSupport.h | 137 ++ .../Eigen/src/OrderingMethods/Amd.h | 444 ++++ .../Eigen/src/OrderingMethods/Eigen_Colamd.h | 1850 +++++++++++++++++ .../Eigen/src/OrderingMethods/Ordering.h | 154 ++ .../Eigen/src/PaStiXSupport/PaStiXSupport.h | 721 +++++++ .../Eigen/src/PardisoSupport/PardisoSupport.h | 592 ++++++ .../Eigen/src/QR/ColPivHouseholderQR.h | 580 ++++++ .../Eigen/src/QR/ColPivHouseholderQR_MKL.h | 99 + .../Eigen/src/QR/FullPivHouseholderQR.h | 622 ++++++ .../eigen-3.2.7/Eigen/src/QR/HouseholderQR.h | 388 ++++ .../Eigen/src/QR/HouseholderQR_MKL.h | 71 + .../src/SPQRSupport/SuiteSparseQRSupport.h | 338 +++ .../eigen-3.2.7/Eigen/src/SVD/JacobiSVD.h | 976 +++++++++ .../eigen-3.2.7/Eigen/src/SVD/JacobiSVD_MKL.h | 92 + .../Eigen/src/SVD/UpperBidiagonalization.h | 148 ++ .../src/SparseCholesky/SimplicialCholesky.h | 671 ++++++ .../SparseCholesky/SimplicialCholesky_impl.h | 199 ++ .../Eigen/src/SparseCore/AmbiVector.h | 373 ++++ .../Eigen/src/SparseCore/CompressedStorage.h | 233 +++ .../ConservativeSparseSparseProduct.h | 245 +++ .../Eigen/src/SparseCore/MappedSparseMatrix.h | 181 ++ .../Eigen/src/SparseCore/SparseBlock.h | 537 +++++ .../Eigen/src/SparseCore/SparseColEtree.h | 206 ++ .../src/SparseCore/SparseCwiseBinaryOp.h | 325 +++ .../Eigen/src/SparseCore/SparseCwiseUnaryOp.h | 163 ++ .../Eigen/src/SparseCore/SparseDenseProduct.h | 311 +++ .../src/SparseCore/SparseDiagonalProduct.h | 196 ++ .../Eigen/src/SparseCore/SparseDot.h | 101 + .../Eigen/src/SparseCore/SparseFuzzy.h | 26 + .../Eigen/src/SparseCore/SparseMatrix.h | 1262 +++++++++++ .../Eigen/src/SparseCore/SparseMatrixBase.h | 461 ++++ .../Eigen/src/SparseCore/SparsePermutation.h | 148 ++ .../Eigen/src/SparseCore/SparseProduct.h | 188 ++ .../Eigen/src/SparseCore/SparseRedux.h | 45 + .../src/SparseCore/SparseSelfAdjointView.h | 507 +++++ .../SparseSparseProductWithPruning.h | 150 ++ .../Eigen/src/SparseCore/SparseTranspose.h | 63 + .../src/SparseCore/SparseTriangularView.h | 179 ++ .../Eigen/src/SparseCore/SparseUtil.h | 172 ++ .../Eigen/src/SparseCore/SparseVector.h | 448 ++++ .../Eigen/src/SparseCore/SparseView.h | 99 + .../Eigen/src/SparseCore/TriangularSolver.h | 334 +++ .../eigen-3.2.7/Eigen/src/SparseLU/SparseLU.h | 806 +++++++ .../Eigen/src/SparseLU/SparseLUImpl.h | 66 + .../Eigen/src/SparseLU/SparseLU_Memory.h | 227 ++ .../Eigen/src/SparseLU/SparseLU_Structs.h | 111 + .../src/SparseLU/SparseLU_SupernodalMatrix.h | 298 +++ .../Eigen/src/SparseLU/SparseLU_Utils.h | 80 + .../Eigen/src/SparseLU/SparseLU_column_bmod.h | 180 ++ .../Eigen/src/SparseLU/SparseLU_column_dfs.h | 177 ++ .../src/SparseLU/SparseLU_copy_to_ucol.h | 106 + .../Eigen/src/SparseLU/SparseLU_gemm_kernel.h | 279 +++ .../src/SparseLU/SparseLU_heap_relax_snode.h | 127 ++ .../Eigen/src/SparseLU/SparseLU_kernel_bmod.h | 130 ++ .../Eigen/src/SparseLU/SparseLU_panel_bmod.h | 223 ++ .../Eigen/src/SparseLU/SparseLU_panel_dfs.h | 258 +++ .../Eigen/src/SparseLU/SparseLU_pivotL.h | 137 ++ .../Eigen/src/SparseLU/SparseLU_pruneL.h | 135 ++ .../Eigen/src/SparseLU/SparseLU_relax_snode.h | 83 + .../eigen-3.2.7/Eigen/src/SparseQR/SparseQR.h | 714 +++++++ .../Eigen/src/StlSupport/StdDeque.h | 134 ++ .../Eigen/src/StlSupport/StdList.h | 114 + .../Eigen/src/StlSupport/StdVector.h | 126 ++ .../Eigen/src/StlSupport/details.h | 84 + .../Eigen/src/SuperLUSupport/SuperLUSupport.h | 1026 +++++++++ .../Eigen/src/UmfPackSupport/UmfPackSupport.h | 474 +++++ thirdparty/eigen-3.2.7/Eigen/src/misc/Image.h | 84 + .../eigen-3.2.7/Eigen/src/misc/Kernel.h | 81 + thirdparty/eigen-3.2.7/Eigen/src/misc/Solve.h | 76 + .../eigen-3.2.7/Eigen/src/misc/SparseSolve.h | 128 ++ thirdparty/eigen-3.2.7/Eigen/src/misc/blas.h | 658 ++++++ .../Eigen/src/plugins/ArrayCwiseBinaryOps.h | 253 +++ .../Eigen/src/plugins/ArrayCwiseUnaryOps.h | 187 ++ .../Eigen/src/plugins/BlockMethods.h | 935 +++++++++ .../Eigen/src/plugins/CommonCwiseBinaryOps.h | 46 + .../Eigen/src/plugins/CommonCwiseUnaryOps.h | 172 ++ .../Eigen/src/plugins/MatrixCwiseBinaryOps.h | 143 ++ .../Eigen/src/plugins/MatrixCwiseUnaryOps.h | 52 + 289 files changed, 80215 insertions(+), 32 deletions(-) delete mode 100644 thirdparty/eigen-3.2.7/.gitignore create mode 100644 thirdparty/eigen-3.2.7/Eigen/Array create mode 100644 thirdparty/eigen-3.2.7/Eigen/Cholesky create mode 100644 thirdparty/eigen-3.2.7/Eigen/CholmodSupport create mode 100644 thirdparty/eigen-3.2.7/Eigen/Core create mode 100644 thirdparty/eigen-3.2.7/Eigen/Dense create mode 100644 thirdparty/eigen-3.2.7/Eigen/Eigen create mode 100644 thirdparty/eigen-3.2.7/Eigen/Eigen2Support create mode 100644 thirdparty/eigen-3.2.7/Eigen/Eigenvalues create mode 100644 thirdparty/eigen-3.2.7/Eigen/Geometry create mode 100644 thirdparty/eigen-3.2.7/Eigen/Householder create mode 100644 thirdparty/eigen-3.2.7/Eigen/IterativeLinearSolvers create mode 100644 thirdparty/eigen-3.2.7/Eigen/Jacobi create mode 100644 thirdparty/eigen-3.2.7/Eigen/LU create mode 100644 thirdparty/eigen-3.2.7/Eigen/LeastSquares create mode 100644 thirdparty/eigen-3.2.7/Eigen/MetisSupport create mode 100644 thirdparty/eigen-3.2.7/Eigen/OrderingMethods create mode 100644 thirdparty/eigen-3.2.7/Eigen/PaStiXSupport create mode 100644 thirdparty/eigen-3.2.7/Eigen/PardisoSupport create mode 100644 thirdparty/eigen-3.2.7/Eigen/QR create mode 100644 thirdparty/eigen-3.2.7/Eigen/QtAlignedMalloc create mode 100644 thirdparty/eigen-3.2.7/Eigen/SPQRSupport create mode 100644 thirdparty/eigen-3.2.7/Eigen/SVD create mode 100644 thirdparty/eigen-3.2.7/Eigen/Sparse create mode 100644 thirdparty/eigen-3.2.7/Eigen/SparseCholesky create mode 100644 thirdparty/eigen-3.2.7/Eigen/SparseCore create mode 100644 thirdparty/eigen-3.2.7/Eigen/SparseLU create mode 100644 thirdparty/eigen-3.2.7/Eigen/SparseQR create mode 100644 thirdparty/eigen-3.2.7/Eigen/StdDeque create mode 100644 thirdparty/eigen-3.2.7/Eigen/StdList create mode 100644 thirdparty/eigen-3.2.7/Eigen/StdVector create mode 100644 thirdparty/eigen-3.2.7/Eigen/SuperLUSupport create mode 100644 thirdparty/eigen-3.2.7/Eigen/UmfPackSupport create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Cholesky/LDLT.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Cholesky/LLT.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Cholesky/LLT_MKL.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/CholmodSupport/CholmodSupport.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/Array.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/ArrayBase.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/ArrayWrapper.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/Assign.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/Assign_MKL.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/BandMatrix.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/Block.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/BooleanRedux.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/CommaInitializer.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/CoreIterators.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/CwiseBinaryOp.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/CwiseNullaryOp.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/CwiseUnaryOp.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/CwiseUnaryView.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/DenseBase.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/DenseCoeffsBase.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/DenseStorage.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/Diagonal.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/DiagonalMatrix.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/DiagonalProduct.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/Dot.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/EigenBase.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/Flagged.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/ForceAlignedAccess.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/Functors.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/Fuzzy.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/GeneralProduct.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/GenericPacketMath.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/GlobalFunctions.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/IO.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/Map.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/MapBase.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/MathFunctions.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/Matrix.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/MatrixBase.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/NestByValue.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/NoAlias.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/NumTraits.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/PermutationMatrix.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/PlainObjectBase.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/ProductBase.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/Random.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/Redux.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/Ref.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/Replicate.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/ReturnByValue.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/Reverse.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/Select.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/SelfAdjointView.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/SelfCwiseBinaryOp.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/SolveTriangular.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/StableNorm.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/Stride.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/Swap.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/Transpose.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/Transpositions.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/TriangularMatrix.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/VectorBlock.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/VectorwiseOp.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/Visitor.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/arch/AltiVec/Complex.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/arch/AltiVec/PacketMath.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/arch/Default/Settings.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/arch/NEON/Complex.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/arch/NEON/PacketMath.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/arch/SSE/Complex.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/arch/SSE/MathFunctions.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/arch/SSE/PacketMath.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/products/CoeffBasedProduct.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/products/GeneralBlockPanelKernel.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/products/GeneralMatrixMatrix.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_MKL.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/products/GeneralMatrixMatrix_MKL.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/products/GeneralMatrixVector.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/products/GeneralMatrixVector_MKL.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/products/Parallelizer.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/products/SelfadjointMatrixMatrix.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/products/SelfadjointMatrixMatrix_MKL.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/products/SelfadjointMatrixVector.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/products/SelfadjointMatrixVector_MKL.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/products/SelfadjointProduct.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/products/SelfadjointRank2Update.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/products/TriangularMatrixMatrix.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/products/TriangularMatrixMatrix_MKL.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/products/TriangularMatrixVector.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/products/TriangularMatrixVector_MKL.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/products/TriangularSolverMatrix.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/products/TriangularSolverMatrix_MKL.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/products/TriangularSolverVector.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/util/BlasUtil.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/util/Constants.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/util/DisableStupidWarnings.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/util/ForwardDeclarations.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/util/MKL_support.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/util/Macros.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/util/Memory.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/util/Meta.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/util/NonMPL2.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/util/ReenableStupidWarnings.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/util/StaticAssert.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Core/util/XprHelper.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Block.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Cwise.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/CwiseOperators.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/AlignedBox.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/All.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/AngleAxis.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/Hyperplane.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/ParametrizedLine.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/Quaternion.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/Rotation2D.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/RotationBase.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/Scaling.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/Transform.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Geometry/Translation.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/LU.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Lazy.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/LeastSquares.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Macros.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/MathFunctions.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Memory.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Meta.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/Minor.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/QR.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/SVD.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/TriangularSolver.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigen2Support/VectorBlock.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/ComplexEigenSolver.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/ComplexSchur.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/ComplexSchur_MKL.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/EigenSolver.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/HessenbergDecomposition.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/RealQZ.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/RealSchur.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/RealSchur_MKL.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_MKL.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Eigenvalues/Tridiagonalization.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Geometry/AlignedBox.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Geometry/AngleAxis.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Geometry/EulerAngles.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Geometry/Homogeneous.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Geometry/Hyperplane.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Geometry/OrthoMethods.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Geometry/ParametrizedLine.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Geometry/Quaternion.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Geometry/Rotation2D.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Geometry/RotationBase.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Geometry/Scaling.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Geometry/Transform.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Geometry/Translation.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Geometry/Umeyama.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Geometry/arch/Geometry_SSE.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Householder/BlockHouseholder.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Householder/Householder.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Householder/HouseholderSequence.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/Jacobi/Jacobi.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/LU/Determinant.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/LU/FullPivLU.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/LU/Inverse.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/LU/PartialPivLU.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/LU/PartialPivLU_MKL.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/LU/arch/Inverse_SSE.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/MetisSupport/MetisSupport.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/OrderingMethods/Amd.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/OrderingMethods/Eigen_Colamd.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/OrderingMethods/Ordering.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/PaStiXSupport/PaStiXSupport.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/PardisoSupport/PardisoSupport.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/QR/ColPivHouseholderQR.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/QR/ColPivHouseholderQR_MKL.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/QR/FullPivHouseholderQR.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/QR/HouseholderQR.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/QR/HouseholderQR_MKL.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SVD/JacobiSVD.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SVD/JacobiSVD_MKL.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SVD/UpperBidiagonalization.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCholesky/SimplicialCholesky.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCholesky/SimplicialCholesky_impl.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCore/AmbiVector.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCore/CompressedStorage.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCore/MappedSparseMatrix.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseBlock.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseColEtree.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseCwiseBinaryOp.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseCwiseUnaryOp.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseDenseProduct.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseDiagonalProduct.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseDot.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseFuzzy.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseMatrix.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseMatrixBase.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparsePermutation.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseProduct.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseRedux.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseSelfAdjointView.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseSparseProductWithPruning.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseTranspose.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseTriangularView.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseUtil.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseVector.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCore/SparseView.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseCore/TriangularSolver.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLUImpl.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_Memory.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_Structs.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_Utils.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_column_bmod.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_column_dfs.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_copy_to_ucol.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_gemm_kernel.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_heap_relax_snode.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_kernel_bmod.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_panel_bmod.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_panel_dfs.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_pivotL.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_pruneL.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseLU/SparseLU_relax_snode.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SparseQR/SparseQR.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/StlSupport/StdDeque.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/StlSupport/StdList.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/StlSupport/StdVector.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/StlSupport/details.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/SuperLUSupport/SuperLUSupport.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/UmfPackSupport/UmfPackSupport.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/misc/Image.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/misc/Kernel.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/misc/Solve.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/misc/SparseSolve.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/misc/blas.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/plugins/ArrayCwiseBinaryOps.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/plugins/ArrayCwiseUnaryOps.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/plugins/BlockMethods.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/plugins/CommonCwiseBinaryOps.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/plugins/CommonCwiseUnaryOps.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/plugins/MatrixCwiseBinaryOps.h create mode 100644 thirdparty/eigen-3.2.7/Eigen/src/plugins/MatrixCwiseUnaryOps.h diff --git a/thirdparty/CMakeLists.txt b/thirdparty/CMakeLists.txt index e4b390aa..63706033 100644 --- a/thirdparty/CMakeLists.txt +++ b/thirdparty/CMakeLists.txt @@ -1 +1,3 @@ -add_subdirectory(eigen-3.2.7) \ No newline at end of file +if (CGOGN_PROVIDE_EIGEN) + add_subdirectory(eigen-3.2.7) +endif() \ No newline at end of file diff --git a/thirdparty/eigen-3.2.7/.gitignore b/thirdparty/eigen-3.2.7/.gitignore deleted file mode 100644 index 18c09451..00000000 --- a/thirdparty/eigen-3.2.7/.gitignore +++ /dev/null @@ -1 +0,0 @@ -Eigen/ diff --git a/thirdparty/eigen-3.2.7/CMakeLists.txt b/thirdparty/eigen-3.2.7/CMakeLists.txt index 984afcb1..5b8d58e9 100644 --- a/thirdparty/eigen-3.2.7/CMakeLists.txt +++ b/thirdparty/eigen-3.2.7/CMakeLists.txt @@ -1,34 +1,6 @@ -if (CGOGN_PROVIDE_EIGEN) - set(EIGEN_ROOT "${CMAKE_CURRENT_SOURCE_DIR}" CACHE PATH "Directory for find_package(Eigen3)") - set(EIGEN3_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}" CACHE PATH "Include directory for find_package(Eigen3)") +set(EIGEN_ROOT "${CMAKE_CURRENT_SOURCE_DIR}" CACHE PATH "Directory for find_package(Eigen3)") +set(EIGEN3_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}" CACHE PATH "Include directory for find_package(Eigen3)") - set(CGOGN_EIGEN_VERSION_STR "3.2.7") - set(CGOGN_EIGEN_MD5 "76959f105cfbda3ba77889bc204f4bd2") - set(CGOGN_OLD_EIGEN_DIRECTORY "eigen-eigen-b30b87236a1b") - if(NOT EXISTS ${PROJECT_BINARY_DIR}/eigen${CGOGN_EIGEN_VERSION_STR}.tar.gz) - file(DOWNLOAD http://bitbucket.org/eigen/eigen/get/${CGOGN_EIGEN_VERSION_STR}.tar.gz ${PROJECT_BINARY_DIR}/eigen${CGOGN_EIGEN_VERSION_STR}.tar.gz - TIMEOUT 180 - SHOW_PROGRESS - EXPECTED_MD5 ${CGOGN_EIGEN_MD5} - ) - - execute_process( - WORKING_DIRECTORY ${PROJECT_BINARY_DIR} - COMMAND ${CMAKE_COMMAND} -E tar xzf eigen${CGOGN_EIGEN_VERSION_STR}.tar.gz - ) - endif() - if(NOT EXISTS ${EIGEN_ROOT}/Eigen) - execute_process( - WORKING_DIRECTORY ${PROJECT_BINARY_DIR} - COMMAND ${CMAKE_COMMAND} -E copy_directory ${CGOGN_OLD_EIGEN_DIRECTORY}/Eigen ${EIGEN_ROOT}/Eigen - ) - file( - GLOB_RECURSE to_remove - "${EIGEN_ROOT}/Eigen/CMakeLists.txt" - ) - file(REMOVE ${to_remove}) - endif() -endif() install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/Eigen COMPONENT Eigen_headers DESTINATION include diff --git a/thirdparty/eigen-3.2.7/Eigen/Array b/thirdparty/eigen-3.2.7/Eigen/Array new file mode 100644 index 00000000..3d004fb6 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/Array @@ -0,0 +1,11 @@ +#ifndef EIGEN_ARRAY_MODULE_H +#define EIGEN_ARRAY_MODULE_H + +// include Core first to handle Eigen2 support macros +#include "Core" + +#ifndef EIGEN2_SUPPORT + #error The Eigen/Array header does no longer exist in Eigen3. All that functionality has moved to Eigen/Core. +#endif + +#endif // EIGEN_ARRAY_MODULE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/Cholesky b/thirdparty/eigen-3.2.7/Eigen/Cholesky new file mode 100644 index 00000000..f727f5d8 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/Cholesky @@ -0,0 +1,32 @@ +#ifndef EIGEN_CHOLESKY_MODULE_H +#define EIGEN_CHOLESKY_MODULE_H + +#include "Core" + +#include "src/Core/util/DisableStupidWarnings.h" + +/** \defgroup Cholesky_Module Cholesky module + * + * + * + * This module provides two variants of the Cholesky decomposition for selfadjoint (hermitian) matrices. + * Those decompositions are accessible via the following MatrixBase methods: + * - MatrixBase::llt(), + * - MatrixBase::ldlt() + * + * \code + * #include + * \endcode + */ + +#include "src/misc/Solve.h" +#include "src/Cholesky/LLT.h" +#include "src/Cholesky/LDLT.h" +#ifdef EIGEN_USE_LAPACKE +#include "src/Cholesky/LLT_MKL.h" +#endif + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_CHOLESKY_MODULE_H +/* vim: set filetype=cpp et sw=2 ts=2 ai: */ diff --git a/thirdparty/eigen-3.2.7/Eigen/CholmodSupport b/thirdparty/eigen-3.2.7/Eigen/CholmodSupport new file mode 100644 index 00000000..745b884e --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/CholmodSupport @@ -0,0 +1,45 @@ +#ifndef EIGEN_CHOLMODSUPPORT_MODULE_H +#define EIGEN_CHOLMODSUPPORT_MODULE_H + +#include "SparseCore" + +#include "src/Core/util/DisableStupidWarnings.h" + +extern "C" { + #include +} + +/** \ingroup Support_modules + * \defgroup CholmodSupport_Module CholmodSupport module + * + * This module provides an interface to the Cholmod library which is part of the suitesparse package. + * It provides the two following main factorization classes: + * - class CholmodSupernodalLLT: a supernodal LLT Cholesky factorization. + * - class CholmodDecomposiiton: a general L(D)LT Cholesky factorization with automatic or explicit runtime selection of the underlying factorization method (supernodal or simplicial). + * + * For the sake of completeness, this module also propose the two following classes: + * - class CholmodSimplicialLLT + * - class CholmodSimplicialLDLT + * Note that these classes does not bring any particular advantage compared to the built-in + * SimplicialLLT and SimplicialLDLT factorization classes. + * + * \code + * #include + * \endcode + * + * In order to use this module, the cholmod headers must be accessible from the include paths, and your binary must be linked to the cholmod library and its dependencies. + * The dependencies depend on how cholmod has been compiled. + * For a cmake based project, you can use our FindCholmod.cmake module to help you in this task. + * + */ + +#include "src/misc/Solve.h" +#include "src/misc/SparseSolve.h" + +#include "src/CholmodSupport/CholmodSupport.h" + + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_CHOLMODSUPPORT_MODULE_H + diff --git a/thirdparty/eigen-3.2.7/Eigen/Core b/thirdparty/eigen-3.2.7/Eigen/Core new file mode 100644 index 00000000..509c529e --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/Core @@ -0,0 +1,376 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008 Gael Guennebaud +// Copyright (C) 2007-2011 Benoit Jacob +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_CORE_H +#define EIGEN_CORE_H + +// first thing Eigen does: stop the compiler from committing suicide +#include "src/Core/util/DisableStupidWarnings.h" + +// then include this file where all our macros are defined. It's really important to do it first because +// it's where we do all the alignment settings (platform detection and honoring the user's will if he +// defined e.g. EIGEN_DONT_ALIGN) so it needs to be done before we do anything with vectorization. +#include "src/Core/util/Macros.h" + +// Disable the ipa-cp-clone optimization flag with MinGW 6.x or newer (enabled by default with -O3) +// See http://eigen.tuxfamily.org/bz/show_bug.cgi?id=556 for details. +#if defined(__MINGW32__) && EIGEN_GNUC_AT_LEAST(4,6) + #pragma GCC optimize ("-fno-ipa-cp-clone") +#endif + +#include + +// this include file manages BLAS and MKL related macros +// and inclusion of their respective header files +#include "src/Core/util/MKL_support.h" + +// if alignment is disabled, then disable vectorization. Note: EIGEN_ALIGN is the proper check, it takes into +// account both the user's will (EIGEN_DONT_ALIGN) and our own platform checks +#if !EIGEN_ALIGN + #ifndef EIGEN_DONT_VECTORIZE + #define EIGEN_DONT_VECTORIZE + #endif +#endif + +#ifdef _MSC_VER + #include // for _aligned_malloc -- need it regardless of whether vectorization is enabled + #if (_MSC_VER >= 1500) // 2008 or later + // Remember that usage of defined() in a #define is undefined by the standard. + // a user reported that in 64-bit mode, MSVC doesn't care to define _M_IX86_FP. + #if (defined(_M_IX86_FP) && (_M_IX86_FP >= 2)) || defined(_M_X64) + #define EIGEN_SSE2_ON_MSVC_2008_OR_LATER + #endif + #endif +#else + // Remember that usage of defined() in a #define is undefined by the standard + #if (defined __SSE2__) && ( (!defined __GNUC__) || (defined __INTEL_COMPILER) || EIGEN_GNUC_AT_LEAST(4,2) ) + #define EIGEN_SSE2_ON_NON_MSVC_BUT_NOT_OLD_GCC + #endif +#endif + +#ifndef EIGEN_DONT_VECTORIZE + + #if defined (EIGEN_SSE2_ON_NON_MSVC_BUT_NOT_OLD_GCC) || defined(EIGEN_SSE2_ON_MSVC_2008_OR_LATER) + + // Defines symbols for compile-time detection of which instructions are + // used. + // EIGEN_VECTORIZE_YY is defined if and only if the instruction set YY is used + #define EIGEN_VECTORIZE + #define EIGEN_VECTORIZE_SSE + #define EIGEN_VECTORIZE_SSE2 + + // Detect sse3/ssse3/sse4: + // gcc and icc defines __SSE3__, ... + // there is no way to know about this on msvc. You can define EIGEN_VECTORIZE_SSE* if you + // want to force the use of those instructions with msvc. + #ifdef __SSE3__ + #define EIGEN_VECTORIZE_SSE3 + #endif + #ifdef __SSSE3__ + #define EIGEN_VECTORIZE_SSSE3 + #endif + #ifdef __SSE4_1__ + #define EIGEN_VECTORIZE_SSE4_1 + #endif + #ifdef __SSE4_2__ + #define EIGEN_VECTORIZE_SSE4_2 + #endif + + // include files + + // This extern "C" works around a MINGW-w64 compilation issue + // https://sourceforge.net/tracker/index.php?func=detail&aid=3018394&group_id=202880&atid=983354 + // In essence, intrin.h is included by windows.h and also declares intrinsics (just as emmintrin.h etc. below do). + // However, intrin.h uses an extern "C" declaration, and g++ thus complains of duplicate declarations + // with conflicting linkage. The linkage for intrinsics doesn't matter, but at that stage the compiler doesn't know; + // so, to avoid compile errors when windows.h is included after Eigen/Core, ensure intrinsics are extern "C" here too. + // notice that since these are C headers, the extern "C" is theoretically needed anyways. + extern "C" { + // In theory we should only include immintrin.h and not the other *mmintrin.h header files directly. + // Doing so triggers some issues with ICC. However old gcc versions seems to not have this file, thus: + #if defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 1110 + #include + #else + #include + #include + #ifdef EIGEN_VECTORIZE_SSE3 + #include + #endif + #ifdef EIGEN_VECTORIZE_SSSE3 + #include + #endif + #ifdef EIGEN_VECTORIZE_SSE4_1 + #include + #endif + #ifdef EIGEN_VECTORIZE_SSE4_2 + #include + #endif + #endif + } // end extern "C" + #elif defined __ALTIVEC__ + #define EIGEN_VECTORIZE + #define EIGEN_VECTORIZE_ALTIVEC + #include + // We need to #undef all these ugly tokens defined in + // => use __vector instead of vector + #undef bool + #undef vector + #undef pixel + #elif defined __ARM_NEON + #define EIGEN_VECTORIZE + #define EIGEN_VECTORIZE_NEON + #include + #endif +#endif + +#if (defined _OPENMP) && (!defined EIGEN_DONT_PARALLELIZE) + #define EIGEN_HAS_OPENMP +#endif + +#ifdef EIGEN_HAS_OPENMP +#include +#endif + +// MSVC for windows mobile does not have the errno.h file +#if !(defined(_MSC_VER) && defined(_WIN32_WCE)) && !defined(__ARMCC_VERSION) +#define EIGEN_HAS_ERRNO +#endif + +#ifdef EIGEN_HAS_ERRNO +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // for CHAR_BIT +// for min/max: +#include + +// for outputting debug info +#ifdef EIGEN_DEBUG_ASSIGN +#include +#endif + +// required for __cpuid, needs to be included after cmath +#if defined(_MSC_VER) && (defined(_M_IX86)||defined(_M_X64)) && (!defined(_WIN32_WCE)) + #include +#endif + +#if defined(_CPPUNWIND) || defined(__EXCEPTIONS) + #define EIGEN_EXCEPTIONS +#endif + +#ifdef EIGEN_EXCEPTIONS + #include +#endif + +/** \brief Namespace containing all symbols from the %Eigen library. */ +namespace Eigen { + +inline static const char *SimdInstructionSetsInUse(void) { +#if defined(EIGEN_VECTORIZE_SSE4_2) + return "SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2"; +#elif defined(EIGEN_VECTORIZE_SSE4_1) + return "SSE, SSE2, SSE3, SSSE3, SSE4.1"; +#elif defined(EIGEN_VECTORIZE_SSSE3) + return "SSE, SSE2, SSE3, SSSE3"; +#elif defined(EIGEN_VECTORIZE_SSE3) + return "SSE, SSE2, SSE3"; +#elif defined(EIGEN_VECTORIZE_SSE2) + return "SSE, SSE2"; +#elif defined(EIGEN_VECTORIZE_ALTIVEC) + return "AltiVec"; +#elif defined(EIGEN_VECTORIZE_NEON) + return "ARM NEON"; +#else + return "None"; +#endif +} + +} // end namespace Eigen + +#define STAGE10_FULL_EIGEN2_API 10 +#define STAGE20_RESOLVE_API_CONFLICTS 20 +#define STAGE30_FULL_EIGEN3_API 30 +#define STAGE40_FULL_EIGEN3_STRICTNESS 40 +#define STAGE99_NO_EIGEN2_SUPPORT 99 + +#if defined EIGEN2_SUPPORT_STAGE40_FULL_EIGEN3_STRICTNESS + #define EIGEN2_SUPPORT + #define EIGEN2_SUPPORT_STAGE STAGE40_FULL_EIGEN3_STRICTNESS +#elif defined EIGEN2_SUPPORT_STAGE30_FULL_EIGEN3_API + #define EIGEN2_SUPPORT + #define EIGEN2_SUPPORT_STAGE STAGE30_FULL_EIGEN3_API +#elif defined EIGEN2_SUPPORT_STAGE20_RESOLVE_API_CONFLICTS + #define EIGEN2_SUPPORT + #define EIGEN2_SUPPORT_STAGE STAGE20_RESOLVE_API_CONFLICTS +#elif defined EIGEN2_SUPPORT_STAGE10_FULL_EIGEN2_API + #define EIGEN2_SUPPORT + #define EIGEN2_SUPPORT_STAGE STAGE10_FULL_EIGEN2_API +#elif defined EIGEN2_SUPPORT + // default to stage 3, that's what it's always meant + #define EIGEN2_SUPPORT_STAGE30_FULL_EIGEN3_API + #define EIGEN2_SUPPORT_STAGE STAGE30_FULL_EIGEN3_API +#else + #define EIGEN2_SUPPORT_STAGE STAGE99_NO_EIGEN2_SUPPORT +#endif + +#ifdef EIGEN2_SUPPORT +#undef minor +#endif + +// we use size_t frequently and we'll never remember to prepend it with std:: everytime just to +// ensure QNX/QCC support +using std::size_t; +// gcc 4.6.0 wants std:: for ptrdiff_t +using std::ptrdiff_t; + +/** \defgroup Core_Module Core module + * This is the main module of Eigen providing dense matrix and vector support + * (both fixed and dynamic size) with all the features corresponding to a BLAS library + * and much more... + * + * \code + * #include + * \endcode + */ + +#include "src/Core/util/Constants.h" +#include "src/Core/util/ForwardDeclarations.h" +#include "src/Core/util/Meta.h" +#include "src/Core/util/StaticAssert.h" +#include "src/Core/util/XprHelper.h" +#include "src/Core/util/Memory.h" + +#include "src/Core/NumTraits.h" +#include "src/Core/MathFunctions.h" +#include "src/Core/GenericPacketMath.h" + +#if defined EIGEN_VECTORIZE_SSE + #include "src/Core/arch/SSE/PacketMath.h" + #include "src/Core/arch/SSE/MathFunctions.h" + #include "src/Core/arch/SSE/Complex.h" +#elif defined EIGEN_VECTORIZE_ALTIVEC + #include "src/Core/arch/AltiVec/PacketMath.h" + #include "src/Core/arch/AltiVec/Complex.h" +#elif defined EIGEN_VECTORIZE_NEON + #include "src/Core/arch/NEON/PacketMath.h" + #include "src/Core/arch/NEON/Complex.h" +#endif + +#include "src/Core/arch/Default/Settings.h" + +#include "src/Core/Functors.h" +#include "src/Core/DenseCoeffsBase.h" +#include "src/Core/DenseBase.h" +#include "src/Core/MatrixBase.h" +#include "src/Core/EigenBase.h" + +#ifndef EIGEN_PARSED_BY_DOXYGEN // work around Doxygen bug triggered by Assign.h r814874 + // at least confirmed with Doxygen 1.5.5 and 1.5.6 + #include "src/Core/Assign.h" +#endif + +#include "src/Core/util/BlasUtil.h" +#include "src/Core/DenseStorage.h" +#include "src/Core/NestByValue.h" +#include "src/Core/ForceAlignedAccess.h" +#include "src/Core/ReturnByValue.h" +#include "src/Core/NoAlias.h" +#include "src/Core/PlainObjectBase.h" +#include "src/Core/Matrix.h" +#include "src/Core/Array.h" +#include "src/Core/CwiseBinaryOp.h" +#include "src/Core/CwiseUnaryOp.h" +#include "src/Core/CwiseNullaryOp.h" +#include "src/Core/CwiseUnaryView.h" +#include "src/Core/SelfCwiseBinaryOp.h" +#include "src/Core/Dot.h" +#include "src/Core/StableNorm.h" +#include "src/Core/MapBase.h" +#include "src/Core/Stride.h" +#include "src/Core/Map.h" +#include "src/Core/Block.h" +#include "src/Core/VectorBlock.h" +#include "src/Core/Ref.h" +#include "src/Core/Transpose.h" +#include "src/Core/DiagonalMatrix.h" +#include "src/Core/Diagonal.h" +#include "src/Core/DiagonalProduct.h" +#include "src/Core/PermutationMatrix.h" +#include "src/Core/Transpositions.h" +#include "src/Core/Redux.h" +#include "src/Core/Visitor.h" +#include "src/Core/Fuzzy.h" +#include "src/Core/IO.h" +#include "src/Core/Swap.h" +#include "src/Core/CommaInitializer.h" +#include "src/Core/Flagged.h" +#include "src/Core/ProductBase.h" +#include "src/Core/GeneralProduct.h" +#include "src/Core/TriangularMatrix.h" +#include "src/Core/SelfAdjointView.h" +#include "src/Core/products/GeneralBlockPanelKernel.h" +#include "src/Core/products/Parallelizer.h" +#include "src/Core/products/CoeffBasedProduct.h" +#include "src/Core/products/GeneralMatrixVector.h" +#include "src/Core/products/GeneralMatrixMatrix.h" +#include "src/Core/SolveTriangular.h" +#include "src/Core/products/GeneralMatrixMatrixTriangular.h" +#include "src/Core/products/SelfadjointMatrixVector.h" +#include "src/Core/products/SelfadjointMatrixMatrix.h" +#include "src/Core/products/SelfadjointProduct.h" +#include "src/Core/products/SelfadjointRank2Update.h" +#include "src/Core/products/TriangularMatrixVector.h" +#include "src/Core/products/TriangularMatrixMatrix.h" +#include "src/Core/products/TriangularSolverMatrix.h" +#include "src/Core/products/TriangularSolverVector.h" +#include "src/Core/BandMatrix.h" +#include "src/Core/CoreIterators.h" + +#include "src/Core/BooleanRedux.h" +#include "src/Core/Select.h" +#include "src/Core/VectorwiseOp.h" +#include "src/Core/Random.h" +#include "src/Core/Replicate.h" +#include "src/Core/Reverse.h" +#include "src/Core/ArrayBase.h" +#include "src/Core/ArrayWrapper.h" + +#ifdef EIGEN_USE_BLAS +#include "src/Core/products/GeneralMatrixMatrix_MKL.h" +#include "src/Core/products/GeneralMatrixVector_MKL.h" +#include "src/Core/products/GeneralMatrixMatrixTriangular_MKL.h" +#include "src/Core/products/SelfadjointMatrixMatrix_MKL.h" +#include "src/Core/products/SelfadjointMatrixVector_MKL.h" +#include "src/Core/products/TriangularMatrixMatrix_MKL.h" +#include "src/Core/products/TriangularMatrixVector_MKL.h" +#include "src/Core/products/TriangularSolverMatrix_MKL.h" +#endif // EIGEN_USE_BLAS + +#ifdef EIGEN_USE_MKL_VML +#include "src/Core/Assign_MKL.h" +#endif + +#include "src/Core/GlobalFunctions.h" + +#include "src/Core/util/ReenableStupidWarnings.h" + +#ifdef EIGEN2_SUPPORT +#include "Eigen2Support" +#endif + +#endif // EIGEN_CORE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/Dense b/thirdparty/eigen-3.2.7/Eigen/Dense new file mode 100644 index 00000000..5768910b --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/Dense @@ -0,0 +1,7 @@ +#include "Core" +#include "LU" +#include "Cholesky" +#include "QR" +#include "SVD" +#include "Geometry" +#include "Eigenvalues" diff --git a/thirdparty/eigen-3.2.7/Eigen/Eigen b/thirdparty/eigen-3.2.7/Eigen/Eigen new file mode 100644 index 00000000..19b40ea4 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/Eigen @@ -0,0 +1,2 @@ +#include "Dense" +//#include "Sparse" diff --git a/thirdparty/eigen-3.2.7/Eigen/Eigen2Support b/thirdparty/eigen-3.2.7/Eigen/Eigen2Support new file mode 100644 index 00000000..6aa009d2 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/Eigen2Support @@ -0,0 +1,95 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2009 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN2SUPPORT_H +#define EIGEN2SUPPORT_H + +#if (!defined(EIGEN2_SUPPORT)) || (!defined(EIGEN_CORE_H)) +#error Eigen2 support must be enabled by defining EIGEN2_SUPPORT before including any Eigen header +#endif + +#ifndef EIGEN_NO_EIGEN2_DEPRECATED_WARNING + +#if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__clang__) +#warning "Eigen2 support is deprecated in Eigen 3.2.x and it will be removed in Eigen 3.3. (Define EIGEN_NO_EIGEN2_DEPRECATED_WARNING to disable this warning)" +#else +#pragma message ("Eigen2 support is deprecated in Eigen 3.2.x and it will be removed in Eigen 3.3. (Define EIGEN_NO_EIGEN2_DEPRECATED_WARNING to disable this warning)") +#endif + +#endif // EIGEN_NO_EIGEN2_DEPRECATED_WARNING + +#include "src/Core/util/DisableStupidWarnings.h" + +/** \ingroup Support_modules + * \defgroup Eigen2Support_Module Eigen2 support module + * + * \warning Eigen2 support is deprecated in Eigen 3.2.x and it will be removed in Eigen 3.3. + * + * This module provides a couple of deprecated functions improving the compatibility with Eigen2. + * + * To use it, define EIGEN2_SUPPORT before including any Eigen header + * \code + * #define EIGEN2_SUPPORT + * \endcode + * + */ + +#include "src/Eigen2Support/Macros.h" +#include "src/Eigen2Support/Memory.h" +#include "src/Eigen2Support/Meta.h" +#include "src/Eigen2Support/Lazy.h" +#include "src/Eigen2Support/Cwise.h" +#include "src/Eigen2Support/CwiseOperators.h" +#include "src/Eigen2Support/TriangularSolver.h" +#include "src/Eigen2Support/Block.h" +#include "src/Eigen2Support/VectorBlock.h" +#include "src/Eigen2Support/Minor.h" +#include "src/Eigen2Support/MathFunctions.h" + + +#include "src/Core/util/ReenableStupidWarnings.h" + +// Eigen2 used to include iostream +#include + +#define EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, SizeSuffix) \ +using Eigen::Matrix##SizeSuffix##TypeSuffix; \ +using Eigen::Vector##SizeSuffix##TypeSuffix; \ +using Eigen::RowVector##SizeSuffix##TypeSuffix; + +#define EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(TypeSuffix) \ +EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 2) \ +EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 3) \ +EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 4) \ +EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, X) \ + +#define EIGEN_USING_MATRIX_TYPEDEFS \ +EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(i) \ +EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(f) \ +EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(d) \ +EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(cf) \ +EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(cd) + +#define USING_PART_OF_NAMESPACE_EIGEN \ +EIGEN_USING_MATRIX_TYPEDEFS \ +using Eigen::Matrix; \ +using Eigen::MatrixBase; \ +using Eigen::ei_random; \ +using Eigen::ei_real; \ +using Eigen::ei_imag; \ +using Eigen::ei_conj; \ +using Eigen::ei_abs; \ +using Eigen::ei_abs2; \ +using Eigen::ei_sqrt; \ +using Eigen::ei_exp; \ +using Eigen::ei_log; \ +using Eigen::ei_sin; \ +using Eigen::ei_cos; + +#endif // EIGEN2SUPPORT_H diff --git a/thirdparty/eigen-3.2.7/Eigen/Eigenvalues b/thirdparty/eigen-3.2.7/Eigen/Eigenvalues new file mode 100644 index 00000000..53c5a73a --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/Eigenvalues @@ -0,0 +1,48 @@ +#ifndef EIGEN_EIGENVALUES_MODULE_H +#define EIGEN_EIGENVALUES_MODULE_H + +#include "Core" + +#include "src/Core/util/DisableStupidWarnings.h" + +#include "Cholesky" +#include "Jacobi" +#include "Householder" +#include "LU" +#include "Geometry" + +/** \defgroup Eigenvalues_Module Eigenvalues module + * + * + * + * This module mainly provides various eigenvalue solvers. + * This module also provides some MatrixBase methods, including: + * - MatrixBase::eigenvalues(), + * - MatrixBase::operatorNorm() + * + * \code + * #include + * \endcode + */ + +#include "src/Eigenvalues/Tridiagonalization.h" +#include "src/Eigenvalues/RealSchur.h" +#include "src/Eigenvalues/EigenSolver.h" +#include "src/Eigenvalues/SelfAdjointEigenSolver.h" +#include "src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h" +#include "src/Eigenvalues/HessenbergDecomposition.h" +#include "src/Eigenvalues/ComplexSchur.h" +#include "src/Eigenvalues/ComplexEigenSolver.h" +#include "src/Eigenvalues/RealQZ.h" +#include "src/Eigenvalues/GeneralizedEigenSolver.h" +#include "src/Eigenvalues/MatrixBaseEigenvalues.h" +#ifdef EIGEN_USE_LAPACKE +#include "src/Eigenvalues/RealSchur_MKL.h" +#include "src/Eigenvalues/ComplexSchur_MKL.h" +#include "src/Eigenvalues/SelfAdjointEigenSolver_MKL.h" +#endif + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_EIGENVALUES_MODULE_H +/* vim: set filetype=cpp et sw=2 ts=2 ai: */ diff --git a/thirdparty/eigen-3.2.7/Eigen/Geometry b/thirdparty/eigen-3.2.7/Eigen/Geometry new file mode 100644 index 00000000..efd9d450 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/Geometry @@ -0,0 +1,63 @@ +#ifndef EIGEN_GEOMETRY_MODULE_H +#define EIGEN_GEOMETRY_MODULE_H + +#include "Core" + +#include "src/Core/util/DisableStupidWarnings.h" + +#include "SVD" +#include "LU" +#include + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +/** \defgroup Geometry_Module Geometry module + * + * + * + * This module provides support for: + * - fixed-size homogeneous transformations + * - translation, scaling, 2D and 3D rotations + * - quaternions + * - \ref MatrixBase::cross() "cross product" + * - \ref MatrixBase::unitOrthogonal() "orthognal vector generation" + * - some linear components: parametrized-lines and hyperplanes + * + * \code + * #include + * \endcode + */ + +#include "src/Geometry/OrthoMethods.h" +#include "src/Geometry/EulerAngles.h" + +#if EIGEN2_SUPPORT_STAGE > STAGE20_RESOLVE_API_CONFLICTS + #include "src/Geometry/Homogeneous.h" + #include "src/Geometry/RotationBase.h" + #include "src/Geometry/Rotation2D.h" + #include "src/Geometry/Quaternion.h" + #include "src/Geometry/AngleAxis.h" + #include "src/Geometry/Transform.h" + #include "src/Geometry/Translation.h" + #include "src/Geometry/Scaling.h" + #include "src/Geometry/Hyperplane.h" + #include "src/Geometry/ParametrizedLine.h" + #include "src/Geometry/AlignedBox.h" + #include "src/Geometry/Umeyama.h" + + #if defined EIGEN_VECTORIZE_SSE + #include "src/Geometry/arch/Geometry_SSE.h" + #endif +#endif + +#ifdef EIGEN2_SUPPORT +#include "src/Eigen2Support/Geometry/All.h" +#endif + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_GEOMETRY_MODULE_H +/* vim: set filetype=cpp et sw=2 ts=2 ai: */ + diff --git a/thirdparty/eigen-3.2.7/Eigen/Householder b/thirdparty/eigen-3.2.7/Eigen/Householder new file mode 100644 index 00000000..6e348db5 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/Householder @@ -0,0 +1,23 @@ +#ifndef EIGEN_HOUSEHOLDER_MODULE_H +#define EIGEN_HOUSEHOLDER_MODULE_H + +#include "Core" + +#include "src/Core/util/DisableStupidWarnings.h" + +/** \defgroup Householder_Module Householder module + * This module provides Householder transformations. + * + * \code + * #include + * \endcode + */ + +#include "src/Householder/Householder.h" +#include "src/Householder/HouseholderSequence.h" +#include "src/Householder/BlockHouseholder.h" + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_HOUSEHOLDER_MODULE_H +/* vim: set filetype=cpp et sw=2 ts=2 ai: */ diff --git a/thirdparty/eigen-3.2.7/Eigen/IterativeLinearSolvers b/thirdparty/eigen-3.2.7/Eigen/IterativeLinearSolvers new file mode 100644 index 00000000..0f4159dc --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/IterativeLinearSolvers @@ -0,0 +1,40 @@ +#ifndef EIGEN_ITERATIVELINEARSOLVERS_MODULE_H +#define EIGEN_ITERATIVELINEARSOLVERS_MODULE_H + +#include "SparseCore" +#include "OrderingMethods" + +#include "src/Core/util/DisableStupidWarnings.h" + +/** + * \defgroup IterativeLinearSolvers_Module IterativeLinearSolvers module + * + * This module currently provides iterative methods to solve problems of the form \c A \c x = \c b, where \c A is a squared matrix, usually very large and sparse. + * Those solvers are accessible via the following classes: + * - ConjugateGradient for selfadjoint (hermitian) matrices, + * - BiCGSTAB for general square matrices. + * + * These iterative solvers are associated with some preconditioners: + * - IdentityPreconditioner - not really useful + * - DiagonalPreconditioner - also called JAcobi preconditioner, work very well on diagonal dominant matrices. + * - IncompleteILUT - incomplete LU factorization with dual thresholding + * + * Such problems can also be solved using the direct sparse decomposition modules: SparseCholesky, CholmodSupport, UmfPackSupport, SuperLUSupport. + * + * \code + * #include + * \endcode + */ + +#include "src/misc/Solve.h" +#include "src/misc/SparseSolve.h" + +#include "src/IterativeLinearSolvers/IterativeSolverBase.h" +#include "src/IterativeLinearSolvers/BasicPreconditioners.h" +#include "src/IterativeLinearSolvers/ConjugateGradient.h" +#include "src/IterativeLinearSolvers/BiCGSTAB.h" +#include "src/IterativeLinearSolvers/IncompleteLUT.h" + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_ITERATIVELINEARSOLVERS_MODULE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/Jacobi b/thirdparty/eigen-3.2.7/Eigen/Jacobi new file mode 100644 index 00000000..ba8a4dc3 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/Jacobi @@ -0,0 +1,26 @@ +#ifndef EIGEN_JACOBI_MODULE_H +#define EIGEN_JACOBI_MODULE_H + +#include "Core" + +#include "src/Core/util/DisableStupidWarnings.h" + +/** \defgroup Jacobi_Module Jacobi module + * This module provides Jacobi and Givens rotations. + * + * \code + * #include + * \endcode + * + * In addition to listed classes, it defines the two following MatrixBase methods to apply a Jacobi or Givens rotation: + * - MatrixBase::applyOnTheLeft() + * - MatrixBase::applyOnTheRight(). + */ + +#include "src/Jacobi/Jacobi.h" + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_JACOBI_MODULE_H +/* vim: set filetype=cpp et sw=2 ts=2 ai: */ + diff --git a/thirdparty/eigen-3.2.7/Eigen/LU b/thirdparty/eigen-3.2.7/Eigen/LU new file mode 100644 index 00000000..db579550 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/LU @@ -0,0 +1,41 @@ +#ifndef EIGEN_LU_MODULE_H +#define EIGEN_LU_MODULE_H + +#include "Core" + +#include "src/Core/util/DisableStupidWarnings.h" + +/** \defgroup LU_Module LU module + * This module includes %LU decomposition and related notions such as matrix inversion and determinant. + * This module defines the following MatrixBase methods: + * - MatrixBase::inverse() + * - MatrixBase::determinant() + * + * \code + * #include + * \endcode + */ + +#include "src/misc/Solve.h" +#include "src/misc/Kernel.h" +#include "src/misc/Image.h" +#include "src/LU/FullPivLU.h" +#include "src/LU/PartialPivLU.h" +#ifdef EIGEN_USE_LAPACKE +#include "src/LU/PartialPivLU_MKL.h" +#endif +#include "src/LU/Determinant.h" +#include "src/LU/Inverse.h" + +#if defined EIGEN_VECTORIZE_SSE + #include "src/LU/arch/Inverse_SSE.h" +#endif + +#ifdef EIGEN2_SUPPORT + #include "src/Eigen2Support/LU.h" +#endif + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_LU_MODULE_H +/* vim: set filetype=cpp et sw=2 ts=2 ai: */ diff --git a/thirdparty/eigen-3.2.7/Eigen/LeastSquares b/thirdparty/eigen-3.2.7/Eigen/LeastSquares new file mode 100644 index 00000000..35137c25 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/LeastSquares @@ -0,0 +1,32 @@ +#ifndef EIGEN_REGRESSION_MODULE_H +#define EIGEN_REGRESSION_MODULE_H + +#ifndef EIGEN2_SUPPORT +#error LeastSquares is only available in Eigen2 support mode (define EIGEN2_SUPPORT) +#endif + +// exclude from normal eigen3-only documentation +#ifdef EIGEN2_SUPPORT + +#include "Core" + +#include "src/Core/util/DisableStupidWarnings.h" + +#include "Eigenvalues" +#include "Geometry" + +/** \defgroup LeastSquares_Module LeastSquares module + * This module provides linear regression and related features. + * + * \code + * #include + * \endcode + */ + +#include "src/Eigen2Support/LeastSquares.h" + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN2_SUPPORT + +#endif // EIGEN_REGRESSION_MODULE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/MetisSupport b/thirdparty/eigen-3.2.7/Eigen/MetisSupport new file mode 100644 index 00000000..6a113f7a --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/MetisSupport @@ -0,0 +1,28 @@ +#ifndef EIGEN_METISSUPPORT_MODULE_H +#define EIGEN_METISSUPPORT_MODULE_H + +#include "SparseCore" + +#include "src/Core/util/DisableStupidWarnings.h" + +extern "C" { +#include +} + + +/** \ingroup Support_modules + * \defgroup MetisSupport_Module MetisSupport module + * + * \code + * #include + * \endcode + * This module defines an interface to the METIS reordering package (http://glaros.dtc.umn.edu/gkhome/views/metis). + * It can be used just as any other built-in method as explained in \link OrderingMethods_Module here. \endlink + */ + + +#include "src/MetisSupport/MetisSupport.h" + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_METISSUPPORT_MODULE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/OrderingMethods b/thirdparty/eigen-3.2.7/Eigen/OrderingMethods new file mode 100644 index 00000000..7c0f1fff --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/OrderingMethods @@ -0,0 +1,66 @@ +#ifndef EIGEN_ORDERINGMETHODS_MODULE_H +#define EIGEN_ORDERINGMETHODS_MODULE_H + +#include "SparseCore" + +#include "src/Core/util/DisableStupidWarnings.h" + +/** + * \defgroup OrderingMethods_Module OrderingMethods module + * + * This module is currently for internal use only + * + * It defines various built-in and external ordering methods for sparse matrices. + * They are typically used to reduce the number of elements during + * the sparse matrix decomposition (LLT, LU, QR). + * Precisely, in a preprocessing step, a permutation matrix P is computed using + * those ordering methods and applied to the columns of the matrix. + * Using for instance the sparse Cholesky decomposition, it is expected that + * the nonzeros elements in LLT(A*P) will be much smaller than that in LLT(A). + * + * + * Usage : + * \code + * #include + * \endcode + * + * A simple usage is as a template parameter in the sparse decomposition classes : + * + * \code + * SparseLU > solver; + * \endcode + * + * \code + * SparseQR > solver; + * \endcode + * + * It is possible as well to call directly a particular ordering method for your own purpose, + * \code + * AMDOrdering ordering; + * PermutationMatrix perm; + * SparseMatrix A; + * //Fill the matrix ... + * + * ordering(A, perm); // Call AMD + * \endcode + * + * \note Some of these methods (like AMD or METIS), need the sparsity pattern + * of the input matrix to be symmetric. When the matrix is structurally unsymmetric, + * Eigen computes internally the pattern of \f$A^T*A\f$ before calling the method. + * If your matrix is already symmetric (at leat in structure), you can avoid that + * by calling the method with a SelfAdjointView type. + * + * \code + * // Call the ordering on the pattern of the lower triangular matrix A + * ordering(A.selfadjointView(), perm); + * \endcode + */ + +#ifndef EIGEN_MPL2_ONLY +#include "src/OrderingMethods/Amd.h" +#endif + +#include "src/OrderingMethods/Ordering.h" +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_ORDERINGMETHODS_MODULE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/PaStiXSupport b/thirdparty/eigen-3.2.7/Eigen/PaStiXSupport new file mode 100644 index 00000000..7c616ee5 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/PaStiXSupport @@ -0,0 +1,46 @@ +#ifndef EIGEN_PASTIXSUPPORT_MODULE_H +#define EIGEN_PASTIXSUPPORT_MODULE_H + +#include "SparseCore" + +#include "src/Core/util/DisableStupidWarnings.h" + +#include +extern "C" { +#include +#include +} + +#ifdef complex +#undef complex +#endif + +/** \ingroup Support_modules + * \defgroup PaStiXSupport_Module PaStiXSupport module + * + * This module provides an interface to the PaSTiX library. + * PaSTiX is a general \b supernodal, \b parallel and \b opensource sparse solver. + * It provides the two following main factorization classes: + * - class PastixLLT : a supernodal, parallel LLt Cholesky factorization. + * - class PastixLDLT: a supernodal, parallel LDLt Cholesky factorization. + * - class PastixLU : a supernodal, parallel LU factorization (optimized for a symmetric pattern). + * + * \code + * #include + * \endcode + * + * In order to use this module, the PaSTiX headers must be accessible from the include paths, and your binary must be linked to the PaSTiX library and its dependencies. + * The dependencies depend on how PaSTiX has been compiled. + * For a cmake based project, you can use our FindPaSTiX.cmake module to help you in this task. + * + */ + +#include "src/misc/Solve.h" +#include "src/misc/SparseSolve.h" + +#include "src/PaStiXSupport/PaStiXSupport.h" + + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_PASTIXSUPPORT_MODULE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/PardisoSupport b/thirdparty/eigen-3.2.7/Eigen/PardisoSupport new file mode 100644 index 00000000..99330ce7 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/PardisoSupport @@ -0,0 +1,30 @@ +#ifndef EIGEN_PARDISOSUPPORT_MODULE_H +#define EIGEN_PARDISOSUPPORT_MODULE_H + +#include "SparseCore" + +#include "src/Core/util/DisableStupidWarnings.h" + +#include + +#include + +/** \ingroup Support_modules + * \defgroup PardisoSupport_Module PardisoSupport module + * + * This module brings support for the Intel(R) MKL PARDISO direct sparse solvers. + * + * \code + * #include + * \endcode + * + * In order to use this module, the MKL headers must be accessible from the include paths, and your binary must be linked to the MKL library and its dependencies. + * See this \ref TopicUsingIntelMKL "page" for more information on MKL-Eigen integration. + * + */ + +#include "src/PardisoSupport/PardisoSupport.h" + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_PARDISOSUPPORT_MODULE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/QR b/thirdparty/eigen-3.2.7/Eigen/QR new file mode 100644 index 00000000..ac5b0269 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/QR @@ -0,0 +1,45 @@ +#ifndef EIGEN_QR_MODULE_H +#define EIGEN_QR_MODULE_H + +#include "Core" + +#include "src/Core/util/DisableStupidWarnings.h" + +#include "Cholesky" +#include "Jacobi" +#include "Householder" + +/** \defgroup QR_Module QR module + * + * + * + * This module provides various QR decompositions + * This module also provides some MatrixBase methods, including: + * - MatrixBase::qr(), + * + * \code + * #include + * \endcode + */ + +#include "src/misc/Solve.h" +#include "src/QR/HouseholderQR.h" +#include "src/QR/FullPivHouseholderQR.h" +#include "src/QR/ColPivHouseholderQR.h" +#ifdef EIGEN_USE_LAPACKE +#include "src/QR/HouseholderQR_MKL.h" +#include "src/QR/ColPivHouseholderQR_MKL.h" +#endif + +#ifdef EIGEN2_SUPPORT +#include "src/Eigen2Support/QR.h" +#endif + +#include "src/Core/util/ReenableStupidWarnings.h" + +#ifdef EIGEN2_SUPPORT +#include "Eigenvalues" +#endif + +#endif // EIGEN_QR_MODULE_H +/* vim: set filetype=cpp et sw=2 ts=2 ai: */ diff --git a/thirdparty/eigen-3.2.7/Eigen/QtAlignedMalloc b/thirdparty/eigen-3.2.7/Eigen/QtAlignedMalloc new file mode 100644 index 00000000..46f7d83b --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/QtAlignedMalloc @@ -0,0 +1,34 @@ + +#ifndef EIGEN_QTMALLOC_MODULE_H +#define EIGEN_QTMALLOC_MODULE_H + +#include "Core" + +#if (!EIGEN_MALLOC_ALREADY_ALIGNED) + +#include "src/Core/util/DisableStupidWarnings.h" + +void *qMalloc(size_t size) +{ + return Eigen::internal::aligned_malloc(size); +} + +void qFree(void *ptr) +{ + Eigen::internal::aligned_free(ptr); +} + +void *qRealloc(void *ptr, size_t size) +{ + void* newPtr = Eigen::internal::aligned_malloc(size); + memcpy(newPtr, ptr, size); + Eigen::internal::aligned_free(ptr); + return newPtr; +} + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif + +#endif // EIGEN_QTMALLOC_MODULE_H +/* vim: set filetype=cpp et sw=2 ts=2 ai: */ diff --git a/thirdparty/eigen-3.2.7/Eigen/SPQRSupport b/thirdparty/eigen-3.2.7/Eigen/SPQRSupport new file mode 100644 index 00000000..77016442 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/SPQRSupport @@ -0,0 +1,29 @@ +#ifndef EIGEN_SPQRSUPPORT_MODULE_H +#define EIGEN_SPQRSUPPORT_MODULE_H + +#include "SparseCore" + +#include "src/Core/util/DisableStupidWarnings.h" + +#include "SuiteSparseQR.hpp" + +/** \ingroup Support_modules + * \defgroup SPQRSupport_Module SuiteSparseQR module + * + * This module provides an interface to the SPQR library, which is part of the suitesparse package. + * + * \code + * #include + * \endcode + * + * In order to use this module, the SPQR headers must be accessible from the include paths, and your binary must be linked to the SPQR library and its dependencies (Cholmod, AMD, COLAMD,...). + * For a cmake based project, you can use our FindSPQR.cmake and FindCholmod.Cmake modules + * + */ + +#include "src/misc/Solve.h" +#include "src/misc/SparseSolve.h" +#include "src/CholmodSupport/CholmodSupport.h" +#include "src/SPQRSupport/SuiteSparseQRSupport.h" + +#endif diff --git a/thirdparty/eigen-3.2.7/Eigen/SVD b/thirdparty/eigen-3.2.7/Eigen/SVD new file mode 100644 index 00000000..fd310017 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/SVD @@ -0,0 +1,37 @@ +#ifndef EIGEN_SVD_MODULE_H +#define EIGEN_SVD_MODULE_H + +#include "QR" +#include "Householder" +#include "Jacobi" + +#include "src/Core/util/DisableStupidWarnings.h" + +/** \defgroup SVD_Module SVD module + * + * + * + * This module provides SVD decomposition for matrices (both real and complex). + * This decomposition is accessible via the following MatrixBase method: + * - MatrixBase::jacobiSvd() + * + * \code + * #include + * \endcode + */ + +#include "src/misc/Solve.h" +#include "src/SVD/JacobiSVD.h" +#if defined(EIGEN_USE_LAPACKE) && !defined(EIGEN_USE_LAPACKE_STRICT) +#include "src/SVD/JacobiSVD_MKL.h" +#endif +#include "src/SVD/UpperBidiagonalization.h" + +#ifdef EIGEN2_SUPPORT +#include "src/Eigen2Support/SVD.h" +#endif + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_SVD_MODULE_H +/* vim: set filetype=cpp et sw=2 ts=2 ai: */ diff --git a/thirdparty/eigen-3.2.7/Eigen/Sparse b/thirdparty/eigen-3.2.7/Eigen/Sparse new file mode 100644 index 00000000..7cc9c091 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/Sparse @@ -0,0 +1,27 @@ +#ifndef EIGEN_SPARSE_MODULE_H +#define EIGEN_SPARSE_MODULE_H + +/** \defgroup Sparse_Module Sparse meta-module + * + * Meta-module including all related modules: + * - \ref SparseCore_Module + * - \ref OrderingMethods_Module + * - \ref SparseCholesky_Module + * - \ref SparseLU_Module + * - \ref SparseQR_Module + * - \ref IterativeLinearSolvers_Module + * + * \code + * #include + * \endcode + */ + +#include "SparseCore" +#include "OrderingMethods" +#include "SparseCholesky" +#include "SparseLU" +#include "SparseQR" +#include "IterativeLinearSolvers" + +#endif // EIGEN_SPARSE_MODULE_H + diff --git a/thirdparty/eigen-3.2.7/Eigen/SparseCholesky b/thirdparty/eigen-3.2.7/Eigen/SparseCholesky new file mode 100644 index 00000000..9f5056aa --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/SparseCholesky @@ -0,0 +1,47 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008-2013 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_SPARSECHOLESKY_MODULE_H +#define EIGEN_SPARSECHOLESKY_MODULE_H + +#include "SparseCore" +#include "OrderingMethods" + +#include "src/Core/util/DisableStupidWarnings.h" + +/** + * \defgroup SparseCholesky_Module SparseCholesky module + * + * This module currently provides two variants of the direct sparse Cholesky decomposition for selfadjoint (hermitian) matrices. + * Those decompositions are accessible via the following classes: + * - SimplicialLLt, + * - SimplicialLDLt + * + * Such problems can also be solved using the ConjugateGradient solver from the IterativeLinearSolvers module. + * + * \code + * #include + * \endcode + */ + +#ifdef EIGEN_MPL2_ONLY +#error The SparseCholesky module has nothing to offer in MPL2 only mode +#endif + +#include "src/misc/Solve.h" +#include "src/misc/SparseSolve.h" +#include "src/SparseCholesky/SimplicialCholesky.h" + +#ifndef EIGEN_MPL2_ONLY +#include "src/SparseCholesky/SimplicialCholesky_impl.h" +#endif + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_SPARSECHOLESKY_MODULE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/SparseCore b/thirdparty/eigen-3.2.7/Eigen/SparseCore new file mode 100644 index 00000000..24bcf015 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/SparseCore @@ -0,0 +1,64 @@ +#ifndef EIGEN_SPARSECORE_MODULE_H +#define EIGEN_SPARSECORE_MODULE_H + +#include "Core" + +#include "src/Core/util/DisableStupidWarnings.h" + +#include +#include +#include +#include +#include + +/** + * \defgroup SparseCore_Module SparseCore module + * + * This module provides a sparse matrix representation, and basic associated matrix manipulations + * and operations. + * + * See the \ref TutorialSparse "Sparse tutorial" + * + * \code + * #include + * \endcode + * + * This module depends on: Core. + */ + +namespace Eigen { + +/** The type used to identify a general sparse storage. */ +struct Sparse {}; + +} + +#include "src/SparseCore/SparseUtil.h" +#include "src/SparseCore/SparseMatrixBase.h" +#include "src/SparseCore/CompressedStorage.h" +#include "src/SparseCore/AmbiVector.h" +#include "src/SparseCore/SparseMatrix.h" +#include "src/SparseCore/MappedSparseMatrix.h" +#include "src/SparseCore/SparseVector.h" +#include "src/SparseCore/SparseBlock.h" +#include "src/SparseCore/SparseTranspose.h" +#include "src/SparseCore/SparseCwiseUnaryOp.h" +#include "src/SparseCore/SparseCwiseBinaryOp.h" +#include "src/SparseCore/SparseDot.h" +#include "src/SparseCore/SparsePermutation.h" +#include "src/SparseCore/SparseRedux.h" +#include "src/SparseCore/SparseFuzzy.h" +#include "src/SparseCore/ConservativeSparseSparseProduct.h" +#include "src/SparseCore/SparseSparseProductWithPruning.h" +#include "src/SparseCore/SparseProduct.h" +#include "src/SparseCore/SparseDenseProduct.h" +#include "src/SparseCore/SparseDiagonalProduct.h" +#include "src/SparseCore/SparseTriangularView.h" +#include "src/SparseCore/SparseSelfAdjointView.h" +#include "src/SparseCore/TriangularSolver.h" +#include "src/SparseCore/SparseView.h" + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_SPARSECORE_MODULE_H + diff --git a/thirdparty/eigen-3.2.7/Eigen/SparseLU b/thirdparty/eigen-3.2.7/Eigen/SparseLU new file mode 100644 index 00000000..8527a49b --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/SparseLU @@ -0,0 +1,49 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2012 Désiré Nuentsa-Wakam +// Copyright (C) 2012 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_SPARSELU_MODULE_H +#define EIGEN_SPARSELU_MODULE_H + +#include "SparseCore" + +/** + * \defgroup SparseLU_Module SparseLU module + * This module defines a supernodal factorization of general sparse matrices. + * The code is fully optimized for supernode-panel updates with specialized kernels. + * Please, see the documentation of the SparseLU class for more details. + */ + +#include "src/misc/Solve.h" +#include "src/misc/SparseSolve.h" + +// Ordering interface +#include "OrderingMethods" + +#include "src/SparseLU/SparseLU_gemm_kernel.h" + +#include "src/SparseLU/SparseLU_Structs.h" +#include "src/SparseLU/SparseLU_SupernodalMatrix.h" +#include "src/SparseLU/SparseLUImpl.h" +#include "src/SparseCore/SparseColEtree.h" +#include "src/SparseLU/SparseLU_Memory.h" +#include "src/SparseLU/SparseLU_heap_relax_snode.h" +#include "src/SparseLU/SparseLU_relax_snode.h" +#include "src/SparseLU/SparseLU_pivotL.h" +#include "src/SparseLU/SparseLU_panel_dfs.h" +#include "src/SparseLU/SparseLU_kernel_bmod.h" +#include "src/SparseLU/SparseLU_panel_bmod.h" +#include "src/SparseLU/SparseLU_column_dfs.h" +#include "src/SparseLU/SparseLU_column_bmod.h" +#include "src/SparseLU/SparseLU_copy_to_ucol.h" +#include "src/SparseLU/SparseLU_pruneL.h" +#include "src/SparseLU/SparseLU_Utils.h" +#include "src/SparseLU/SparseLU.h" + +#endif // EIGEN_SPARSELU_MODULE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/SparseQR b/thirdparty/eigen-3.2.7/Eigen/SparseQR new file mode 100644 index 00000000..4ee42065 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/SparseQR @@ -0,0 +1,33 @@ +#ifndef EIGEN_SPARSEQR_MODULE_H +#define EIGEN_SPARSEQR_MODULE_H + +#include "SparseCore" +#include "OrderingMethods" +#include "src/Core/util/DisableStupidWarnings.h" + +/** \defgroup SparseQR_Module SparseQR module + * \brief Provides QR decomposition for sparse matrices + * + * This module provides a simplicial version of the left-looking Sparse QR decomposition. + * The columns of the input matrix should be reordered to limit the fill-in during the + * decomposition. Built-in methods (COLAMD, AMD) or external methods (METIS) can be used to this end. + * See the \link OrderingMethods_Module OrderingMethods\endlink module for the list + * of built-in and external ordering methods. + * + * \code + * #include + * \endcode + * + * + */ + +#include "src/misc/Solve.h" +#include "src/misc/SparseSolve.h" + +#include "OrderingMethods" +#include "src/SparseCore/SparseColEtree.h" +#include "src/SparseQR/SparseQR.h" + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif diff --git a/thirdparty/eigen-3.2.7/Eigen/StdDeque b/thirdparty/eigen-3.2.7/Eigen/StdDeque new file mode 100644 index 00000000..f2723477 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/StdDeque @@ -0,0 +1,27 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2009 Gael Guennebaud +// Copyright (C) 2009 Hauke Heibel +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_STDDEQUE_MODULE_H +#define EIGEN_STDDEQUE_MODULE_H + +#include "Core" +#include + +#if (defined(_MSC_VER) && defined(_WIN64)) /* MSVC auto aligns in 64 bit builds */ + +#define EIGEN_DEFINE_STL_DEQUE_SPECIALIZATION(...) + +#else + +#include "src/StlSupport/StdDeque.h" + +#endif + +#endif // EIGEN_STDDEQUE_MODULE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/StdList b/thirdparty/eigen-3.2.7/Eigen/StdList new file mode 100644 index 00000000..225c1e18 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/StdList @@ -0,0 +1,26 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2009 Hauke Heibel +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_STDLIST_MODULE_H +#define EIGEN_STDLIST_MODULE_H + +#include "Core" +#include + +#if (defined(_MSC_VER) && defined(_WIN64)) /* MSVC auto aligns in 64 bit builds */ + +#define EIGEN_DEFINE_STL_LIST_SPECIALIZATION(...) + +#else + +#include "src/StlSupport/StdList.h" + +#endif + +#endif // EIGEN_STDLIST_MODULE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/StdVector b/thirdparty/eigen-3.2.7/Eigen/StdVector new file mode 100644 index 00000000..6b22627f --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/StdVector @@ -0,0 +1,27 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2009 Gael Guennebaud +// Copyright (C) 2009 Hauke Heibel +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_STDVECTOR_MODULE_H +#define EIGEN_STDVECTOR_MODULE_H + +#include "Core" +#include + +#if (defined(_MSC_VER) && defined(_WIN64)) /* MSVC auto aligns in 64 bit builds */ + +#define EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(...) + +#else + +#include "src/StlSupport/StdVector.h" + +#endif + +#endif // EIGEN_STDVECTOR_MODULE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/SuperLUSupport b/thirdparty/eigen-3.2.7/Eigen/SuperLUSupport new file mode 100644 index 00000000..575e14fb --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/SuperLUSupport @@ -0,0 +1,59 @@ +#ifndef EIGEN_SUPERLUSUPPORT_MODULE_H +#define EIGEN_SUPERLUSUPPORT_MODULE_H + +#include "SparseCore" + +#include "src/Core/util/DisableStupidWarnings.h" + +#ifdef EMPTY +#define EIGEN_EMPTY_WAS_ALREADY_DEFINED +#endif + +typedef int int_t; +#include +#include +#include + +// slu_util.h defines a preprocessor token named EMPTY which is really polluting, +// so we remove it in favor of a SUPERLU_EMPTY token. +// If EMPTY was already defined then we don't undef it. + +#if defined(EIGEN_EMPTY_WAS_ALREADY_DEFINED) +# undef EIGEN_EMPTY_WAS_ALREADY_DEFINED +#elif defined(EMPTY) +# undef EMPTY +#endif + +#define SUPERLU_EMPTY (-1) + +namespace Eigen { struct SluMatrix; } + +/** \ingroup Support_modules + * \defgroup SuperLUSupport_Module SuperLUSupport module + * + * This module provides an interface to the SuperLU library. + * It provides the following factorization class: + * - class SuperLU: a supernodal sequential LU factorization. + * - class SuperILU: a supernodal sequential incomplete LU factorization (to be used as a preconditioner for iterative methods). + * + * \warning When including this module, you have to use SUPERLU_EMPTY instead of EMPTY which is no longer defined because it is too polluting. + * + * \code + * #include + * \endcode + * + * In order to use this module, the superlu headers must be accessible from the include paths, and your binary must be linked to the superlu library and its dependencies. + * The dependencies depend on how superlu has been compiled. + * For a cmake based project, you can use our FindSuperLU.cmake module to help you in this task. + * + */ + +#include "src/misc/Solve.h" +#include "src/misc/SparseSolve.h" + +#include "src/SuperLUSupport/SuperLUSupport.h" + + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_SUPERLUSUPPORT_MODULE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/UmfPackSupport b/thirdparty/eigen-3.2.7/Eigen/UmfPackSupport new file mode 100644 index 00000000..984f64a8 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/UmfPackSupport @@ -0,0 +1,36 @@ +#ifndef EIGEN_UMFPACKSUPPORT_MODULE_H +#define EIGEN_UMFPACKSUPPORT_MODULE_H + +#include "SparseCore" + +#include "src/Core/util/DisableStupidWarnings.h" + +extern "C" { +#include +} + +/** \ingroup Support_modules + * \defgroup UmfPackSupport_Module UmfPackSupport module + * + * This module provides an interface to the UmfPack library which is part of the suitesparse package. + * It provides the following factorization class: + * - class UmfPackLU: a multifrontal sequential LU factorization. + * + * \code + * #include + * \endcode + * + * In order to use this module, the umfpack headers must be accessible from the include paths, and your binary must be linked to the umfpack library and its dependencies. + * The dependencies depend on how umfpack has been compiled. + * For a cmake based project, you can use our FindUmfPack.cmake module to help you in this task. + * + */ + +#include "src/misc/Solve.h" +#include "src/misc/SparseSolve.h" + +#include "src/UmfPackSupport/UmfPackSupport.h" + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_UMFPACKSUPPORT_MODULE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Cholesky/LDLT.h b/thirdparty/eigen-3.2.7/Eigen/src/Cholesky/LDLT.h new file mode 100644 index 00000000..abd30bd9 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Cholesky/LDLT.h @@ -0,0 +1,611 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008-2011 Gael Guennebaud +// Copyright (C) 2009 Keir Mierle +// Copyright (C) 2009 Benoit Jacob +// Copyright (C) 2011 Timothy E. Holy +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_LDLT_H +#define EIGEN_LDLT_H + +namespace Eigen { + +namespace internal { + template struct LDLT_Traits; + + // PositiveSemiDef means positive semi-definite and non-zero; same for NegativeSemiDef + enum SignMatrix { PositiveSemiDef, NegativeSemiDef, ZeroSign, Indefinite }; +} + +/** \ingroup Cholesky_Module + * + * \class LDLT + * + * \brief Robust Cholesky decomposition of a matrix with pivoting + * + * \param MatrixType the type of the matrix of which to compute the LDL^T Cholesky decomposition + * \param UpLo the triangular part that will be used for the decompositon: Lower (default) or Upper. + * The other triangular part won't be read. + * + * Perform a robust Cholesky decomposition of a positive semidefinite or negative semidefinite + * matrix \f$ A \f$ such that \f$ A = P^TLDL^*P \f$, where P is a permutation matrix, L + * is lower triangular with a unit diagonal and D is a diagonal matrix. + * + * The decomposition uses pivoting to ensure stability, so that L will have + * zeros in the bottom right rank(A) - n submatrix. Avoiding the square root + * on D also stabilizes the computation. + * + * Remember that Cholesky decompositions are not rank-revealing. Also, do not use a Cholesky + * decomposition to determine whether a system of equations has a solution. + * + * \sa MatrixBase::ldlt(), class LLT + */ +template class LDLT +{ + public: + typedef _MatrixType MatrixType; + enum { + RowsAtCompileTime = MatrixType::RowsAtCompileTime, + ColsAtCompileTime = MatrixType::ColsAtCompileTime, + Options = MatrixType::Options & ~RowMajorBit, // these are the options for the TmpMatrixType, we need a ColMajor matrix here! + MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime, + MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime, + UpLo = _UpLo + }; + typedef typename MatrixType::Scalar Scalar; + typedef typename NumTraits::Real RealScalar; + typedef typename MatrixType::Index Index; + typedef Matrix TmpMatrixType; + + typedef Transpositions TranspositionType; + typedef PermutationMatrix PermutationType; + + typedef internal::LDLT_Traits Traits; + + /** \brief Default Constructor. + * + * The default constructor is useful in cases in which the user intends to + * perform decompositions via LDLT::compute(const MatrixType&). + */ + LDLT() + : m_matrix(), + m_transpositions(), + m_sign(internal::ZeroSign), + m_isInitialized(false) + {} + + /** \brief Default Constructor with memory preallocation + * + * Like the default constructor but with preallocation of the internal data + * according to the specified problem \a size. + * \sa LDLT() + */ + LDLT(Index size) + : m_matrix(size, size), + m_transpositions(size), + m_temporary(size), + m_sign(internal::ZeroSign), + m_isInitialized(false) + {} + + /** \brief Constructor with decomposition + * + * This calculates the decomposition for the input \a matrix. + * \sa LDLT(Index size) + */ + LDLT(const MatrixType& matrix) + : m_matrix(matrix.rows(), matrix.cols()), + m_transpositions(matrix.rows()), + m_temporary(matrix.rows()), + m_sign(internal::ZeroSign), + m_isInitialized(false) + { + compute(matrix); + } + + /** Clear any existing decomposition + * \sa rankUpdate(w,sigma) + */ + void setZero() + { + m_isInitialized = false; + } + + /** \returns a view of the upper triangular matrix U */ + inline typename Traits::MatrixU matrixU() const + { + eigen_assert(m_isInitialized && "LDLT is not initialized."); + return Traits::getU(m_matrix); + } + + /** \returns a view of the lower triangular matrix L */ + inline typename Traits::MatrixL matrixL() const + { + eigen_assert(m_isInitialized && "LDLT is not initialized."); + return Traits::getL(m_matrix); + } + + /** \returns the permutation matrix P as a transposition sequence. + */ + inline const TranspositionType& transpositionsP() const + { + eigen_assert(m_isInitialized && "LDLT is not initialized."); + return m_transpositions; + } + + /** \returns the coefficients of the diagonal matrix D */ + inline Diagonal vectorD() const + { + eigen_assert(m_isInitialized && "LDLT is not initialized."); + return m_matrix.diagonal(); + } + + /** \returns true if the matrix is positive (semidefinite) */ + inline bool isPositive() const + { + eigen_assert(m_isInitialized && "LDLT is not initialized."); + return m_sign == internal::PositiveSemiDef || m_sign == internal::ZeroSign; + } + + #ifdef EIGEN2_SUPPORT + inline bool isPositiveDefinite() const + { + return isPositive(); + } + #endif + + /** \returns true if the matrix is negative (semidefinite) */ + inline bool isNegative(void) const + { + eigen_assert(m_isInitialized && "LDLT is not initialized."); + return m_sign == internal::NegativeSemiDef || m_sign == internal::ZeroSign; + } + + /** \returns a solution x of \f$ A x = b \f$ using the current decomposition of A. + * + * This function also supports in-place solves using the syntax x = decompositionObject.solve(x) . + * + * \note_about_checking_solutions + * + * More precisely, this method solves \f$ A x = b \f$ using the decomposition \f$ A = P^T L D L^* P \f$ + * by solving the systems \f$ P^T y_1 = b \f$, \f$ L y_2 = y_1 \f$, \f$ D y_3 = y_2 \f$, + * \f$ L^* y_4 = y_3 \f$ and \f$ P x = y_4 \f$ in succession. If the matrix \f$ A \f$ is singular, then + * \f$ D \f$ will also be singular (all the other matrices are invertible). In that case, the + * least-square solution of \f$ D y_3 = y_2 \f$ is computed. This does not mean that this function + * computes the least-square solution of \f$ A x = b \f$ is \f$ A \f$ is singular. + * + * \sa MatrixBase::ldlt() + */ + template + inline const internal::solve_retval + solve(const MatrixBase& b) const + { + eigen_assert(m_isInitialized && "LDLT is not initialized."); + eigen_assert(m_matrix.rows()==b.rows() + && "LDLT::solve(): invalid number of rows of the right hand side matrix b"); + return internal::solve_retval(*this, b.derived()); + } + + #ifdef EIGEN2_SUPPORT + template + bool solve(const MatrixBase& b, ResultType *result) const + { + *result = this->solve(b); + return true; + } + #endif + + template + bool solveInPlace(MatrixBase &bAndX) const; + + LDLT& compute(const MatrixType& matrix); + + template + LDLT& rankUpdate(const MatrixBase& w, const RealScalar& alpha=1); + + /** \returns the internal LDLT decomposition matrix + * + * TODO: document the storage layout + */ + inline const MatrixType& matrixLDLT() const + { + eigen_assert(m_isInitialized && "LDLT is not initialized."); + return m_matrix; + } + + MatrixType reconstructedMatrix() const; + + inline Index rows() const { return m_matrix.rows(); } + inline Index cols() const { return m_matrix.cols(); } + + /** \brief Reports whether previous computation was successful. + * + * \returns \c Success if computation was succesful, + * \c NumericalIssue if the matrix.appears to be negative. + */ + ComputationInfo info() const + { + eigen_assert(m_isInitialized && "LDLT is not initialized."); + return Success; + } + + protected: + + static void check_template_parameters() + { + EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar); + } + + /** \internal + * Used to compute and store the Cholesky decomposition A = L D L^* = U^* D U. + * The strict upper part is used during the decomposition, the strict lower + * part correspond to the coefficients of L (its diagonal is equal to 1 and + * is not stored), and the diagonal entries correspond to D. + */ + MatrixType m_matrix; + TranspositionType m_transpositions; + TmpMatrixType m_temporary; + internal::SignMatrix m_sign; + bool m_isInitialized; +}; + +namespace internal { + +template struct ldlt_inplace; + +template<> struct ldlt_inplace +{ + template + static bool unblocked(MatrixType& mat, TranspositionType& transpositions, Workspace& temp, SignMatrix& sign) + { + using std::abs; + typedef typename MatrixType::Scalar Scalar; + typedef typename MatrixType::RealScalar RealScalar; + typedef typename MatrixType::Index Index; + eigen_assert(mat.rows()==mat.cols()); + const Index size = mat.rows(); + + if (size <= 1) + { + transpositions.setIdentity(); + if (numext::real(mat.coeff(0,0)) > 0) sign = PositiveSemiDef; + else if (numext::real(mat.coeff(0,0)) < 0) sign = NegativeSemiDef; + else sign = ZeroSign; + return true; + } + + for (Index k = 0; k < size; ++k) + { + // Find largest diagonal element + Index index_of_biggest_in_corner; + mat.diagonal().tail(size-k).cwiseAbs().maxCoeff(&index_of_biggest_in_corner); + index_of_biggest_in_corner += k; + + transpositions.coeffRef(k) = index_of_biggest_in_corner; + if(k != index_of_biggest_in_corner) + { + // apply the transposition while taking care to consider only + // the lower triangular part + Index s = size-index_of_biggest_in_corner-1; // trailing size after the biggest element + mat.row(k).head(k).swap(mat.row(index_of_biggest_in_corner).head(k)); + mat.col(k).tail(s).swap(mat.col(index_of_biggest_in_corner).tail(s)); + std::swap(mat.coeffRef(k,k),mat.coeffRef(index_of_biggest_in_corner,index_of_biggest_in_corner)); + for(int i=k+1;i::IsComplex) + mat.coeffRef(index_of_biggest_in_corner,k) = numext::conj(mat.coeff(index_of_biggest_in_corner,k)); + } + + // partition the matrix: + // A00 | - | - + // lu = A10 | A11 | - + // A20 | A21 | A22 + Index rs = size - k - 1; + Block A21(mat,k+1,k,rs,1); + Block A10(mat,k,0,1,k); + Block A20(mat,k+1,0,rs,k); + + if(k>0) + { + temp.head(k) = mat.diagonal().real().head(k).asDiagonal() * A10.adjoint(); + mat.coeffRef(k,k) -= (A10 * temp.head(k)).value(); + if(rs>0) + A21.noalias() -= A20 * temp.head(k); + } + + // In some previous versions of Eigen (e.g., 3.2.1), the scaling was omitted if the pivot + // was smaller than the cutoff value. However, soince LDLT is not rank-revealing + // we should only make sure we do not introduce INF or NaN values. + // LAPACK also uses 0 as the cutoff value. + RealScalar realAkk = numext::real(mat.coeffRef(k,k)); + if((rs>0) && (abs(realAkk) > RealScalar(0))) + A21 /= realAkk; + + if (sign == PositiveSemiDef) { + if (realAkk < 0) sign = Indefinite; + } else if (sign == NegativeSemiDef) { + if (realAkk > 0) sign = Indefinite; + } else if (sign == ZeroSign) { + if (realAkk > 0) sign = PositiveSemiDef; + else if (realAkk < 0) sign = NegativeSemiDef; + } + } + + return true; + } + + // Reference for the algorithm: Davis and Hager, "Multiple Rank + // Modifications of a Sparse Cholesky Factorization" (Algorithm 1) + // Trivial rearrangements of their computations (Timothy E. Holy) + // allow their algorithm to work for rank-1 updates even if the + // original matrix is not of full rank. + // Here only rank-1 updates are implemented, to reduce the + // requirement for intermediate storage and improve accuracy + template + static bool updateInPlace(MatrixType& mat, MatrixBase& w, const typename MatrixType::RealScalar& sigma=1) + { + using numext::isfinite; + typedef typename MatrixType::Scalar Scalar; + typedef typename MatrixType::RealScalar RealScalar; + typedef typename MatrixType::Index Index; + + const Index size = mat.rows(); + eigen_assert(mat.cols() == size && w.size()==size); + + RealScalar alpha = 1; + + // Apply the update + for (Index j = 0; j < size; j++) + { + // Check for termination due to an original decomposition of low-rank + if (!(isfinite)(alpha)) + break; + + // Update the diagonal terms + RealScalar dj = numext::real(mat.coeff(j,j)); + Scalar wj = w.coeff(j); + RealScalar swj2 = sigma*numext::abs2(wj); + RealScalar gamma = dj*alpha + swj2; + + mat.coeffRef(j,j) += swj2/alpha; + alpha += swj2/dj; + + + // Update the terms of L + Index rs = size-j-1; + w.tail(rs) -= wj * mat.col(j).tail(rs); + if(gamma != 0) + mat.col(j).tail(rs) += (sigma*numext::conj(wj)/gamma)*w.tail(rs); + } + return true; + } + + template + static bool update(MatrixType& mat, const TranspositionType& transpositions, Workspace& tmp, const WType& w, const typename MatrixType::RealScalar& sigma=1) + { + // Apply the permutation to the input w + tmp = transpositions * w; + + return ldlt_inplace::updateInPlace(mat,tmp,sigma); + } +}; + +template<> struct ldlt_inplace +{ + template + static EIGEN_STRONG_INLINE bool unblocked(MatrixType& mat, TranspositionType& transpositions, Workspace& temp, SignMatrix& sign) + { + Transpose matt(mat); + return ldlt_inplace::unblocked(matt, transpositions, temp, sign); + } + + template + static EIGEN_STRONG_INLINE bool update(MatrixType& mat, TranspositionType& transpositions, Workspace& tmp, WType& w, const typename MatrixType::RealScalar& sigma=1) + { + Transpose matt(mat); + return ldlt_inplace::update(matt, transpositions, tmp, w.conjugate(), sigma); + } +}; + +template struct LDLT_Traits +{ + typedef const TriangularView MatrixL; + typedef const TriangularView MatrixU; + static inline MatrixL getL(const MatrixType& m) { return m; } + static inline MatrixU getU(const MatrixType& m) { return m.adjoint(); } +}; + +template struct LDLT_Traits +{ + typedef const TriangularView MatrixL; + typedef const TriangularView MatrixU; + static inline MatrixL getL(const MatrixType& m) { return m.adjoint(); } + static inline MatrixU getU(const MatrixType& m) { return m; } +}; + +} // end namespace internal + +/** Compute / recompute the LDLT decomposition A = L D L^* = U^* D U of \a matrix + */ +template +LDLT& LDLT::compute(const MatrixType& a) +{ + check_template_parameters(); + + eigen_assert(a.rows()==a.cols()); + const Index size = a.rows(); + + m_matrix = a; + + m_transpositions.resize(size); + m_isInitialized = false; + m_temporary.resize(size); + m_sign = internal::ZeroSign; + + internal::ldlt_inplace::unblocked(m_matrix, m_transpositions, m_temporary, m_sign); + + m_isInitialized = true; + return *this; +} + +/** Update the LDLT decomposition: given A = L D L^T, efficiently compute the decomposition of A + sigma w w^T. + * \param w a vector to be incorporated into the decomposition. + * \param sigma a scalar, +1 for updates and -1 for "downdates," which correspond to removing previously-added column vectors. Optional; default value is +1. + * \sa setZero() + */ +template +template +LDLT& LDLT::rankUpdate(const MatrixBase& w, const typename LDLT::RealScalar& sigma) +{ + const Index size = w.rows(); + if (m_isInitialized) + { + eigen_assert(m_matrix.rows()==size); + } + else + { + m_matrix.resize(size,size); + m_matrix.setZero(); + m_transpositions.resize(size); + for (Index i = 0; i < size; i++) + m_transpositions.coeffRef(i) = i; + m_temporary.resize(size); + m_sign = sigma>=0 ? internal::PositiveSemiDef : internal::NegativeSemiDef; + m_isInitialized = true; + } + + internal::ldlt_inplace::update(m_matrix, m_transpositions, m_temporary, w, sigma); + + return *this; +} + +namespace internal { +template +struct solve_retval, Rhs> + : solve_retval_base, Rhs> +{ + typedef LDLT<_MatrixType,_UpLo> LDLTType; + EIGEN_MAKE_SOLVE_HELPERS(LDLTType,Rhs) + + template void evalTo(Dest& dst) const + { + eigen_assert(rhs().rows() == dec().matrixLDLT().rows()); + // dst = P b + dst = dec().transpositionsP() * rhs(); + + // dst = L^-1 (P b) + dec().matrixL().solveInPlace(dst); + + // dst = D^-1 (L^-1 P b) + // more precisely, use pseudo-inverse of D (see bug 241) + using std::abs; + using std::max; + typedef typename LDLTType::MatrixType MatrixType; + typedef typename LDLTType::RealScalar RealScalar; + const typename Diagonal::RealReturnType vectorD(dec().vectorD()); + // In some previous versions, tolerance was set to the max of 1/highest and the maximal diagonal entry * epsilon + // as motivated by LAPACK's xGELSS: + // RealScalar tolerance = (max)(vectorD.array().abs().maxCoeff() *NumTraits::epsilon(),RealScalar(1) / NumTraits::highest()); + // However, LDLT is not rank revealing, and so adjusting the tolerance wrt to the highest + // diagonal element is not well justified and to numerical issues in some cases. + // Moreover, Lapack's xSYTRS routines use 0 for the tolerance. + RealScalar tolerance = RealScalar(1) / NumTraits::highest(); + + for (Index i = 0; i < vectorD.size(); ++i) { + if(abs(vectorD(i)) > tolerance) + dst.row(i) /= vectorD(i); + else + dst.row(i).setZero(); + } + + // dst = L^-T (D^-1 L^-1 P b) + dec().matrixU().solveInPlace(dst); + + // dst = P^-1 (L^-T D^-1 L^-1 P b) = A^-1 b + dst = dec().transpositionsP().transpose() * dst; + } +}; +} + +/** \internal use x = ldlt_object.solve(x); + * + * This is the \em in-place version of solve(). + * + * \param bAndX represents both the right-hand side matrix b and result x. + * + * \returns true always! If you need to check for existence of solutions, use another decomposition like LU, QR, or SVD. + * + * This version avoids a copy when the right hand side matrix b is not + * needed anymore. + * + * \sa LDLT::solve(), MatrixBase::ldlt() + */ +template +template +bool LDLT::solveInPlace(MatrixBase &bAndX) const +{ + eigen_assert(m_isInitialized && "LDLT is not initialized."); + eigen_assert(m_matrix.rows() == bAndX.rows()); + + bAndX = this->solve(bAndX); + + return true; +} + +/** \returns the matrix represented by the decomposition, + * i.e., it returns the product: P^T L D L^* P. + * This function is provided for debug purpose. */ +template +MatrixType LDLT::reconstructedMatrix() const +{ + eigen_assert(m_isInitialized && "LDLT is not initialized."); + const Index size = m_matrix.rows(); + MatrixType res(size,size); + + // P + res.setIdentity(); + res = transpositionsP() * res; + // L^* P + res = matrixU() * res; + // D(L^*P) + res = vectorD().real().asDiagonal() * res; + // L(DL^*P) + res = matrixL() * res; + // P^T (LDL^*P) + res = transpositionsP().transpose() * res; + + return res; +} + +/** \cholesky_module + * \returns the Cholesky decomposition with full pivoting without square root of \c *this + */ +template +inline const LDLT::PlainObject, UpLo> +SelfAdjointView::ldlt() const +{ + return LDLT(m_matrix); +} + +/** \cholesky_module + * \returns the Cholesky decomposition with full pivoting without square root of \c *this + */ +template +inline const LDLT::PlainObject> +MatrixBase::ldlt() const +{ + return LDLT(derived()); +} + +} // end namespace Eigen + +#endif // EIGEN_LDLT_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Cholesky/LLT.h b/thirdparty/eigen-3.2.7/Eigen/src/Cholesky/LLT.h new file mode 100644 index 00000000..7c11a2dc --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Cholesky/LLT.h @@ -0,0 +1,498 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_LLT_H +#define EIGEN_LLT_H + +namespace Eigen { + +namespace internal{ +template struct LLT_Traits; +} + +/** \ingroup Cholesky_Module + * + * \class LLT + * + * \brief Standard Cholesky decomposition (LL^T) of a matrix and associated features + * + * \param MatrixType the type of the matrix of which we are computing the LL^T Cholesky decomposition + * \param UpLo the triangular part that will be used for the decompositon: Lower (default) or Upper. + * The other triangular part won't be read. + * + * This class performs a LL^T Cholesky decomposition of a symmetric, positive definite + * matrix A such that A = LL^* = U^*U, where L is lower triangular. + * + * While the Cholesky decomposition is particularly useful to solve selfadjoint problems like D^*D x = b, + * for that purpose, we recommend the Cholesky decomposition without square root which is more stable + * and even faster. Nevertheless, this standard Cholesky decomposition remains useful in many other + * situations like generalised eigen problems with hermitian matrices. + * + * Remember that Cholesky decompositions are not rank-revealing. This LLT decomposition is only stable on positive definite matrices, + * use LDLT instead for the semidefinite case. Also, do not use a Cholesky decomposition to determine whether a system of equations + * has a solution. + * + * Example: \include LLT_example.cpp + * Output: \verbinclude LLT_example.out + * + * \sa MatrixBase::llt(), class LDLT + */ + /* HEY THIS DOX IS DISABLED BECAUSE THERE's A BUG EITHER HERE OR IN LDLT ABOUT THAT (OR BOTH) + * Note that during the decomposition, only the upper triangular part of A is considered. Therefore, + * the strict lower part does not have to store correct values. + */ +template class LLT +{ + public: + typedef _MatrixType MatrixType; + enum { + RowsAtCompileTime = MatrixType::RowsAtCompileTime, + ColsAtCompileTime = MatrixType::ColsAtCompileTime, + Options = MatrixType::Options, + MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime + }; + typedef typename MatrixType::Scalar Scalar; + typedef typename NumTraits::Real RealScalar; + typedef typename MatrixType::Index Index; + + enum { + PacketSize = internal::packet_traits::size, + AlignmentMask = int(PacketSize)-1, + UpLo = _UpLo + }; + + typedef internal::LLT_Traits Traits; + + /** + * \brief Default Constructor. + * + * The default constructor is useful in cases in which the user intends to + * perform decompositions via LLT::compute(const MatrixType&). + */ + LLT() : m_matrix(), m_isInitialized(false) {} + + /** \brief Default Constructor with memory preallocation + * + * Like the default constructor but with preallocation of the internal data + * according to the specified problem \a size. + * \sa LLT() + */ + LLT(Index size) : m_matrix(size, size), + m_isInitialized(false) {} + + LLT(const MatrixType& matrix) + : m_matrix(matrix.rows(), matrix.cols()), + m_isInitialized(false) + { + compute(matrix); + } + + /** \returns a view of the upper triangular matrix U */ + inline typename Traits::MatrixU matrixU() const + { + eigen_assert(m_isInitialized && "LLT is not initialized."); + return Traits::getU(m_matrix); + } + + /** \returns a view of the lower triangular matrix L */ + inline typename Traits::MatrixL matrixL() const + { + eigen_assert(m_isInitialized && "LLT is not initialized."); + return Traits::getL(m_matrix); + } + + /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. + * + * Since this LLT class assumes anyway that the matrix A is invertible, the solution + * theoretically exists and is unique regardless of b. + * + * Example: \include LLT_solve.cpp + * Output: \verbinclude LLT_solve.out + * + * \sa solveInPlace(), MatrixBase::llt() + */ + template + inline const internal::solve_retval + solve(const MatrixBase& b) const + { + eigen_assert(m_isInitialized && "LLT is not initialized."); + eigen_assert(m_matrix.rows()==b.rows() + && "LLT::solve(): invalid number of rows of the right hand side matrix b"); + return internal::solve_retval(*this, b.derived()); + } + + #ifdef EIGEN2_SUPPORT + template + bool solve(const MatrixBase& b, ResultType *result) const + { + *result = this->solve(b); + return true; + } + + bool isPositiveDefinite() const { return true; } + #endif + + template + void solveInPlace(MatrixBase &bAndX) const; + + LLT& compute(const MatrixType& matrix); + + /** \returns the LLT decomposition matrix + * + * TODO: document the storage layout + */ + inline const MatrixType& matrixLLT() const + { + eigen_assert(m_isInitialized && "LLT is not initialized."); + return m_matrix; + } + + MatrixType reconstructedMatrix() const; + + + /** \brief Reports whether previous computation was successful. + * + * \returns \c Success if computation was succesful, + * \c NumericalIssue if the matrix.appears to be negative. + */ + ComputationInfo info() const + { + eigen_assert(m_isInitialized && "LLT is not initialized."); + return m_info; + } + + inline Index rows() const { return m_matrix.rows(); } + inline Index cols() const { return m_matrix.cols(); } + + template + LLT rankUpdate(const VectorType& vec, const RealScalar& sigma = 1); + + protected: + + static void check_template_parameters() + { + EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar); + } + + /** \internal + * Used to compute and store L + * The strict upper part is not used and even not initialized. + */ + MatrixType m_matrix; + bool m_isInitialized; + ComputationInfo m_info; +}; + +namespace internal { + +template struct llt_inplace; + +template +static typename MatrixType::Index llt_rank_update_lower(MatrixType& mat, const VectorType& vec, const typename MatrixType::RealScalar& sigma) +{ + using std::sqrt; + typedef typename MatrixType::Scalar Scalar; + typedef typename MatrixType::RealScalar RealScalar; + typedef typename MatrixType::Index Index; + typedef typename MatrixType::ColXpr ColXpr; + typedef typename internal::remove_all::type ColXprCleaned; + typedef typename ColXprCleaned::SegmentReturnType ColXprSegment; + typedef Matrix TempVectorType; + typedef typename TempVectorType::SegmentReturnType TempVecSegment; + + Index n = mat.cols(); + eigen_assert(mat.rows()==n && vec.size()==n); + + TempVectorType temp; + + if(sigma>0) + { + // This version is based on Givens rotations. + // It is faster than the other one below, but only works for updates, + // i.e., for sigma > 0 + temp = sqrt(sigma) * vec; + + for(Index i=0; i g; + g.makeGivens(mat(i,i), -temp(i), &mat(i,i)); + + Index rs = n-i-1; + if(rs>0) + { + ColXprSegment x(mat.col(i).tail(rs)); + TempVecSegment y(temp.tail(rs)); + apply_rotation_in_the_plane(x, y, g); + } + } + } + else + { + temp = vec; + RealScalar beta = 1; + for(Index j=0; j struct llt_inplace +{ + typedef typename NumTraits::Real RealScalar; + template + static typename MatrixType::Index unblocked(MatrixType& mat) + { + using std::sqrt; + typedef typename MatrixType::Index Index; + + eigen_assert(mat.rows()==mat.cols()); + const Index size = mat.rows(); + for(Index k = 0; k < size; ++k) + { + Index rs = size-k-1; // remaining size + + Block A21(mat,k+1,k,rs,1); + Block A10(mat,k,0,1,k); + Block A20(mat,k+1,0,rs,k); + + RealScalar x = numext::real(mat.coeff(k,k)); + if (k>0) x -= A10.squaredNorm(); + if (x<=RealScalar(0)) + return k; + mat.coeffRef(k,k) = x = sqrt(x); + if (k>0 && rs>0) A21.noalias() -= A20 * A10.adjoint(); + if (rs>0) A21 /= x; + } + return -1; + } + + template + static typename MatrixType::Index blocked(MatrixType& m) + { + typedef typename MatrixType::Index Index; + eigen_assert(m.rows()==m.cols()); + Index size = m.rows(); + if(size<32) + return unblocked(m); + + Index blockSize = size/8; + blockSize = (blockSize/16)*16; + blockSize = (std::min)((std::max)(blockSize,Index(8)), Index(128)); + + for (Index k=0; k A11(m,k, k, bs,bs); + Block A21(m,k+bs,k, rs,bs); + Block A22(m,k+bs,k+bs,rs,rs); + + Index ret; + if((ret=unblocked(A11))>=0) return k+ret; + if(rs>0) A11.adjoint().template triangularView().template solveInPlace(A21); + if(rs>0) A22.template selfadjointView().rankUpdate(A21,-1); // bottleneck + } + return -1; + } + + template + static typename MatrixType::Index rankUpdate(MatrixType& mat, const VectorType& vec, const RealScalar& sigma) + { + return Eigen::internal::llt_rank_update_lower(mat, vec, sigma); + } +}; + +template struct llt_inplace +{ + typedef typename NumTraits::Real RealScalar; + + template + static EIGEN_STRONG_INLINE typename MatrixType::Index unblocked(MatrixType& mat) + { + Transpose matt(mat); + return llt_inplace::unblocked(matt); + } + template + static EIGEN_STRONG_INLINE typename MatrixType::Index blocked(MatrixType& mat) + { + Transpose matt(mat); + return llt_inplace::blocked(matt); + } + template + static typename MatrixType::Index rankUpdate(MatrixType& mat, const VectorType& vec, const RealScalar& sigma) + { + Transpose matt(mat); + return llt_inplace::rankUpdate(matt, vec.conjugate(), sigma); + } +}; + +template struct LLT_Traits +{ + typedef const TriangularView MatrixL; + typedef const TriangularView MatrixU; + static inline MatrixL getL(const MatrixType& m) { return m; } + static inline MatrixU getU(const MatrixType& m) { return m.adjoint(); } + static bool inplace_decomposition(MatrixType& m) + { return llt_inplace::blocked(m)==-1; } +}; + +template struct LLT_Traits +{ + typedef const TriangularView MatrixL; + typedef const TriangularView MatrixU; + static inline MatrixL getL(const MatrixType& m) { return m.adjoint(); } + static inline MatrixU getU(const MatrixType& m) { return m; } + static bool inplace_decomposition(MatrixType& m) + { return llt_inplace::blocked(m)==-1; } +}; + +} // end namespace internal + +/** Computes / recomputes the Cholesky decomposition A = LL^* = U^*U of \a matrix + * + * \returns a reference to *this + * + * Example: \include TutorialLinAlgComputeTwice.cpp + * Output: \verbinclude TutorialLinAlgComputeTwice.out + */ +template +LLT& LLT::compute(const MatrixType& a) +{ + check_template_parameters(); + + eigen_assert(a.rows()==a.cols()); + const Index size = a.rows(); + m_matrix.resize(size, size); + m_matrix = a; + + m_isInitialized = true; + bool ok = Traits::inplace_decomposition(m_matrix); + m_info = ok ? Success : NumericalIssue; + + return *this; +} + +/** Performs a rank one update (or dowdate) of the current decomposition. + * If A = LL^* before the rank one update, + * then after it we have LL^* = A + sigma * v v^* where \a v must be a vector + * of same dimension. + */ +template +template +LLT<_MatrixType,_UpLo> LLT<_MatrixType,_UpLo>::rankUpdate(const VectorType& v, const RealScalar& sigma) +{ + EIGEN_STATIC_ASSERT_VECTOR_ONLY(VectorType); + eigen_assert(v.size()==m_matrix.cols()); + eigen_assert(m_isInitialized); + if(internal::llt_inplace::rankUpdate(m_matrix,v,sigma)>=0) + m_info = NumericalIssue; + else + m_info = Success; + + return *this; +} + +namespace internal { +template +struct solve_retval, Rhs> + : solve_retval_base, Rhs> +{ + typedef LLT<_MatrixType,UpLo> LLTType; + EIGEN_MAKE_SOLVE_HELPERS(LLTType,Rhs) + + template void evalTo(Dest& dst) const + { + dst = rhs(); + dec().solveInPlace(dst); + } +}; +} + +/** \internal use x = llt_object.solve(x); + * + * This is the \em in-place version of solve(). + * + * \param bAndX represents both the right-hand side matrix b and result x. + * + * \returns true always! If you need to check for existence of solutions, use another decomposition like LU, QR, or SVD. + * + * This version avoids a copy when the right hand side matrix b is not + * needed anymore. + * + * \sa LLT::solve(), MatrixBase::llt() + */ +template +template +void LLT::solveInPlace(MatrixBase &bAndX) const +{ + eigen_assert(m_isInitialized && "LLT is not initialized."); + eigen_assert(m_matrix.rows()==bAndX.rows()); + matrixL().solveInPlace(bAndX); + matrixU().solveInPlace(bAndX); +} + +/** \returns the matrix represented by the decomposition, + * i.e., it returns the product: L L^*. + * This function is provided for debug purpose. */ +template +MatrixType LLT::reconstructedMatrix() const +{ + eigen_assert(m_isInitialized && "LLT is not initialized."); + return matrixL() * matrixL().adjoint().toDenseMatrix(); +} + +/** \cholesky_module + * \returns the LLT decomposition of \c *this + */ +template +inline const LLT::PlainObject> +MatrixBase::llt() const +{ + return LLT(derived()); +} + +/** \cholesky_module + * \returns the LLT decomposition of \c *this + */ +template +inline const LLT::PlainObject, UpLo> +SelfAdjointView::llt() const +{ + return LLT(m_matrix); +} + +} // end namespace Eigen + +#endif // EIGEN_LLT_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Cholesky/LLT_MKL.h b/thirdparty/eigen-3.2.7/Eigen/src/Cholesky/LLT_MKL.h new file mode 100644 index 00000000..66675d74 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Cholesky/LLT_MKL.h @@ -0,0 +1,102 @@ +/* + Copyright (c) 2011, Intel Corporation. All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of Intel Corporation nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ******************************************************************************** + * Content : Eigen bindings to Intel(R) MKL + * LLt decomposition based on LAPACKE_?potrf function. + ******************************************************************************** +*/ + +#ifndef EIGEN_LLT_MKL_H +#define EIGEN_LLT_MKL_H + +#include "Eigen/src/Core/util/MKL_support.h" +#include + +namespace Eigen { + +namespace internal { + +template struct mkl_llt; + +#define EIGEN_MKL_LLT(EIGTYPE, MKLTYPE, MKLPREFIX) \ +template<> struct mkl_llt \ +{ \ + template \ + static inline typename MatrixType::Index potrf(MatrixType& m, char uplo) \ + { \ + lapack_int matrix_order; \ + lapack_int size, lda, info, StorageOrder; \ + EIGTYPE* a; \ + eigen_assert(m.rows()==m.cols()); \ + /* Set up parameters for ?potrf */ \ + size = m.rows(); \ + StorageOrder = MatrixType::Flags&RowMajorBit?RowMajor:ColMajor; \ + matrix_order = StorageOrder==RowMajor ? LAPACK_ROW_MAJOR : LAPACK_COL_MAJOR; \ + a = &(m.coeffRef(0,0)); \ + lda = m.outerStride(); \ +\ + info = LAPACKE_##MKLPREFIX##potrf( matrix_order, uplo, size, (MKLTYPE*)a, lda ); \ + info = (info==0) ? -1 : info>0 ? info-1 : size; \ + return info; \ + } \ +}; \ +template<> struct llt_inplace \ +{ \ + template \ + static typename MatrixType::Index blocked(MatrixType& m) \ + { \ + return mkl_llt::potrf(m, 'L'); \ + } \ + template \ + static typename MatrixType::Index rankUpdate(MatrixType& mat, const VectorType& vec, const typename MatrixType::RealScalar& sigma) \ + { return Eigen::internal::llt_rank_update_lower(mat, vec, sigma); } \ +}; \ +template<> struct llt_inplace \ +{ \ + template \ + static typename MatrixType::Index blocked(MatrixType& m) \ + { \ + return mkl_llt::potrf(m, 'U'); \ + } \ + template \ + static typename MatrixType::Index rankUpdate(MatrixType& mat, const VectorType& vec, const typename MatrixType::RealScalar& sigma) \ + { \ + Transpose matt(mat); \ + return llt_inplace::rankUpdate(matt, vec.conjugate(), sigma); \ + } \ +}; + +EIGEN_MKL_LLT(double, double, d) +EIGEN_MKL_LLT(float, float, s) +EIGEN_MKL_LLT(dcomplex, MKL_Complex16, z) +EIGEN_MKL_LLT(scomplex, MKL_Complex8, c) + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_LLT_MKL_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/CholmodSupport/CholmodSupport.h b/thirdparty/eigen-3.2.7/Eigen/src/CholmodSupport/CholmodSupport.h new file mode 100644 index 00000000..99dbe171 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/CholmodSupport/CholmodSupport.h @@ -0,0 +1,607 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008-2010 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_CHOLMODSUPPORT_H +#define EIGEN_CHOLMODSUPPORT_H + +namespace Eigen { + +namespace internal { + +template +void cholmod_configure_matrix(CholmodType& mat) +{ + if (internal::is_same::value) + { + mat.xtype = CHOLMOD_REAL; + mat.dtype = CHOLMOD_SINGLE; + } + else if (internal::is_same::value) + { + mat.xtype = CHOLMOD_REAL; + mat.dtype = CHOLMOD_DOUBLE; + } + else if (internal::is_same >::value) + { + mat.xtype = CHOLMOD_COMPLEX; + mat.dtype = CHOLMOD_SINGLE; + } + else if (internal::is_same >::value) + { + mat.xtype = CHOLMOD_COMPLEX; + mat.dtype = CHOLMOD_DOUBLE; + } + else + { + eigen_assert(false && "Scalar type not supported by CHOLMOD"); + } +} + +} // namespace internal + +/** Wraps the Eigen sparse matrix \a mat into a Cholmod sparse matrix object. + * Note that the data are shared. + */ +template +cholmod_sparse viewAsCholmod(SparseMatrix<_Scalar,_Options,_Index>& mat) +{ + cholmod_sparse res; + res.nzmax = mat.nonZeros(); + res.nrow = mat.rows();; + res.ncol = mat.cols(); + res.p = mat.outerIndexPtr(); + res.i = mat.innerIndexPtr(); + res.x = mat.valuePtr(); + res.z = 0; + res.sorted = 1; + if(mat.isCompressed()) + { + res.packed = 1; + res.nz = 0; + } + else + { + res.packed = 0; + res.nz = mat.innerNonZeroPtr(); + } + + res.dtype = 0; + res.stype = -1; + + if (internal::is_same<_Index,int>::value) + { + res.itype = CHOLMOD_INT; + } + else if (internal::is_same<_Index,SuiteSparse_long>::value) + { + res.itype = CHOLMOD_LONG; + } + else + { + eigen_assert(false && "Index type not supported yet"); + } + + // setup res.xtype + internal::cholmod_configure_matrix<_Scalar>(res); + + res.stype = 0; + + return res; +} + +template +const cholmod_sparse viewAsCholmod(const SparseMatrix<_Scalar,_Options,_Index>& mat) +{ + cholmod_sparse res = viewAsCholmod(mat.const_cast_derived()); + return res; +} + +/** Returns a view of the Eigen sparse matrix \a mat as Cholmod sparse matrix. + * The data are not copied but shared. */ +template +cholmod_sparse viewAsCholmod(const SparseSelfAdjointView, UpLo>& mat) +{ + cholmod_sparse res = viewAsCholmod(mat.matrix().const_cast_derived()); + + if(UpLo==Upper) res.stype = 1; + if(UpLo==Lower) res.stype = -1; + + return res; +} + +/** Returns a view of the Eigen \b dense matrix \a mat as Cholmod dense matrix. + * The data are not copied but shared. */ +template +cholmod_dense viewAsCholmod(MatrixBase& mat) +{ + EIGEN_STATIC_ASSERT((internal::traits::Flags&RowMajorBit)==0,THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES); + typedef typename Derived::Scalar Scalar; + + cholmod_dense res; + res.nrow = mat.rows(); + res.ncol = mat.cols(); + res.nzmax = res.nrow * res.ncol; + res.d = Derived::IsVectorAtCompileTime ? mat.derived().size() : mat.derived().outerStride(); + res.x = (void*)(mat.derived().data()); + res.z = 0; + + internal::cholmod_configure_matrix(res); + + return res; +} + +/** Returns a view of the Cholmod sparse matrix \a cm as an Eigen sparse matrix. + * The data are not copied but shared. */ +template +MappedSparseMatrix viewAsEigen(cholmod_sparse& cm) +{ + return MappedSparseMatrix + (cm.nrow, cm.ncol, static_cast(cm.p)[cm.ncol], + static_cast(cm.p), static_cast(cm.i),static_cast(cm.x) ); +} + +enum CholmodMode { + CholmodAuto, CholmodSimplicialLLt, CholmodSupernodalLLt, CholmodLDLt +}; + + +/** \ingroup CholmodSupport_Module + * \class CholmodBase + * \brief The base class for the direct Cholesky factorization of Cholmod + * \sa class CholmodSupernodalLLT, class CholmodSimplicialLDLT, class CholmodSimplicialLLT + */ +template +class CholmodBase : internal::noncopyable +{ + public: + typedef _MatrixType MatrixType; + enum { UpLo = _UpLo }; + typedef typename MatrixType::Scalar Scalar; + typedef typename MatrixType::RealScalar RealScalar; + typedef MatrixType CholMatrixType; + typedef typename MatrixType::Index Index; + + public: + + CholmodBase() + : m_cholmodFactor(0), m_info(Success), m_isInitialized(false) + { + m_shiftOffset[0] = m_shiftOffset[1] = RealScalar(0.0); + cholmod_start(&m_cholmod); + } + + CholmodBase(const MatrixType& matrix) + : m_cholmodFactor(0), m_info(Success), m_isInitialized(false) + { + m_shiftOffset[0] = m_shiftOffset[1] = RealScalar(0.0); + cholmod_start(&m_cholmod); + compute(matrix); + } + + ~CholmodBase() + { + if(m_cholmodFactor) + cholmod_free_factor(&m_cholmodFactor, &m_cholmod); + cholmod_finish(&m_cholmod); + } + + inline Index cols() const { return m_cholmodFactor->n; } + inline Index rows() const { return m_cholmodFactor->n; } + + Derived& derived() { return *static_cast(this); } + const Derived& derived() const { return *static_cast(this); } + + /** \brief Reports whether previous computation was successful. + * + * \returns \c Success if computation was succesful, + * \c NumericalIssue if the matrix.appears to be negative. + */ + ComputationInfo info() const + { + eigen_assert(m_isInitialized && "Decomposition is not initialized."); + return m_info; + } + + /** Computes the sparse Cholesky decomposition of \a matrix */ + Derived& compute(const MatrixType& matrix) + { + analyzePattern(matrix); + factorize(matrix); + return derived(); + } + + /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. + * + * \sa compute() + */ + template + inline const internal::solve_retval + solve(const MatrixBase& b) const + { + eigen_assert(m_isInitialized && "LLT is not initialized."); + eigen_assert(rows()==b.rows() + && "CholmodDecomposition::solve(): invalid number of rows of the right hand side matrix b"); + return internal::solve_retval(*this, b.derived()); + } + + /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. + * + * \sa compute() + */ + template + inline const internal::sparse_solve_retval + solve(const SparseMatrixBase& b) const + { + eigen_assert(m_isInitialized && "LLT is not initialized."); + eigen_assert(rows()==b.rows() + && "CholmodDecomposition::solve(): invalid number of rows of the right hand side matrix b"); + return internal::sparse_solve_retval(*this, b.derived()); + } + + /** Performs a symbolic decomposition on the sparsity pattern of \a matrix. + * + * This function is particularly useful when solving for several problems having the same structure. + * + * \sa factorize() + */ + void analyzePattern(const MatrixType& matrix) + { + if(m_cholmodFactor) + { + cholmod_free_factor(&m_cholmodFactor, &m_cholmod); + m_cholmodFactor = 0; + } + cholmod_sparse A = viewAsCholmod(matrix.template selfadjointView()); + m_cholmodFactor = cholmod_analyze(&A, &m_cholmod); + + this->m_isInitialized = true; + this->m_info = Success; + m_analysisIsOk = true; + m_factorizationIsOk = false; + } + + /** Performs a numeric decomposition of \a matrix + * + * The given matrix must have the same sparsity pattern as the matrix on which the symbolic decomposition has been performed. + * + * \sa analyzePattern() + */ + void factorize(const MatrixType& matrix) + { + eigen_assert(m_analysisIsOk && "You must first call analyzePattern()"); + cholmod_sparse A = viewAsCholmod(matrix.template selfadjointView()); + cholmod_factorize_p(&A, m_shiftOffset, 0, 0, m_cholmodFactor, &m_cholmod); + + // If the factorization failed, minor is the column at which it did. On success minor == n. + this->m_info = (m_cholmodFactor->minor == m_cholmodFactor->n ? Success : NumericalIssue); + m_factorizationIsOk = true; + } + + /** Returns a reference to the Cholmod's configuration structure to get a full control over the performed operations. + * See the Cholmod user guide for details. */ + cholmod_common& cholmod() { return m_cholmod; } + + #ifndef EIGEN_PARSED_BY_DOXYGEN + /** \internal */ + template + void _solve(const MatrixBase &b, MatrixBase &dest) const + { + eigen_assert(m_factorizationIsOk && "The decomposition is not in a valid state for solving, you must first call either compute() or symbolic()/numeric()"); + const Index size = m_cholmodFactor->n; + EIGEN_UNUSED_VARIABLE(size); + eigen_assert(size==b.rows()); + + // note: cd stands for Cholmod Dense + Rhs& b_ref(b.const_cast_derived()); + cholmod_dense b_cd = viewAsCholmod(b_ref); + cholmod_dense* x_cd = cholmod_solve(CHOLMOD_A, m_cholmodFactor, &b_cd, &m_cholmod); + if(!x_cd) + { + this->m_info = NumericalIssue; + } + // TODO optimize this copy by swapping when possible (be careful with alignment, etc.) + dest = Matrix::Map(reinterpret_cast(x_cd->x),b.rows(),b.cols()); + cholmod_free_dense(&x_cd, &m_cholmod); + } + + /** \internal */ + template + void _solve(const SparseMatrix &b, SparseMatrix &dest) const + { + eigen_assert(m_factorizationIsOk && "The decomposition is not in a valid state for solving, you must first call either compute() or symbolic()/numeric()"); + const Index size = m_cholmodFactor->n; + EIGEN_UNUSED_VARIABLE(size); + eigen_assert(size==b.rows()); + + // note: cs stands for Cholmod Sparse + cholmod_sparse b_cs = viewAsCholmod(b); + cholmod_sparse* x_cs = cholmod_spsolve(CHOLMOD_A, m_cholmodFactor, &b_cs, &m_cholmod); + if(!x_cs) + { + this->m_info = NumericalIssue; + } + // TODO optimize this copy by swapping when possible (be careful with alignment, etc.) + dest = viewAsEigen(*x_cs); + cholmod_free_sparse(&x_cs, &m_cholmod); + } + #endif // EIGEN_PARSED_BY_DOXYGEN + + + /** Sets the shift parameter that will be used to adjust the diagonal coefficients during the numerical factorization. + * + * During the numerical factorization, an offset term is added to the diagonal coefficients:\n + * \c d_ii = \a offset + \c d_ii + * + * The default is \a offset=0. + * + * \returns a reference to \c *this. + */ + Derived& setShift(const RealScalar& offset) + { + m_shiftOffset[0] = offset; + return derived(); + } + + template + void dumpMemory(Stream& /*s*/) + {} + + protected: + mutable cholmod_common m_cholmod; + cholmod_factor* m_cholmodFactor; + RealScalar m_shiftOffset[2]; + mutable ComputationInfo m_info; + bool m_isInitialized; + int m_factorizationIsOk; + int m_analysisIsOk; +}; + +/** \ingroup CholmodSupport_Module + * \class CholmodSimplicialLLT + * \brief A simplicial direct Cholesky (LLT) factorization and solver based on Cholmod + * + * This class allows to solve for A.X = B sparse linear problems via a simplicial LL^T Cholesky factorization + * using the Cholmod library. + * This simplicial variant is equivalent to Eigen's built-in SimplicialLLT class. Therefore, it has little practical interest. + * The sparse matrix A must be selfadjoint and positive definite. The vectors or matrices + * X and B can be either dense or sparse. + * + * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> + * \tparam _UpLo the triangular part that will be used for the computations. It can be Lower + * or Upper. Default is Lower. + * + * This class supports all kind of SparseMatrix<>: row or column major; upper, lower, or both; compressed or non compressed. + * + * \sa \ref TutorialSparseDirectSolvers, class CholmodSupernodalLLT, class SimplicialLLT + */ +template +class CholmodSimplicialLLT : public CholmodBase<_MatrixType, _UpLo, CholmodSimplicialLLT<_MatrixType, _UpLo> > +{ + typedef CholmodBase<_MatrixType, _UpLo, CholmodSimplicialLLT> Base; + using Base::m_cholmod; + + public: + + typedef _MatrixType MatrixType; + + CholmodSimplicialLLT() : Base() { init(); } + + CholmodSimplicialLLT(const MatrixType& matrix) : Base() + { + init(); + Base::compute(matrix); + } + + ~CholmodSimplicialLLT() {} + protected: + void init() + { + m_cholmod.final_asis = 0; + m_cholmod.supernodal = CHOLMOD_SIMPLICIAL; + m_cholmod.final_ll = 1; + } +}; + + +/** \ingroup CholmodSupport_Module + * \class CholmodSimplicialLDLT + * \brief A simplicial direct Cholesky (LDLT) factorization and solver based on Cholmod + * + * This class allows to solve for A.X = B sparse linear problems via a simplicial LDL^T Cholesky factorization + * using the Cholmod library. + * This simplicial variant is equivalent to Eigen's built-in SimplicialLDLT class. Therefore, it has little practical interest. + * The sparse matrix A must be selfadjoint and positive definite. The vectors or matrices + * X and B can be either dense or sparse. + * + * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> + * \tparam _UpLo the triangular part that will be used for the computations. It can be Lower + * or Upper. Default is Lower. + * + * This class supports all kind of SparseMatrix<>: row or column major; upper, lower, or both; compressed or non compressed. + * + * \sa \ref TutorialSparseDirectSolvers, class CholmodSupernodalLLT, class SimplicialLDLT + */ +template +class CholmodSimplicialLDLT : public CholmodBase<_MatrixType, _UpLo, CholmodSimplicialLDLT<_MatrixType, _UpLo> > +{ + typedef CholmodBase<_MatrixType, _UpLo, CholmodSimplicialLDLT> Base; + using Base::m_cholmod; + + public: + + typedef _MatrixType MatrixType; + + CholmodSimplicialLDLT() : Base() { init(); } + + CholmodSimplicialLDLT(const MatrixType& matrix) : Base() + { + init(); + Base::compute(matrix); + } + + ~CholmodSimplicialLDLT() {} + protected: + void init() + { + m_cholmod.final_asis = 1; + m_cholmod.supernodal = CHOLMOD_SIMPLICIAL; + } +}; + +/** \ingroup CholmodSupport_Module + * \class CholmodSupernodalLLT + * \brief A supernodal Cholesky (LLT) factorization and solver based on Cholmod + * + * This class allows to solve for A.X = B sparse linear problems via a supernodal LL^T Cholesky factorization + * using the Cholmod library. + * This supernodal variant performs best on dense enough problems, e.g., 3D FEM, or very high order 2D FEM. + * The sparse matrix A must be selfadjoint and positive definite. The vectors or matrices + * X and B can be either dense or sparse. + * + * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> + * \tparam _UpLo the triangular part that will be used for the computations. It can be Lower + * or Upper. Default is Lower. + * + * This class supports all kind of SparseMatrix<>: row or column major; upper, lower, or both; compressed or non compressed. + * + * \sa \ref TutorialSparseDirectSolvers + */ +template +class CholmodSupernodalLLT : public CholmodBase<_MatrixType, _UpLo, CholmodSupernodalLLT<_MatrixType, _UpLo> > +{ + typedef CholmodBase<_MatrixType, _UpLo, CholmodSupernodalLLT> Base; + using Base::m_cholmod; + + public: + + typedef _MatrixType MatrixType; + + CholmodSupernodalLLT() : Base() { init(); } + + CholmodSupernodalLLT(const MatrixType& matrix) : Base() + { + init(); + Base::compute(matrix); + } + + ~CholmodSupernodalLLT() {} + protected: + void init() + { + m_cholmod.final_asis = 1; + m_cholmod.supernodal = CHOLMOD_SUPERNODAL; + } +}; + +/** \ingroup CholmodSupport_Module + * \class CholmodDecomposition + * \brief A general Cholesky factorization and solver based on Cholmod + * + * This class allows to solve for A.X = B sparse linear problems via a LL^T or LDL^T Cholesky factorization + * using the Cholmod library. The sparse matrix A must be selfadjoint and positive definite. The vectors or matrices + * X and B can be either dense or sparse. + * + * This variant permits to change the underlying Cholesky method at runtime. + * On the other hand, it does not provide access to the result of the factorization. + * The default is to let Cholmod automatically choose between a simplicial and supernodal factorization. + * + * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> + * \tparam _UpLo the triangular part that will be used for the computations. It can be Lower + * or Upper. Default is Lower. + * + * This class supports all kind of SparseMatrix<>: row or column major; upper, lower, or both; compressed or non compressed. + * + * \sa \ref TutorialSparseDirectSolvers + */ +template +class CholmodDecomposition : public CholmodBase<_MatrixType, _UpLo, CholmodDecomposition<_MatrixType, _UpLo> > +{ + typedef CholmodBase<_MatrixType, _UpLo, CholmodDecomposition> Base; + using Base::m_cholmod; + + public: + + typedef _MatrixType MatrixType; + + CholmodDecomposition() : Base() { init(); } + + CholmodDecomposition(const MatrixType& matrix) : Base() + { + init(); + Base::compute(matrix); + } + + ~CholmodDecomposition() {} + + void setMode(CholmodMode mode) + { + switch(mode) + { + case CholmodAuto: + m_cholmod.final_asis = 1; + m_cholmod.supernodal = CHOLMOD_AUTO; + break; + case CholmodSimplicialLLt: + m_cholmod.final_asis = 0; + m_cholmod.supernodal = CHOLMOD_SIMPLICIAL; + m_cholmod.final_ll = 1; + break; + case CholmodSupernodalLLt: + m_cholmod.final_asis = 1; + m_cholmod.supernodal = CHOLMOD_SUPERNODAL; + break; + case CholmodLDLt: + m_cholmod.final_asis = 1; + m_cholmod.supernodal = CHOLMOD_SIMPLICIAL; + break; + default: + break; + } + } + protected: + void init() + { + m_cholmod.final_asis = 1; + m_cholmod.supernodal = CHOLMOD_AUTO; + } +}; + +namespace internal { + +template +struct solve_retval, Rhs> + : solve_retval_base, Rhs> +{ + typedef CholmodBase<_MatrixType,_UpLo,Derived> Dec; + EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs) + + template void evalTo(Dest& dst) const + { + dec()._solve(rhs(),dst); + } +}; + +template +struct sparse_solve_retval, Rhs> + : sparse_solve_retval_base, Rhs> +{ + typedef CholmodBase<_MatrixType,_UpLo,Derived> Dec; + EIGEN_MAKE_SPARSE_SOLVE_HELPERS(Dec,Rhs) + + template void evalTo(Dest& dst) const + { + dec()._solve(rhs(),dst); + } +}; + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_CHOLMODSUPPORT_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/Array.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/Array.h new file mode 100644 index 00000000..0b9c38c8 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/Array.h @@ -0,0 +1,323 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2009 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_ARRAY_H +#define EIGEN_ARRAY_H + +namespace Eigen { + +/** \class Array + * \ingroup Core_Module + * + * \brief General-purpose arrays with easy API for coefficient-wise operations + * + * The %Array class is very similar to the Matrix class. It provides + * general-purpose one- and two-dimensional arrays. The difference between the + * %Array and the %Matrix class is primarily in the API: the API for the + * %Array class provides easy access to coefficient-wise operations, while the + * API for the %Matrix class provides easy access to linear-algebra + * operations. + * + * This class can be extended with the help of the plugin mechanism described on the page + * \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_ARRAY_PLUGIN. + * + * \sa \ref TutorialArrayClass, \ref TopicClassHierarchy + */ +namespace internal { +template +struct traits > : traits > +{ + typedef ArrayXpr XprKind; + typedef ArrayBase > XprBase; +}; +} + +template +class Array + : public PlainObjectBase > +{ + public: + + typedef PlainObjectBase Base; + EIGEN_DENSE_PUBLIC_INTERFACE(Array) + + enum { Options = _Options }; + typedef typename Base::PlainObject PlainObject; + + protected: + template + friend struct internal::conservative_resize_like_impl; + + using Base::m_storage; + + public: + + using Base::base; + using Base::coeff; + using Base::coeffRef; + + /** + * The usage of + * using Base::operator=; + * fails on MSVC. Since the code below is working with GCC and MSVC, we skipped + * the usage of 'using'. This should be done only for operator=. + */ + template + EIGEN_STRONG_INLINE Array& operator=(const EigenBase &other) + { + return Base::operator=(other); + } + + /** Copies the value of the expression \a other into \c *this with automatic resizing. + * + * *this might be resized to match the dimensions of \a other. If *this was a null matrix (not already initialized), + * it will be initialized. + * + * Note that copying a row-vector into a vector (and conversely) is allowed. + * The resizing, if any, is then done in the appropriate way so that row-vectors + * remain row-vectors and vectors remain vectors. + */ + template + EIGEN_STRONG_INLINE Array& operator=(const ArrayBase& other) + { + return Base::_set(other); + } + + /** This is a special case of the templated operator=. Its purpose is to + * prevent a default operator= from hiding the templated operator=. + */ + EIGEN_STRONG_INLINE Array& operator=(const Array& other) + { + return Base::_set(other); + } + + /** Default constructor. + * + * For fixed-size matrices, does nothing. + * + * For dynamic-size matrices, creates an empty matrix of size 0. Does not allocate any array. Such a matrix + * is called a null matrix. This constructor is the unique way to create null matrices: resizing + * a matrix to 0 is not supported. + * + * \sa resize(Index,Index) + */ + EIGEN_STRONG_INLINE Array() : Base() + { + Base::_check_template_params(); + EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED + } + +#ifndef EIGEN_PARSED_BY_DOXYGEN + // FIXME is it still needed ?? + /** \internal */ + Array(internal::constructor_without_unaligned_array_assert) + : Base(internal::constructor_without_unaligned_array_assert()) + { + Base::_check_template_params(); + EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED + } +#endif + +#ifdef EIGEN_HAVE_RVALUE_REFERENCES + Array(Array&& other) + : Base(std::move(other)) + { + Base::_check_template_params(); + if (RowsAtCompileTime!=Dynamic && ColsAtCompileTime!=Dynamic) + Base::_set_noalias(other); + } + Array& operator=(Array&& other) + { + other.swap(*this); + return *this; + } +#endif + + /** Constructs a vector or row-vector with given dimension. \only_for_vectors + * + * Note that this is only useful for dynamic-size vectors. For fixed-size vectors, + * it is redundant to pass the dimension here, so it makes more sense to use the default + * constructor Matrix() instead. + */ + EIGEN_STRONG_INLINE explicit Array(Index dim) + : Base(dim, RowsAtCompileTime == 1 ? 1 : dim, ColsAtCompileTime == 1 ? 1 : dim) + { + Base::_check_template_params(); + EIGEN_STATIC_ASSERT_VECTOR_ONLY(Array) + eigen_assert(dim >= 0); + eigen_assert(SizeAtCompileTime == Dynamic || SizeAtCompileTime == dim); + EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED + } + + #ifndef EIGEN_PARSED_BY_DOXYGEN + template + EIGEN_STRONG_INLINE Array(const T0& val0, const T1& val1) + { + Base::_check_template_params(); + this->template _init2(val0, val1); + } + #else + /** constructs an uninitialized matrix with \a rows rows and \a cols columns. + * + * This is useful for dynamic-size matrices. For fixed-size matrices, + * it is redundant to pass these parameters, so one should use the default constructor + * Matrix() instead. */ + Array(Index rows, Index cols); + /** constructs an initialized 2D vector with given coefficients */ + Array(const Scalar& val0, const Scalar& val1); + #endif + + /** constructs an initialized 3D vector with given coefficients */ + EIGEN_STRONG_INLINE Array(const Scalar& val0, const Scalar& val1, const Scalar& val2) + { + Base::_check_template_params(); + EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Array, 3) + m_storage.data()[0] = val0; + m_storage.data()[1] = val1; + m_storage.data()[2] = val2; + } + /** constructs an initialized 4D vector with given coefficients */ + EIGEN_STRONG_INLINE Array(const Scalar& val0, const Scalar& val1, const Scalar& val2, const Scalar& val3) + { + Base::_check_template_params(); + EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Array, 4) + m_storage.data()[0] = val0; + m_storage.data()[1] = val1; + m_storage.data()[2] = val2; + m_storage.data()[3] = val3; + } + + explicit Array(const Scalar *data); + + /** Constructor copying the value of the expression \a other */ + template + EIGEN_STRONG_INLINE Array(const ArrayBase& other) + : Base(other.rows() * other.cols(), other.rows(), other.cols()) + { + Base::_check_template_params(); + Base::_set_noalias(other); + } + /** Copy constructor */ + EIGEN_STRONG_INLINE Array(const Array& other) + : Base(other.rows() * other.cols(), other.rows(), other.cols()) + { + Base::_check_template_params(); + Base::_set_noalias(other); + } + /** Copy constructor with in-place evaluation */ + template + EIGEN_STRONG_INLINE Array(const ReturnByValue& other) + { + Base::_check_template_params(); + Base::resize(other.rows(), other.cols()); + other.evalTo(*this); + } + + /** \sa MatrixBase::operator=(const EigenBase&) */ + template + EIGEN_STRONG_INLINE Array(const EigenBase &other) + : Base(other.derived().rows() * other.derived().cols(), other.derived().rows(), other.derived().cols()) + { + Base::_check_template_params(); + Base::_resize_to_match(other); + *this = other; + } + + /** Override MatrixBase::swap() since for dynamic-sized matrices of same type it is enough to swap the + * data pointers. + */ + template + void swap(ArrayBase const & other) + { this->_swap(other.derived()); } + + inline Index innerStride() const { return 1; } + inline Index outerStride() const { return this->innerSize(); } + + #ifdef EIGEN_ARRAY_PLUGIN + #include EIGEN_ARRAY_PLUGIN + #endif + + private: + + template + friend struct internal::matrix_swap_impl; +}; + +/** \defgroup arraytypedefs Global array typedefs + * \ingroup Core_Module + * + * Eigen defines several typedef shortcuts for most common 1D and 2D array types. + * + * The general patterns are the following: + * + * \c ArrayRowsColsType where \c Rows and \c Cols can be \c 2,\c 3,\c 4 for fixed size square matrices or \c X for dynamic size, + * and where \c Type can be \c i for integer, \c f for float, \c d for double, \c cf for complex float, \c cd + * for complex double. + * + * For example, \c Array33d is a fixed-size 3x3 array type of doubles, and \c ArrayXXf is a dynamic-size matrix of floats. + * + * There are also \c ArraySizeType which are self-explanatory. For example, \c Array4cf is + * a fixed-size 1D array of 4 complex floats. + * + * \sa class Array + */ + +#define EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, Size, SizeSuffix) \ +/** \ingroup arraytypedefs */ \ +typedef Array Array##SizeSuffix##SizeSuffix##TypeSuffix; \ +/** \ingroup arraytypedefs */ \ +typedef Array Array##SizeSuffix##TypeSuffix; + +#define EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Type, TypeSuffix, Size) \ +/** \ingroup arraytypedefs */ \ +typedef Array Array##Size##X##TypeSuffix; \ +/** \ingroup arraytypedefs */ \ +typedef Array Array##X##Size##TypeSuffix; + +#define EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(Type, TypeSuffix) \ +EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, 2, 2) \ +EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, 3, 3) \ +EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, 4, 4) \ +EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, Dynamic, X) \ +EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Type, TypeSuffix, 2) \ +EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Type, TypeSuffix, 3) \ +EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Type, TypeSuffix, 4) + +EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(int, i) +EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(float, f) +EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(double, d) +EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(std::complex, cf) +EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(std::complex, cd) + +#undef EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES +#undef EIGEN_MAKE_ARRAY_TYPEDEFS + +#undef EIGEN_MAKE_ARRAY_TYPEDEFS_LARGE + +#define EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, SizeSuffix) \ +using Eigen::Matrix##SizeSuffix##TypeSuffix; \ +using Eigen::Vector##SizeSuffix##TypeSuffix; \ +using Eigen::RowVector##SizeSuffix##TypeSuffix; + +#define EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(TypeSuffix) \ +EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 2) \ +EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 3) \ +EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 4) \ +EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, X) \ + +#define EIGEN_USING_ARRAY_TYPEDEFS \ +EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(i) \ +EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(f) \ +EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(d) \ +EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(cf) \ +EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(cd) + +} // end namespace Eigen + +#endif // EIGEN_ARRAY_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/ArrayBase.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/ArrayBase.h new file mode 100644 index 00000000..33ff5537 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/ArrayBase.h @@ -0,0 +1,226 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2009 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_ARRAYBASE_H +#define EIGEN_ARRAYBASE_H + +namespace Eigen { + +template class MatrixWrapper; + +/** \class ArrayBase + * \ingroup Core_Module + * + * \brief Base class for all 1D and 2D array, and related expressions + * + * An array is similar to a dense vector or matrix. While matrices are mathematical + * objects with well defined linear algebra operators, an array is just a collection + * of scalar values arranged in a one or two dimensionnal fashion. As the main consequence, + * all operations applied to an array are performed coefficient wise. Furthermore, + * arrays support scalar math functions of the c++ standard library (e.g., std::sin(x)), and convenient + * constructors allowing to easily write generic code working for both scalar values + * and arrays. + * + * This class is the base that is inherited by all array expression types. + * + * \tparam Derived is the derived type, e.g., an array or an expression type. + * + * This class can be extended with the help of the plugin mechanism described on the page + * \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_ARRAYBASE_PLUGIN. + * + * \sa class MatrixBase, \ref TopicClassHierarchy + */ +template class ArrayBase + : public DenseBase +{ + public: +#ifndef EIGEN_PARSED_BY_DOXYGEN + /** The base class for a given storage type. */ + typedef ArrayBase StorageBaseType; + + typedef ArrayBase Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl; + + typedef typename internal::traits::StorageKind StorageKind; + typedef typename internal::traits::Index Index; + typedef typename internal::traits::Scalar Scalar; + typedef typename internal::packet_traits::type PacketScalar; + typedef typename NumTraits::Real RealScalar; + + typedef DenseBase Base; + using Base::operator*; + using Base::RowsAtCompileTime; + using Base::ColsAtCompileTime; + using Base::SizeAtCompileTime; + using Base::MaxRowsAtCompileTime; + using Base::MaxColsAtCompileTime; + using Base::MaxSizeAtCompileTime; + using Base::IsVectorAtCompileTime; + using Base::Flags; + using Base::CoeffReadCost; + + using Base::derived; + using Base::const_cast_derived; + using Base::rows; + using Base::cols; + using Base::size; + using Base::coeff; + using Base::coeffRef; + using Base::lazyAssign; + using Base::operator=; + using Base::operator+=; + using Base::operator-=; + using Base::operator*=; + using Base::operator/=; + + typedef typename Base::CoeffReturnType CoeffReturnType; + +#endif // not EIGEN_PARSED_BY_DOXYGEN + +#ifndef EIGEN_PARSED_BY_DOXYGEN + /** \internal the plain matrix type corresponding to this expression. Note that is not necessarily + * exactly the return type of eval(): in the case of plain matrices, the return type of eval() is a const + * reference to a matrix, not a matrix! It is however guaranteed that the return type of eval() is either + * PlainObject or const PlainObject&. + */ + typedef Array::Scalar, + internal::traits::RowsAtCompileTime, + internal::traits::ColsAtCompileTime, + AutoAlign | (internal::traits::Flags&RowMajorBit ? RowMajor : ColMajor), + internal::traits::MaxRowsAtCompileTime, + internal::traits::MaxColsAtCompileTime + > PlainObject; + + + /** \internal Represents a matrix with all coefficients equal to one another*/ + typedef CwiseNullaryOp,Derived> ConstantReturnType; +#endif // not EIGEN_PARSED_BY_DOXYGEN + +#define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::ArrayBase +# include "../plugins/CommonCwiseUnaryOps.h" +# include "../plugins/MatrixCwiseUnaryOps.h" +# include "../plugins/ArrayCwiseUnaryOps.h" +# include "../plugins/CommonCwiseBinaryOps.h" +# include "../plugins/MatrixCwiseBinaryOps.h" +# include "../plugins/ArrayCwiseBinaryOps.h" +# ifdef EIGEN_ARRAYBASE_PLUGIN +# include EIGEN_ARRAYBASE_PLUGIN +# endif +#undef EIGEN_CURRENT_STORAGE_BASE_CLASS + + /** Special case of the template operator=, in order to prevent the compiler + * from generating a default operator= (issue hit with g++ 4.1) + */ + Derived& operator=(const ArrayBase& other) + { + return internal::assign_selector::run(derived(), other.derived()); + } + + Derived& operator+=(const Scalar& scalar) + { return *this = derived() + scalar; } + Derived& operator-=(const Scalar& scalar) + { return *this = derived() - scalar; } + + template + Derived& operator+=(const ArrayBase& other); + template + Derived& operator-=(const ArrayBase& other); + + template + Derived& operator*=(const ArrayBase& other); + + template + Derived& operator/=(const ArrayBase& other); + + public: + ArrayBase& array() { return *this; } + const ArrayBase& array() const { return *this; } + + /** \returns an \link Eigen::MatrixBase Matrix \endlink expression of this array + * \sa MatrixBase::array() */ + MatrixWrapper matrix() { return derived(); } + const MatrixWrapper matrix() const { return derived(); } + +// template +// inline void evalTo(Dest& dst) const { dst = matrix(); } + + protected: + ArrayBase() : Base() {} + + private: + explicit ArrayBase(Index); + ArrayBase(Index,Index); + template explicit ArrayBase(const ArrayBase&); + protected: + // mixing arrays and matrices is not legal + template Derived& operator+=(const MatrixBase& ) + {EIGEN_STATIC_ASSERT(std::ptrdiff_t(sizeof(typename OtherDerived::Scalar))==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES); return *this;} + // mixing arrays and matrices is not legal + template Derived& operator-=(const MatrixBase& ) + {EIGEN_STATIC_ASSERT(std::ptrdiff_t(sizeof(typename OtherDerived::Scalar))==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES); return *this;} +}; + +/** replaces \c *this by \c *this - \a other. + * + * \returns a reference to \c *this + */ +template +template +EIGEN_STRONG_INLINE Derived & +ArrayBase::operator-=(const ArrayBase &other) +{ + SelfCwiseBinaryOp, Derived, OtherDerived> tmp(derived()); + tmp = other.derived(); + return derived(); +} + +/** replaces \c *this by \c *this + \a other. + * + * \returns a reference to \c *this + */ +template +template +EIGEN_STRONG_INLINE Derived & +ArrayBase::operator+=(const ArrayBase& other) +{ + SelfCwiseBinaryOp, Derived, OtherDerived> tmp(derived()); + tmp = other.derived(); + return derived(); +} + +/** replaces \c *this by \c *this * \a other coefficient wise. + * + * \returns a reference to \c *this + */ +template +template +EIGEN_STRONG_INLINE Derived & +ArrayBase::operator*=(const ArrayBase& other) +{ + SelfCwiseBinaryOp, Derived, OtherDerived> tmp(derived()); + tmp = other.derived(); + return derived(); +} + +/** replaces \c *this by \c *this / \a other coefficient wise. + * + * \returns a reference to \c *this + */ +template +template +EIGEN_STRONG_INLINE Derived & +ArrayBase::operator/=(const ArrayBase& other) +{ + SelfCwiseBinaryOp, Derived, OtherDerived> tmp(derived()); + tmp = other.derived(); + return derived(); +} + +} // end namespace Eigen + +#endif // EIGEN_ARRAYBASE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/ArrayWrapper.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/ArrayWrapper.h new file mode 100644 index 00000000..b4641e2a --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/ArrayWrapper.h @@ -0,0 +1,264 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2009-2010 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_ARRAYWRAPPER_H +#define EIGEN_ARRAYWRAPPER_H + +namespace Eigen { + +/** \class ArrayWrapper + * \ingroup Core_Module + * + * \brief Expression of a mathematical vector or matrix as an array object + * + * This class is the return type of MatrixBase::array(), and most of the time + * this is the only way it is use. + * + * \sa MatrixBase::array(), class MatrixWrapper + */ + +namespace internal { +template +struct traits > + : public traits::type > +{ + typedef ArrayXpr XprKind; + // Let's remove NestByRefBit + enum { + Flags0 = traits::type >::Flags, + Flags = Flags0 & ~NestByRefBit + }; +}; +} + +template +class ArrayWrapper : public ArrayBase > +{ + public: + typedef ArrayBase Base; + EIGEN_DENSE_PUBLIC_INTERFACE(ArrayWrapper) + EIGEN_INHERIT_ASSIGNMENT_OPERATORS(ArrayWrapper) + + typedef typename internal::conditional< + internal::is_lvalue::value, + Scalar, + const Scalar + >::type ScalarWithConstIfNotLvalue; + + typedef typename internal::nested::type NestedExpressionType; + + inline ArrayWrapper(ExpressionType& matrix) : m_expression(matrix) {} + + inline Index rows() const { return m_expression.rows(); } + inline Index cols() const { return m_expression.cols(); } + inline Index outerStride() const { return m_expression.outerStride(); } + inline Index innerStride() const { return m_expression.innerStride(); } + + inline ScalarWithConstIfNotLvalue* data() { return m_expression.const_cast_derived().data(); } + inline const Scalar* data() const { return m_expression.data(); } + + inline CoeffReturnType coeff(Index rowId, Index colId) const + { + return m_expression.coeff(rowId, colId); + } + + inline Scalar& coeffRef(Index rowId, Index colId) + { + return m_expression.const_cast_derived().coeffRef(rowId, colId); + } + + inline const Scalar& coeffRef(Index rowId, Index colId) const + { + return m_expression.const_cast_derived().coeffRef(rowId, colId); + } + + inline CoeffReturnType coeff(Index index) const + { + return m_expression.coeff(index); + } + + inline Scalar& coeffRef(Index index) + { + return m_expression.const_cast_derived().coeffRef(index); + } + + inline const Scalar& coeffRef(Index index) const + { + return m_expression.const_cast_derived().coeffRef(index); + } + + template + inline const PacketScalar packet(Index rowId, Index colId) const + { + return m_expression.template packet(rowId, colId); + } + + template + inline void writePacket(Index rowId, Index colId, const PacketScalar& val) + { + m_expression.const_cast_derived().template writePacket(rowId, colId, val); + } + + template + inline const PacketScalar packet(Index index) const + { + return m_expression.template packet(index); + } + + template + inline void writePacket(Index index, const PacketScalar& val) + { + m_expression.const_cast_derived().template writePacket(index, val); + } + + template + inline void evalTo(Dest& dst) const { dst = m_expression; } + + const typename internal::remove_all::type& + nestedExpression() const + { + return m_expression; + } + + /** Forwards the resizing request to the nested expression + * \sa DenseBase::resize(Index) */ + void resize(Index newSize) { m_expression.const_cast_derived().resize(newSize); } + /** Forwards the resizing request to the nested expression + * \sa DenseBase::resize(Index,Index)*/ + void resize(Index nbRows, Index nbCols) { m_expression.const_cast_derived().resize(nbRows,nbCols); } + + protected: + NestedExpressionType m_expression; +}; + +/** \class MatrixWrapper + * \ingroup Core_Module + * + * \brief Expression of an array as a mathematical vector or matrix + * + * This class is the return type of ArrayBase::matrix(), and most of the time + * this is the only way it is use. + * + * \sa MatrixBase::matrix(), class ArrayWrapper + */ + +namespace internal { +template +struct traits > + : public traits::type > +{ + typedef MatrixXpr XprKind; + // Let's remove NestByRefBit + enum { + Flags0 = traits::type >::Flags, + Flags = Flags0 & ~NestByRefBit + }; +}; +} + +template +class MatrixWrapper : public MatrixBase > +{ + public: + typedef MatrixBase > Base; + EIGEN_DENSE_PUBLIC_INTERFACE(MatrixWrapper) + EIGEN_INHERIT_ASSIGNMENT_OPERATORS(MatrixWrapper) + + typedef typename internal::conditional< + internal::is_lvalue::value, + Scalar, + const Scalar + >::type ScalarWithConstIfNotLvalue; + + typedef typename internal::nested::type NestedExpressionType; + + inline MatrixWrapper(ExpressionType& a_matrix) : m_expression(a_matrix) {} + + inline Index rows() const { return m_expression.rows(); } + inline Index cols() const { return m_expression.cols(); } + inline Index outerStride() const { return m_expression.outerStride(); } + inline Index innerStride() const { return m_expression.innerStride(); } + + inline ScalarWithConstIfNotLvalue* data() { return m_expression.const_cast_derived().data(); } + inline const Scalar* data() const { return m_expression.data(); } + + inline CoeffReturnType coeff(Index rowId, Index colId) const + { + return m_expression.coeff(rowId, colId); + } + + inline Scalar& coeffRef(Index rowId, Index colId) + { + return m_expression.const_cast_derived().coeffRef(rowId, colId); + } + + inline const Scalar& coeffRef(Index rowId, Index colId) const + { + return m_expression.derived().coeffRef(rowId, colId); + } + + inline CoeffReturnType coeff(Index index) const + { + return m_expression.coeff(index); + } + + inline Scalar& coeffRef(Index index) + { + return m_expression.const_cast_derived().coeffRef(index); + } + + inline const Scalar& coeffRef(Index index) const + { + return m_expression.const_cast_derived().coeffRef(index); + } + + template + inline const PacketScalar packet(Index rowId, Index colId) const + { + return m_expression.template packet(rowId, colId); + } + + template + inline void writePacket(Index rowId, Index colId, const PacketScalar& val) + { + m_expression.const_cast_derived().template writePacket(rowId, colId, val); + } + + template + inline const PacketScalar packet(Index index) const + { + return m_expression.template packet(index); + } + + template + inline void writePacket(Index index, const PacketScalar& val) + { + m_expression.const_cast_derived().template writePacket(index, val); + } + + const typename internal::remove_all::type& + nestedExpression() const + { + return m_expression; + } + + /** Forwards the resizing request to the nested expression + * \sa DenseBase::resize(Index) */ + void resize(Index newSize) { m_expression.const_cast_derived().resize(newSize); } + /** Forwards the resizing request to the nested expression + * \sa DenseBase::resize(Index,Index)*/ + void resize(Index nbRows, Index nbCols) { m_expression.const_cast_derived().resize(nbRows,nbCols); } + + protected: + NestedExpressionType m_expression; +}; + +} // end namespace Eigen + +#endif // EIGEN_ARRAYWRAPPER_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/Assign.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/Assign.h new file mode 100644 index 00000000..f4817317 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/Assign.h @@ -0,0 +1,590 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2007 Michael Olbrich +// Copyright (C) 2006-2010 Benoit Jacob +// Copyright (C) 2008 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_ASSIGN_H +#define EIGEN_ASSIGN_H + +namespace Eigen { + +namespace internal { + +/*************************************************************************** +* Part 1 : the logic deciding a strategy for traversal and unrolling * +***************************************************************************/ + +template +struct assign_traits +{ +public: + enum { + DstIsAligned = Derived::Flags & AlignedBit, + DstHasDirectAccess = Derived::Flags & DirectAccessBit, + SrcIsAligned = OtherDerived::Flags & AlignedBit, + JointAlignment = bool(DstIsAligned) && bool(SrcIsAligned) ? Aligned : Unaligned + }; + +private: + enum { + InnerSize = int(Derived::IsVectorAtCompileTime) ? int(Derived::SizeAtCompileTime) + : int(Derived::Flags)&RowMajorBit ? int(Derived::ColsAtCompileTime) + : int(Derived::RowsAtCompileTime), + InnerMaxSize = int(Derived::IsVectorAtCompileTime) ? int(Derived::MaxSizeAtCompileTime) + : int(Derived::Flags)&RowMajorBit ? int(Derived::MaxColsAtCompileTime) + : int(Derived::MaxRowsAtCompileTime), + MaxSizeAtCompileTime = Derived::SizeAtCompileTime, + PacketSize = packet_traits::size + }; + + enum { + StorageOrdersAgree = (int(Derived::IsRowMajor) == int(OtherDerived::IsRowMajor)), + MightVectorize = StorageOrdersAgree + && (int(Derived::Flags) & int(OtherDerived::Flags) & ActualPacketAccessBit), + MayInnerVectorize = MightVectorize && int(InnerSize)!=Dynamic && int(InnerSize)%int(PacketSize)==0 + && int(DstIsAligned) && int(SrcIsAligned), + MayLinearize = StorageOrdersAgree && (int(Derived::Flags) & int(OtherDerived::Flags) & LinearAccessBit), + MayLinearVectorize = MightVectorize && MayLinearize && DstHasDirectAccess + && (DstIsAligned || MaxSizeAtCompileTime == Dynamic), + /* If the destination isn't aligned, we have to do runtime checks and we don't unroll, + so it's only good for large enough sizes. */ + MaySliceVectorize = MightVectorize && DstHasDirectAccess + && (int(InnerMaxSize)==Dynamic || int(InnerMaxSize)>=3*PacketSize) + /* slice vectorization can be slow, so we only want it if the slices are big, which is + indicated by InnerMaxSize rather than InnerSize, think of the case of a dynamic block + in a fixed-size matrix */ + }; + +public: + enum { + Traversal = int(MayInnerVectorize) ? int(InnerVectorizedTraversal) + : int(MayLinearVectorize) ? int(LinearVectorizedTraversal) + : int(MaySliceVectorize) ? int(SliceVectorizedTraversal) + : int(MayLinearize) ? int(LinearTraversal) + : int(DefaultTraversal), + Vectorized = int(Traversal) == InnerVectorizedTraversal + || int(Traversal) == LinearVectorizedTraversal + || int(Traversal) == SliceVectorizedTraversal + }; + +private: + enum { + UnrollingLimit = EIGEN_UNROLLING_LIMIT * (Vectorized ? int(PacketSize) : 1), + MayUnrollCompletely = int(Derived::SizeAtCompileTime) != Dynamic + && int(OtherDerived::CoeffReadCost) != Dynamic + && int(Derived::SizeAtCompileTime) * int(OtherDerived::CoeffReadCost) <= int(UnrollingLimit), + MayUnrollInner = int(InnerSize) != Dynamic + && int(OtherDerived::CoeffReadCost) != Dynamic + && int(InnerSize) * int(OtherDerived::CoeffReadCost) <= int(UnrollingLimit) + }; + +public: + enum { + Unrolling = (int(Traversal) == int(InnerVectorizedTraversal) || int(Traversal) == int(DefaultTraversal)) + ? ( + int(MayUnrollCompletely) ? int(CompleteUnrolling) + : int(MayUnrollInner) ? int(InnerUnrolling) + : int(NoUnrolling) + ) + : int(Traversal) == int(LinearVectorizedTraversal) + ? ( bool(MayUnrollCompletely) && bool(DstIsAligned) ? int(CompleteUnrolling) : int(NoUnrolling) ) + : int(Traversal) == int(LinearTraversal) + ? ( bool(MayUnrollCompletely) ? int(CompleteUnrolling) : int(NoUnrolling) ) + : int(NoUnrolling) + }; + +#ifdef EIGEN_DEBUG_ASSIGN + static void debug() + { + EIGEN_DEBUG_VAR(DstIsAligned) + EIGEN_DEBUG_VAR(SrcIsAligned) + EIGEN_DEBUG_VAR(JointAlignment) + EIGEN_DEBUG_VAR(InnerSize) + EIGEN_DEBUG_VAR(InnerMaxSize) + EIGEN_DEBUG_VAR(PacketSize) + EIGEN_DEBUG_VAR(StorageOrdersAgree) + EIGEN_DEBUG_VAR(MightVectorize) + EIGEN_DEBUG_VAR(MayLinearize) + EIGEN_DEBUG_VAR(MayInnerVectorize) + EIGEN_DEBUG_VAR(MayLinearVectorize) + EIGEN_DEBUG_VAR(MaySliceVectorize) + EIGEN_DEBUG_VAR(Traversal) + EIGEN_DEBUG_VAR(UnrollingLimit) + EIGEN_DEBUG_VAR(MayUnrollCompletely) + EIGEN_DEBUG_VAR(MayUnrollInner) + EIGEN_DEBUG_VAR(Unrolling) + } +#endif +}; + +/*************************************************************************** +* Part 2 : meta-unrollers +***************************************************************************/ + +/************************ +*** Default traversal *** +************************/ + +template +struct assign_DefaultTraversal_CompleteUnrolling +{ + enum { + outer = Index / Derived1::InnerSizeAtCompileTime, + inner = Index % Derived1::InnerSizeAtCompileTime + }; + + static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) + { + dst.copyCoeffByOuterInner(outer, inner, src); + assign_DefaultTraversal_CompleteUnrolling::run(dst, src); + } +}; + +template +struct assign_DefaultTraversal_CompleteUnrolling +{ + static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &) {} +}; + +template +struct assign_DefaultTraversal_InnerUnrolling +{ + static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src, typename Derived1::Index outer) + { + dst.copyCoeffByOuterInner(outer, Index, src); + assign_DefaultTraversal_InnerUnrolling::run(dst, src, outer); + } +}; + +template +struct assign_DefaultTraversal_InnerUnrolling +{ + static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &, typename Derived1::Index) {} +}; + +/*********************** +*** Linear traversal *** +***********************/ + +template +struct assign_LinearTraversal_CompleteUnrolling +{ + static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) + { + dst.copyCoeff(Index, src); + assign_LinearTraversal_CompleteUnrolling::run(dst, src); + } +}; + +template +struct assign_LinearTraversal_CompleteUnrolling +{ + static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &) {} +}; + +/************************** +*** Inner vectorization *** +**************************/ + +template +struct assign_innervec_CompleteUnrolling +{ + enum { + outer = Index / Derived1::InnerSizeAtCompileTime, + inner = Index % Derived1::InnerSizeAtCompileTime, + JointAlignment = assign_traits::JointAlignment + }; + + static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) + { + dst.template copyPacketByOuterInner(outer, inner, src); + assign_innervec_CompleteUnrolling::size, Stop>::run(dst, src); + } +}; + +template +struct assign_innervec_CompleteUnrolling +{ + static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &) {} +}; + +template +struct assign_innervec_InnerUnrolling +{ + static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src, typename Derived1::Index outer) + { + dst.template copyPacketByOuterInner(outer, Index, src); + assign_innervec_InnerUnrolling::size, Stop>::run(dst, src, outer); + } +}; + +template +struct assign_innervec_InnerUnrolling +{ + static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &, typename Derived1::Index) {} +}; + +/*************************************************************************** +* Part 3 : implementation of all cases +***************************************************************************/ + +template::Traversal, + int Unrolling = assign_traits::Unrolling, + int Version = Specialized> +struct assign_impl; + +/************************ +*** Default traversal *** +************************/ + +template +struct assign_impl +{ + static inline void run(Derived1 &, const Derived2 &) { } +}; + +template +struct assign_impl +{ + typedef typename Derived1::Index Index; + static inline void run(Derived1 &dst, const Derived2 &src) + { + const Index innerSize = dst.innerSize(); + const Index outerSize = dst.outerSize(); + for(Index outer = 0; outer < outerSize; ++outer) + for(Index inner = 0; inner < innerSize; ++inner) + dst.copyCoeffByOuterInner(outer, inner, src); + } +}; + +template +struct assign_impl +{ + static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) + { + assign_DefaultTraversal_CompleteUnrolling + ::run(dst, src); + } +}; + +template +struct assign_impl +{ + typedef typename Derived1::Index Index; + static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) + { + const Index outerSize = dst.outerSize(); + for(Index outer = 0; outer < outerSize; ++outer) + assign_DefaultTraversal_InnerUnrolling + ::run(dst, src, outer); + } +}; + +/*********************** +*** Linear traversal *** +***********************/ + +template +struct assign_impl +{ + typedef typename Derived1::Index Index; + static inline void run(Derived1 &dst, const Derived2 &src) + { + const Index size = dst.size(); + for(Index i = 0; i < size; ++i) + dst.copyCoeff(i, src); + } +}; + +template +struct assign_impl +{ + static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) + { + assign_LinearTraversal_CompleteUnrolling + ::run(dst, src); + } +}; + +/************************** +*** Inner vectorization *** +**************************/ + +template +struct assign_impl +{ + typedef typename Derived1::Index Index; + static inline void run(Derived1 &dst, const Derived2 &src) + { + const Index innerSize = dst.innerSize(); + const Index outerSize = dst.outerSize(); + const Index packetSize = packet_traits::size; + for(Index outer = 0; outer < outerSize; ++outer) + for(Index inner = 0; inner < innerSize; inner+=packetSize) + dst.template copyPacketByOuterInner(outer, inner, src); + } +}; + +template +struct assign_impl +{ + static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) + { + assign_innervec_CompleteUnrolling + ::run(dst, src); + } +}; + +template +struct assign_impl +{ + typedef typename Derived1::Index Index; + static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) + { + const Index outerSize = dst.outerSize(); + for(Index outer = 0; outer < outerSize; ++outer) + assign_innervec_InnerUnrolling + ::run(dst, src, outer); + } +}; + +/*************************** +*** Linear vectorization *** +***************************/ + +template +struct unaligned_assign_impl +{ + template + static EIGEN_STRONG_INLINE void run(const Derived&, OtherDerived&, typename Derived::Index, typename Derived::Index) {} +}; + +template <> +struct unaligned_assign_impl +{ + // MSVC must not inline this functions. If it does, it fails to optimize the + // packet access path. +#ifdef _MSC_VER + template + static EIGEN_DONT_INLINE void run(const Derived& src, OtherDerived& dst, typename Derived::Index start, typename Derived::Index end) +#else + template + static EIGEN_STRONG_INLINE void run(const Derived& src, OtherDerived& dst, typename Derived::Index start, typename Derived::Index end) +#endif + { + for (typename Derived::Index index = start; index < end; ++index) + dst.copyCoeff(index, src); + } +}; + +template +struct assign_impl +{ + typedef typename Derived1::Index Index; + static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) + { + const Index size = dst.size(); + typedef packet_traits PacketTraits; + enum { + packetSize = PacketTraits::size, + dstAlignment = PacketTraits::AlignedOnScalar ? Aligned : int(assign_traits::DstIsAligned) , + srcAlignment = assign_traits::JointAlignment + }; + const Index alignedStart = assign_traits::DstIsAligned ? 0 + : internal::first_aligned(&dst.coeffRef(0), size); + const Index alignedEnd = alignedStart + ((size-alignedStart)/packetSize)*packetSize; + + unaligned_assign_impl::DstIsAligned!=0>::run(src,dst,0,alignedStart); + + for(Index index = alignedStart; index < alignedEnd; index += packetSize) + { + dst.template copyPacket(index, src); + } + + unaligned_assign_impl<>::run(src,dst,alignedEnd,size); + } +}; + +template +struct assign_impl +{ + typedef typename Derived1::Index Index; + static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) + { + enum { size = Derived1::SizeAtCompileTime, + packetSize = packet_traits::size, + alignedSize = (size/packetSize)*packetSize }; + + assign_innervec_CompleteUnrolling::run(dst, src); + assign_DefaultTraversal_CompleteUnrolling::run(dst, src); + } +}; + +/************************** +*** Slice vectorization *** +***************************/ + +template +struct assign_impl +{ + typedef typename Derived1::Index Index; + static inline void run(Derived1 &dst, const Derived2 &src) + { + typedef typename Derived1::Scalar Scalar; + typedef packet_traits PacketTraits; + enum { + packetSize = PacketTraits::size, + alignable = PacketTraits::AlignedOnScalar, + dstIsAligned = assign_traits::DstIsAligned, + dstAlignment = alignable ? Aligned : int(dstIsAligned), + srcAlignment = assign_traits::JointAlignment + }; + const Scalar *dst_ptr = &dst.coeffRef(0,0); + if((!bool(dstIsAligned)) && (size_t(dst_ptr) % sizeof(Scalar))>0) + { + // the pointer is not aligend-on scalar, so alignment is not possible + return assign_impl::run(dst, src); + } + const Index packetAlignedMask = packetSize - 1; + const Index innerSize = dst.innerSize(); + const Index outerSize = dst.outerSize(); + const Index alignedStep = alignable ? (packetSize - dst.outerStride() % packetSize) & packetAlignedMask : 0; + Index alignedStart = ((!alignable) || bool(dstIsAligned)) ? 0 : internal::first_aligned(dst_ptr, innerSize); + + for(Index outer = 0; outer < outerSize; ++outer) + { + const Index alignedEnd = alignedStart + ((innerSize-alignedStart) & ~packetAlignedMask); + // do the non-vectorizable part of the assignment + for(Index inner = 0; inner(outer, inner, src); + + // do the non-vectorizable part of the assignment + for(Index inner = alignedEnd; inner((alignedStart+alignedStep)%packetSize, innerSize); + } + } +}; + +} // end namespace internal + +/*************************************************************************** +* Part 4 : implementation of DenseBase methods +***************************************************************************/ + +template +template +EIGEN_STRONG_INLINE Derived& DenseBase + ::lazyAssign(const DenseBase& other) +{ + enum{ + SameType = internal::is_same::value + }; + + EIGEN_STATIC_ASSERT_LVALUE(Derived) + EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Derived,OtherDerived) + EIGEN_STATIC_ASSERT(SameType,YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) + +#ifdef EIGEN_DEBUG_ASSIGN + internal::assign_traits::debug(); +#endif + eigen_assert(rows() == other.rows() && cols() == other.cols()); + internal::assign_impl::Traversal) + : int(InvalidTraversal)>::run(derived(),other.derived()); +#ifndef EIGEN_NO_DEBUG + checkTransposeAliasing(other.derived()); +#endif + return derived(); +} + +namespace internal { + +template::Flags) & EvalBeforeAssigningBit) != 0, + bool NeedToTranspose = ((int(Derived::RowsAtCompileTime) == 1 && int(OtherDerived::ColsAtCompileTime) == 1) + | // FIXME | instead of || to please GCC 4.4.0 stupid warning "suggest parentheses around &&". + // revert to || as soon as not needed anymore. + (int(Derived::ColsAtCompileTime) == 1 && int(OtherDerived::RowsAtCompileTime) == 1)) + && int(Derived::SizeAtCompileTime) != 1> +struct assign_selector; + +template +struct assign_selector { + static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.derived()); } + template + static EIGEN_STRONG_INLINE Derived& evalTo(ActualDerived& dst, const ActualOtherDerived& other) { other.evalTo(dst); return dst; } +}; +template +struct assign_selector { + static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.eval()); } +}; +template +struct assign_selector { + static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.transpose()); } + template + static EIGEN_STRONG_INLINE Derived& evalTo(ActualDerived& dst, const ActualOtherDerived& other) { Transpose dstTrans(dst); other.evalTo(dstTrans); return dst; } +}; +template +struct assign_selector { + static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.transpose().eval()); } +}; + +} // end namespace internal + +template +template +EIGEN_STRONG_INLINE Derived& DenseBase::operator=(const DenseBase& other) +{ + return internal::assign_selector::run(derived(), other.derived()); +} + +template +EIGEN_STRONG_INLINE Derived& DenseBase::operator=(const DenseBase& other) +{ + return internal::assign_selector::run(derived(), other.derived()); +} + +template +EIGEN_STRONG_INLINE Derived& MatrixBase::operator=(const MatrixBase& other) +{ + return internal::assign_selector::run(derived(), other.derived()); +} + +template +template +EIGEN_STRONG_INLINE Derived& MatrixBase::operator=(const DenseBase& other) +{ + return internal::assign_selector::run(derived(), other.derived()); +} + +template +template +EIGEN_STRONG_INLINE Derived& MatrixBase::operator=(const EigenBase& other) +{ + return internal::assign_selector::evalTo(derived(), other.derived()); +} + +template +template +EIGEN_STRONG_INLINE Derived& MatrixBase::operator=(const ReturnByValue& other) +{ + return internal::assign_selector::evalTo(derived(), other.derived()); +} + +} // end namespace Eigen + +#endif // EIGEN_ASSIGN_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/Assign_MKL.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/Assign_MKL.h new file mode 100644 index 00000000..7772951b --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/Assign_MKL.h @@ -0,0 +1,224 @@ +/* + Copyright (c) 2011, Intel Corporation. All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of Intel Corporation nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ******************************************************************************** + * Content : Eigen bindings to Intel(R) MKL + * MKL VML support for coefficient-wise unary Eigen expressions like a=b.sin() + ******************************************************************************** +*/ + +#ifndef EIGEN_ASSIGN_VML_H +#define EIGEN_ASSIGN_VML_H + +namespace Eigen { + +namespace internal { + +template struct vml_call +{ enum { IsSupported = 0 }; }; + +template +class vml_assign_traits +{ + private: + enum { + DstHasDirectAccess = Dst::Flags & DirectAccessBit, + SrcHasDirectAccess = Src::Flags & DirectAccessBit, + + StorageOrdersAgree = (int(Dst::IsRowMajor) == int(Src::IsRowMajor)), + InnerSize = int(Dst::IsVectorAtCompileTime) ? int(Dst::SizeAtCompileTime) + : int(Dst::Flags)&RowMajorBit ? int(Dst::ColsAtCompileTime) + : int(Dst::RowsAtCompileTime), + InnerMaxSize = int(Dst::IsVectorAtCompileTime) ? int(Dst::MaxSizeAtCompileTime) + : int(Dst::Flags)&RowMajorBit ? int(Dst::MaxColsAtCompileTime) + : int(Dst::MaxRowsAtCompileTime), + MaxSizeAtCompileTime = Dst::SizeAtCompileTime, + + MightEnableVml = vml_call::IsSupported && StorageOrdersAgree && DstHasDirectAccess && SrcHasDirectAccess + && Src::InnerStrideAtCompileTime==1 && Dst::InnerStrideAtCompileTime==1, + MightLinearize = MightEnableVml && (int(Dst::Flags) & int(Src::Flags) & LinearAccessBit), + VmlSize = MightLinearize ? MaxSizeAtCompileTime : InnerMaxSize, + LargeEnough = VmlSize==Dynamic || VmlSize>=EIGEN_MKL_VML_THRESHOLD, + MayEnableVml = MightEnableVml && LargeEnough, + MayLinearize = MayEnableVml && MightLinearize + }; + public: + enum { + Traversal = MayLinearize ? LinearVectorizedTraversal + : MayEnableVml ? InnerVectorizedTraversal + : DefaultTraversal + }; +}; + +template::Traversal > +struct vml_assign_impl + : assign_impl,Traversal,Unrolling,BuiltIn> +{ +}; + +template +struct vml_assign_impl +{ + typedef typename Derived1::Scalar Scalar; + typedef typename Derived1::Index Index; + static inline void run(Derived1& dst, const CwiseUnaryOp& src) + { + // in case we want to (or have to) skip VML at runtime we can call: + // assign_impl,Traversal,Unrolling,BuiltIn>::run(dst,src); + const Index innerSize = dst.innerSize(); + const Index outerSize = dst.outerSize(); + for(Index outer = 0; outer < outerSize; ++outer) { + const Scalar *src_ptr = src.IsRowMajor ? &(src.nestedExpression().coeffRef(outer,0)) : + &(src.nestedExpression().coeffRef(0, outer)); + Scalar *dst_ptr = dst.IsRowMajor ? &(dst.coeffRef(outer,0)) : &(dst.coeffRef(0, outer)); + vml_call::run(src.functor(), innerSize, src_ptr, dst_ptr ); + } + } +}; + +template +struct vml_assign_impl +{ + static inline void run(Derived1& dst, const CwiseUnaryOp& src) + { + // in case we want to (or have to) skip VML at runtime we can call: + // assign_impl,Traversal,Unrolling,BuiltIn>::run(dst,src); + vml_call::run(src.functor(), dst.size(), src.nestedExpression().data(), dst.data() ); + } +}; + +// Macroses + +#define EIGEN_MKL_VML_SPECIALIZE_ASSIGN(TRAVERSAL,UNROLLING) \ + template \ + struct assign_impl, TRAVERSAL, UNROLLING, Specialized> { \ + static inline void run(Derived1 &dst, const Eigen::CwiseUnaryOp &src) { \ + vml_assign_impl::run(dst, src); \ + } \ + }; + +EIGEN_MKL_VML_SPECIALIZE_ASSIGN(DefaultTraversal,NoUnrolling) +EIGEN_MKL_VML_SPECIALIZE_ASSIGN(DefaultTraversal,CompleteUnrolling) +EIGEN_MKL_VML_SPECIALIZE_ASSIGN(DefaultTraversal,InnerUnrolling) +EIGEN_MKL_VML_SPECIALIZE_ASSIGN(LinearTraversal,NoUnrolling) +EIGEN_MKL_VML_SPECIALIZE_ASSIGN(LinearTraversal,CompleteUnrolling) +EIGEN_MKL_VML_SPECIALIZE_ASSIGN(InnerVectorizedTraversal,NoUnrolling) +EIGEN_MKL_VML_SPECIALIZE_ASSIGN(InnerVectorizedTraversal,CompleteUnrolling) +EIGEN_MKL_VML_SPECIALIZE_ASSIGN(InnerVectorizedTraversal,InnerUnrolling) +EIGEN_MKL_VML_SPECIALIZE_ASSIGN(LinearVectorizedTraversal,CompleteUnrolling) +EIGEN_MKL_VML_SPECIALIZE_ASSIGN(LinearVectorizedTraversal,NoUnrolling) +EIGEN_MKL_VML_SPECIALIZE_ASSIGN(SliceVectorizedTraversal,NoUnrolling) + + +#if !defined (EIGEN_FAST_MATH) || (EIGEN_FAST_MATH != 1) +#define EIGEN_MKL_VML_MODE VML_HA +#else +#define EIGEN_MKL_VML_MODE VML_LA +#endif + +#define EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, VMLOP, EIGENTYPE, VMLTYPE) \ + template<> struct vml_call< scalar_##EIGENOP##_op > { \ + enum { IsSupported = 1 }; \ + static inline void run( const scalar_##EIGENOP##_op& /*func*/, \ + int size, const EIGENTYPE* src, EIGENTYPE* dst) { \ + VMLOP(size, (const VMLTYPE*)src, (VMLTYPE*)dst); \ + } \ + }; + +#define EIGEN_MKL_VML_DECLARE_UNARY_CALL_LA(EIGENOP, VMLOP, EIGENTYPE, VMLTYPE) \ + template<> struct vml_call< scalar_##EIGENOP##_op > { \ + enum { IsSupported = 1 }; \ + static inline void run( const scalar_##EIGENOP##_op& /*func*/, \ + int size, const EIGENTYPE* src, EIGENTYPE* dst) { \ + MKL_INT64 vmlMode = EIGEN_MKL_VML_MODE; \ + VMLOP(size, (const VMLTYPE*)src, (VMLTYPE*)dst, vmlMode); \ + } \ + }; + +#define EIGEN_MKL_VML_DECLARE_POW_CALL(EIGENOP, VMLOP, EIGENTYPE, VMLTYPE) \ + template<> struct vml_call< scalar_##EIGENOP##_op > { \ + enum { IsSupported = 1 }; \ + static inline void run( const scalar_##EIGENOP##_op& func, \ + int size, const EIGENTYPE* src, EIGENTYPE* dst) { \ + EIGENTYPE exponent = func.m_exponent; \ + MKL_INT64 vmlMode = EIGEN_MKL_VML_MODE; \ + VMLOP(&size, (const VMLTYPE*)src, (const VMLTYPE*)&exponent, \ + (VMLTYPE*)dst, &vmlMode); \ + } \ + }; + +#define EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(EIGENOP, VMLOP) \ + EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, vs##VMLOP, float, float) \ + EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, vd##VMLOP, double, double) + +#define EIGEN_MKL_VML_DECLARE_UNARY_CALLS_COMPLEX(EIGENOP, VMLOP) \ + EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, vc##VMLOP, scomplex, MKL_Complex8) \ + EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, vz##VMLOP, dcomplex, MKL_Complex16) + +#define EIGEN_MKL_VML_DECLARE_UNARY_CALLS(EIGENOP, VMLOP) \ + EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(EIGENOP, VMLOP) \ + EIGEN_MKL_VML_DECLARE_UNARY_CALLS_COMPLEX(EIGENOP, VMLOP) + + +#define EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL_LA(EIGENOP, VMLOP) \ + EIGEN_MKL_VML_DECLARE_UNARY_CALL_LA(EIGENOP, vms##VMLOP, float, float) \ + EIGEN_MKL_VML_DECLARE_UNARY_CALL_LA(EIGENOP, vmd##VMLOP, double, double) + +#define EIGEN_MKL_VML_DECLARE_UNARY_CALLS_COMPLEX_LA(EIGENOP, VMLOP) \ + EIGEN_MKL_VML_DECLARE_UNARY_CALL_LA(EIGENOP, vmc##VMLOP, scomplex, MKL_Complex8) \ + EIGEN_MKL_VML_DECLARE_UNARY_CALL_LA(EIGENOP, vmz##VMLOP, dcomplex, MKL_Complex16) + +#define EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(EIGENOP, VMLOP) \ + EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL_LA(EIGENOP, VMLOP) \ + EIGEN_MKL_VML_DECLARE_UNARY_CALLS_COMPLEX_LA(EIGENOP, VMLOP) + + +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(sin, Sin) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(asin, Asin) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(cos, Cos) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(acos, Acos) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(tan, Tan) +//EIGEN_MKL_VML_DECLARE_UNARY_CALLS(abs, Abs) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(exp, Exp) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(log, Ln) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(sqrt, Sqrt) + +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(square, Sqr) + +// The vm*powx functions are not avaibale in the windows version of MKL. +#ifndef _WIN32 +EIGEN_MKL_VML_DECLARE_POW_CALL(pow, vmspowx_, float, float) +EIGEN_MKL_VML_DECLARE_POW_CALL(pow, vmdpowx_, double, double) +EIGEN_MKL_VML_DECLARE_POW_CALL(pow, vmcpowx_, scomplex, MKL_Complex8) +EIGEN_MKL_VML_DECLARE_POW_CALL(pow, vmzpowx_, dcomplex, MKL_Complex16) +#endif + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_ASSIGN_VML_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/BandMatrix.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/BandMatrix.h new file mode 100644 index 00000000..ffd7fe8b --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/BandMatrix.h @@ -0,0 +1,334 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2009 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_BANDMATRIX_H +#define EIGEN_BANDMATRIX_H + +namespace Eigen { + +namespace internal { + +template +class BandMatrixBase : public EigenBase +{ + public: + + enum { + Flags = internal::traits::Flags, + CoeffReadCost = internal::traits::CoeffReadCost, + RowsAtCompileTime = internal::traits::RowsAtCompileTime, + ColsAtCompileTime = internal::traits::ColsAtCompileTime, + MaxRowsAtCompileTime = internal::traits::MaxRowsAtCompileTime, + MaxColsAtCompileTime = internal::traits::MaxColsAtCompileTime, + Supers = internal::traits::Supers, + Subs = internal::traits::Subs, + Options = internal::traits::Options + }; + typedef typename internal::traits::Scalar Scalar; + typedef Matrix DenseMatrixType; + typedef typename DenseMatrixType::Index Index; + typedef typename internal::traits::CoefficientsType CoefficientsType; + typedef EigenBase Base; + + protected: + enum { + DataRowsAtCompileTime = ((Supers!=Dynamic) && (Subs!=Dynamic)) + ? 1 + Supers + Subs + : Dynamic, + SizeAtCompileTime = EIGEN_SIZE_MIN_PREFER_DYNAMIC(RowsAtCompileTime,ColsAtCompileTime) + }; + + public: + + using Base::derived; + using Base::rows; + using Base::cols; + + /** \returns the number of super diagonals */ + inline Index supers() const { return derived().supers(); } + + /** \returns the number of sub diagonals */ + inline Index subs() const { return derived().subs(); } + + /** \returns an expression of the underlying coefficient matrix */ + inline const CoefficientsType& coeffs() const { return derived().coeffs(); } + + /** \returns an expression of the underlying coefficient matrix */ + inline CoefficientsType& coeffs() { return derived().coeffs(); } + + /** \returns a vector expression of the \a i -th column, + * only the meaningful part is returned. + * \warning the internal storage must be column major. */ + inline Block col(Index i) + { + EIGEN_STATIC_ASSERT((Options&RowMajor)==0,THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES); + Index start = 0; + Index len = coeffs().rows(); + if (i<=supers()) + { + start = supers()-i; + len = (std::min)(rows(),std::max(0,coeffs().rows() - (supers()-i))); + } + else if (i>=rows()-subs()) + len = std::max(0,coeffs().rows() - (i + 1 - rows() + subs())); + return Block(coeffs(), start, i, len, 1); + } + + /** \returns a vector expression of the main diagonal */ + inline Block diagonal() + { return Block(coeffs(),supers(),0,1,(std::min)(rows(),cols())); } + + /** \returns a vector expression of the main diagonal (const version) */ + inline const Block diagonal() const + { return Block(coeffs(),supers(),0,1,(std::min)(rows(),cols())); } + + template struct DiagonalIntReturnType { + enum { + ReturnOpposite = (Options&SelfAdjoint) && (((Index)>0 && Supers==0) || ((Index)<0 && Subs==0)), + Conjugate = ReturnOpposite && NumTraits::IsComplex, + ActualIndex = ReturnOpposite ? -Index : Index, + DiagonalSize = (RowsAtCompileTime==Dynamic || ColsAtCompileTime==Dynamic) + ? Dynamic + : (ActualIndex<0 + ? EIGEN_SIZE_MIN_PREFER_DYNAMIC(ColsAtCompileTime, RowsAtCompileTime + ActualIndex) + : EIGEN_SIZE_MIN_PREFER_DYNAMIC(RowsAtCompileTime, ColsAtCompileTime - ActualIndex)) + }; + typedef Block BuildType; + typedef typename internal::conditional,BuildType >, + BuildType>::type Type; + }; + + /** \returns a vector expression of the \a N -th sub or super diagonal */ + template inline typename DiagonalIntReturnType::Type diagonal() + { + return typename DiagonalIntReturnType::BuildType(coeffs(), supers()-N, (std::max)(0,N), 1, diagonalLength(N)); + } + + /** \returns a vector expression of the \a N -th sub or super diagonal */ + template inline const typename DiagonalIntReturnType::Type diagonal() const + { + return typename DiagonalIntReturnType::BuildType(coeffs(), supers()-N, (std::max)(0,N), 1, diagonalLength(N)); + } + + /** \returns a vector expression of the \a i -th sub or super diagonal */ + inline Block diagonal(Index i) + { + eigen_assert((i<0 && -i<=subs()) || (i>=0 && i<=supers())); + return Block(coeffs(), supers()-i, std::max(0,i), 1, diagonalLength(i)); + } + + /** \returns a vector expression of the \a i -th sub or super diagonal */ + inline const Block diagonal(Index i) const + { + eigen_assert((i<0 && -i<=subs()) || (i>=0 && i<=supers())); + return Block(coeffs(), supers()-i, std::max(0,i), 1, diagonalLength(i)); + } + + template inline void evalTo(Dest& dst) const + { + dst.resize(rows(),cols()); + dst.setZero(); + dst.diagonal() = diagonal(); + for (Index i=1; i<=supers();++i) + dst.diagonal(i) = diagonal(i); + for (Index i=1; i<=subs();++i) + dst.diagonal(-i) = diagonal(-i); + } + + DenseMatrixType toDenseMatrix() const + { + DenseMatrixType res(rows(),cols()); + evalTo(res); + return res; + } + + protected: + + inline Index diagonalLength(Index i) const + { return i<0 ? (std::min)(cols(),rows()+i) : (std::min)(rows(),cols()-i); } +}; + +/** + * \class BandMatrix + * \ingroup Core_Module + * + * \brief Represents a rectangular matrix with a banded storage + * + * \param _Scalar Numeric type, i.e. float, double, int + * \param Rows Number of rows, or \b Dynamic + * \param Cols Number of columns, or \b Dynamic + * \param Supers Number of super diagonal + * \param Subs Number of sub diagonal + * \param _Options A combination of either \b #RowMajor or \b #ColMajor, and of \b #SelfAdjoint + * The former controls \ref TopicStorageOrders "storage order", and defaults to + * column-major. The latter controls whether the matrix represents a selfadjoint + * matrix in which case either Supers of Subs have to be null. + * + * \sa class TridiagonalMatrix + */ + +template +struct traits > +{ + typedef _Scalar Scalar; + typedef Dense StorageKind; + typedef DenseIndex Index; + enum { + CoeffReadCost = NumTraits::ReadCost, + RowsAtCompileTime = _Rows, + ColsAtCompileTime = _Cols, + MaxRowsAtCompileTime = _Rows, + MaxColsAtCompileTime = _Cols, + Flags = LvalueBit, + Supers = _Supers, + Subs = _Subs, + Options = _Options, + DataRowsAtCompileTime = ((Supers!=Dynamic) && (Subs!=Dynamic)) ? 1 + Supers + Subs : Dynamic + }; + typedef Matrix CoefficientsType; +}; + +template +class BandMatrix : public BandMatrixBase > +{ + public: + + typedef typename internal::traits::Scalar Scalar; + typedef typename internal::traits::Index Index; + typedef typename internal::traits::CoefficientsType CoefficientsType; + + inline BandMatrix(Index rows=Rows, Index cols=Cols, Index supers=Supers, Index subs=Subs) + : m_coeffs(1+supers+subs,cols), + m_rows(rows), m_supers(supers), m_subs(subs) + { + } + + /** \returns the number of columns */ + inline Index rows() const { return m_rows.value(); } + + /** \returns the number of rows */ + inline Index cols() const { return m_coeffs.cols(); } + + /** \returns the number of super diagonals */ + inline Index supers() const { return m_supers.value(); } + + /** \returns the number of sub diagonals */ + inline Index subs() const { return m_subs.value(); } + + inline const CoefficientsType& coeffs() const { return m_coeffs; } + inline CoefficientsType& coeffs() { return m_coeffs; } + + protected: + + CoefficientsType m_coeffs; + internal::variable_if_dynamic m_rows; + internal::variable_if_dynamic m_supers; + internal::variable_if_dynamic m_subs; +}; + +template +class BandMatrixWrapper; + +template +struct traits > +{ + typedef typename _CoefficientsType::Scalar Scalar; + typedef typename _CoefficientsType::StorageKind StorageKind; + typedef typename _CoefficientsType::Index Index; + enum { + CoeffReadCost = internal::traits<_CoefficientsType>::CoeffReadCost, + RowsAtCompileTime = _Rows, + ColsAtCompileTime = _Cols, + MaxRowsAtCompileTime = _Rows, + MaxColsAtCompileTime = _Cols, + Flags = LvalueBit, + Supers = _Supers, + Subs = _Subs, + Options = _Options, + DataRowsAtCompileTime = ((Supers!=Dynamic) && (Subs!=Dynamic)) ? 1 + Supers + Subs : Dynamic + }; + typedef _CoefficientsType CoefficientsType; +}; + +template +class BandMatrixWrapper : public BandMatrixBase > +{ + public: + + typedef typename internal::traits::Scalar Scalar; + typedef typename internal::traits::CoefficientsType CoefficientsType; + typedef typename internal::traits::Index Index; + + inline BandMatrixWrapper(const CoefficientsType& coeffs, Index rows=_Rows, Index cols=_Cols, Index supers=_Supers, Index subs=_Subs) + : m_coeffs(coeffs), + m_rows(rows), m_supers(supers), m_subs(subs) + { + EIGEN_UNUSED_VARIABLE(cols); + //internal::assert(coeffs.cols()==cols() && (supers()+subs()+1)==coeffs.rows()); + } + + /** \returns the number of columns */ + inline Index rows() const { return m_rows.value(); } + + /** \returns the number of rows */ + inline Index cols() const { return m_coeffs.cols(); } + + /** \returns the number of super diagonals */ + inline Index supers() const { return m_supers.value(); } + + /** \returns the number of sub diagonals */ + inline Index subs() const { return m_subs.value(); } + + inline const CoefficientsType& coeffs() const { return m_coeffs; } + + protected: + + const CoefficientsType& m_coeffs; + internal::variable_if_dynamic m_rows; + internal::variable_if_dynamic m_supers; + internal::variable_if_dynamic m_subs; +}; + +/** + * \class TridiagonalMatrix + * \ingroup Core_Module + * + * \brief Represents a tridiagonal matrix with a compact banded storage + * + * \param _Scalar Numeric type, i.e. float, double, int + * \param Size Number of rows and cols, or \b Dynamic + * \param _Options Can be 0 or \b SelfAdjoint + * + * \sa class BandMatrix + */ +template +class TridiagonalMatrix : public BandMatrix +{ + typedef BandMatrix Base; + typedef typename Base::Index Index; + public: + TridiagonalMatrix(Index size = Size) : Base(size,size,Options&SelfAdjoint?0:1,1) {} + + inline typename Base::template DiagonalIntReturnType<1>::Type super() + { return Base::template diagonal<1>(); } + inline const typename Base::template DiagonalIntReturnType<1>::Type super() const + { return Base::template diagonal<1>(); } + inline typename Base::template DiagonalIntReturnType<-1>::Type sub() + { return Base::template diagonal<-1>(); } + inline const typename Base::template DiagonalIntReturnType<-1>::Type sub() const + { return Base::template diagonal<-1>(); } + protected: +}; + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_BANDMATRIX_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/Block.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/Block.h new file mode 100644 index 00000000..82789444 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/Block.h @@ -0,0 +1,406 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008 Gael Guennebaud +// Copyright (C) 2006-2010 Benoit Jacob +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_BLOCK_H +#define EIGEN_BLOCK_H + +namespace Eigen { + +/** \class Block + * \ingroup Core_Module + * + * \brief Expression of a fixed-size or dynamic-size block + * + * \param XprType the type of the expression in which we are taking a block + * \param BlockRows the number of rows of the block we are taking at compile time (optional) + * \param BlockCols the number of columns of the block we are taking at compile time (optional) + * + * This class represents an expression of either a fixed-size or dynamic-size block. It is the return + * type of DenseBase::block(Index,Index,Index,Index) and DenseBase::block(Index,Index) and + * most of the time this is the only way it is used. + * + * However, if you want to directly maniputate block expressions, + * for instance if you want to write a function returning such an expression, you + * will need to use this class. + * + * Here is an example illustrating the dynamic case: + * \include class_Block.cpp + * Output: \verbinclude class_Block.out + * + * \note Even though this expression has dynamic size, in the case where \a XprType + * has fixed size, this expression inherits a fixed maximal size which means that evaluating + * it does not cause a dynamic memory allocation. + * + * Here is an example illustrating the fixed-size case: + * \include class_FixedBlock.cpp + * Output: \verbinclude class_FixedBlock.out + * + * \sa DenseBase::block(Index,Index,Index,Index), DenseBase::block(Index,Index), class VectorBlock + */ + +namespace internal { +template +struct traits > : traits +{ + typedef typename traits::Scalar Scalar; + typedef typename traits::StorageKind StorageKind; + typedef typename traits::XprKind XprKind; + typedef typename nested::type XprTypeNested; + typedef typename remove_reference::type _XprTypeNested; + enum{ + MatrixRows = traits::RowsAtCompileTime, + MatrixCols = traits::ColsAtCompileTime, + RowsAtCompileTime = MatrixRows == 0 ? 0 : BlockRows, + ColsAtCompileTime = MatrixCols == 0 ? 0 : BlockCols, + MaxRowsAtCompileTime = BlockRows==0 ? 0 + : RowsAtCompileTime != Dynamic ? int(RowsAtCompileTime) + : int(traits::MaxRowsAtCompileTime), + MaxColsAtCompileTime = BlockCols==0 ? 0 + : ColsAtCompileTime != Dynamic ? int(ColsAtCompileTime) + : int(traits::MaxColsAtCompileTime), + XprTypeIsRowMajor = (int(traits::Flags)&RowMajorBit) != 0, + IsDense = is_same::value, + IsRowMajor = (IsDense&&MaxRowsAtCompileTime==1&&MaxColsAtCompileTime!=1) ? 1 + : (IsDense&&MaxColsAtCompileTime==1&&MaxRowsAtCompileTime!=1) ? 0 + : XprTypeIsRowMajor, + HasSameStorageOrderAsXprType = (IsRowMajor == XprTypeIsRowMajor), + InnerSize = IsRowMajor ? int(ColsAtCompileTime) : int(RowsAtCompileTime), + InnerStrideAtCompileTime = HasSameStorageOrderAsXprType + ? int(inner_stride_at_compile_time::ret) + : int(outer_stride_at_compile_time::ret), + OuterStrideAtCompileTime = HasSameStorageOrderAsXprType + ? int(outer_stride_at_compile_time::ret) + : int(inner_stride_at_compile_time::ret), + MaskPacketAccessBit = (InnerSize == Dynamic || (InnerSize % packet_traits::size) == 0) + && (InnerStrideAtCompileTime == 1) + ? PacketAccessBit : 0, + MaskAlignedBit = (InnerPanel && (OuterStrideAtCompileTime!=Dynamic) && (((OuterStrideAtCompileTime * int(sizeof(Scalar))) % 16) == 0)) ? AlignedBit : 0, + FlagsLinearAccessBit = (RowsAtCompileTime == 1 || ColsAtCompileTime == 1 || (InnerPanel && (traits::Flags&LinearAccessBit))) ? LinearAccessBit : 0, + FlagsLvalueBit = is_lvalue::value ? LvalueBit : 0, + FlagsRowMajorBit = IsRowMajor ? RowMajorBit : 0, + Flags0 = traits::Flags & ( (HereditaryBits & ~RowMajorBit) | + DirectAccessBit | + MaskPacketAccessBit | + MaskAlignedBit), + Flags = Flags0 | FlagsLinearAccessBit | FlagsLvalueBit | FlagsRowMajorBit + }; +}; + +template::ret> class BlockImpl_dense; + +} // end namespace internal + +template class BlockImpl; + +template class Block + : public BlockImpl::StorageKind> +{ + typedef BlockImpl::StorageKind> Impl; + public: + //typedef typename Impl::Base Base; + typedef Impl Base; + EIGEN_GENERIC_PUBLIC_INTERFACE(Block) + EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Block) + + /** Column or Row constructor + */ + inline Block(XprType& xpr, Index i) : Impl(xpr,i) + { + eigen_assert( (i>=0) && ( + ((BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) && i= 0 && BlockRows >= 1 && a_startRow + BlockRows <= xpr.rows() + && a_startCol >= 0 && BlockCols >= 1 && a_startCol + BlockCols <= xpr.cols()); + } + + /** Dynamic-size constructor + */ + inline Block(XprType& xpr, + Index a_startRow, Index a_startCol, + Index blockRows, Index blockCols) + : Impl(xpr, a_startRow, a_startCol, blockRows, blockCols) + { + eigen_assert((RowsAtCompileTime==Dynamic || RowsAtCompileTime==blockRows) + && (ColsAtCompileTime==Dynamic || ColsAtCompileTime==blockCols)); + eigen_assert(a_startRow >= 0 && blockRows >= 0 && a_startRow <= xpr.rows() - blockRows + && a_startCol >= 0 && blockCols >= 0 && a_startCol <= xpr.cols() - blockCols); + } +}; + +// The generic default implementation for dense block simplu forward to the internal::BlockImpl_dense +// that must be specialized for direct and non-direct access... +template +class BlockImpl + : public internal::BlockImpl_dense +{ + typedef internal::BlockImpl_dense Impl; + typedef typename XprType::Index Index; + public: + typedef Impl Base; + EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl) + inline BlockImpl(XprType& xpr, Index i) : Impl(xpr,i) {} + inline BlockImpl(XprType& xpr, Index a_startRow, Index a_startCol) : Impl(xpr, a_startRow, a_startCol) {} + inline BlockImpl(XprType& xpr, Index a_startRow, Index a_startCol, Index blockRows, Index blockCols) + : Impl(xpr, a_startRow, a_startCol, blockRows, blockCols) {} +}; + +namespace internal { + +/** \internal Internal implementation of dense Blocks in the general case. */ +template class BlockImpl_dense + : public internal::dense_xpr_base >::type +{ + typedef Block BlockType; + public: + + typedef typename internal::dense_xpr_base::type Base; + EIGEN_DENSE_PUBLIC_INTERFACE(BlockType) + EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl_dense) + + class InnerIterator; + + /** Column or Row constructor + */ + inline BlockImpl_dense(XprType& xpr, Index i) + : m_xpr(xpr), + // It is a row if and only if BlockRows==1 and BlockCols==XprType::ColsAtCompileTime, + // and it is a column if and only if BlockRows==XprType::RowsAtCompileTime and BlockCols==1, + // all other cases are invalid. + // The case a 1x1 matrix seems ambiguous, but the result is the same anyway. + m_startRow( (BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) ? i : 0), + m_startCol( (BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) ? i : 0), + m_blockRows(BlockRows==1 ? 1 : xpr.rows()), + m_blockCols(BlockCols==1 ? 1 : xpr.cols()) + {} + + /** Fixed-size constructor + */ + inline BlockImpl_dense(XprType& xpr, Index a_startRow, Index a_startCol) + : m_xpr(xpr), m_startRow(a_startRow), m_startCol(a_startCol), + m_blockRows(BlockRows), m_blockCols(BlockCols) + {} + + /** Dynamic-size constructor + */ + inline BlockImpl_dense(XprType& xpr, + Index a_startRow, Index a_startCol, + Index blockRows, Index blockCols) + : m_xpr(xpr), m_startRow(a_startRow), m_startCol(a_startCol), + m_blockRows(blockRows), m_blockCols(blockCols) + {} + + inline Index rows() const { return m_blockRows.value(); } + inline Index cols() const { return m_blockCols.value(); } + + inline Scalar& coeffRef(Index rowId, Index colId) + { + EIGEN_STATIC_ASSERT_LVALUE(XprType) + return m_xpr.const_cast_derived() + .coeffRef(rowId + m_startRow.value(), colId + m_startCol.value()); + } + + inline const Scalar& coeffRef(Index rowId, Index colId) const + { + return m_xpr.derived() + .coeffRef(rowId + m_startRow.value(), colId + m_startCol.value()); + } + + EIGEN_STRONG_INLINE const CoeffReturnType coeff(Index rowId, Index colId) const + { + return m_xpr.coeff(rowId + m_startRow.value(), colId + m_startCol.value()); + } + + inline Scalar& coeffRef(Index index) + { + EIGEN_STATIC_ASSERT_LVALUE(XprType) + return m_xpr.const_cast_derived() + .coeffRef(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index), + m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0)); + } + + inline const Scalar& coeffRef(Index index) const + { + return m_xpr.const_cast_derived() + .coeffRef(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index), + m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0)); + } + + inline const CoeffReturnType coeff(Index index) const + { + return m_xpr + .coeff(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index), + m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0)); + } + + template + inline PacketScalar packet(Index rowId, Index colId) const + { + return m_xpr.template packet + (rowId + m_startRow.value(), colId + m_startCol.value()); + } + + template + inline void writePacket(Index rowId, Index colId, const PacketScalar& val) + { + m_xpr.const_cast_derived().template writePacket + (rowId + m_startRow.value(), colId + m_startCol.value(), val); + } + + template + inline PacketScalar packet(Index index) const + { + return m_xpr.template packet + (m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index), + m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0)); + } + + template + inline void writePacket(Index index, const PacketScalar& val) + { + m_xpr.const_cast_derived().template writePacket + (m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index), + m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0), val); + } + + #ifdef EIGEN_PARSED_BY_DOXYGEN + /** \sa MapBase::data() */ + inline const Scalar* data() const; + inline Index innerStride() const; + inline Index outerStride() const; + #endif + + const typename internal::remove_all::type& nestedExpression() const + { + return m_xpr; + } + + Index startRow() const + { + return m_startRow.value(); + } + + Index startCol() const + { + return m_startCol.value(); + } + + protected: + + const typename XprType::Nested m_xpr; + const internal::variable_if_dynamic m_startRow; + const internal::variable_if_dynamic m_startCol; + const internal::variable_if_dynamic m_blockRows; + const internal::variable_if_dynamic m_blockCols; +}; + +/** \internal Internal implementation of dense Blocks in the direct access case.*/ +template +class BlockImpl_dense + : public MapBase > +{ + typedef Block BlockType; + public: + + typedef MapBase Base; + EIGEN_DENSE_PUBLIC_INTERFACE(BlockType) + EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl_dense) + + /** Column or Row constructor + */ + inline BlockImpl_dense(XprType& xpr, Index i) + : Base(internal::const_cast_ptr(&xpr.coeffRef( + (BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) ? i : 0, + (BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) ? i : 0)), + BlockRows==1 ? 1 : xpr.rows(), + BlockCols==1 ? 1 : xpr.cols()), + m_xpr(xpr) + { + init(); + } + + /** Fixed-size constructor + */ + inline BlockImpl_dense(XprType& xpr, Index startRow, Index startCol) + : Base(internal::const_cast_ptr(&xpr.coeffRef(startRow,startCol))), m_xpr(xpr) + { + init(); + } + + /** Dynamic-size constructor + */ + inline BlockImpl_dense(XprType& xpr, + Index startRow, Index startCol, + Index blockRows, Index blockCols) + : Base(internal::const_cast_ptr(&xpr.coeffRef(startRow,startCol)), blockRows, blockCols), + m_xpr(xpr) + { + init(); + } + + const typename internal::remove_all::type& nestedExpression() const + { + return m_xpr; + } + + /** \sa MapBase::innerStride() */ + inline Index innerStride() const + { + return internal::traits::HasSameStorageOrderAsXprType + ? m_xpr.innerStride() + : m_xpr.outerStride(); + } + + /** \sa MapBase::outerStride() */ + inline Index outerStride() const + { + return m_outerStride; + } + + #ifndef __SUNPRO_CC + // FIXME sunstudio is not friendly with the above friend... + // META-FIXME there is no 'friend' keyword around here. Is this obsolete? + protected: + #endif + + #ifndef EIGEN_PARSED_BY_DOXYGEN + /** \internal used by allowAligned() */ + inline BlockImpl_dense(XprType& xpr, const Scalar* data, Index blockRows, Index blockCols) + : Base(data, blockRows, blockCols), m_xpr(xpr) + { + init(); + } + #endif + + protected: + void init() + { + m_outerStride = internal::traits::HasSameStorageOrderAsXprType + ? m_xpr.outerStride() + : m_xpr.innerStride(); + } + + typename XprType::Nested m_xpr; + Index m_outerStride; +}; + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_BLOCK_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/BooleanRedux.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/BooleanRedux.h new file mode 100644 index 00000000..be9f48a8 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/BooleanRedux.h @@ -0,0 +1,154 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_ALLANDANY_H +#define EIGEN_ALLANDANY_H + +namespace Eigen { + +namespace internal { + +template +struct all_unroller +{ + enum { + col = (UnrollCount-1) / Derived::RowsAtCompileTime, + row = (UnrollCount-1) % Derived::RowsAtCompileTime + }; + + static inline bool run(const Derived &mat) + { + return all_unroller::run(mat) && mat.coeff(row, col); + } +}; + +template +struct all_unroller +{ + static inline bool run(const Derived &/*mat*/) { return true; } +}; + +template +struct all_unroller +{ + static inline bool run(const Derived &) { return false; } +}; + +template +struct any_unroller +{ + enum { + col = (UnrollCount-1) / Derived::RowsAtCompileTime, + row = (UnrollCount-1) % Derived::RowsAtCompileTime + }; + + static inline bool run(const Derived &mat) + { + return any_unroller::run(mat) || mat.coeff(row, col); + } +}; + +template +struct any_unroller +{ + static inline bool run(const Derived & /*mat*/) { return false; } +}; + +template +struct any_unroller +{ + static inline bool run(const Derived &) { return false; } +}; + +} // end namespace internal + +/** \returns true if all coefficients are true + * + * Example: \include MatrixBase_all.cpp + * Output: \verbinclude MatrixBase_all.out + * + * \sa any(), Cwise::operator<() + */ +template +inline bool DenseBase::all() const +{ + enum { + unroll = SizeAtCompileTime != Dynamic + && CoeffReadCost != Dynamic + && NumTraits::AddCost != Dynamic + && SizeAtCompileTime * (CoeffReadCost + NumTraits::AddCost) <= EIGEN_UNROLLING_LIMIT + }; + if(unroll) + return internal::all_unroller::run(derived()); + else + { + for(Index j = 0; j < cols(); ++j) + for(Index i = 0; i < rows(); ++i) + if (!coeff(i, j)) return false; + return true; + } +} + +/** \returns true if at least one coefficient is true + * + * \sa all() + */ +template +inline bool DenseBase::any() const +{ + enum { + unroll = SizeAtCompileTime != Dynamic + && CoeffReadCost != Dynamic + && NumTraits::AddCost != Dynamic + && SizeAtCompileTime * (CoeffReadCost + NumTraits::AddCost) <= EIGEN_UNROLLING_LIMIT + }; + if(unroll) + return internal::any_unroller::run(derived()); + else + { + for(Index j = 0; j < cols(); ++j) + for(Index i = 0; i < rows(); ++i) + if (coeff(i, j)) return true; + return false; + } +} + +/** \returns the number of coefficients which evaluate to true + * + * \sa all(), any() + */ +template +inline typename DenseBase::Index DenseBase::count() const +{ + return derived().template cast().template cast().sum(); +} + +/** \returns true is \c *this contains at least one Not A Number (NaN). + * + * \sa allFinite() + */ +template +inline bool DenseBase::hasNaN() const +{ + return !((derived().array()==derived().array()).all()); +} + +/** \returns true if \c *this contains only finite numbers, i.e., no NaN and no +/-INF values. + * + * \sa hasNaN() + */ +template +inline bool DenseBase::allFinite() const +{ + return !((derived()-derived()).hasNaN()); +} + +} // end namespace Eigen + +#endif // EIGEN_ALLANDANY_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/CommaInitializer.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/CommaInitializer.h new file mode 100644 index 00000000..a036d8c3 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/CommaInitializer.h @@ -0,0 +1,154 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008 Gael Guennebaud +// Copyright (C) 2006-2008 Benoit Jacob +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_COMMAINITIALIZER_H +#define EIGEN_COMMAINITIALIZER_H + +namespace Eigen { + +/** \class CommaInitializer + * \ingroup Core_Module + * + * \brief Helper class used by the comma initializer operator + * + * This class is internally used to implement the comma initializer feature. It is + * the return type of MatrixBase::operator<<, and most of the time this is the only + * way it is used. + * + * \sa \ref MatrixBaseCommaInitRef "MatrixBase::operator<<", CommaInitializer::finished() + */ +template +struct CommaInitializer +{ + typedef typename XprType::Scalar Scalar; + typedef typename XprType::Index Index; + + inline CommaInitializer(XprType& xpr, const Scalar& s) + : m_xpr(xpr), m_row(0), m_col(1), m_currentBlockRows(1) + { + m_xpr.coeffRef(0,0) = s; + } + + template + inline CommaInitializer(XprType& xpr, const DenseBase& other) + : m_xpr(xpr), m_row(0), m_col(other.cols()), m_currentBlockRows(other.rows()) + { + m_xpr.block(0, 0, other.rows(), other.cols()) = other; + } + + /* Copy/Move constructor which transfers ownership. This is crucial in + * absence of return value optimization to avoid assertions during destruction. */ + // FIXME in C++11 mode this could be replaced by a proper RValue constructor + inline CommaInitializer(const CommaInitializer& o) + : m_xpr(o.m_xpr), m_row(o.m_row), m_col(o.m_col), m_currentBlockRows(o.m_currentBlockRows) { + // Mark original object as finished. In absence of R-value references we need to const_cast: + const_cast(o).m_row = m_xpr.rows(); + const_cast(o).m_col = m_xpr.cols(); + const_cast(o).m_currentBlockRows = 0; + } + + /* inserts a scalar value in the target matrix */ + CommaInitializer& operator,(const Scalar& s) + { + if (m_col==m_xpr.cols()) + { + m_row+=m_currentBlockRows; + m_col = 0; + m_currentBlockRows = 1; + eigen_assert(m_row + CommaInitializer& operator,(const DenseBase& other) + { + if(other.cols()==0 || other.rows()==0) + return *this; + if (m_col==m_xpr.cols()) + { + m_row+=m_currentBlockRows; + m_col = 0; + m_currentBlockRows = other.rows(); + eigen_assert(m_row+m_currentBlockRows<=m_xpr.rows() + && "Too many rows passed to comma initializer (operator<<)"); + } + eigen_assert(m_col + (m_row, m_col) = other; + else + m_xpr.block(m_row, m_col, other.rows(), other.cols()) = other; + m_col += other.cols(); + return *this; + } + + inline ~CommaInitializer() + { + eigen_assert((m_row+m_currentBlockRows) == m_xpr.rows() + && m_col == m_xpr.cols() + && "Too few coefficients passed to comma initializer (operator<<)"); + } + + /** \returns the built matrix once all its coefficients have been set. + * Calling finished is 100% optional. Its purpose is to write expressions + * like this: + * \code + * quaternion.fromRotationMatrix((Matrix3f() << axis0, axis1, axis2).finished()); + * \endcode + */ + inline XprType& finished() { return m_xpr; } + + XprType& m_xpr; // target expression + Index m_row; // current row id + Index m_col; // current col id + Index m_currentBlockRows; // current block height +}; + +/** \anchor MatrixBaseCommaInitRef + * Convenient operator to set the coefficients of a matrix. + * + * The coefficients must be provided in a row major order and exactly match + * the size of the matrix. Otherwise an assertion is raised. + * + * Example: \include MatrixBase_set.cpp + * Output: \verbinclude MatrixBase_set.out + * + * \note According the c++ standard, the argument expressions of this comma initializer are evaluated in arbitrary order. + * + * \sa CommaInitializer::finished(), class CommaInitializer + */ +template +inline CommaInitializer DenseBase::operator<< (const Scalar& s) +{ + return CommaInitializer(*static_cast(this), s); +} + +/** \sa operator<<(const Scalar&) */ +template +template +inline CommaInitializer +DenseBase::operator<<(const DenseBase& other) +{ + return CommaInitializer(*static_cast(this), other); +} + +} // end namespace Eigen + +#endif // EIGEN_COMMAINITIALIZER_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/CoreIterators.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/CoreIterators.h new file mode 100644 index 00000000..6da4683d --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/CoreIterators.h @@ -0,0 +1,61 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008-2010 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_COREITERATORS_H +#define EIGEN_COREITERATORS_H + +namespace Eigen { + +/* This file contains the respective InnerIterator definition of the expressions defined in Eigen/Core + */ + +/** \ingroup SparseCore_Module + * \class InnerIterator + * \brief An InnerIterator allows to loop over the element of a sparse (or dense) matrix or expression + * + * todo + */ + +// generic version for dense matrix and expressions +template class DenseBase::InnerIterator +{ + protected: + typedef typename Derived::Scalar Scalar; + typedef typename Derived::Index Index; + + enum { IsRowMajor = (Derived::Flags&RowMajorBit)==RowMajorBit }; + public: + EIGEN_STRONG_INLINE InnerIterator(const Derived& expr, Index outer) + : m_expression(expr), m_inner(0), m_outer(outer), m_end(expr.innerSize()) + {} + + EIGEN_STRONG_INLINE Scalar value() const + { + return (IsRowMajor) ? m_expression.coeff(m_outer, m_inner) + : m_expression.coeff(m_inner, m_outer); + } + + EIGEN_STRONG_INLINE InnerIterator& operator++() { m_inner++; return *this; } + + EIGEN_STRONG_INLINE Index index() const { return m_inner; } + inline Index row() const { return IsRowMajor ? m_outer : index(); } + inline Index col() const { return IsRowMajor ? index() : m_outer; } + + EIGEN_STRONG_INLINE operator bool() const { return m_inner < m_end && m_inner>=0; } + + protected: + const Derived& m_expression; + Index m_inner; + const Index m_outer; + const Index m_end; +}; + +} // end namespace Eigen + +#endif // EIGEN_COREITERATORS_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/CwiseBinaryOp.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/CwiseBinaryOp.h new file mode 100644 index 00000000..519a866e --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/CwiseBinaryOp.h @@ -0,0 +1,230 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008-2009 Gael Guennebaud +// Copyright (C) 2006-2008 Benoit Jacob +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_CWISE_BINARY_OP_H +#define EIGEN_CWISE_BINARY_OP_H + +namespace Eigen { + +/** \class CwiseBinaryOp + * \ingroup Core_Module + * + * \brief Generic expression where a coefficient-wise binary operator is applied to two expressions + * + * \param BinaryOp template functor implementing the operator + * \param Lhs the type of the left-hand side + * \param Rhs the type of the right-hand side + * + * This class represents an expression where a coefficient-wise binary operator is applied to two expressions. + * It is the return type of binary operators, by which we mean only those binary operators where + * both the left-hand side and the right-hand side are Eigen expressions. + * For example, the return type of matrix1+matrix2 is a CwiseBinaryOp. + * + * Most of the time, this is the only way that it is used, so you typically don't have to name + * CwiseBinaryOp types explicitly. + * + * \sa MatrixBase::binaryExpr(const MatrixBase &,const CustomBinaryOp &) const, class CwiseUnaryOp, class CwiseNullaryOp + */ + +namespace internal { +template +struct traits > +{ + // we must not inherit from traits since it has + // the potential to cause problems with MSVC + typedef typename remove_all::type Ancestor; + typedef typename traits::XprKind XprKind; + enum { + RowsAtCompileTime = traits::RowsAtCompileTime, + ColsAtCompileTime = traits::ColsAtCompileTime, + MaxRowsAtCompileTime = traits::MaxRowsAtCompileTime, + MaxColsAtCompileTime = traits::MaxColsAtCompileTime + }; + + // even though we require Lhs and Rhs to have the same scalar type (see CwiseBinaryOp constructor), + // we still want to handle the case when the result type is different. + typedef typename result_of< + BinaryOp( + typename Lhs::Scalar, + typename Rhs::Scalar + ) + >::type Scalar; + typedef typename promote_storage_type::StorageKind, + typename traits::StorageKind>::ret StorageKind; + typedef typename promote_index_type::Index, + typename traits::Index>::type Index; + typedef typename Lhs::Nested LhsNested; + typedef typename Rhs::Nested RhsNested; + typedef typename remove_reference::type _LhsNested; + typedef typename remove_reference::type _RhsNested; + enum { + LhsCoeffReadCost = _LhsNested::CoeffReadCost, + RhsCoeffReadCost = _RhsNested::CoeffReadCost, + LhsFlags = _LhsNested::Flags, + RhsFlags = _RhsNested::Flags, + SameType = is_same::value, + StorageOrdersAgree = (int(Lhs::Flags)&RowMajorBit)==(int(Rhs::Flags)&RowMajorBit), + Flags0 = (int(LhsFlags) | int(RhsFlags)) & ( + HereditaryBits + | (int(LhsFlags) & int(RhsFlags) & + ( AlignedBit + | (StorageOrdersAgree ? LinearAccessBit : 0) + | (functor_traits::PacketAccess && StorageOrdersAgree && SameType ? PacketAccessBit : 0) + ) + ) + ), + Flags = (Flags0 & ~RowMajorBit) | (LhsFlags & RowMajorBit), + Cost0 = EIGEN_ADD_COST(LhsCoeffReadCost,RhsCoeffReadCost), + CoeffReadCost = EIGEN_ADD_COST(Cost0,functor_traits::Cost) + }; +}; +} // end namespace internal + +// we require Lhs and Rhs to have the same scalar type. Currently there is no example of a binary functor +// that would take two operands of different types. If there were such an example, then this check should be +// moved to the BinaryOp functors, on a per-case basis. This would however require a change in the BinaryOp functors, as +// currently they take only one typename Scalar template parameter. +// It is tempting to always allow mixing different types but remember that this is often impossible in the vectorized paths. +// So allowing mixing different types gives very unexpected errors when enabling vectorization, when the user tries to +// add together a float matrix and a double matrix. +#define EIGEN_CHECK_BINARY_COMPATIBILIY(BINOP,LHS,RHS) \ + EIGEN_STATIC_ASSERT((internal::functor_is_product_like::ret \ + ? int(internal::scalar_product_traits::Defined) \ + : int(internal::is_same::value)), \ + YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) + +template +class CwiseBinaryOpImpl; + +template +class CwiseBinaryOp : internal::no_assignment_operator, + public CwiseBinaryOpImpl< + BinaryOp, Lhs, Rhs, + typename internal::promote_storage_type::StorageKind, + typename internal::traits::StorageKind>::ret> +{ + public: + + typedef typename CwiseBinaryOpImpl< + BinaryOp, Lhs, Rhs, + typename internal::promote_storage_type::StorageKind, + typename internal::traits::StorageKind>::ret>::Base Base; + EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseBinaryOp) + + typedef typename internal::nested::type LhsNested; + typedef typename internal::nested::type RhsNested; + typedef typename internal::remove_reference::type _LhsNested; + typedef typename internal::remove_reference::type _RhsNested; + + EIGEN_STRONG_INLINE CwiseBinaryOp(const Lhs& aLhs, const Rhs& aRhs, const BinaryOp& func = BinaryOp()) + : m_lhs(aLhs), m_rhs(aRhs), m_functor(func) + { + EIGEN_CHECK_BINARY_COMPATIBILIY(BinaryOp,typename Lhs::Scalar,typename Rhs::Scalar); + // require the sizes to match + EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Lhs, Rhs) + eigen_assert(aLhs.rows() == aRhs.rows() && aLhs.cols() == aRhs.cols()); + } + + EIGEN_STRONG_INLINE Index rows() const { + // return the fixed size type if available to enable compile time optimizations + if (internal::traits::type>::RowsAtCompileTime==Dynamic) + return m_rhs.rows(); + else + return m_lhs.rows(); + } + EIGEN_STRONG_INLINE Index cols() const { + // return the fixed size type if available to enable compile time optimizations + if (internal::traits::type>::ColsAtCompileTime==Dynamic) + return m_rhs.cols(); + else + return m_lhs.cols(); + } + + /** \returns the left hand side nested expression */ + const _LhsNested& lhs() const { return m_lhs; } + /** \returns the right hand side nested expression */ + const _RhsNested& rhs() const { return m_rhs; } + /** \returns the functor representing the binary operation */ + const BinaryOp& functor() const { return m_functor; } + + protected: + LhsNested m_lhs; + RhsNested m_rhs; + const BinaryOp m_functor; +}; + +template +class CwiseBinaryOpImpl + : public internal::dense_xpr_base >::type +{ + typedef CwiseBinaryOp Derived; + public: + + typedef typename internal::dense_xpr_base >::type Base; + EIGEN_DENSE_PUBLIC_INTERFACE( Derived ) + + EIGEN_STRONG_INLINE const Scalar coeff(Index rowId, Index colId) const + { + return derived().functor()(derived().lhs().coeff(rowId, colId), + derived().rhs().coeff(rowId, colId)); + } + + template + EIGEN_STRONG_INLINE PacketScalar packet(Index rowId, Index colId) const + { + return derived().functor().packetOp(derived().lhs().template packet(rowId, colId), + derived().rhs().template packet(rowId, colId)); + } + + EIGEN_STRONG_INLINE const Scalar coeff(Index index) const + { + return derived().functor()(derived().lhs().coeff(index), + derived().rhs().coeff(index)); + } + + template + EIGEN_STRONG_INLINE PacketScalar packet(Index index) const + { + return derived().functor().packetOp(derived().lhs().template packet(index), + derived().rhs().template packet(index)); + } +}; + +/** replaces \c *this by \c *this - \a other. + * + * \returns a reference to \c *this + */ +template +template +EIGEN_STRONG_INLINE Derived & +MatrixBase::operator-=(const MatrixBase &other) +{ + SelfCwiseBinaryOp, Derived, OtherDerived> tmp(derived()); + tmp = other.derived(); + return derived(); +} + +/** replaces \c *this by \c *this + \a other. + * + * \returns a reference to \c *this + */ +template +template +EIGEN_STRONG_INLINE Derived & +MatrixBase::operator+=(const MatrixBase& other) +{ + SelfCwiseBinaryOp, Derived, OtherDerived> tmp(derived()); + tmp = other.derived(); + return derived(); +} + +} // end namespace Eigen + +#endif // EIGEN_CWISE_BINARY_OP_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/CwiseNullaryOp.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/CwiseNullaryOp.h new file mode 100644 index 00000000..a93bab2d --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/CwiseNullaryOp.h @@ -0,0 +1,864 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008-2010 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_CWISE_NULLARY_OP_H +#define EIGEN_CWISE_NULLARY_OP_H + +namespace Eigen { + +/** \class CwiseNullaryOp + * \ingroup Core_Module + * + * \brief Generic expression of a matrix where all coefficients are defined by a functor + * + * \param NullaryOp template functor implementing the operator + * \param PlainObjectType the underlying plain matrix/array type + * + * This class represents an expression of a generic nullary operator. + * It is the return type of the Ones(), Zero(), Constant(), Identity() and Random() methods, + * and most of the time this is the only way it is used. + * + * However, if you want to write a function returning such an expression, you + * will need to use this class. + * + * \sa class CwiseUnaryOp, class CwiseBinaryOp, DenseBase::NullaryExpr() + */ + +namespace internal { +template +struct traits > : traits +{ + enum { + Flags = (traits::Flags + & ( HereditaryBits + | (functor_has_linear_access::ret ? LinearAccessBit : 0) + | (functor_traits::PacketAccess ? PacketAccessBit : 0))) + | (functor_traits::IsRepeatable ? 0 : EvalBeforeNestingBit), + CoeffReadCost = functor_traits::Cost + }; +}; +} + +template +class CwiseNullaryOp : internal::no_assignment_operator, + public internal::dense_xpr_base< CwiseNullaryOp >::type +{ + public: + + typedef typename internal::dense_xpr_base::type Base; + EIGEN_DENSE_PUBLIC_INTERFACE(CwiseNullaryOp) + + CwiseNullaryOp(Index nbRows, Index nbCols, const NullaryOp& func = NullaryOp()) + : m_rows(nbRows), m_cols(nbCols), m_functor(func) + { + eigen_assert(nbRows >= 0 + && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == nbRows) + && nbCols >= 0 + && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == nbCols)); + } + + EIGEN_STRONG_INLINE Index rows() const { return m_rows.value(); } + EIGEN_STRONG_INLINE Index cols() const { return m_cols.value(); } + + EIGEN_STRONG_INLINE const Scalar coeff(Index rowId, Index colId) const + { + return m_functor(rowId, colId); + } + + template + EIGEN_STRONG_INLINE PacketScalar packet(Index rowId, Index colId) const + { + return m_functor.packetOp(rowId, colId); + } + + EIGEN_STRONG_INLINE const Scalar coeff(Index index) const + { + return m_functor(index); + } + + template + EIGEN_STRONG_INLINE PacketScalar packet(Index index) const + { + return m_functor.packetOp(index); + } + + /** \returns the functor representing the nullary operation */ + const NullaryOp& functor() const { return m_functor; } + + protected: + const internal::variable_if_dynamic m_rows; + const internal::variable_if_dynamic m_cols; + const NullaryOp m_functor; +}; + + +/** \returns an expression of a matrix defined by a custom functor \a func + * + * The parameters \a rows and \a cols are the number of rows and of columns of + * the returned matrix. Must be compatible with this MatrixBase type. + * + * This variant is meant to be used for dynamic-size matrix types. For fixed-size types, + * it is redundant to pass \a rows and \a cols as arguments, so Zero() should be used + * instead. + * + * The template parameter \a CustomNullaryOp is the type of the functor. + * + * \sa class CwiseNullaryOp + */ +template +template +EIGEN_STRONG_INLINE const CwiseNullaryOp +DenseBase::NullaryExpr(Index rows, Index cols, const CustomNullaryOp& func) +{ + return CwiseNullaryOp(rows, cols, func); +} + +/** \returns an expression of a matrix defined by a custom functor \a func + * + * The parameter \a size is the size of the returned vector. + * Must be compatible with this MatrixBase type. + * + * \only_for_vectors + * + * This variant is meant to be used for dynamic-size vector types. For fixed-size types, + * it is redundant to pass \a size as argument, so Zero() should be used + * instead. + * + * The template parameter \a CustomNullaryOp is the type of the functor. + * + * \sa class CwiseNullaryOp + */ +template +template +EIGEN_STRONG_INLINE const CwiseNullaryOp +DenseBase::NullaryExpr(Index size, const CustomNullaryOp& func) +{ + EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) + if(RowsAtCompileTime == 1) return CwiseNullaryOp(1, size, func); + else return CwiseNullaryOp(size, 1, func); +} + +/** \returns an expression of a matrix defined by a custom functor \a func + * + * This variant is only for fixed-size DenseBase types. For dynamic-size types, you + * need to use the variants taking size arguments. + * + * The template parameter \a CustomNullaryOp is the type of the functor. + * + * \sa class CwiseNullaryOp + */ +template +template +EIGEN_STRONG_INLINE const CwiseNullaryOp +DenseBase::NullaryExpr(const CustomNullaryOp& func) +{ + return CwiseNullaryOp(RowsAtCompileTime, ColsAtCompileTime, func); +} + +/** \returns an expression of a constant matrix of value \a value + * + * The parameters \a nbRows and \a nbCols are the number of rows and of columns of + * the returned matrix. Must be compatible with this DenseBase type. + * + * This variant is meant to be used for dynamic-size matrix types. For fixed-size types, + * it is redundant to pass \a nbRows and \a nbCols as arguments, so Zero() should be used + * instead. + * + * The template parameter \a CustomNullaryOp is the type of the functor. + * + * \sa class CwiseNullaryOp + */ +template +EIGEN_STRONG_INLINE const typename DenseBase::ConstantReturnType +DenseBase::Constant(Index nbRows, Index nbCols, const Scalar& value) +{ + return DenseBase::NullaryExpr(nbRows, nbCols, internal::scalar_constant_op(value)); +} + +/** \returns an expression of a constant matrix of value \a value + * + * The parameter \a size is the size of the returned vector. + * Must be compatible with this DenseBase type. + * + * \only_for_vectors + * + * This variant is meant to be used for dynamic-size vector types. For fixed-size types, + * it is redundant to pass \a size as argument, so Zero() should be used + * instead. + * + * The template parameter \a CustomNullaryOp is the type of the functor. + * + * \sa class CwiseNullaryOp + */ +template +EIGEN_STRONG_INLINE const typename DenseBase::ConstantReturnType +DenseBase::Constant(Index size, const Scalar& value) +{ + return DenseBase::NullaryExpr(size, internal::scalar_constant_op(value)); +} + +/** \returns an expression of a constant matrix of value \a value + * + * This variant is only for fixed-size DenseBase types. For dynamic-size types, you + * need to use the variants taking size arguments. + * + * The template parameter \a CustomNullaryOp is the type of the functor. + * + * \sa class CwiseNullaryOp + */ +template +EIGEN_STRONG_INLINE const typename DenseBase::ConstantReturnType +DenseBase::Constant(const Scalar& value) +{ + EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived) + return DenseBase::NullaryExpr(RowsAtCompileTime, ColsAtCompileTime, internal::scalar_constant_op(value)); +} + +/** + * \brief Sets a linearly space vector. + * + * The function generates 'size' equally spaced values in the closed interval [low,high]. + * This particular version of LinSpaced() uses sequential access, i.e. vector access is + * assumed to be a(0), a(1), ..., a(size). This assumption allows for better vectorization + * and yields faster code than the random access version. + * + * When size is set to 1, a vector of length 1 containing 'high' is returned. + * + * \only_for_vectors + * + * Example: \include DenseBase_LinSpaced_seq.cpp + * Output: \verbinclude DenseBase_LinSpaced_seq.out + * + * \sa setLinSpaced(Index,const Scalar&,const Scalar&), LinSpaced(Index,Scalar,Scalar), CwiseNullaryOp + */ +template +EIGEN_STRONG_INLINE const typename DenseBase::SequentialLinSpacedReturnType +DenseBase::LinSpaced(Sequential_t, Index size, const Scalar& low, const Scalar& high) +{ + EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) + return DenseBase::NullaryExpr(size, internal::linspaced_op(low,high,size)); +} + +/** + * \copydoc DenseBase::LinSpaced(Sequential_t, Index, const Scalar&, const Scalar&) + * Special version for fixed size types which does not require the size parameter. + */ +template +EIGEN_STRONG_INLINE const typename DenseBase::SequentialLinSpacedReturnType +DenseBase::LinSpaced(Sequential_t, const Scalar& low, const Scalar& high) +{ + EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) + EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived) + return DenseBase::NullaryExpr(Derived::SizeAtCompileTime, internal::linspaced_op(low,high,Derived::SizeAtCompileTime)); +} + +/** + * \brief Sets a linearly space vector. + * + * The function generates 'size' equally spaced values in the closed interval [low,high]. + * When size is set to 1, a vector of length 1 containing 'high' is returned. + * + * \only_for_vectors + * + * Example: \include DenseBase_LinSpaced.cpp + * Output: \verbinclude DenseBase_LinSpaced.out + * + * \sa setLinSpaced(Index,const Scalar&,const Scalar&), LinSpaced(Sequential_t,Index,const Scalar&,const Scalar&,Index), CwiseNullaryOp + */ +template +EIGEN_STRONG_INLINE const typename DenseBase::RandomAccessLinSpacedReturnType +DenseBase::LinSpaced(Index size, const Scalar& low, const Scalar& high) +{ + EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) + return DenseBase::NullaryExpr(size, internal::linspaced_op(low,high,size)); +} + +/** + * \copydoc DenseBase::LinSpaced(Index, const Scalar&, const Scalar&) + * Special version for fixed size types which does not require the size parameter. + */ +template +EIGEN_STRONG_INLINE const typename DenseBase::RandomAccessLinSpacedReturnType +DenseBase::LinSpaced(const Scalar& low, const Scalar& high) +{ + EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) + EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived) + return DenseBase::NullaryExpr(Derived::SizeAtCompileTime, internal::linspaced_op(low,high,Derived::SizeAtCompileTime)); +} + +/** \returns true if all coefficients in this matrix are approximately equal to \a val, to within precision \a prec */ +template +bool DenseBase::isApproxToConstant +(const Scalar& val, const RealScalar& prec) const +{ + for(Index j = 0; j < cols(); ++j) + for(Index i = 0; i < rows(); ++i) + if(!internal::isApprox(this->coeff(i, j), val, prec)) + return false; + return true; +} + +/** This is just an alias for isApproxToConstant(). + * + * \returns true if all coefficients in this matrix are approximately equal to \a value, to within precision \a prec */ +template +bool DenseBase::isConstant +(const Scalar& val, const RealScalar& prec) const +{ + return isApproxToConstant(val, prec); +} + +/** Alias for setConstant(): sets all coefficients in this expression to \a val. + * + * \sa setConstant(), Constant(), class CwiseNullaryOp + */ +template +EIGEN_STRONG_INLINE void DenseBase::fill(const Scalar& val) +{ + setConstant(val); +} + +/** Sets all coefficients in this expression to \a value. + * + * \sa fill(), setConstant(Index,const Scalar&), setConstant(Index,Index,const Scalar&), setZero(), setOnes(), Constant(), class CwiseNullaryOp, setZero(), setOnes() + */ +template +EIGEN_STRONG_INLINE Derived& DenseBase::setConstant(const Scalar& val) +{ + return derived() = Constant(rows(), cols(), val); +} + +/** Resizes to the given \a size, and sets all coefficients in this expression to the given \a value. + * + * \only_for_vectors + * + * Example: \include Matrix_setConstant_int.cpp + * Output: \verbinclude Matrix_setConstant_int.out + * + * \sa MatrixBase::setConstant(const Scalar&), setConstant(Index,Index,const Scalar&), class CwiseNullaryOp, MatrixBase::Constant(const Scalar&) + */ +template +EIGEN_STRONG_INLINE Derived& +PlainObjectBase::setConstant(Index size, const Scalar& val) +{ + resize(size); + return setConstant(val); +} + +/** Resizes to the given size, and sets all coefficients in this expression to the given \a value. + * + * \param nbRows the new number of rows + * \param nbCols the new number of columns + * \param val the value to which all coefficients are set + * + * Example: \include Matrix_setConstant_int_int.cpp + * Output: \verbinclude Matrix_setConstant_int_int.out + * + * \sa MatrixBase::setConstant(const Scalar&), setConstant(Index,const Scalar&), class CwiseNullaryOp, MatrixBase::Constant(const Scalar&) + */ +template +EIGEN_STRONG_INLINE Derived& +PlainObjectBase::setConstant(Index nbRows, Index nbCols, const Scalar& val) +{ + resize(nbRows, nbCols); + return setConstant(val); +} + +/** + * \brief Sets a linearly space vector. + * + * The function generates 'size' equally spaced values in the closed interval [low,high]. + * When size is set to 1, a vector of length 1 containing 'high' is returned. + * + * \only_for_vectors + * + * Example: \include DenseBase_setLinSpaced.cpp + * Output: \verbinclude DenseBase_setLinSpaced.out + * + * \sa CwiseNullaryOp + */ +template +EIGEN_STRONG_INLINE Derived& DenseBase::setLinSpaced(Index newSize, const Scalar& low, const Scalar& high) +{ + EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) + return derived() = Derived::NullaryExpr(newSize, internal::linspaced_op(low,high,newSize)); +} + +/** + * \brief Sets a linearly space vector. + * + * The function fill *this with equally spaced values in the closed interval [low,high]. + * When size is set to 1, a vector of length 1 containing 'high' is returned. + * + * \only_for_vectors + * + * \sa setLinSpaced(Index, const Scalar&, const Scalar&), CwiseNullaryOp + */ +template +EIGEN_STRONG_INLINE Derived& DenseBase::setLinSpaced(const Scalar& low, const Scalar& high) +{ + EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) + return setLinSpaced(size(), low, high); +} + +// zero: + +/** \returns an expression of a zero matrix. + * + * The parameters \a rows and \a cols are the number of rows and of columns of + * the returned matrix. Must be compatible with this MatrixBase type. + * + * This variant is meant to be used for dynamic-size matrix types. For fixed-size types, + * it is redundant to pass \a rows and \a cols as arguments, so Zero() should be used + * instead. + * + * Example: \include MatrixBase_zero_int_int.cpp + * Output: \verbinclude MatrixBase_zero_int_int.out + * + * \sa Zero(), Zero(Index) + */ +template +EIGEN_STRONG_INLINE const typename DenseBase::ConstantReturnType +DenseBase::Zero(Index nbRows, Index nbCols) +{ + return Constant(nbRows, nbCols, Scalar(0)); +} + +/** \returns an expression of a zero vector. + * + * The parameter \a size is the size of the returned vector. + * Must be compatible with this MatrixBase type. + * + * \only_for_vectors + * + * This variant is meant to be used for dynamic-size vector types. For fixed-size types, + * it is redundant to pass \a size as argument, so Zero() should be used + * instead. + * + * Example: \include MatrixBase_zero_int.cpp + * Output: \verbinclude MatrixBase_zero_int.out + * + * \sa Zero(), Zero(Index,Index) + */ +template +EIGEN_STRONG_INLINE const typename DenseBase::ConstantReturnType +DenseBase::Zero(Index size) +{ + return Constant(size, Scalar(0)); +} + +/** \returns an expression of a fixed-size zero matrix or vector. + * + * This variant is only for fixed-size MatrixBase types. For dynamic-size types, you + * need to use the variants taking size arguments. + * + * Example: \include MatrixBase_zero.cpp + * Output: \verbinclude MatrixBase_zero.out + * + * \sa Zero(Index), Zero(Index,Index) + */ +template +EIGEN_STRONG_INLINE const typename DenseBase::ConstantReturnType +DenseBase::Zero() +{ + return Constant(Scalar(0)); +} + +/** \returns true if *this is approximately equal to the zero matrix, + * within the precision given by \a prec. + * + * Example: \include MatrixBase_isZero.cpp + * Output: \verbinclude MatrixBase_isZero.out + * + * \sa class CwiseNullaryOp, Zero() + */ +template +bool DenseBase::isZero(const RealScalar& prec) const +{ + for(Index j = 0; j < cols(); ++j) + for(Index i = 0; i < rows(); ++i) + if(!internal::isMuchSmallerThan(this->coeff(i, j), static_cast(1), prec)) + return false; + return true; +} + +/** Sets all coefficients in this expression to zero. + * + * Example: \include MatrixBase_setZero.cpp + * Output: \verbinclude MatrixBase_setZero.out + * + * \sa class CwiseNullaryOp, Zero() + */ +template +EIGEN_STRONG_INLINE Derived& DenseBase::setZero() +{ + return setConstant(Scalar(0)); +} + +/** Resizes to the given \a size, and sets all coefficients in this expression to zero. + * + * \only_for_vectors + * + * Example: \include Matrix_setZero_int.cpp + * Output: \verbinclude Matrix_setZero_int.out + * + * \sa DenseBase::setZero(), setZero(Index,Index), class CwiseNullaryOp, DenseBase::Zero() + */ +template +EIGEN_STRONG_INLINE Derived& +PlainObjectBase::setZero(Index newSize) +{ + resize(newSize); + return setConstant(Scalar(0)); +} + +/** Resizes to the given size, and sets all coefficients in this expression to zero. + * + * \param nbRows the new number of rows + * \param nbCols the new number of columns + * + * Example: \include Matrix_setZero_int_int.cpp + * Output: \verbinclude Matrix_setZero_int_int.out + * + * \sa DenseBase::setZero(), setZero(Index), class CwiseNullaryOp, DenseBase::Zero() + */ +template +EIGEN_STRONG_INLINE Derived& +PlainObjectBase::setZero(Index nbRows, Index nbCols) +{ + resize(nbRows, nbCols); + return setConstant(Scalar(0)); +} + +// ones: + +/** \returns an expression of a matrix where all coefficients equal one. + * + * The parameters \a nbRows and \a nbCols are the number of rows and of columns of + * the returned matrix. Must be compatible with this MatrixBase type. + * + * This variant is meant to be used for dynamic-size matrix types. For fixed-size types, + * it is redundant to pass \a rows and \a cols as arguments, so Ones() should be used + * instead. + * + * Example: \include MatrixBase_ones_int_int.cpp + * Output: \verbinclude MatrixBase_ones_int_int.out + * + * \sa Ones(), Ones(Index), isOnes(), class Ones + */ +template +EIGEN_STRONG_INLINE const typename DenseBase::ConstantReturnType +DenseBase::Ones(Index nbRows, Index nbCols) +{ + return Constant(nbRows, nbCols, Scalar(1)); +} + +/** \returns an expression of a vector where all coefficients equal one. + * + * The parameter \a newSize is the size of the returned vector. + * Must be compatible with this MatrixBase type. + * + * \only_for_vectors + * + * This variant is meant to be used for dynamic-size vector types. For fixed-size types, + * it is redundant to pass \a size as argument, so Ones() should be used + * instead. + * + * Example: \include MatrixBase_ones_int.cpp + * Output: \verbinclude MatrixBase_ones_int.out + * + * \sa Ones(), Ones(Index,Index), isOnes(), class Ones + */ +template +EIGEN_STRONG_INLINE const typename DenseBase::ConstantReturnType +DenseBase::Ones(Index newSize) +{ + return Constant(newSize, Scalar(1)); +} + +/** \returns an expression of a fixed-size matrix or vector where all coefficients equal one. + * + * This variant is only for fixed-size MatrixBase types. For dynamic-size types, you + * need to use the variants taking size arguments. + * + * Example: \include MatrixBase_ones.cpp + * Output: \verbinclude MatrixBase_ones.out + * + * \sa Ones(Index), Ones(Index,Index), isOnes(), class Ones + */ +template +EIGEN_STRONG_INLINE const typename DenseBase::ConstantReturnType +DenseBase::Ones() +{ + return Constant(Scalar(1)); +} + +/** \returns true if *this is approximately equal to the matrix where all coefficients + * are equal to 1, within the precision given by \a prec. + * + * Example: \include MatrixBase_isOnes.cpp + * Output: \verbinclude MatrixBase_isOnes.out + * + * \sa class CwiseNullaryOp, Ones() + */ +template +bool DenseBase::isOnes +(const RealScalar& prec) const +{ + return isApproxToConstant(Scalar(1), prec); +} + +/** Sets all coefficients in this expression to one. + * + * Example: \include MatrixBase_setOnes.cpp + * Output: \verbinclude MatrixBase_setOnes.out + * + * \sa class CwiseNullaryOp, Ones() + */ +template +EIGEN_STRONG_INLINE Derived& DenseBase::setOnes() +{ + return setConstant(Scalar(1)); +} + +/** Resizes to the given \a newSize, and sets all coefficients in this expression to one. + * + * \only_for_vectors + * + * Example: \include Matrix_setOnes_int.cpp + * Output: \verbinclude Matrix_setOnes_int.out + * + * \sa MatrixBase::setOnes(), setOnes(Index,Index), class CwiseNullaryOp, MatrixBase::Ones() + */ +template +EIGEN_STRONG_INLINE Derived& +PlainObjectBase::setOnes(Index newSize) +{ + resize(newSize); + return setConstant(Scalar(1)); +} + +/** Resizes to the given size, and sets all coefficients in this expression to one. + * + * \param nbRows the new number of rows + * \param nbCols the new number of columns + * + * Example: \include Matrix_setOnes_int_int.cpp + * Output: \verbinclude Matrix_setOnes_int_int.out + * + * \sa MatrixBase::setOnes(), setOnes(Index), class CwiseNullaryOp, MatrixBase::Ones() + */ +template +EIGEN_STRONG_INLINE Derived& +PlainObjectBase::setOnes(Index nbRows, Index nbCols) +{ + resize(nbRows, nbCols); + return setConstant(Scalar(1)); +} + +// Identity: + +/** \returns an expression of the identity matrix (not necessarily square). + * + * The parameters \a nbRows and \a nbCols are the number of rows and of columns of + * the returned matrix. Must be compatible with this MatrixBase type. + * + * This variant is meant to be used for dynamic-size matrix types. For fixed-size types, + * it is redundant to pass \a rows and \a cols as arguments, so Identity() should be used + * instead. + * + * Example: \include MatrixBase_identity_int_int.cpp + * Output: \verbinclude MatrixBase_identity_int_int.out + * + * \sa Identity(), setIdentity(), isIdentity() + */ +template +EIGEN_STRONG_INLINE const typename MatrixBase::IdentityReturnType +MatrixBase::Identity(Index nbRows, Index nbCols) +{ + return DenseBase::NullaryExpr(nbRows, nbCols, internal::scalar_identity_op()); +} + +/** \returns an expression of the identity matrix (not necessarily square). + * + * This variant is only for fixed-size MatrixBase types. For dynamic-size types, you + * need to use the variant taking size arguments. + * + * Example: \include MatrixBase_identity.cpp + * Output: \verbinclude MatrixBase_identity.out + * + * \sa Identity(Index,Index), setIdentity(), isIdentity() + */ +template +EIGEN_STRONG_INLINE const typename MatrixBase::IdentityReturnType +MatrixBase::Identity() +{ + EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived) + return MatrixBase::NullaryExpr(RowsAtCompileTime, ColsAtCompileTime, internal::scalar_identity_op()); +} + +/** \returns true if *this is approximately equal to the identity matrix + * (not necessarily square), + * within the precision given by \a prec. + * + * Example: \include MatrixBase_isIdentity.cpp + * Output: \verbinclude MatrixBase_isIdentity.out + * + * \sa class CwiseNullaryOp, Identity(), Identity(Index,Index), setIdentity() + */ +template +bool MatrixBase::isIdentity +(const RealScalar& prec) const +{ + for(Index j = 0; j < cols(); ++j) + { + for(Index i = 0; i < rows(); ++i) + { + if(i == j) + { + if(!internal::isApprox(this->coeff(i, j), static_cast(1), prec)) + return false; + } + else + { + if(!internal::isMuchSmallerThan(this->coeff(i, j), static_cast(1), prec)) + return false; + } + } + } + return true; +} + +namespace internal { + +template=16)> +struct setIdentity_impl +{ + static EIGEN_STRONG_INLINE Derived& run(Derived& m) + { + return m = Derived::Identity(m.rows(), m.cols()); + } +}; + +template +struct setIdentity_impl +{ + typedef typename Derived::Index Index; + static EIGEN_STRONG_INLINE Derived& run(Derived& m) + { + m.setZero(); + const Index size = (std::min)(m.rows(), m.cols()); + for(Index i = 0; i < size; ++i) m.coeffRef(i,i) = typename Derived::Scalar(1); + return m; + } +}; + +} // end namespace internal + +/** Writes the identity expression (not necessarily square) into *this. + * + * Example: \include MatrixBase_setIdentity.cpp + * Output: \verbinclude MatrixBase_setIdentity.out + * + * \sa class CwiseNullaryOp, Identity(), Identity(Index,Index), isIdentity() + */ +template +EIGEN_STRONG_INLINE Derived& MatrixBase::setIdentity() +{ + return internal::setIdentity_impl::run(derived()); +} + +/** \brief Resizes to the given size, and writes the identity expression (not necessarily square) into *this. + * + * \param nbRows the new number of rows + * \param nbCols the new number of columns + * + * Example: \include Matrix_setIdentity_int_int.cpp + * Output: \verbinclude Matrix_setIdentity_int_int.out + * + * \sa MatrixBase::setIdentity(), class CwiseNullaryOp, MatrixBase::Identity() + */ +template +EIGEN_STRONG_INLINE Derived& MatrixBase::setIdentity(Index nbRows, Index nbCols) +{ + derived().resize(nbRows, nbCols); + return setIdentity(); +} + +/** \returns an expression of the i-th unit (basis) vector. + * + * \only_for_vectors + * + * \sa MatrixBase::Unit(Index), MatrixBase::UnitX(), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW() + */ +template +EIGEN_STRONG_INLINE const typename MatrixBase::BasisReturnType MatrixBase::Unit(Index newSize, Index i) +{ + EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) + return BasisReturnType(SquareMatrixType::Identity(newSize,newSize), i); +} + +/** \returns an expression of the i-th unit (basis) vector. + * + * \only_for_vectors + * + * This variant is for fixed-size vector only. + * + * \sa MatrixBase::Unit(Index,Index), MatrixBase::UnitX(), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW() + */ +template +EIGEN_STRONG_INLINE const typename MatrixBase::BasisReturnType MatrixBase::Unit(Index i) +{ + EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) + return BasisReturnType(SquareMatrixType::Identity(),i); +} + +/** \returns an expression of the X axis unit vector (1{,0}^*) + * + * \only_for_vectors + * + * \sa MatrixBase::Unit(Index,Index), MatrixBase::Unit(Index), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW() + */ +template +EIGEN_STRONG_INLINE const typename MatrixBase::BasisReturnType MatrixBase::UnitX() +{ return Derived::Unit(0); } + +/** \returns an expression of the Y axis unit vector (0,1{,0}^*) + * + * \only_for_vectors + * + * \sa MatrixBase::Unit(Index,Index), MatrixBase::Unit(Index), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW() + */ +template +EIGEN_STRONG_INLINE const typename MatrixBase::BasisReturnType MatrixBase::UnitY() +{ return Derived::Unit(1); } + +/** \returns an expression of the Z axis unit vector (0,0,1{,0}^*) + * + * \only_for_vectors + * + * \sa MatrixBase::Unit(Index,Index), MatrixBase::Unit(Index), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW() + */ +template +EIGEN_STRONG_INLINE const typename MatrixBase::BasisReturnType MatrixBase::UnitZ() +{ return Derived::Unit(2); } + +/** \returns an expression of the W axis unit vector (0,0,0,1) + * + * \only_for_vectors + * + * \sa MatrixBase::Unit(Index,Index), MatrixBase::Unit(Index), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW() + */ +template +EIGEN_STRONG_INLINE const typename MatrixBase::BasisReturnType MatrixBase::UnitW() +{ return Derived::Unit(3); } + +} // end namespace Eigen + +#endif // EIGEN_CWISE_NULLARY_OP_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/CwiseUnaryOp.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/CwiseUnaryOp.h new file mode 100644 index 00000000..f7ee60e9 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/CwiseUnaryOp.h @@ -0,0 +1,126 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008-2010 Gael Guennebaud +// Copyright (C) 2006-2008 Benoit Jacob +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_CWISE_UNARY_OP_H +#define EIGEN_CWISE_UNARY_OP_H + +namespace Eigen { + +/** \class CwiseUnaryOp + * \ingroup Core_Module + * + * \brief Generic expression where a coefficient-wise unary operator is applied to an expression + * + * \param UnaryOp template functor implementing the operator + * \param XprType the type of the expression to which we are applying the unary operator + * + * This class represents an expression where a unary operator is applied to an expression. + * It is the return type of all operations taking exactly 1 input expression, regardless of the + * presence of other inputs such as scalars. For example, the operator* in the expression 3*matrix + * is considered unary, because only the right-hand side is an expression, and its + * return type is a specialization of CwiseUnaryOp. + * + * Most of the time, this is the only way that it is used, so you typically don't have to name + * CwiseUnaryOp types explicitly. + * + * \sa MatrixBase::unaryExpr(const CustomUnaryOp &) const, class CwiseBinaryOp, class CwiseNullaryOp + */ + +namespace internal { +template +struct traits > + : traits +{ + typedef typename result_of< + UnaryOp(typename XprType::Scalar) + >::type Scalar; + typedef typename XprType::Nested XprTypeNested; + typedef typename remove_reference::type _XprTypeNested; + enum { + Flags = _XprTypeNested::Flags & ( + HereditaryBits | LinearAccessBit | AlignedBit + | (functor_traits::PacketAccess ? PacketAccessBit : 0)), + CoeffReadCost = EIGEN_ADD_COST(_XprTypeNested::CoeffReadCost, functor_traits::Cost) + }; +}; +} + +template +class CwiseUnaryOpImpl; + +template +class CwiseUnaryOp : internal::no_assignment_operator, + public CwiseUnaryOpImpl::StorageKind> +{ + public: + + typedef typename CwiseUnaryOpImpl::StorageKind>::Base Base; + EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseUnaryOp) + + inline CwiseUnaryOp(const XprType& xpr, const UnaryOp& func = UnaryOp()) + : m_xpr(xpr), m_functor(func) {} + + EIGEN_STRONG_INLINE Index rows() const { return m_xpr.rows(); } + EIGEN_STRONG_INLINE Index cols() const { return m_xpr.cols(); } + + /** \returns the functor representing the unary operation */ + const UnaryOp& functor() const { return m_functor; } + + /** \returns the nested expression */ + const typename internal::remove_all::type& + nestedExpression() const { return m_xpr; } + + /** \returns the nested expression */ + typename internal::remove_all::type& + nestedExpression() { return m_xpr.const_cast_derived(); } + + protected: + typename XprType::Nested m_xpr; + const UnaryOp m_functor; +}; + +// This is the generic implementation for dense storage. +// It can be used for any expression types implementing the dense concept. +template +class CwiseUnaryOpImpl + : public internal::dense_xpr_base >::type +{ + public: + + typedef CwiseUnaryOp Derived; + typedef typename internal::dense_xpr_base >::type Base; + EIGEN_DENSE_PUBLIC_INTERFACE(Derived) + + EIGEN_STRONG_INLINE const Scalar coeff(Index rowId, Index colId) const + { + return derived().functor()(derived().nestedExpression().coeff(rowId, colId)); + } + + template + EIGEN_STRONG_INLINE PacketScalar packet(Index rowId, Index colId) const + { + return derived().functor().packetOp(derived().nestedExpression().template packet(rowId, colId)); + } + + EIGEN_STRONG_INLINE const Scalar coeff(Index index) const + { + return derived().functor()(derived().nestedExpression().coeff(index)); + } + + template + EIGEN_STRONG_INLINE PacketScalar packet(Index index) const + { + return derived().functor().packetOp(derived().nestedExpression().template packet(index)); + } +}; + +} // end namespace Eigen + +#endif // EIGEN_CWISE_UNARY_OP_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/CwiseUnaryView.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/CwiseUnaryView.h new file mode 100644 index 00000000..b2638d32 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/CwiseUnaryView.h @@ -0,0 +1,139 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2009-2010 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_CWISE_UNARY_VIEW_H +#define EIGEN_CWISE_UNARY_VIEW_H + +namespace Eigen { + +/** \class CwiseUnaryView + * \ingroup Core_Module + * + * \brief Generic lvalue expression of a coefficient-wise unary operator of a matrix or a vector + * + * \param ViewOp template functor implementing the view + * \param MatrixType the type of the matrix we are applying the unary operator + * + * This class represents a lvalue expression of a generic unary view operator of a matrix or a vector. + * It is the return type of real() and imag(), and most of the time this is the only way it is used. + * + * \sa MatrixBase::unaryViewExpr(const CustomUnaryOp &) const, class CwiseUnaryOp + */ + +namespace internal { +template +struct traits > + : traits +{ + typedef typename result_of< + ViewOp(typename traits::Scalar) + >::type Scalar; + typedef typename MatrixType::Nested MatrixTypeNested; + typedef typename remove_all::type _MatrixTypeNested; + enum { + Flags = (traits<_MatrixTypeNested>::Flags & (HereditaryBits | LvalueBit | LinearAccessBit | DirectAccessBit)), + CoeffReadCost = traits<_MatrixTypeNested>::CoeffReadCost + functor_traits::Cost, + MatrixTypeInnerStride = inner_stride_at_compile_time::ret, + // need to cast the sizeof's from size_t to int explicitly, otherwise: + // "error: no integral type can represent all of the enumerator values + InnerStrideAtCompileTime = MatrixTypeInnerStride == Dynamic + ? int(Dynamic) + : int(MatrixTypeInnerStride) * int(sizeof(typename traits::Scalar) / sizeof(Scalar)), + OuterStrideAtCompileTime = outer_stride_at_compile_time::ret == Dynamic + ? int(Dynamic) + : outer_stride_at_compile_time::ret * int(sizeof(typename traits::Scalar) / sizeof(Scalar)) + }; +}; +} + +template +class CwiseUnaryViewImpl; + +template +class CwiseUnaryView : public CwiseUnaryViewImpl::StorageKind> +{ + public: + + typedef typename CwiseUnaryViewImpl::StorageKind>::Base Base; + EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseUnaryView) + + inline CwiseUnaryView(const MatrixType& mat, const ViewOp& func = ViewOp()) + : m_matrix(mat), m_functor(func) {} + + EIGEN_INHERIT_ASSIGNMENT_OPERATORS(CwiseUnaryView) + + EIGEN_STRONG_INLINE Index rows() const { return m_matrix.rows(); } + EIGEN_STRONG_INLINE Index cols() const { return m_matrix.cols(); } + + /** \returns the functor representing unary operation */ + const ViewOp& functor() const { return m_functor; } + + /** \returns the nested expression */ + const typename internal::remove_all::type& + nestedExpression() const { return m_matrix; } + + /** \returns the nested expression */ + typename internal::remove_all::type& + nestedExpression() { return m_matrix.const_cast_derived(); } + + protected: + // FIXME changed from MatrixType::Nested because of a weird compilation error with sun CC + typename internal::nested::type m_matrix; + ViewOp m_functor; +}; + +template +class CwiseUnaryViewImpl + : public internal::dense_xpr_base< CwiseUnaryView >::type +{ + public: + + typedef CwiseUnaryView Derived; + typedef typename internal::dense_xpr_base< CwiseUnaryView >::type Base; + + EIGEN_DENSE_PUBLIC_INTERFACE(Derived) + EIGEN_INHERIT_ASSIGNMENT_OPERATORS(CwiseUnaryViewImpl) + + inline Scalar* data() { return &coeffRef(0); } + inline const Scalar* data() const { return &coeff(0); } + + inline Index innerStride() const + { + return derived().nestedExpression().innerStride() * sizeof(typename internal::traits::Scalar) / sizeof(Scalar); + } + + inline Index outerStride() const + { + return derived().nestedExpression().outerStride() * sizeof(typename internal::traits::Scalar) / sizeof(Scalar); + } + + EIGEN_STRONG_INLINE CoeffReturnType coeff(Index row, Index col) const + { + return derived().functor()(derived().nestedExpression().coeff(row, col)); + } + + EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index) const + { + return derived().functor()(derived().nestedExpression().coeff(index)); + } + + EIGEN_STRONG_INLINE Scalar& coeffRef(Index row, Index col) + { + return derived().functor()(const_cast_derived().nestedExpression().coeffRef(row, col)); + } + + EIGEN_STRONG_INLINE Scalar& coeffRef(Index index) + { + return derived().functor()(const_cast_derived().nestedExpression().coeffRef(index)); + } +}; + +} // end namespace Eigen + +#endif // EIGEN_CWISE_UNARY_VIEW_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/DenseBase.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/DenseBase.h new file mode 100644 index 00000000..4b371b07 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/DenseBase.h @@ -0,0 +1,521 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2007-2010 Benoit Jacob +// Copyright (C) 2008-2010 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_DENSEBASE_H +#define EIGEN_DENSEBASE_H + +namespace Eigen { + +namespace internal { + +// The index type defined by EIGEN_DEFAULT_DENSE_INDEX_TYPE must be a signed type. +// This dummy function simply aims at checking that at compile time. +static inline void check_DenseIndex_is_signed() { + EIGEN_STATIC_ASSERT(NumTraits::IsSigned,THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE); +} + +} // end namespace internal + +/** \class DenseBase + * \ingroup Core_Module + * + * \brief Base class for all dense matrices, vectors, and arrays + * + * This class is the base that is inherited by all dense objects (matrix, vector, arrays, + * and related expression types). The common Eigen API for dense objects is contained in this class. + * + * \tparam Derived is the derived type, e.g., a matrix type or an expression. + * + * This class can be extended with the help of the plugin mechanism described on the page + * \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_DENSEBASE_PLUGIN. + * + * \sa \ref TopicClassHierarchy + */ +template class DenseBase +#ifndef EIGEN_PARSED_BY_DOXYGEN + : public internal::special_scalar_op_base::Scalar, + typename NumTraits::Scalar>::Real, + DenseCoeffsBase > +#else + : public DenseCoeffsBase +#endif // not EIGEN_PARSED_BY_DOXYGEN +{ + public: + + class InnerIterator; + + typedef typename internal::traits::StorageKind StorageKind; + + /** \brief The type of indices + * \details To change this, \c \#define the preprocessor symbol \c EIGEN_DEFAULT_DENSE_INDEX_TYPE. + * \sa \ref TopicPreprocessorDirectives. + */ + typedef typename internal::traits::Index Index; + + typedef typename internal::traits::Scalar Scalar; + typedef typename internal::packet_traits::type PacketScalar; + typedef typename NumTraits::Real RealScalar; + typedef internal::special_scalar_op_base > Base; + + using Base::operator*; + using Base::derived; + using Base::const_cast_derived; + using Base::rows; + using Base::cols; + using Base::size; + using Base::rowIndexByOuterInner; + using Base::colIndexByOuterInner; + using Base::coeff; + using Base::coeffByOuterInner; + using Base::packet; + using Base::packetByOuterInner; + using Base::writePacket; + using Base::writePacketByOuterInner; + using Base::coeffRef; + using Base::coeffRefByOuterInner; + using Base::copyCoeff; + using Base::copyCoeffByOuterInner; + using Base::copyPacket; + using Base::copyPacketByOuterInner; + using Base::operator(); + using Base::operator[]; + using Base::x; + using Base::y; + using Base::z; + using Base::w; + using Base::stride; + using Base::innerStride; + using Base::outerStride; + using Base::rowStride; + using Base::colStride; + typedef typename Base::CoeffReturnType CoeffReturnType; + + enum { + + RowsAtCompileTime = internal::traits::RowsAtCompileTime, + /**< The number of rows at compile-time. This is just a copy of the value provided + * by the \a Derived type. If a value is not known at compile-time, + * it is set to the \a Dynamic constant. + * \sa MatrixBase::rows(), MatrixBase::cols(), ColsAtCompileTime, SizeAtCompileTime */ + + ColsAtCompileTime = internal::traits::ColsAtCompileTime, + /**< The number of columns at compile-time. This is just a copy of the value provided + * by the \a Derived type. If a value is not known at compile-time, + * it is set to the \a Dynamic constant. + * \sa MatrixBase::rows(), MatrixBase::cols(), RowsAtCompileTime, SizeAtCompileTime */ + + + SizeAtCompileTime = (internal::size_at_compile_time::RowsAtCompileTime, + internal::traits::ColsAtCompileTime>::ret), + /**< This is equal to the number of coefficients, i.e. the number of + * rows times the number of columns, or to \a Dynamic if this is not + * known at compile-time. \sa RowsAtCompileTime, ColsAtCompileTime */ + + MaxRowsAtCompileTime = internal::traits::MaxRowsAtCompileTime, + /**< This value is equal to the maximum possible number of rows that this expression + * might have. If this expression might have an arbitrarily high number of rows, + * this value is set to \a Dynamic. + * + * This value is useful to know when evaluating an expression, in order to determine + * whether it is possible to avoid doing a dynamic memory allocation. + * + * \sa RowsAtCompileTime, MaxColsAtCompileTime, MaxSizeAtCompileTime + */ + + MaxColsAtCompileTime = internal::traits::MaxColsAtCompileTime, + /**< This value is equal to the maximum possible number of columns that this expression + * might have. If this expression might have an arbitrarily high number of columns, + * this value is set to \a Dynamic. + * + * This value is useful to know when evaluating an expression, in order to determine + * whether it is possible to avoid doing a dynamic memory allocation. + * + * \sa ColsAtCompileTime, MaxRowsAtCompileTime, MaxSizeAtCompileTime + */ + + MaxSizeAtCompileTime = (internal::size_at_compile_time::MaxRowsAtCompileTime, + internal::traits::MaxColsAtCompileTime>::ret), + /**< This value is equal to the maximum possible number of coefficients that this expression + * might have. If this expression might have an arbitrarily high number of coefficients, + * this value is set to \a Dynamic. + * + * This value is useful to know when evaluating an expression, in order to determine + * whether it is possible to avoid doing a dynamic memory allocation. + * + * \sa SizeAtCompileTime, MaxRowsAtCompileTime, MaxColsAtCompileTime + */ + + IsVectorAtCompileTime = internal::traits::MaxRowsAtCompileTime == 1 + || internal::traits::MaxColsAtCompileTime == 1, + /**< This is set to true if either the number of rows or the number of + * columns is known at compile-time to be equal to 1. Indeed, in that case, + * we are dealing with a column-vector (if there is only one column) or with + * a row-vector (if there is only one row). */ + + Flags = internal::traits::Flags, + /**< This stores expression \ref flags flags which may or may not be inherited by new expressions + * constructed from this one. See the \ref flags "list of flags". + */ + + IsRowMajor = int(Flags) & RowMajorBit, /**< True if this expression has row-major storage order. */ + + InnerSizeAtCompileTime = int(IsVectorAtCompileTime) ? int(SizeAtCompileTime) + : int(IsRowMajor) ? int(ColsAtCompileTime) : int(RowsAtCompileTime), + + CoeffReadCost = internal::traits::CoeffReadCost, + /**< This is a rough measure of how expensive it is to read one coefficient from + * this expression. + */ + + InnerStrideAtCompileTime = internal::inner_stride_at_compile_time::ret, + OuterStrideAtCompileTime = internal::outer_stride_at_compile_time::ret + }; + + enum { ThisConstantIsPrivateInPlainObjectBase }; + + /** \returns the number of nonzero coefficients which is in practice the number + * of stored coefficients. */ + inline Index nonZeros() const { return size(); } + + /** \returns the outer size. + * + * \note For a vector, this returns just 1. For a matrix (non-vector), this is the major dimension + * with respect to the \ref TopicStorageOrders "storage order", i.e., the number of columns for a + * column-major matrix, and the number of rows for a row-major matrix. */ + Index outerSize() const + { + return IsVectorAtCompileTime ? 1 + : int(IsRowMajor) ? this->rows() : this->cols(); + } + + /** \returns the inner size. + * + * \note For a vector, this is just the size. For a matrix (non-vector), this is the minor dimension + * with respect to the \ref TopicStorageOrders "storage order", i.e., the number of rows for a + * column-major matrix, and the number of columns for a row-major matrix. */ + Index innerSize() const + { + return IsVectorAtCompileTime ? this->size() + : int(IsRowMajor) ? this->cols() : this->rows(); + } + + /** Only plain matrices/arrays, not expressions, may be resized; therefore the only useful resize methods are + * Matrix::resize() and Array::resize(). The present method only asserts that the new size equals the old size, and does + * nothing else. + */ + void resize(Index newSize) + { + EIGEN_ONLY_USED_FOR_DEBUG(newSize); + eigen_assert(newSize == this->size() + && "DenseBase::resize() does not actually allow to resize."); + } + /** Only plain matrices/arrays, not expressions, may be resized; therefore the only useful resize methods are + * Matrix::resize() and Array::resize(). The present method only asserts that the new size equals the old size, and does + * nothing else. + */ + void resize(Index nbRows, Index nbCols) + { + EIGEN_ONLY_USED_FOR_DEBUG(nbRows); + EIGEN_ONLY_USED_FOR_DEBUG(nbCols); + eigen_assert(nbRows == this->rows() && nbCols == this->cols() + && "DenseBase::resize() does not actually allow to resize."); + } + +#ifndef EIGEN_PARSED_BY_DOXYGEN + + /** \internal Represents a matrix with all coefficients equal to one another*/ + typedef CwiseNullaryOp,Derived> ConstantReturnType; + /** \internal Represents a vector with linearly spaced coefficients that allows sequential access only. */ + typedef CwiseNullaryOp,Derived> SequentialLinSpacedReturnType; + /** \internal Represents a vector with linearly spaced coefficients that allows random access. */ + typedef CwiseNullaryOp,Derived> RandomAccessLinSpacedReturnType; + /** \internal the return type of MatrixBase::eigenvalues() */ + typedef Matrix::Scalar>::Real, internal::traits::ColsAtCompileTime, 1> EigenvaluesReturnType; + +#endif // not EIGEN_PARSED_BY_DOXYGEN + + /** Copies \a other into *this. \returns a reference to *this. */ + template + Derived& operator=(const DenseBase& other); + + /** Special case of the template operator=, in order to prevent the compiler + * from generating a default operator= (issue hit with g++ 4.1) + */ + Derived& operator=(const DenseBase& other); + + template + Derived& operator=(const EigenBase &other); + + template + Derived& operator+=(const EigenBase &other); + + template + Derived& operator-=(const EigenBase &other); + + template + Derived& operator=(const ReturnByValue& func); + + /** \internal Copies \a other into *this without evaluating other. \returns a reference to *this. */ + template + Derived& lazyAssign(const DenseBase& other); + + /** \internal Evaluates \a other into *this. \returns a reference to *this. */ + template + Derived& lazyAssign(const ReturnByValue& other); + + CommaInitializer operator<< (const Scalar& s); + + template + const Flagged flagged() const; + + template + CommaInitializer operator<< (const DenseBase& other); + + Eigen::Transpose transpose(); + typedef typename internal::add_const >::type ConstTransposeReturnType; + ConstTransposeReturnType transpose() const; + void transposeInPlace(); +#ifndef EIGEN_NO_DEBUG + protected: + template + void checkTransposeAliasing(const OtherDerived& other) const; + public: +#endif + + + static const ConstantReturnType + Constant(Index rows, Index cols, const Scalar& value); + static const ConstantReturnType + Constant(Index size, const Scalar& value); + static const ConstantReturnType + Constant(const Scalar& value); + + static const SequentialLinSpacedReturnType + LinSpaced(Sequential_t, Index size, const Scalar& low, const Scalar& high); + static const RandomAccessLinSpacedReturnType + LinSpaced(Index size, const Scalar& low, const Scalar& high); + static const SequentialLinSpacedReturnType + LinSpaced(Sequential_t, const Scalar& low, const Scalar& high); + static const RandomAccessLinSpacedReturnType + LinSpaced(const Scalar& low, const Scalar& high); + + template + static const CwiseNullaryOp + NullaryExpr(Index rows, Index cols, const CustomNullaryOp& func); + template + static const CwiseNullaryOp + NullaryExpr(Index size, const CustomNullaryOp& func); + template + static const CwiseNullaryOp + NullaryExpr(const CustomNullaryOp& func); + + static const ConstantReturnType Zero(Index rows, Index cols); + static const ConstantReturnType Zero(Index size); + static const ConstantReturnType Zero(); + static const ConstantReturnType Ones(Index rows, Index cols); + static const ConstantReturnType Ones(Index size); + static const ConstantReturnType Ones(); + + void fill(const Scalar& value); + Derived& setConstant(const Scalar& value); + Derived& setLinSpaced(Index size, const Scalar& low, const Scalar& high); + Derived& setLinSpaced(const Scalar& low, const Scalar& high); + Derived& setZero(); + Derived& setOnes(); + Derived& setRandom(); + + template + bool isApprox(const DenseBase& other, + const RealScalar& prec = NumTraits::dummy_precision()) const; + bool isMuchSmallerThan(const RealScalar& other, + const RealScalar& prec = NumTraits::dummy_precision()) const; + template + bool isMuchSmallerThan(const DenseBase& other, + const RealScalar& prec = NumTraits::dummy_precision()) const; + + bool isApproxToConstant(const Scalar& value, const RealScalar& prec = NumTraits::dummy_precision()) const; + bool isConstant(const Scalar& value, const RealScalar& prec = NumTraits::dummy_precision()) const; + bool isZero(const RealScalar& prec = NumTraits::dummy_precision()) const; + bool isOnes(const RealScalar& prec = NumTraits::dummy_precision()) const; + + inline bool hasNaN() const; + inline bool allFinite() const; + + inline Derived& operator*=(const Scalar& other); + inline Derived& operator/=(const Scalar& other); + + typedef typename internal::add_const_on_value_type::type>::type EvalReturnType; + /** \returns the matrix or vector obtained by evaluating this expression. + * + * Notice that in the case of a plain matrix or vector (not an expression) this function just returns + * a const reference, in order to avoid a useless copy. + */ + EIGEN_STRONG_INLINE EvalReturnType eval() const + { + // Even though MSVC does not honor strong inlining when the return type + // is a dynamic matrix, we desperately need strong inlining for fixed + // size types on MSVC. + return typename internal::eval::type(derived()); + } + + /** swaps *this with the expression \a other. + * + */ + template + void swap(const DenseBase& other, + int = OtherDerived::ThisConstantIsPrivateInPlainObjectBase) + { + SwapWrapper(derived()).lazyAssign(other.derived()); + } + + /** swaps *this with the matrix or array \a other. + * + */ + template + void swap(PlainObjectBase& other) + { + SwapWrapper(derived()).lazyAssign(other.derived()); + } + + + inline const NestByValue nestByValue() const; + inline const ForceAlignedAccess forceAlignedAccess() const; + inline ForceAlignedAccess forceAlignedAccess(); + template inline const typename internal::conditional,Derived&>::type forceAlignedAccessIf() const; + template inline typename internal::conditional,Derived&>::type forceAlignedAccessIf(); + + Scalar sum() const; + Scalar mean() const; + Scalar trace() const; + + Scalar prod() const; + + typename internal::traits::Scalar minCoeff() const; + typename internal::traits::Scalar maxCoeff() const; + + template + typename internal::traits::Scalar minCoeff(IndexType* row, IndexType* col) const; + template + typename internal::traits::Scalar maxCoeff(IndexType* row, IndexType* col) const; + template + typename internal::traits::Scalar minCoeff(IndexType* index) const; + template + typename internal::traits::Scalar maxCoeff(IndexType* index) const; + + template + typename internal::result_of::Scalar)>::type + redux(const BinaryOp& func) const; + + template + void visit(Visitor& func) const; + + inline const WithFormat format(const IOFormat& fmt) const; + + /** \returns the unique coefficient of a 1x1 expression */ + CoeffReturnType value() const + { + EIGEN_STATIC_ASSERT_SIZE_1x1(Derived) + eigen_assert(this->rows() == 1 && this->cols() == 1); + return derived().coeff(0,0); + } + + bool all(void) const; + bool any(void) const; + Index count() const; + + typedef VectorwiseOp RowwiseReturnType; + typedef const VectorwiseOp ConstRowwiseReturnType; + typedef VectorwiseOp ColwiseReturnType; + typedef const VectorwiseOp ConstColwiseReturnType; + + ConstRowwiseReturnType rowwise() const; + RowwiseReturnType rowwise(); + ConstColwiseReturnType colwise() const; + ColwiseReturnType colwise(); + + static const CwiseNullaryOp,Derived> Random(Index rows, Index cols); + static const CwiseNullaryOp,Derived> Random(Index size); + static const CwiseNullaryOp,Derived> Random(); + + template + const Select + select(const DenseBase& thenMatrix, + const DenseBase& elseMatrix) const; + + template + inline const Select + select(const DenseBase& thenMatrix, const typename ThenDerived::Scalar& elseScalar) const; + + template + inline const Select + select(const typename ElseDerived::Scalar& thenScalar, const DenseBase& elseMatrix) const; + + template RealScalar lpNorm() const; + + template + inline const Replicate replicate() const; + + typedef Replicate ReplicateReturnType; + inline const ReplicateReturnType replicate(Index rowFacor,Index colFactor) const; + + typedef Reverse ReverseReturnType; + typedef const Reverse ConstReverseReturnType; + ReverseReturnType reverse(); + ConstReverseReturnType reverse() const; + void reverseInPlace(); + +#define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::DenseBase +# include "../plugins/BlockMethods.h" +# ifdef EIGEN_DENSEBASE_PLUGIN +# include EIGEN_DENSEBASE_PLUGIN +# endif +#undef EIGEN_CURRENT_STORAGE_BASE_CLASS + +#ifdef EIGEN2_SUPPORT + + Block corner(CornerType type, Index cRows, Index cCols); + const Block corner(CornerType type, Index cRows, Index cCols) const; + template + Block corner(CornerType type); + template + const Block corner(CornerType type) const; + +#endif // EIGEN2_SUPPORT + + + // disable the use of evalTo for dense objects with a nice compilation error + template inline void evalTo(Dest& ) const + { + EIGEN_STATIC_ASSERT((internal::is_same::value),THE_EVAL_EVALTO_FUNCTION_SHOULD_NEVER_BE_CALLED_FOR_DENSE_OBJECTS); + } + + protected: + /** Default constructor. Do nothing. */ + DenseBase() + { + /* Just checks for self-consistency of the flags. + * Only do it when debugging Eigen, as this borders on paranoiac and could slow compilation down + */ +#ifdef EIGEN_INTERNAL_DEBUGGING + EIGEN_STATIC_ASSERT((EIGEN_IMPLIES(MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1, int(IsRowMajor)) + && EIGEN_IMPLIES(MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1, int(!IsRowMajor))), + INVALID_STORAGE_ORDER_FOR_THIS_VECTOR_EXPRESSION) +#endif + } + + private: + explicit DenseBase(int); + DenseBase(int,int); + template explicit DenseBase(const DenseBase&); +}; + +} // end namespace Eigen + +#endif // EIGEN_DENSEBASE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/DenseCoeffsBase.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/DenseCoeffsBase.h new file mode 100644 index 00000000..3c890f21 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/DenseCoeffsBase.h @@ -0,0 +1,754 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2006-2010 Benoit Jacob +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_DENSECOEFFSBASE_H +#define EIGEN_DENSECOEFFSBASE_H + +namespace Eigen { + +namespace internal { +template struct add_const_on_value_type_if_arithmetic +{ + typedef typename conditional::value, T, typename add_const_on_value_type::type>::type type; +}; +} + +/** \brief Base class providing read-only coefficient access to matrices and arrays. + * \ingroup Core_Module + * \tparam Derived Type of the derived class + * \tparam #ReadOnlyAccessors Constant indicating read-only access + * + * This class defines the \c operator() \c const function and friends, which can be used to read specific + * entries of a matrix or array. + * + * \sa DenseCoeffsBase, DenseCoeffsBase, + * \ref TopicClassHierarchy + */ +template +class DenseCoeffsBase : public EigenBase +{ + public: + typedef typename internal::traits::StorageKind StorageKind; + typedef typename internal::traits::Index Index; + typedef typename internal::traits::Scalar Scalar; + typedef typename internal::packet_traits::type PacketScalar; + + // Explanation for this CoeffReturnType typedef. + // - This is the return type of the coeff() method. + // - The LvalueBit means exactly that we can offer a coeffRef() method, which means exactly that we can get references + // to coeffs, which means exactly that we can have coeff() return a const reference (as opposed to returning a value). + // - The is_artihmetic check is required since "const int", "const double", etc. will cause warnings on some systems + // while the declaration of "const T", where T is a non arithmetic type does not. Always returning "const Scalar&" is + // not possible, since the underlying expressions might not offer a valid address the reference could be referring to. + typedef typename internal::conditional::Flags&LvalueBit), + const Scalar&, + typename internal::conditional::value, Scalar, const Scalar>::type + >::type CoeffReturnType; + + typedef typename internal::add_const_on_value_type_if_arithmetic< + typename internal::packet_traits::type + >::type PacketReturnType; + + typedef EigenBase Base; + using Base::rows; + using Base::cols; + using Base::size; + using Base::derived; + + EIGEN_STRONG_INLINE Index rowIndexByOuterInner(Index outer, Index inner) const + { + return int(Derived::RowsAtCompileTime) == 1 ? 0 + : int(Derived::ColsAtCompileTime) == 1 ? inner + : int(Derived::Flags)&RowMajorBit ? outer + : inner; + } + + EIGEN_STRONG_INLINE Index colIndexByOuterInner(Index outer, Index inner) const + { + return int(Derived::ColsAtCompileTime) == 1 ? 0 + : int(Derived::RowsAtCompileTime) == 1 ? inner + : int(Derived::Flags)&RowMajorBit ? inner + : outer; + } + + /** Short version: don't use this function, use + * \link operator()(Index,Index) const \endlink instead. + * + * Long version: this function is similar to + * \link operator()(Index,Index) const \endlink, but without the assertion. + * Use this for limiting the performance cost of debugging code when doing + * repeated coefficient access. Only use this when it is guaranteed that the + * parameters \a row and \a col are in range. + * + * If EIGEN_INTERNAL_DEBUGGING is defined, an assertion will be made, making this + * function equivalent to \link operator()(Index,Index) const \endlink. + * + * \sa operator()(Index,Index) const, coeffRef(Index,Index), coeff(Index) const + */ + EIGEN_STRONG_INLINE CoeffReturnType coeff(Index row, Index col) const + { + eigen_internal_assert(row >= 0 && row < rows() + && col >= 0 && col < cols()); + return derived().coeff(row, col); + } + + EIGEN_STRONG_INLINE CoeffReturnType coeffByOuterInner(Index outer, Index inner) const + { + return coeff(rowIndexByOuterInner(outer, inner), + colIndexByOuterInner(outer, inner)); + } + + /** \returns the coefficient at given the given row and column. + * + * \sa operator()(Index,Index), operator[](Index) + */ + EIGEN_STRONG_INLINE CoeffReturnType operator()(Index row, Index col) const + { + eigen_assert(row >= 0 && row < rows() + && col >= 0 && col < cols()); + return derived().coeff(row, col); + } + + /** Short version: don't use this function, use + * \link operator[](Index) const \endlink instead. + * + * Long version: this function is similar to + * \link operator[](Index) const \endlink, but without the assertion. + * Use this for limiting the performance cost of debugging code when doing + * repeated coefficient access. Only use this when it is guaranteed that the + * parameter \a index is in range. + * + * If EIGEN_INTERNAL_DEBUGGING is defined, an assertion will be made, making this + * function equivalent to \link operator[](Index) const \endlink. + * + * \sa operator[](Index) const, coeffRef(Index), coeff(Index,Index) const + */ + + EIGEN_STRONG_INLINE CoeffReturnType + coeff(Index index) const + { + eigen_internal_assert(index >= 0 && index < size()); + return derived().coeff(index); + } + + + /** \returns the coefficient at given index. + * + * This method is allowed only for vector expressions, and for matrix expressions having the LinearAccessBit. + * + * \sa operator[](Index), operator()(Index,Index) const, x() const, y() const, + * z() const, w() const + */ + + EIGEN_STRONG_INLINE CoeffReturnType + operator[](Index index) const + { + #ifndef EIGEN2_SUPPORT + EIGEN_STATIC_ASSERT(Derived::IsVectorAtCompileTime, + THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD) + #endif + eigen_assert(index >= 0 && index < size()); + return derived().coeff(index); + } + + /** \returns the coefficient at given index. + * + * This is synonymous to operator[](Index) const. + * + * This method is allowed only for vector expressions, and for matrix expressions having the LinearAccessBit. + * + * \sa operator[](Index), operator()(Index,Index) const, x() const, y() const, + * z() const, w() const + */ + + EIGEN_STRONG_INLINE CoeffReturnType + operator()(Index index) const + { + eigen_assert(index >= 0 && index < size()); + return derived().coeff(index); + } + + /** equivalent to operator[](0). */ + + EIGEN_STRONG_INLINE CoeffReturnType + x() const { return (*this)[0]; } + + /** equivalent to operator[](1). */ + + EIGEN_STRONG_INLINE CoeffReturnType + y() const { return (*this)[1]; } + + /** equivalent to operator[](2). */ + + EIGEN_STRONG_INLINE CoeffReturnType + z() const { return (*this)[2]; } + + /** equivalent to operator[](3). */ + + EIGEN_STRONG_INLINE CoeffReturnType + w() const { return (*this)[3]; } + + /** \internal + * \returns the packet of coefficients starting at the given row and column. It is your responsibility + * to ensure that a packet really starts there. This method is only available on expressions having the + * PacketAccessBit. + * + * The \a LoadMode parameter may have the value \a #Aligned or \a #Unaligned. Its effect is to select + * the appropriate vectorization instruction. Aligned access is faster, but is only possible for packets + * starting at an address which is a multiple of the packet size. + */ + + template + EIGEN_STRONG_INLINE PacketReturnType packet(Index row, Index col) const + { + eigen_internal_assert(row >= 0 && row < rows() + && col >= 0 && col < cols()); + return derived().template packet(row,col); + } + + + /** \internal */ + template + EIGEN_STRONG_INLINE PacketReturnType packetByOuterInner(Index outer, Index inner) const + { + return packet(rowIndexByOuterInner(outer, inner), + colIndexByOuterInner(outer, inner)); + } + + /** \internal + * \returns the packet of coefficients starting at the given index. It is your responsibility + * to ensure that a packet really starts there. This method is only available on expressions having the + * PacketAccessBit and the LinearAccessBit. + * + * The \a LoadMode parameter may have the value \a #Aligned or \a #Unaligned. Its effect is to select + * the appropriate vectorization instruction. Aligned access is faster, but is only possible for packets + * starting at an address which is a multiple of the packet size. + */ + + template + EIGEN_STRONG_INLINE PacketReturnType packet(Index index) const + { + eigen_internal_assert(index >= 0 && index < size()); + return derived().template packet(index); + } + + protected: + // explanation: DenseBase is doing "using ..." on the methods from DenseCoeffsBase. + // But some methods are only available in the DirectAccess case. + // So we add dummy methods here with these names, so that "using... " doesn't fail. + // It's not private so that the child class DenseBase can access them, and it's not public + // either since it's an implementation detail, so has to be protected. + void coeffRef(); + void coeffRefByOuterInner(); + void writePacket(); + void writePacketByOuterInner(); + void copyCoeff(); + void copyCoeffByOuterInner(); + void copyPacket(); + void copyPacketByOuterInner(); + void stride(); + void innerStride(); + void outerStride(); + void rowStride(); + void colStride(); +}; + +/** \brief Base class providing read/write coefficient access to matrices and arrays. + * \ingroup Core_Module + * \tparam Derived Type of the derived class + * \tparam #WriteAccessors Constant indicating read/write access + * + * This class defines the non-const \c operator() function and friends, which can be used to write specific + * entries of a matrix or array. This class inherits DenseCoeffsBase which + * defines the const variant for reading specific entries. + * + * \sa DenseCoeffsBase, \ref TopicClassHierarchy + */ +template +class DenseCoeffsBase : public DenseCoeffsBase +{ + public: + + typedef DenseCoeffsBase Base; + + typedef typename internal::traits::StorageKind StorageKind; + typedef typename internal::traits::Index Index; + typedef typename internal::traits::Scalar Scalar; + typedef typename internal::packet_traits::type PacketScalar; + typedef typename NumTraits::Real RealScalar; + + using Base::coeff; + using Base::rows; + using Base::cols; + using Base::size; + using Base::derived; + using Base::rowIndexByOuterInner; + using Base::colIndexByOuterInner; + using Base::operator[]; + using Base::operator(); + using Base::x; + using Base::y; + using Base::z; + using Base::w; + + /** Short version: don't use this function, use + * \link operator()(Index,Index) \endlink instead. + * + * Long version: this function is similar to + * \link operator()(Index,Index) \endlink, but without the assertion. + * Use this for limiting the performance cost of debugging code when doing + * repeated coefficient access. Only use this when it is guaranteed that the + * parameters \a row and \a col are in range. + * + * If EIGEN_INTERNAL_DEBUGGING is defined, an assertion will be made, making this + * function equivalent to \link operator()(Index,Index) \endlink. + * + * \sa operator()(Index,Index), coeff(Index, Index) const, coeffRef(Index) + */ + EIGEN_STRONG_INLINE Scalar& coeffRef(Index row, Index col) + { + eigen_internal_assert(row >= 0 && row < rows() + && col >= 0 && col < cols()); + return derived().coeffRef(row, col); + } + + EIGEN_STRONG_INLINE Scalar& + coeffRefByOuterInner(Index outer, Index inner) + { + return coeffRef(rowIndexByOuterInner(outer, inner), + colIndexByOuterInner(outer, inner)); + } + + /** \returns a reference to the coefficient at given the given row and column. + * + * \sa operator[](Index) + */ + + EIGEN_STRONG_INLINE Scalar& + operator()(Index row, Index col) + { + eigen_assert(row >= 0 && row < rows() + && col >= 0 && col < cols()); + return derived().coeffRef(row, col); + } + + + /** Short version: don't use this function, use + * \link operator[](Index) \endlink instead. + * + * Long version: this function is similar to + * \link operator[](Index) \endlink, but without the assertion. + * Use this for limiting the performance cost of debugging code when doing + * repeated coefficient access. Only use this when it is guaranteed that the + * parameters \a row and \a col are in range. + * + * If EIGEN_INTERNAL_DEBUGGING is defined, an assertion will be made, making this + * function equivalent to \link operator[](Index) \endlink. + * + * \sa operator[](Index), coeff(Index) const, coeffRef(Index,Index) + */ + + EIGEN_STRONG_INLINE Scalar& + coeffRef(Index index) + { + eigen_internal_assert(index >= 0 && index < size()); + return derived().coeffRef(index); + } + + /** \returns a reference to the coefficient at given index. + * + * This method is allowed only for vector expressions, and for matrix expressions having the LinearAccessBit. + * + * \sa operator[](Index) const, operator()(Index,Index), x(), y(), z(), w() + */ + + EIGEN_STRONG_INLINE Scalar& + operator[](Index index) + { + #ifndef EIGEN2_SUPPORT + EIGEN_STATIC_ASSERT(Derived::IsVectorAtCompileTime, + THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD) + #endif + eigen_assert(index >= 0 && index < size()); + return derived().coeffRef(index); + } + + /** \returns a reference to the coefficient at given index. + * + * This is synonymous to operator[](Index). + * + * This method is allowed only for vector expressions, and for matrix expressions having the LinearAccessBit. + * + * \sa operator[](Index) const, operator()(Index,Index), x(), y(), z(), w() + */ + + EIGEN_STRONG_INLINE Scalar& + operator()(Index index) + { + eigen_assert(index >= 0 && index < size()); + return derived().coeffRef(index); + } + + /** equivalent to operator[](0). */ + + EIGEN_STRONG_INLINE Scalar& + x() { return (*this)[0]; } + + /** equivalent to operator[](1). */ + + EIGEN_STRONG_INLINE Scalar& + y() { return (*this)[1]; } + + /** equivalent to operator[](2). */ + + EIGEN_STRONG_INLINE Scalar& + z() { return (*this)[2]; } + + /** equivalent to operator[](3). */ + + EIGEN_STRONG_INLINE Scalar& + w() { return (*this)[3]; } + + /** \internal + * Stores the given packet of coefficients, at the given row and column of this expression. It is your responsibility + * to ensure that a packet really starts there. This method is only available on expressions having the + * PacketAccessBit. + * + * The \a LoadMode parameter may have the value \a #Aligned or \a #Unaligned. Its effect is to select + * the appropriate vectorization instruction. Aligned access is faster, but is only possible for packets + * starting at an address which is a multiple of the packet size. + */ + + template + EIGEN_STRONG_INLINE void writePacket + (Index row, Index col, const typename internal::packet_traits::type& val) + { + eigen_internal_assert(row >= 0 && row < rows() + && col >= 0 && col < cols()); + derived().template writePacket(row,col,val); + } + + + /** \internal */ + template + EIGEN_STRONG_INLINE void writePacketByOuterInner + (Index outer, Index inner, const typename internal::packet_traits::type& val) + { + writePacket(rowIndexByOuterInner(outer, inner), + colIndexByOuterInner(outer, inner), + val); + } + + /** \internal + * Stores the given packet of coefficients, at the given index in this expression. It is your responsibility + * to ensure that a packet really starts there. This method is only available on expressions having the + * PacketAccessBit and the LinearAccessBit. + * + * The \a LoadMode parameter may have the value \a Aligned or \a Unaligned. Its effect is to select + * the appropriate vectorization instruction. Aligned access is faster, but is only possible for packets + * starting at an address which is a multiple of the packet size. + */ + template + EIGEN_STRONG_INLINE void writePacket + (Index index, const typename internal::packet_traits::type& val) + { + eigen_internal_assert(index >= 0 && index < size()); + derived().template writePacket(index,val); + } + +#ifndef EIGEN_PARSED_BY_DOXYGEN + + /** \internal Copies the coefficient at position (row,col) of other into *this. + * + * This method is overridden in SwapWrapper, allowing swap() assignments to share 99% of their code + * with usual assignments. + * + * Outside of this internal usage, this method has probably no usefulness. It is hidden in the public API dox. + */ + + template + EIGEN_STRONG_INLINE void copyCoeff(Index row, Index col, const DenseBase& other) + { + eigen_internal_assert(row >= 0 && row < rows() + && col >= 0 && col < cols()); + derived().coeffRef(row, col) = other.derived().coeff(row, col); + } + + /** \internal Copies the coefficient at the given index of other into *this. + * + * This method is overridden in SwapWrapper, allowing swap() assignments to share 99% of their code + * with usual assignments. + * + * Outside of this internal usage, this method has probably no usefulness. It is hidden in the public API dox. + */ + + template + EIGEN_STRONG_INLINE void copyCoeff(Index index, const DenseBase& other) + { + eigen_internal_assert(index >= 0 && index < size()); + derived().coeffRef(index) = other.derived().coeff(index); + } + + + template + EIGEN_STRONG_INLINE void copyCoeffByOuterInner(Index outer, Index inner, const DenseBase& other) + { + const Index row = rowIndexByOuterInner(outer,inner); + const Index col = colIndexByOuterInner(outer,inner); + // derived() is important here: copyCoeff() may be reimplemented in Derived! + derived().copyCoeff(row, col, other); + } + + /** \internal Copies the packet at position (row,col) of other into *this. + * + * This method is overridden in SwapWrapper, allowing swap() assignments to share 99% of their code + * with usual assignments. + * + * Outside of this internal usage, this method has probably no usefulness. It is hidden in the public API dox. + */ + + template + EIGEN_STRONG_INLINE void copyPacket(Index row, Index col, const DenseBase& other) + { + eigen_internal_assert(row >= 0 && row < rows() + && col >= 0 && col < cols()); + derived().template writePacket(row, col, + other.derived().template packet(row, col)); + } + + /** \internal Copies the packet at the given index of other into *this. + * + * This method is overridden in SwapWrapper, allowing swap() assignments to share 99% of their code + * with usual assignments. + * + * Outside of this internal usage, this method has probably no usefulness. It is hidden in the public API dox. + */ + + template + EIGEN_STRONG_INLINE void copyPacket(Index index, const DenseBase& other) + { + eigen_internal_assert(index >= 0 && index < size()); + derived().template writePacket(index, + other.derived().template packet(index)); + } + + /** \internal */ + template + EIGEN_STRONG_INLINE void copyPacketByOuterInner(Index outer, Index inner, const DenseBase& other) + { + const Index row = rowIndexByOuterInner(outer,inner); + const Index col = colIndexByOuterInner(outer,inner); + // derived() is important here: copyCoeff() may be reimplemented in Derived! + derived().template copyPacket< OtherDerived, StoreMode, LoadMode>(row, col, other); + } +#endif + +}; + +/** \brief Base class providing direct read-only coefficient access to matrices and arrays. + * \ingroup Core_Module + * \tparam Derived Type of the derived class + * \tparam #DirectAccessors Constant indicating direct access + * + * This class defines functions to work with strides which can be used to access entries directly. This class + * inherits DenseCoeffsBase which defines functions to access entries read-only using + * \c operator() . + * + * \sa \ref TopicClassHierarchy + */ +template +class DenseCoeffsBase : public DenseCoeffsBase +{ + public: + + typedef DenseCoeffsBase Base; + typedef typename internal::traits::Index Index; + typedef typename internal::traits::Scalar Scalar; + typedef typename NumTraits::Real RealScalar; + + using Base::rows; + using Base::cols; + using Base::size; + using Base::derived; + + /** \returns the pointer increment between two consecutive elements within a slice in the inner direction. + * + * \sa outerStride(), rowStride(), colStride() + */ + inline Index innerStride() const + { + return derived().innerStride(); + } + + /** \returns the pointer increment between two consecutive inner slices (for example, between two consecutive columns + * in a column-major matrix). + * + * \sa innerStride(), rowStride(), colStride() + */ + inline Index outerStride() const + { + return derived().outerStride(); + } + + // FIXME shall we remove it ? + inline Index stride() const + { + return Derived::IsVectorAtCompileTime ? innerStride() : outerStride(); + } + + /** \returns the pointer increment between two consecutive rows. + * + * \sa innerStride(), outerStride(), colStride() + */ + inline Index rowStride() const + { + return Derived::IsRowMajor ? outerStride() : innerStride(); + } + + /** \returns the pointer increment between two consecutive columns. + * + * \sa innerStride(), outerStride(), rowStride() + */ + inline Index colStride() const + { + return Derived::IsRowMajor ? innerStride() : outerStride(); + } +}; + +/** \brief Base class providing direct read/write coefficient access to matrices and arrays. + * \ingroup Core_Module + * \tparam Derived Type of the derived class + * \tparam #DirectWriteAccessors Constant indicating direct access + * + * This class defines functions to work with strides which can be used to access entries directly. This class + * inherits DenseCoeffsBase which defines functions to access entries read/write using + * \c operator(). + * + * \sa \ref TopicClassHierarchy + */ +template +class DenseCoeffsBase + : public DenseCoeffsBase +{ + public: + + typedef DenseCoeffsBase Base; + typedef typename internal::traits::Index Index; + typedef typename internal::traits::Scalar Scalar; + typedef typename NumTraits::Real RealScalar; + + using Base::rows; + using Base::cols; + using Base::size; + using Base::derived; + + /** \returns the pointer increment between two consecutive elements within a slice in the inner direction. + * + * \sa outerStride(), rowStride(), colStride() + */ + inline Index innerStride() const + { + return derived().innerStride(); + } + + /** \returns the pointer increment between two consecutive inner slices (for example, between two consecutive columns + * in a column-major matrix). + * + * \sa innerStride(), rowStride(), colStride() + */ + inline Index outerStride() const + { + return derived().outerStride(); + } + + // FIXME shall we remove it ? + inline Index stride() const + { + return Derived::IsVectorAtCompileTime ? innerStride() : outerStride(); + } + + /** \returns the pointer increment between two consecutive rows. + * + * \sa innerStride(), outerStride(), colStride() + */ + inline Index rowStride() const + { + return Derived::IsRowMajor ? outerStride() : innerStride(); + } + + /** \returns the pointer increment between two consecutive columns. + * + * \sa innerStride(), outerStride(), rowStride() + */ + inline Index colStride() const + { + return Derived::IsRowMajor ? innerStride() : outerStride(); + } +}; + +namespace internal { + +template +struct first_aligned_impl +{ + static inline typename Derived::Index run(const Derived&) + { return 0; } +}; + +template +struct first_aligned_impl +{ + static inline typename Derived::Index run(const Derived& m) + { + return internal::first_aligned(&m.const_cast_derived().coeffRef(0,0), m.size()); + } +}; + +/** \internal \returns the index of the first element of the array that is well aligned for vectorization. + * + * There is also the variant first_aligned(const Scalar*, Integer) defined in Memory.h. See it for more + * documentation. + */ +template +static inline typename Derived::Index first_aligned(const Derived& m) +{ + return first_aligned_impl + + ::run(m); +} + +template::ret> +struct inner_stride_at_compile_time +{ + enum { ret = traits::InnerStrideAtCompileTime }; +}; + +template +struct inner_stride_at_compile_time +{ + enum { ret = 0 }; +}; + +template::ret> +struct outer_stride_at_compile_time +{ + enum { ret = traits::OuterStrideAtCompileTime }; +}; + +template +struct outer_stride_at_compile_time +{ + enum { ret = 0 }; +}; + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_DENSECOEFFSBASE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/DenseStorage.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/DenseStorage.h new file mode 100644 index 00000000..568493cb --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/DenseStorage.h @@ -0,0 +1,434 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008 Gael Guennebaud +// Copyright (C) 2006-2009 Benoit Jacob +// Copyright (C) 2010 Hauke Heibel +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_MATRIXSTORAGE_H +#define EIGEN_MATRIXSTORAGE_H + +#ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN + #define EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN EIGEN_DENSE_STORAGE_CTOR_PLUGIN; +#else + #define EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN +#endif + +namespace Eigen { + +namespace internal { + +struct constructor_without_unaligned_array_assert {}; + +template void check_static_allocation_size() +{ + // if EIGEN_STACK_ALLOCATION_LIMIT is defined to 0, then no limit + #if EIGEN_STACK_ALLOCATION_LIMIT + EIGEN_STATIC_ASSERT(Size * sizeof(T) <= EIGEN_STACK_ALLOCATION_LIMIT, OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG); + #endif +} + +/** \internal + * Static array. If the MatrixOrArrayOptions require auto-alignment, the array will be automatically aligned: + * to 16 bytes boundary if the total size is a multiple of 16 bytes. + */ +template +struct plain_array +{ + T array[Size]; + + plain_array() + { + check_static_allocation_size(); + } + + plain_array(constructor_without_unaligned_array_assert) + { + check_static_allocation_size(); + } +}; + +#if defined(EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT) + #define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask) +#elif EIGEN_GNUC_AT_LEAST(4,7) + // GCC 4.7 is too aggressive in its optimizations and remove the alignement test based on the fact the array is declared to be aligned. + // See this bug report: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53900 + // Hiding the origin of the array pointer behind a function argument seems to do the trick even if the function is inlined: + template + EIGEN_ALWAYS_INLINE PtrType eigen_unaligned_array_assert_workaround_gcc47(PtrType array) { return array; } + #define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask) \ + eigen_assert((reinterpret_cast(eigen_unaligned_array_assert_workaround_gcc47(array)) & sizemask) == 0 \ + && "this assertion is explained here: " \ + "http://eigen.tuxfamily.org/dox-devel/group__TopicUnalignedArrayAssert.html" \ + " **** READ THIS WEB PAGE !!! ****"); +#else + #define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask) \ + eigen_assert((reinterpret_cast(array) & sizemask) == 0 \ + && "this assertion is explained here: " \ + "http://eigen.tuxfamily.org/dox-devel/group__TopicUnalignedArrayAssert.html" \ + " **** READ THIS WEB PAGE !!! ****"); +#endif + +template +struct plain_array +{ + EIGEN_USER_ALIGN16 T array[Size]; + + plain_array() + { + EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(0xf); + check_static_allocation_size(); + } + + plain_array(constructor_without_unaligned_array_assert) + { + check_static_allocation_size(); + } +}; + +template +struct plain_array +{ + EIGEN_USER_ALIGN16 T array[1]; + plain_array() {} + plain_array(constructor_without_unaligned_array_assert) {} +}; + +} // end namespace internal + +/** \internal + * + * \class DenseStorage + * \ingroup Core_Module + * + * \brief Stores the data of a matrix + * + * This class stores the data of fixed-size, dynamic-size or mixed matrices + * in a way as compact as possible. + * + * \sa Matrix + */ +template class DenseStorage; + +// purely fixed-size matrix +template class DenseStorage +{ + internal::plain_array m_data; + public: + DenseStorage() {} + DenseStorage(internal::constructor_without_unaligned_array_assert) + : m_data(internal::constructor_without_unaligned_array_assert()) {} + DenseStorage(const DenseStorage& other) : m_data(other.m_data) {} + DenseStorage& operator=(const DenseStorage& other) + { + if (this != &other) m_data = other.m_data; + return *this; + } + DenseStorage(DenseIndex,DenseIndex,DenseIndex) {} + void swap(DenseStorage& other) { std::swap(m_data,other.m_data); } + static DenseIndex rows(void) {return _Rows;} + static DenseIndex cols(void) {return _Cols;} + void conservativeResize(DenseIndex,DenseIndex,DenseIndex) {} + void resize(DenseIndex,DenseIndex,DenseIndex) {} + const T *data() const { return m_data.array; } + T *data() { return m_data.array; } +}; + +// null matrix +template class DenseStorage +{ + public: + DenseStorage() {} + DenseStorage(internal::constructor_without_unaligned_array_assert) {} + DenseStorage(const DenseStorage&) {} + DenseStorage& operator=(const DenseStorage&) { return *this; } + DenseStorage(DenseIndex,DenseIndex,DenseIndex) {} + void swap(DenseStorage& ) {} + static DenseIndex rows(void) {return _Rows;} + static DenseIndex cols(void) {return _Cols;} + void conservativeResize(DenseIndex,DenseIndex,DenseIndex) {} + void resize(DenseIndex,DenseIndex,DenseIndex) {} + const T *data() const { return 0; } + T *data() { return 0; } +}; + +// more specializations for null matrices; these are necessary to resolve ambiguities +template class DenseStorage +: public DenseStorage { }; + +template class DenseStorage +: public DenseStorage { }; + +template class DenseStorage +: public DenseStorage { }; + +// dynamic-size matrix with fixed-size storage +template class DenseStorage +{ + internal::plain_array m_data; + DenseIndex m_rows; + DenseIndex m_cols; + public: + DenseStorage() : m_rows(0), m_cols(0) {} + DenseStorage(internal::constructor_without_unaligned_array_assert) + : m_data(internal::constructor_without_unaligned_array_assert()), m_rows(0), m_cols(0) {} + DenseStorage(const DenseStorage& other) : m_data(other.m_data), m_rows(other.m_rows), m_cols(other.m_cols) {} + DenseStorage& operator=(const DenseStorage& other) + { + if (this != &other) + { + m_data = other.m_data; + m_rows = other.m_rows; + m_cols = other.m_cols; + } + return *this; + } + DenseStorage(DenseIndex, DenseIndex nbRows, DenseIndex nbCols) : m_rows(nbRows), m_cols(nbCols) {} + void swap(DenseStorage& other) + { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); std::swap(m_cols,other.m_cols); } + DenseIndex rows() const {return m_rows;} + DenseIndex cols() const {return m_cols;} + void conservativeResize(DenseIndex, DenseIndex nbRows, DenseIndex nbCols) { m_rows = nbRows; m_cols = nbCols; } + void resize(DenseIndex, DenseIndex nbRows, DenseIndex nbCols) { m_rows = nbRows; m_cols = nbCols; } + const T *data() const { return m_data.array; } + T *data() { return m_data.array; } +}; + +// dynamic-size matrix with fixed-size storage and fixed width +template class DenseStorage +{ + internal::plain_array m_data; + DenseIndex m_rows; + public: + DenseStorage() : m_rows(0) {} + DenseStorage(internal::constructor_without_unaligned_array_assert) + : m_data(internal::constructor_without_unaligned_array_assert()), m_rows(0) {} + DenseStorage(const DenseStorage& other) : m_data(other.m_data), m_rows(other.m_rows) {} + DenseStorage& operator=(const DenseStorage& other) + { + if (this != &other) + { + m_data = other.m_data; + m_rows = other.m_rows; + } + return *this; + } + DenseStorage(DenseIndex, DenseIndex nbRows, DenseIndex) : m_rows(nbRows) {} + void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); } + DenseIndex rows(void) const {return m_rows;} + DenseIndex cols(void) const {return _Cols;} + void conservativeResize(DenseIndex, DenseIndex nbRows, DenseIndex) { m_rows = nbRows; } + void resize(DenseIndex, DenseIndex nbRows, DenseIndex) { m_rows = nbRows; } + const T *data() const { return m_data.array; } + T *data() { return m_data.array; } +}; + +// dynamic-size matrix with fixed-size storage and fixed height +template class DenseStorage +{ + internal::plain_array m_data; + DenseIndex m_cols; + public: + DenseStorage() : m_cols(0) {} + DenseStorage(internal::constructor_without_unaligned_array_assert) + : m_data(internal::constructor_without_unaligned_array_assert()), m_cols(0) {} + DenseStorage(const DenseStorage& other) : m_data(other.m_data), m_cols(other.m_cols) {} + DenseStorage& operator=(const DenseStorage& other) + { + if (this != &other) + { + m_data = other.m_data; + m_cols = other.m_cols; + } + return *this; + } + DenseStorage(DenseIndex, DenseIndex, DenseIndex nbCols) : m_cols(nbCols) {} + void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); } + DenseIndex rows(void) const {return _Rows;} + DenseIndex cols(void) const {return m_cols;} + void conservativeResize(DenseIndex, DenseIndex, DenseIndex nbCols) { m_cols = nbCols; } + void resize(DenseIndex, DenseIndex, DenseIndex nbCols) { m_cols = nbCols; } + const T *data() const { return m_data.array; } + T *data() { return m_data.array; } +}; + +// purely dynamic matrix. +template class DenseStorage +{ + T *m_data; + DenseIndex m_rows; + DenseIndex m_cols; + public: + DenseStorage() : m_data(0), m_rows(0), m_cols(0) {} + DenseStorage(internal::constructor_without_unaligned_array_assert) + : m_data(0), m_rows(0), m_cols(0) {} + DenseStorage(DenseIndex size, DenseIndex nbRows, DenseIndex nbCols) + : m_data(internal::conditional_aligned_new_auto(size)), m_rows(nbRows), m_cols(nbCols) + { EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN } +#ifdef EIGEN_HAVE_RVALUE_REFERENCES + DenseStorage(DenseStorage&& other) + : m_data(std::move(other.m_data)) + , m_rows(std::move(other.m_rows)) + , m_cols(std::move(other.m_cols)) + { + other.m_data = nullptr; + } + DenseStorage& operator=(DenseStorage&& other) + { + using std::swap; + swap(m_data, other.m_data); + swap(m_rows, other.m_rows); + swap(m_cols, other.m_cols); + return *this; + } +#endif + ~DenseStorage() { internal::conditional_aligned_delete_auto(m_data, m_rows*m_cols); } + void swap(DenseStorage& other) + { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); std::swap(m_cols,other.m_cols); } + DenseIndex rows(void) const {return m_rows;} + DenseIndex cols(void) const {return m_cols;} + void conservativeResize(DenseIndex size, DenseIndex nbRows, DenseIndex nbCols) + { + m_data = internal::conditional_aligned_realloc_new_auto(m_data, size, m_rows*m_cols); + m_rows = nbRows; + m_cols = nbCols; + } + void resize(DenseIndex size, DenseIndex nbRows, DenseIndex nbCols) + { + if(size != m_rows*m_cols) + { + internal::conditional_aligned_delete_auto(m_data, m_rows*m_cols); + if (size) + m_data = internal::conditional_aligned_new_auto(size); + else + m_data = 0; + EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN + } + m_rows = nbRows; + m_cols = nbCols; + } + const T *data() const { return m_data; } + T *data() { return m_data; } + private: + DenseStorage(const DenseStorage&); + DenseStorage& operator=(const DenseStorage&); +}; + +// matrix with dynamic width and fixed height (so that matrix has dynamic size). +template class DenseStorage +{ + T *m_data; + DenseIndex m_cols; + public: + DenseStorage() : m_data(0), m_cols(0) {} + DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_cols(0) {} + DenseStorage(DenseIndex size, DenseIndex, DenseIndex nbCols) : m_data(internal::conditional_aligned_new_auto(size)), m_cols(nbCols) + { EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN } +#ifdef EIGEN_HAVE_RVALUE_REFERENCES + DenseStorage(DenseStorage&& other) + : m_data(std::move(other.m_data)) + , m_cols(std::move(other.m_cols)) + { + other.m_data = nullptr; + } + DenseStorage& operator=(DenseStorage&& other) + { + using std::swap; + swap(m_data, other.m_data); + swap(m_cols, other.m_cols); + return *this; + } +#endif + ~DenseStorage() { internal::conditional_aligned_delete_auto(m_data, _Rows*m_cols); } + void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); } + static DenseIndex rows(void) {return _Rows;} + DenseIndex cols(void) const {return m_cols;} + void conservativeResize(DenseIndex size, DenseIndex, DenseIndex nbCols) + { + m_data = internal::conditional_aligned_realloc_new_auto(m_data, size, _Rows*m_cols); + m_cols = nbCols; + } + EIGEN_STRONG_INLINE void resize(DenseIndex size, DenseIndex, DenseIndex nbCols) + { + if(size != _Rows*m_cols) + { + internal::conditional_aligned_delete_auto(m_data, _Rows*m_cols); + if (size) + m_data = internal::conditional_aligned_new_auto(size); + else + m_data = 0; + EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN + } + m_cols = nbCols; + } + const T *data() const { return m_data; } + T *data() { return m_data; } + private: + DenseStorage(const DenseStorage&); + DenseStorage& operator=(const DenseStorage&); +}; + +// matrix with dynamic height and fixed width (so that matrix has dynamic size). +template class DenseStorage +{ + T *m_data; + DenseIndex m_rows; + public: + DenseStorage() : m_data(0), m_rows(0) {} + DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_rows(0) {} + DenseStorage(DenseIndex size, DenseIndex nbRows, DenseIndex) : m_data(internal::conditional_aligned_new_auto(size)), m_rows(nbRows) + { EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN } +#ifdef EIGEN_HAVE_RVALUE_REFERENCES + DenseStorage(DenseStorage&& other) + : m_data(std::move(other.m_data)) + , m_rows(std::move(other.m_rows)) + { + other.m_data = nullptr; + } + DenseStorage& operator=(DenseStorage&& other) + { + using std::swap; + swap(m_data, other.m_data); + swap(m_rows, other.m_rows); + return *this; + } +#endif + ~DenseStorage() { internal::conditional_aligned_delete_auto(m_data, _Cols*m_rows); } + void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); } + DenseIndex rows(void) const {return m_rows;} + static DenseIndex cols(void) {return _Cols;} + void conservativeResize(DenseIndex size, DenseIndex nbRows, DenseIndex) + { + m_data = internal::conditional_aligned_realloc_new_auto(m_data, size, m_rows*_Cols); + m_rows = nbRows; + } + EIGEN_STRONG_INLINE void resize(DenseIndex size, DenseIndex nbRows, DenseIndex) + { + if(size != m_rows*_Cols) + { + internal::conditional_aligned_delete_auto(m_data, _Cols*m_rows); + if (size) + m_data = internal::conditional_aligned_new_auto(size); + else + m_data = 0; + EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN + } + m_rows = nbRows; + } + const T *data() const { return m_data; } + T *data() { return m_data; } + private: + DenseStorage(const DenseStorage&); + DenseStorage& operator=(const DenseStorage&); +}; + +} // end namespace Eigen + +#endif // EIGEN_MATRIX_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/Diagonal.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/Diagonal.h new file mode 100644 index 00000000..68cf6d4b --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/Diagonal.h @@ -0,0 +1,237 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2007-2009 Benoit Jacob +// Copyright (C) 2009-2010 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_DIAGONAL_H +#define EIGEN_DIAGONAL_H + +namespace Eigen { + +/** \class Diagonal + * \ingroup Core_Module + * + * \brief Expression of a diagonal/subdiagonal/superdiagonal in a matrix + * + * \param MatrixType the type of the object in which we are taking a sub/main/super diagonal + * \param DiagIndex the index of the sub/super diagonal. The default is 0 and it means the main diagonal. + * A positive value means a superdiagonal, a negative value means a subdiagonal. + * You can also use Dynamic so the index can be set at runtime. + * + * The matrix is not required to be square. + * + * This class represents an expression of the main diagonal, or any sub/super diagonal + * of a square matrix. It is the return type of MatrixBase::diagonal() and MatrixBase::diagonal(Index) and most of the + * time this is the only way it is used. + * + * \sa MatrixBase::diagonal(), MatrixBase::diagonal(Index) + */ + +namespace internal { +template +struct traits > + : traits +{ + typedef typename nested::type MatrixTypeNested; + typedef typename remove_reference::type _MatrixTypeNested; + typedef typename MatrixType::StorageKind StorageKind; + enum { + RowsAtCompileTime = (int(DiagIndex) == DynamicIndex || int(MatrixType::SizeAtCompileTime) == Dynamic) ? Dynamic + : (EIGEN_PLAIN_ENUM_MIN(MatrixType::RowsAtCompileTime - EIGEN_PLAIN_ENUM_MAX(-DiagIndex, 0), + MatrixType::ColsAtCompileTime - EIGEN_PLAIN_ENUM_MAX( DiagIndex, 0))), + ColsAtCompileTime = 1, + MaxRowsAtCompileTime = int(MatrixType::MaxSizeAtCompileTime) == Dynamic ? Dynamic + : DiagIndex == DynamicIndex ? EIGEN_SIZE_MIN_PREFER_FIXED(MatrixType::MaxRowsAtCompileTime, + MatrixType::MaxColsAtCompileTime) + : (EIGEN_PLAIN_ENUM_MIN(MatrixType::MaxRowsAtCompileTime - EIGEN_PLAIN_ENUM_MAX(-DiagIndex, 0), + MatrixType::MaxColsAtCompileTime - EIGEN_PLAIN_ENUM_MAX( DiagIndex, 0))), + MaxColsAtCompileTime = 1, + MaskLvalueBit = is_lvalue::value ? LvalueBit : 0, + Flags = (unsigned int)_MatrixTypeNested::Flags & (HereditaryBits | LinearAccessBit | MaskLvalueBit | DirectAccessBit) & ~RowMajorBit, + CoeffReadCost = _MatrixTypeNested::CoeffReadCost, + MatrixTypeOuterStride = outer_stride_at_compile_time::ret, + InnerStrideAtCompileTime = MatrixTypeOuterStride == Dynamic ? Dynamic : MatrixTypeOuterStride+1, + OuterStrideAtCompileTime = 0 + }; +}; +} + +template class Diagonal + : public internal::dense_xpr_base< Diagonal >::type +{ + public: + + enum { DiagIndex = _DiagIndex }; + typedef typename internal::dense_xpr_base::type Base; + EIGEN_DENSE_PUBLIC_INTERFACE(Diagonal) + + inline Diagonal(MatrixType& matrix, Index a_index = DiagIndex) : m_matrix(matrix), m_index(a_index) {} + + EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Diagonal) + + inline Index rows() const + { return m_index.value()<0 ? (std::min)(m_matrix.cols(),m_matrix.rows()+m_index.value()) : (std::min)(m_matrix.rows(),m_matrix.cols()-m_index.value()); } + + inline Index cols() const { return 1; } + + inline Index innerStride() const + { + return m_matrix.outerStride() + 1; + } + + inline Index outerStride() const + { + return 0; + } + + typedef typename internal::conditional< + internal::is_lvalue::value, + Scalar, + const Scalar + >::type ScalarWithConstIfNotLvalue; + + inline ScalarWithConstIfNotLvalue* data() { return &(m_matrix.const_cast_derived().coeffRef(rowOffset(), colOffset())); } + inline const Scalar* data() const { return &(m_matrix.const_cast_derived().coeffRef(rowOffset(), colOffset())); } + + inline Scalar& coeffRef(Index row, Index) + { + EIGEN_STATIC_ASSERT_LVALUE(MatrixType) + return m_matrix.const_cast_derived().coeffRef(row+rowOffset(), row+colOffset()); + } + + inline const Scalar& coeffRef(Index row, Index) const + { + return m_matrix.const_cast_derived().coeffRef(row+rowOffset(), row+colOffset()); + } + + inline CoeffReturnType coeff(Index row, Index) const + { + return m_matrix.coeff(row+rowOffset(), row+colOffset()); + } + + inline Scalar& coeffRef(Index idx) + { + EIGEN_STATIC_ASSERT_LVALUE(MatrixType) + return m_matrix.const_cast_derived().coeffRef(idx+rowOffset(), idx+colOffset()); + } + + inline const Scalar& coeffRef(Index idx) const + { + return m_matrix.const_cast_derived().coeffRef(idx+rowOffset(), idx+colOffset()); + } + + inline CoeffReturnType coeff(Index idx) const + { + return m_matrix.coeff(idx+rowOffset(), idx+colOffset()); + } + + const typename internal::remove_all::type& + nestedExpression() const + { + return m_matrix; + } + + int index() const + { + return m_index.value(); + } + + protected: + typename MatrixType::Nested m_matrix; + const internal::variable_if_dynamicindex m_index; + + private: + // some compilers may fail to optimize std::max etc in case of compile-time constants... + EIGEN_STRONG_INLINE Index absDiagIndex() const { return m_index.value()>0 ? m_index.value() : -m_index.value(); } + EIGEN_STRONG_INLINE Index rowOffset() const { return m_index.value()>0 ? 0 : -m_index.value(); } + EIGEN_STRONG_INLINE Index colOffset() const { return m_index.value()>0 ? m_index.value() : 0; } + // triger a compile time error is someone try to call packet + template typename MatrixType::PacketReturnType packet(Index) const; + template typename MatrixType::PacketReturnType packet(Index,Index) const; +}; + +/** \returns an expression of the main diagonal of the matrix \c *this + * + * \c *this is not required to be square. + * + * Example: \include MatrixBase_diagonal.cpp + * Output: \verbinclude MatrixBase_diagonal.out + * + * \sa class Diagonal */ +template +inline typename MatrixBase::DiagonalReturnType +MatrixBase::diagonal() +{ + return derived(); +} + +/** This is the const version of diagonal(). */ +template +inline typename MatrixBase::ConstDiagonalReturnType +MatrixBase::diagonal() const +{ + return ConstDiagonalReturnType(derived()); +} + +/** \returns an expression of the \a DiagIndex-th sub or super diagonal of the matrix \c *this + * + * \c *this is not required to be square. + * + * The template parameter \a DiagIndex represent a super diagonal if \a DiagIndex > 0 + * and a sub diagonal otherwise. \a DiagIndex == 0 is equivalent to the main diagonal. + * + * Example: \include MatrixBase_diagonal_int.cpp + * Output: \verbinclude MatrixBase_diagonal_int.out + * + * \sa MatrixBase::diagonal(), class Diagonal */ +template +inline typename MatrixBase::DiagonalDynamicIndexReturnType +MatrixBase::diagonal(Index index) +{ + return DiagonalDynamicIndexReturnType(derived(), index); +} + +/** This is the const version of diagonal(Index). */ +template +inline typename MatrixBase::ConstDiagonalDynamicIndexReturnType +MatrixBase::diagonal(Index index) const +{ + return ConstDiagonalDynamicIndexReturnType(derived(), index); +} + +/** \returns an expression of the \a DiagIndex-th sub or super diagonal of the matrix \c *this + * + * \c *this is not required to be square. + * + * The template parameter \a DiagIndex represent a super diagonal if \a DiagIndex > 0 + * and a sub diagonal otherwise. \a DiagIndex == 0 is equivalent to the main diagonal. + * + * Example: \include MatrixBase_diagonal_template_int.cpp + * Output: \verbinclude MatrixBase_diagonal_template_int.out + * + * \sa MatrixBase::diagonal(), class Diagonal */ +template +template +inline typename MatrixBase::template DiagonalIndexReturnType::Type +MatrixBase::diagonal() +{ + return derived(); +} + +/** This is the const version of diagonal(). */ +template +template +inline typename MatrixBase::template ConstDiagonalIndexReturnType::Type +MatrixBase::diagonal() const +{ + return derived(); +} + +} // end namespace Eigen + +#endif // EIGEN_DIAGONAL_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/DiagonalMatrix.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/DiagonalMatrix.h new file mode 100644 index 00000000..e6c220f4 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/DiagonalMatrix.h @@ -0,0 +1,313 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2009 Gael Guennebaud +// Copyright (C) 2007-2009 Benoit Jacob +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_DIAGONALMATRIX_H +#define EIGEN_DIAGONALMATRIX_H + +namespace Eigen { + +#ifndef EIGEN_PARSED_BY_DOXYGEN +template +class DiagonalBase : public EigenBase +{ + public: + typedef typename internal::traits::DiagonalVectorType DiagonalVectorType; + typedef typename DiagonalVectorType::Scalar Scalar; + typedef typename DiagonalVectorType::RealScalar RealScalar; + typedef typename internal::traits::StorageKind StorageKind; + typedef typename internal::traits::Index Index; + + enum { + RowsAtCompileTime = DiagonalVectorType::SizeAtCompileTime, + ColsAtCompileTime = DiagonalVectorType::SizeAtCompileTime, + MaxRowsAtCompileTime = DiagonalVectorType::MaxSizeAtCompileTime, + MaxColsAtCompileTime = DiagonalVectorType::MaxSizeAtCompileTime, + IsVectorAtCompileTime = 0, + Flags = 0 + }; + + typedef Matrix DenseMatrixType; + typedef DenseMatrixType DenseType; + typedef DiagonalMatrix PlainObject; + + inline const Derived& derived() const { return *static_cast(this); } + inline Derived& derived() { return *static_cast(this); } + + DenseMatrixType toDenseMatrix() const { return derived(); } + template + void evalTo(MatrixBase &other) const; + template + void addTo(MatrixBase &other) const + { other.diagonal() += diagonal(); } + template + void subTo(MatrixBase &other) const + { other.diagonal() -= diagonal(); } + + inline const DiagonalVectorType& diagonal() const { return derived().diagonal(); } + inline DiagonalVectorType& diagonal() { return derived().diagonal(); } + + inline Index rows() const { return diagonal().size(); } + inline Index cols() const { return diagonal().size(); } + + /** \returns the diagonal matrix product of \c *this by the matrix \a matrix. + */ + template + const DiagonalProduct + operator*(const MatrixBase &matrix) const + { + return DiagonalProduct(matrix.derived(), derived()); + } + + inline const DiagonalWrapper, const DiagonalVectorType> > + inverse() const + { + return diagonal().cwiseInverse(); + } + + inline const DiagonalWrapper, const DiagonalVectorType> > + operator*(const Scalar& scalar) const + { + return diagonal() * scalar; + } + friend inline const DiagonalWrapper, const DiagonalVectorType> > + operator*(const Scalar& scalar, const DiagonalBase& other) + { + return other.diagonal() * scalar; + } + + #ifdef EIGEN2_SUPPORT + template + bool isApprox(const DiagonalBase& other, typename NumTraits::Real precision = NumTraits::dummy_precision()) const + { + return diagonal().isApprox(other.diagonal(), precision); + } + template + bool isApprox(const MatrixBase& other, typename NumTraits::Real precision = NumTraits::dummy_precision()) const + { + return toDenseMatrix().isApprox(other, precision); + } + #endif +}; + +template +template +void DiagonalBase::evalTo(MatrixBase &other) const +{ + other.setZero(); + other.diagonal() = diagonal(); +} +#endif + +/** \class DiagonalMatrix + * \ingroup Core_Module + * + * \brief Represents a diagonal matrix with its storage + * + * \param _Scalar the type of coefficients + * \param SizeAtCompileTime the dimension of the matrix, or Dynamic + * \param MaxSizeAtCompileTime the dimension of the matrix, or Dynamic. This parameter is optional and defaults + * to SizeAtCompileTime. Most of the time, you do not need to specify it. + * + * \sa class DiagonalWrapper + */ + +namespace internal { +template +struct traits > + : traits > +{ + typedef Matrix<_Scalar,SizeAtCompileTime,1,0,MaxSizeAtCompileTime,1> DiagonalVectorType; + typedef Dense StorageKind; + typedef DenseIndex Index; + enum { + Flags = LvalueBit + }; +}; +} +template +class DiagonalMatrix + : public DiagonalBase > +{ + public: + #ifndef EIGEN_PARSED_BY_DOXYGEN + typedef typename internal::traits::DiagonalVectorType DiagonalVectorType; + typedef const DiagonalMatrix& Nested; + typedef _Scalar Scalar; + typedef typename internal::traits::StorageKind StorageKind; + typedef typename internal::traits::Index Index; + #endif + + protected: + + DiagonalVectorType m_diagonal; + + public: + + /** const version of diagonal(). */ + inline const DiagonalVectorType& diagonal() const { return m_diagonal; } + /** \returns a reference to the stored vector of diagonal coefficients. */ + inline DiagonalVectorType& diagonal() { return m_diagonal; } + + /** Default constructor without initialization */ + inline DiagonalMatrix() {} + + /** Constructs a diagonal matrix with given dimension */ + inline DiagonalMatrix(Index dim) : m_diagonal(dim) {} + + /** 2D constructor. */ + inline DiagonalMatrix(const Scalar& x, const Scalar& y) : m_diagonal(x,y) {} + + /** 3D constructor. */ + inline DiagonalMatrix(const Scalar& x, const Scalar& y, const Scalar& z) : m_diagonal(x,y,z) {} + + /** Copy constructor. */ + template + inline DiagonalMatrix(const DiagonalBase& other) : m_diagonal(other.diagonal()) {} + + #ifndef EIGEN_PARSED_BY_DOXYGEN + /** copy constructor. prevent a default copy constructor from hiding the other templated constructor */ + inline DiagonalMatrix(const DiagonalMatrix& other) : m_diagonal(other.diagonal()) {} + #endif + + /** generic constructor from expression of the diagonal coefficients */ + template + explicit inline DiagonalMatrix(const MatrixBase& other) : m_diagonal(other) + {} + + /** Copy operator. */ + template + DiagonalMatrix& operator=(const DiagonalBase& other) + { + m_diagonal = other.diagonal(); + return *this; + } + + #ifndef EIGEN_PARSED_BY_DOXYGEN + /** This is a special case of the templated operator=. Its purpose is to + * prevent a default operator= from hiding the templated operator=. + */ + DiagonalMatrix& operator=(const DiagonalMatrix& other) + { + m_diagonal = other.diagonal(); + return *this; + } + #endif + + /** Resizes to given size. */ + inline void resize(Index size) { m_diagonal.resize(size); } + /** Sets all coefficients to zero. */ + inline void setZero() { m_diagonal.setZero(); } + /** Resizes and sets all coefficients to zero. */ + inline void setZero(Index size) { m_diagonal.setZero(size); } + /** Sets this matrix to be the identity matrix of the current size. */ + inline void setIdentity() { m_diagonal.setOnes(); } + /** Sets this matrix to be the identity matrix of the given size. */ + inline void setIdentity(Index size) { m_diagonal.setOnes(size); } +}; + +/** \class DiagonalWrapper + * \ingroup Core_Module + * + * \brief Expression of a diagonal matrix + * + * \param _DiagonalVectorType the type of the vector of diagonal coefficients + * + * This class is an expression of a diagonal matrix, but not storing its own vector of diagonal coefficients, + * instead wrapping an existing vector expression. It is the return type of MatrixBase::asDiagonal() + * and most of the time this is the only way that it is used. + * + * \sa class DiagonalMatrix, class DiagonalBase, MatrixBase::asDiagonal() + */ + +namespace internal { +template +struct traits > +{ + typedef _DiagonalVectorType DiagonalVectorType; + typedef typename DiagonalVectorType::Scalar Scalar; + typedef typename DiagonalVectorType::Index Index; + typedef typename DiagonalVectorType::StorageKind StorageKind; + enum { + RowsAtCompileTime = DiagonalVectorType::SizeAtCompileTime, + ColsAtCompileTime = DiagonalVectorType::SizeAtCompileTime, + MaxRowsAtCompileTime = DiagonalVectorType::SizeAtCompileTime, + MaxColsAtCompileTime = DiagonalVectorType::SizeAtCompileTime, + Flags = traits::Flags & LvalueBit + }; +}; +} + +template +class DiagonalWrapper + : public DiagonalBase >, internal::no_assignment_operator +{ + public: + #ifndef EIGEN_PARSED_BY_DOXYGEN + typedef _DiagonalVectorType DiagonalVectorType; + typedef DiagonalWrapper Nested; + #endif + + /** Constructor from expression of diagonal coefficients to wrap. */ + inline DiagonalWrapper(DiagonalVectorType& a_diagonal) : m_diagonal(a_diagonal) {} + + /** \returns a const reference to the wrapped expression of diagonal coefficients. */ + const DiagonalVectorType& diagonal() const { return m_diagonal; } + + protected: + typename DiagonalVectorType::Nested m_diagonal; +}; + +/** \returns a pseudo-expression of a diagonal matrix with *this as vector of diagonal coefficients + * + * \only_for_vectors + * + * Example: \include MatrixBase_asDiagonal.cpp + * Output: \verbinclude MatrixBase_asDiagonal.out + * + * \sa class DiagonalWrapper, class DiagonalMatrix, diagonal(), isDiagonal() + **/ +template +inline const DiagonalWrapper +MatrixBase::asDiagonal() const +{ + return derived(); +} + +/** \returns true if *this is approximately equal to a diagonal matrix, + * within the precision given by \a prec. + * + * Example: \include MatrixBase_isDiagonal.cpp + * Output: \verbinclude MatrixBase_isDiagonal.out + * + * \sa asDiagonal() + */ +template +bool MatrixBase::isDiagonal(const RealScalar& prec) const +{ + using std::abs; + if(cols() != rows()) return false; + RealScalar maxAbsOnDiagonal = static_cast(-1); + for(Index j = 0; j < cols(); ++j) + { + RealScalar absOnDiagonal = abs(coeff(j,j)); + if(absOnDiagonal > maxAbsOnDiagonal) maxAbsOnDiagonal = absOnDiagonal; + } + for(Index j = 0; j < cols(); ++j) + for(Index i = 0; i < j; ++i) + { + if(!internal::isMuchSmallerThan(coeff(i, j), maxAbsOnDiagonal, prec)) return false; + if(!internal::isMuchSmallerThan(coeff(j, i), maxAbsOnDiagonal, prec)) return false; + } + return true; +} + +} // end namespace Eigen + +#endif // EIGEN_DIAGONALMATRIX_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/DiagonalProduct.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/DiagonalProduct.h new file mode 100644 index 00000000..cc6b536e --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/DiagonalProduct.h @@ -0,0 +1,131 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008 Gael Guennebaud +// Copyright (C) 2007-2009 Benoit Jacob +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_DIAGONALPRODUCT_H +#define EIGEN_DIAGONALPRODUCT_H + +namespace Eigen { + +namespace internal { +template +struct traits > + : traits +{ + typedef typename scalar_product_traits::ReturnType Scalar; + enum { + RowsAtCompileTime = MatrixType::RowsAtCompileTime, + ColsAtCompileTime = MatrixType::ColsAtCompileTime, + MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime, + MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime, + + _StorageOrder = MatrixType::Flags & RowMajorBit ? RowMajor : ColMajor, + _ScalarAccessOnDiag = !((int(_StorageOrder) == ColMajor && int(ProductOrder) == OnTheLeft) + ||(int(_StorageOrder) == RowMajor && int(ProductOrder) == OnTheRight)), + _SameTypes = is_same::value, + // FIXME currently we need same types, but in the future the next rule should be the one + //_Vectorizable = bool(int(MatrixType::Flags)&PacketAccessBit) && ((!_PacketOnDiag) || (_SameTypes && bool(int(DiagonalType::DiagonalVectorType::Flags)&PacketAccessBit))), + _Vectorizable = bool(int(MatrixType::Flags)&PacketAccessBit) && _SameTypes && (_ScalarAccessOnDiag || (bool(int(DiagonalType::DiagonalVectorType::Flags)&PacketAccessBit))), + _LinearAccessMask = (RowsAtCompileTime==1 || ColsAtCompileTime==1) ? LinearAccessBit : 0, + + Flags = ((HereditaryBits|_LinearAccessMask|AlignedBit) & (unsigned int)(MatrixType::Flags)) | (_Vectorizable ? PacketAccessBit : 0),//(int(MatrixType::Flags)&int(DiagonalType::DiagonalVectorType::Flags)&AlignedBit), + Cost0 = EIGEN_ADD_COST(NumTraits::MulCost, MatrixType::CoeffReadCost), + CoeffReadCost = EIGEN_ADD_COST(Cost0,DiagonalType::DiagonalVectorType::CoeffReadCost) + }; +}; +} + +template +class DiagonalProduct : internal::no_assignment_operator, + public MatrixBase > +{ + public: + + typedef MatrixBase Base; + EIGEN_DENSE_PUBLIC_INTERFACE(DiagonalProduct) + + inline DiagonalProduct(const MatrixType& matrix, const DiagonalType& diagonal) + : m_matrix(matrix), m_diagonal(diagonal) + { + eigen_assert(diagonal.diagonal().size() == (ProductOrder == OnTheLeft ? matrix.rows() : matrix.cols())); + } + + EIGEN_STRONG_INLINE Index rows() const { return m_matrix.rows(); } + EIGEN_STRONG_INLINE Index cols() const { return m_matrix.cols(); } + + EIGEN_STRONG_INLINE const Scalar coeff(Index row, Index col) const + { + return m_diagonal.diagonal().coeff(ProductOrder == OnTheLeft ? row : col) * m_matrix.coeff(row, col); + } + + EIGEN_STRONG_INLINE const Scalar coeff(Index idx) const + { + enum { + StorageOrder = int(MatrixType::Flags) & RowMajorBit ? RowMajor : ColMajor + }; + return coeff(int(StorageOrder)==ColMajor?idx:0,int(StorageOrder)==ColMajor?0:idx); + } + + template + EIGEN_STRONG_INLINE PacketScalar packet(Index row, Index col) const + { + enum { + StorageOrder = Flags & RowMajorBit ? RowMajor : ColMajor + }; + const Index indexInDiagonalVector = ProductOrder == OnTheLeft ? row : col; + return packet_impl(row,col,indexInDiagonalVector,typename internal::conditional< + ((int(StorageOrder) == RowMajor && int(ProductOrder) == OnTheLeft) + ||(int(StorageOrder) == ColMajor && int(ProductOrder) == OnTheRight)), internal::true_type, internal::false_type>::type()); + } + + template + EIGEN_STRONG_INLINE PacketScalar packet(Index idx) const + { + enum { + StorageOrder = int(MatrixType::Flags) & RowMajorBit ? RowMajor : ColMajor + }; + return packet(int(StorageOrder)==ColMajor?idx:0,int(StorageOrder)==ColMajor?0:idx); + } + + protected: + template + EIGEN_STRONG_INLINE PacketScalar packet_impl(Index row, Index col, Index id, internal::true_type) const + { + return internal::pmul(m_matrix.template packet(row, col), + internal::pset1(m_diagonal.diagonal().coeff(id))); + } + + template + EIGEN_STRONG_INLINE PacketScalar packet_impl(Index row, Index col, Index id, internal::false_type) const + { + enum { + InnerSize = (MatrixType::Flags & RowMajorBit) ? MatrixType::ColsAtCompileTime : MatrixType::RowsAtCompileTime, + DiagonalVectorPacketLoadMode = (LoadMode == Aligned && (((InnerSize%16) == 0) || (int(DiagonalType::DiagonalVectorType::Flags)&AlignedBit)==AlignedBit) ? Aligned : Unaligned) + }; + return internal::pmul(m_matrix.template packet(row, col), + m_diagonal.diagonal().template packet(id)); + } + + typename MatrixType::Nested m_matrix; + typename DiagonalType::Nested m_diagonal; +}; + +/** \returns the diagonal matrix product of \c *this by the diagonal matrix \a diagonal. + */ +template +template +inline const DiagonalProduct +MatrixBase::operator*(const DiagonalBase &a_diagonal) const +{ + return DiagonalProduct(derived(), a_diagonal.derived()); +} + +} // end namespace Eigen + +#endif // EIGEN_DIAGONALPRODUCT_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/Dot.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/Dot.h new file mode 100644 index 00000000..9d7651f1 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/Dot.h @@ -0,0 +1,263 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2006-2008, 2010 Benoit Jacob +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_DOT_H +#define EIGEN_DOT_H + +namespace Eigen { + +namespace internal { + +// helper function for dot(). The problem is that if we put that in the body of dot(), then upon calling dot +// with mismatched types, the compiler emits errors about failing to instantiate cwiseProduct BEFORE +// looking at the static assertions. Thus this is a trick to get better compile errors. +template +struct dot_nocheck +{ + typedef typename scalar_product_traits::Scalar,typename traits::Scalar>::ReturnType ResScalar; + static inline ResScalar run(const MatrixBase& a, const MatrixBase& b) + { + return a.template binaryExpr::Scalar,typename traits::Scalar> >(b).sum(); + } +}; + +template +struct dot_nocheck +{ + typedef typename scalar_product_traits::Scalar,typename traits::Scalar>::ReturnType ResScalar; + static inline ResScalar run(const MatrixBase& a, const MatrixBase& b) + { + return a.transpose().template binaryExpr::Scalar,typename traits::Scalar> >(b).sum(); + } +}; + +} // end namespace internal + +/** \returns the dot product of *this with other. + * + * \only_for_vectors + * + * \note If the scalar type is complex numbers, then this function returns the hermitian + * (sesquilinear) dot product, conjugate-linear in the first variable and linear in the + * second variable. + * + * \sa squaredNorm(), norm() + */ +template +template +typename internal::scalar_product_traits::Scalar,typename internal::traits::Scalar>::ReturnType +MatrixBase::dot(const MatrixBase& other) const +{ + EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) + EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived) + EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(Derived,OtherDerived) + typedef internal::scalar_conj_product_op func; + EIGEN_CHECK_BINARY_COMPATIBILIY(func,Scalar,typename OtherDerived::Scalar); + + eigen_assert(size() == other.size()); + + return internal::dot_nocheck::run(*this, other); +} + +#ifdef EIGEN2_SUPPORT +/** \returns the dot product of *this with other, with the Eigen2 convention that the dot product is linear in the first variable + * (conjugating the second variable). Of course this only makes a difference in the complex case. + * + * This method is only available in EIGEN2_SUPPORT mode. + * + * \only_for_vectors + * + * \sa dot() + */ +template +template +typename internal::traits::Scalar +MatrixBase::eigen2_dot(const MatrixBase& other) const +{ + EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) + EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived) + EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(Derived,OtherDerived) + EIGEN_STATIC_ASSERT((internal::is_same::value), + YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) + + eigen_assert(size() == other.size()); + + return internal::dot_nocheck::run(other,*this); +} +#endif + + +//---------- implementation of L2 norm and related functions ---------- + +/** \returns, for vectors, the squared \em l2 norm of \c *this, and for matrices the Frobenius norm. + * In both cases, it consists in the sum of the square of all the matrix entries. + * For vectors, this is also equals to the dot product of \c *this with itself. + * + * \sa dot(), norm() + */ +template +EIGEN_STRONG_INLINE typename NumTraits::Scalar>::Real MatrixBase::squaredNorm() const +{ + return numext::real((*this).cwiseAbs2().sum()); +} + +/** \returns, for vectors, the \em l2 norm of \c *this, and for matrices the Frobenius norm. + * In both cases, it consists in the square root of the sum of the square of all the matrix entries. + * For vectors, this is also equals to the square root of the dot product of \c *this with itself. + * + * \sa dot(), squaredNorm() + */ +template +inline typename NumTraits::Scalar>::Real MatrixBase::norm() const +{ + using std::sqrt; + return sqrt(squaredNorm()); +} + +/** \returns an expression of the quotient of *this by its own norm. + * + * \only_for_vectors + * + * \sa norm(), normalize() + */ +template +inline const typename MatrixBase::PlainObject +MatrixBase::normalized() const +{ + typedef typename internal::nested::type Nested; + typedef typename internal::remove_reference::type _Nested; + _Nested n(derived()); + return n / n.norm(); +} + +/** Normalizes the vector, i.e. divides it by its own norm. + * + * \only_for_vectors + * + * \sa norm(), normalized() + */ +template +inline void MatrixBase::normalize() +{ + *this /= norm(); +} + +//---------- implementation of other norms ---------- + +namespace internal { + +template +struct lpNorm_selector +{ + typedef typename NumTraits::Scalar>::Real RealScalar; + static inline RealScalar run(const MatrixBase& m) + { + using std::pow; + return pow(m.cwiseAbs().array().pow(p).sum(), RealScalar(1)/p); + } +}; + +template +struct lpNorm_selector +{ + static inline typename NumTraits::Scalar>::Real run(const MatrixBase& m) + { + return m.cwiseAbs().sum(); + } +}; + +template +struct lpNorm_selector +{ + static inline typename NumTraits::Scalar>::Real run(const MatrixBase& m) + { + return m.norm(); + } +}; + +template +struct lpNorm_selector +{ + static inline typename NumTraits::Scalar>::Real run(const MatrixBase& m) + { + return m.cwiseAbs().maxCoeff(); + } +}; + +} // end namespace internal + +/** \returns the \f$ \ell^p \f$ norm of *this, that is, returns the p-th root of the sum of the p-th powers of the absolute values + * of the coefficients of *this. If \a p is the special value \a Eigen::Infinity, this function returns the \f$ \ell^\infty \f$ + * norm, that is the maximum of the absolute values of the coefficients of *this. + * + * \sa norm() + */ +template +template +inline typename NumTraits::Scalar>::Real +MatrixBase::lpNorm() const +{ + return internal::lpNorm_selector::run(*this); +} + +//---------- implementation of isOrthogonal / isUnitary ---------- + +/** \returns true if *this is approximately orthogonal to \a other, + * within the precision given by \a prec. + * + * Example: \include MatrixBase_isOrthogonal.cpp + * Output: \verbinclude MatrixBase_isOrthogonal.out + */ +template +template +bool MatrixBase::isOrthogonal +(const MatrixBase& other, const RealScalar& prec) const +{ + typename internal::nested::type nested(derived()); + typename internal::nested::type otherNested(other.derived()); + return numext::abs2(nested.dot(otherNested)) <= prec * prec * nested.squaredNorm() * otherNested.squaredNorm(); +} + +/** \returns true if *this is approximately an unitary matrix, + * within the precision given by \a prec. In the case where the \a Scalar + * type is real numbers, a unitary matrix is an orthogonal matrix, whence the name. + * + * \note This can be used to check whether a family of vectors forms an orthonormal basis. + * Indeed, \c m.isUnitary() returns true if and only if the columns (equivalently, the rows) of m form an + * orthonormal basis. + * + * Example: \include MatrixBase_isUnitary.cpp + * Output: \verbinclude MatrixBase_isUnitary.out + */ +template +bool MatrixBase::isUnitary(const RealScalar& prec) const +{ + typename Derived::Nested nested(derived()); + for(Index i = 0; i < cols(); ++i) + { + if(!internal::isApprox(nested.col(i).squaredNorm(), static_cast(1), prec)) + return false; + for(Index j = 0; j < i; ++j) + if(!internal::isMuchSmallerThan(nested.col(i).dot(nested.col(j)), static_cast(1), prec)) + return false; + } + return true; +} + +} // end namespace Eigen + +#endif // EIGEN_DOT_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/EigenBase.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/EigenBase.h new file mode 100644 index 00000000..fadb4585 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/EigenBase.h @@ -0,0 +1,131 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2009 Benoit Jacob +// Copyright (C) 2009 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_EIGENBASE_H +#define EIGEN_EIGENBASE_H + +namespace Eigen { + +/** Common base class for all classes T such that MatrixBase has an operator=(T) and a constructor MatrixBase(T). + * + * In other words, an EigenBase object is an object that can be copied into a MatrixBase. + * + * Besides MatrixBase-derived classes, this also includes special matrix classes such as diagonal matrices, etc. + * + * Notice that this class is trivial, it is only used to disambiguate overloaded functions. + * + * \sa \ref TopicClassHierarchy + */ +template struct EigenBase +{ +// typedef typename internal::plain_matrix_type::type PlainObject; + + typedef typename internal::traits::StorageKind StorageKind; + typedef typename internal::traits::Index Index; + + /** \returns a reference to the derived object */ + Derived& derived() { return *static_cast(this); } + /** \returns a const reference to the derived object */ + const Derived& derived() const { return *static_cast(this); } + + inline Derived& const_cast_derived() const + { return *static_cast(const_cast(this)); } + inline const Derived& const_derived() const + { return *static_cast(this); } + + /** \returns the number of rows. \sa cols(), RowsAtCompileTime */ + inline Index rows() const { return derived().rows(); } + /** \returns the number of columns. \sa rows(), ColsAtCompileTime*/ + inline Index cols() const { return derived().cols(); } + /** \returns the number of coefficients, which is rows()*cols(). + * \sa rows(), cols(), SizeAtCompileTime. */ + inline Index size() const { return rows() * cols(); } + + /** \internal Don't use it, but do the equivalent: \code dst = *this; \endcode */ + template inline void evalTo(Dest& dst) const + { derived().evalTo(dst); } + + /** \internal Don't use it, but do the equivalent: \code dst += *this; \endcode */ + template inline void addTo(Dest& dst) const + { + // This is the default implementation, + // derived class can reimplement it in a more optimized way. + typename Dest::PlainObject res(rows(),cols()); + evalTo(res); + dst += res; + } + + /** \internal Don't use it, but do the equivalent: \code dst -= *this; \endcode */ + template inline void subTo(Dest& dst) const + { + // This is the default implementation, + // derived class can reimplement it in a more optimized way. + typename Dest::PlainObject res(rows(),cols()); + evalTo(res); + dst -= res; + } + + /** \internal Don't use it, but do the equivalent: \code dst.applyOnTheRight(*this); \endcode */ + template inline void applyThisOnTheRight(Dest& dst) const + { + // This is the default implementation, + // derived class can reimplement it in a more optimized way. + dst = dst * this->derived(); + } + + /** \internal Don't use it, but do the equivalent: \code dst.applyOnTheLeft(*this); \endcode */ + template inline void applyThisOnTheLeft(Dest& dst) const + { + // This is the default implementation, + // derived class can reimplement it in a more optimized way. + dst = this->derived() * dst; + } + +}; + +/*************************************************************************** +* Implementation of matrix base methods +***************************************************************************/ + +/** \brief Copies the generic expression \a other into *this. + * + * \details The expression must provide a (templated) evalTo(Derived& dst) const + * function which does the actual job. In practice, this allows any user to write + * its own special matrix without having to modify MatrixBase + * + * \returns a reference to *this. + */ +template +template +Derived& DenseBase::operator=(const EigenBase &other) +{ + other.derived().evalTo(derived()); + return derived(); +} + +template +template +Derived& DenseBase::operator+=(const EigenBase &other) +{ + other.derived().addTo(derived()); + return derived(); +} + +template +template +Derived& DenseBase::operator-=(const EigenBase &other) +{ + other.derived().subTo(derived()); + return derived(); +} + +} // end namespace Eigen + +#endif // EIGEN_EIGENBASE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/Flagged.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/Flagged.h new file mode 100644 index 00000000..1f2955fc --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/Flagged.h @@ -0,0 +1,140 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008 Benoit Jacob +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_FLAGGED_H +#define EIGEN_FLAGGED_H + +namespace Eigen { + +/** \class Flagged + * \ingroup Core_Module + * + * \brief Expression with modified flags + * + * \param ExpressionType the type of the object of which we are modifying the flags + * \param Added the flags added to the expression + * \param Removed the flags removed from the expression (has priority over Added). + * + * This class represents an expression whose flags have been modified. + * It is the return type of MatrixBase::flagged() + * and most of the time this is the only way it is used. + * + * \sa MatrixBase::flagged() + */ + +namespace internal { +template +struct traits > : traits +{ + enum { Flags = (ExpressionType::Flags | Added) & ~Removed }; +}; +} + +template class Flagged + : public MatrixBase > +{ + public: + + typedef MatrixBase Base; + + EIGEN_DENSE_PUBLIC_INTERFACE(Flagged) + typedef typename internal::conditional::ret, + ExpressionType, const ExpressionType&>::type ExpressionTypeNested; + typedef typename ExpressionType::InnerIterator InnerIterator; + + inline Flagged(const ExpressionType& matrix) : m_matrix(matrix) {} + + inline Index rows() const { return m_matrix.rows(); } + inline Index cols() const { return m_matrix.cols(); } + inline Index outerStride() const { return m_matrix.outerStride(); } + inline Index innerStride() const { return m_matrix.innerStride(); } + + inline CoeffReturnType coeff(Index row, Index col) const + { + return m_matrix.coeff(row, col); + } + + inline CoeffReturnType coeff(Index index) const + { + return m_matrix.coeff(index); + } + + inline const Scalar& coeffRef(Index row, Index col) const + { + return m_matrix.const_cast_derived().coeffRef(row, col); + } + + inline const Scalar& coeffRef(Index index) const + { + return m_matrix.const_cast_derived().coeffRef(index); + } + + inline Scalar& coeffRef(Index row, Index col) + { + return m_matrix.const_cast_derived().coeffRef(row, col); + } + + inline Scalar& coeffRef(Index index) + { + return m_matrix.const_cast_derived().coeffRef(index); + } + + template + inline const PacketScalar packet(Index row, Index col) const + { + return m_matrix.template packet(row, col); + } + + template + inline void writePacket(Index row, Index col, const PacketScalar& x) + { + m_matrix.const_cast_derived().template writePacket(row, col, x); + } + + template + inline const PacketScalar packet(Index index) const + { + return m_matrix.template packet(index); + } + + template + inline void writePacket(Index index, const PacketScalar& x) + { + m_matrix.const_cast_derived().template writePacket(index, x); + } + + const ExpressionType& _expression() const { return m_matrix; } + + template + typename ExpressionType::PlainObject solveTriangular(const MatrixBase& other) const; + + template + void solveTriangularInPlace(const MatrixBase& other) const; + + protected: + ExpressionTypeNested m_matrix; +}; + +/** \returns an expression of *this with added and removed flags + * + * This is mostly for internal use. + * + * \sa class Flagged + */ +template +template +inline const Flagged +DenseBase::flagged() const +{ + return derived(); +} + +} // end namespace Eigen + +#endif // EIGEN_FLAGGED_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/ForceAlignedAccess.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/ForceAlignedAccess.h new file mode 100644 index 00000000..807c7a29 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/ForceAlignedAccess.h @@ -0,0 +1,146 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2009-2010 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_FORCEALIGNEDACCESS_H +#define EIGEN_FORCEALIGNEDACCESS_H + +namespace Eigen { + +/** \class ForceAlignedAccess + * \ingroup Core_Module + * + * \brief Enforce aligned packet loads and stores regardless of what is requested + * + * \param ExpressionType the type of the object of which we are forcing aligned packet access + * + * This class is the return type of MatrixBase::forceAlignedAccess() + * and most of the time this is the only way it is used. + * + * \sa MatrixBase::forceAlignedAccess() + */ + +namespace internal { +template +struct traits > : public traits +{}; +} + +template class ForceAlignedAccess + : public internal::dense_xpr_base< ForceAlignedAccess >::type +{ + public: + + typedef typename internal::dense_xpr_base::type Base; + EIGEN_DENSE_PUBLIC_INTERFACE(ForceAlignedAccess) + + inline ForceAlignedAccess(const ExpressionType& matrix) : m_expression(matrix) {} + + inline Index rows() const { return m_expression.rows(); } + inline Index cols() const { return m_expression.cols(); } + inline Index outerStride() const { return m_expression.outerStride(); } + inline Index innerStride() const { return m_expression.innerStride(); } + + inline const CoeffReturnType coeff(Index row, Index col) const + { + return m_expression.coeff(row, col); + } + + inline Scalar& coeffRef(Index row, Index col) + { + return m_expression.const_cast_derived().coeffRef(row, col); + } + + inline const CoeffReturnType coeff(Index index) const + { + return m_expression.coeff(index); + } + + inline Scalar& coeffRef(Index index) + { + return m_expression.const_cast_derived().coeffRef(index); + } + + template + inline const PacketScalar packet(Index row, Index col) const + { + return m_expression.template packet(row, col); + } + + template + inline void writePacket(Index row, Index col, const PacketScalar& x) + { + m_expression.const_cast_derived().template writePacket(row, col, x); + } + + template + inline const PacketScalar packet(Index index) const + { + return m_expression.template packet(index); + } + + template + inline void writePacket(Index index, const PacketScalar& x) + { + m_expression.const_cast_derived().template writePacket(index, x); + } + + operator const ExpressionType&() const { return m_expression; } + + protected: + const ExpressionType& m_expression; + + private: + ForceAlignedAccess& operator=(const ForceAlignedAccess&); +}; + +/** \returns an expression of *this with forced aligned access + * \sa forceAlignedAccessIf(),class ForceAlignedAccess + */ +template +inline const ForceAlignedAccess +MatrixBase::forceAlignedAccess() const +{ + return ForceAlignedAccess(derived()); +} + +/** \returns an expression of *this with forced aligned access + * \sa forceAlignedAccessIf(), class ForceAlignedAccess + */ +template +inline ForceAlignedAccess +MatrixBase::forceAlignedAccess() +{ + return ForceAlignedAccess(derived()); +} + +/** \returns an expression of *this with forced aligned access if \a Enable is true. + * \sa forceAlignedAccess(), class ForceAlignedAccess + */ +template +template +inline typename internal::add_const_on_value_type,Derived&>::type>::type +MatrixBase::forceAlignedAccessIf() const +{ + return derived(); +} + +/** \returns an expression of *this with forced aligned access if \a Enable is true. + * \sa forceAlignedAccess(), class ForceAlignedAccess + */ +template +template +inline typename internal::conditional,Derived&>::type +MatrixBase::forceAlignedAccessIf() +{ + return derived(); +} + +} // end namespace Eigen + +#endif // EIGEN_FORCEALIGNEDACCESS_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/Functors.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/Functors.h new file mode 100644 index 00000000..5f14c658 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/Functors.h @@ -0,0 +1,1026 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008-2010 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_FUNCTORS_H +#define EIGEN_FUNCTORS_H + +namespace Eigen { + +namespace internal { + +// associative functors: + +/** \internal + * \brief Template functor to compute the sum of two scalars + * + * \sa class CwiseBinaryOp, MatrixBase::operator+, class VectorwiseOp, MatrixBase::sum() + */ +template struct scalar_sum_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_sum_op) + EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a + b; } + template + EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const + { return internal::padd(a,b); } + template + EIGEN_STRONG_INLINE const Scalar predux(const Packet& a) const + { return internal::predux(a); } +}; +template +struct functor_traits > { + enum { + Cost = NumTraits::AddCost, + PacketAccess = packet_traits::HasAdd + }; +}; + +/** \internal + * \brief Template functor to compute the product of two scalars + * + * \sa class CwiseBinaryOp, Cwise::operator*(), class VectorwiseOp, MatrixBase::redux() + */ +template struct scalar_product_op { + enum { + // TODO vectorize mixed product + Vectorizable = is_same::value && packet_traits::HasMul && packet_traits::HasMul + }; + typedef typename scalar_product_traits::ReturnType result_type; + EIGEN_EMPTY_STRUCT_CTOR(scalar_product_op) + EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a * b; } + template + EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const + { return internal::pmul(a,b); } + template + EIGEN_STRONG_INLINE const result_type predux(const Packet& a) const + { return internal::predux_mul(a); } +}; +template +struct functor_traits > { + enum { + Cost = (NumTraits::MulCost + NumTraits::MulCost)/2, // rough estimate! + PacketAccess = scalar_product_op::Vectorizable + }; +}; + +/** \internal + * \brief Template functor to compute the conjugate product of two scalars + * + * This is a short cut for conj(x) * y which is needed for optimization purpose; in Eigen2 support mode, this becomes x * conj(y) + */ +template struct scalar_conj_product_op { + + enum { + Conj = NumTraits::IsComplex + }; + + typedef typename scalar_product_traits::ReturnType result_type; + + EIGEN_EMPTY_STRUCT_CTOR(scalar_conj_product_op) + EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const + { return conj_helper().pmul(a,b); } + + template + EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const + { return conj_helper().pmul(a,b); } +}; +template +struct functor_traits > { + enum { + Cost = NumTraits::MulCost, + PacketAccess = internal::is_same::value && packet_traits::HasMul + }; +}; + +/** \internal + * \brief Template functor to compute the min of two scalars + * + * \sa class CwiseBinaryOp, MatrixBase::cwiseMin, class VectorwiseOp, MatrixBase::minCoeff() + */ +template struct scalar_min_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_min_op) + EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { using std::min; return (min)(a, b); } + template + EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const + { return internal::pmin(a,b); } + template + EIGEN_STRONG_INLINE const Scalar predux(const Packet& a) const + { return internal::predux_min(a); } +}; +template +struct functor_traits > { + enum { + Cost = NumTraits::AddCost, + PacketAccess = packet_traits::HasMin + }; +}; + +/** \internal + * \brief Template functor to compute the max of two scalars + * + * \sa class CwiseBinaryOp, MatrixBase::cwiseMax, class VectorwiseOp, MatrixBase::maxCoeff() + */ +template struct scalar_max_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_max_op) + EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { using std::max; return (max)(a, b); } + template + EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const + { return internal::pmax(a,b); } + template + EIGEN_STRONG_INLINE const Scalar predux(const Packet& a) const + { return internal::predux_max(a); } +}; +template +struct functor_traits > { + enum { + Cost = NumTraits::AddCost, + PacketAccess = packet_traits::HasMax + }; +}; + +/** \internal + * \brief Template functor to compute the hypot of two scalars + * + * \sa MatrixBase::stableNorm(), class Redux + */ +template struct scalar_hypot_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_hypot_op) +// typedef typename NumTraits::Real result_type; + EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& _x, const Scalar& _y) const + { + using std::max; + using std::min; + using std::sqrt; + Scalar p = (max)(_x, _y); + Scalar q = (min)(_x, _y); + Scalar qp = q/p; + return p * sqrt(Scalar(1) + qp*qp); + } +}; +template +struct functor_traits > { + enum { Cost = 5 * NumTraits::MulCost, PacketAccess=0 }; +}; + +/** \internal + * \brief Template functor to compute the pow of two scalars + */ +template struct scalar_binary_pow_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_binary_pow_op) + inline Scalar operator() (const Scalar& a, const OtherScalar& b) const { return numext::pow(a, b); } +}; +template +struct functor_traits > { + enum { Cost = 5 * NumTraits::MulCost, PacketAccess = false }; +}; + +// other binary functors: + +/** \internal + * \brief Template functor to compute the difference of two scalars + * + * \sa class CwiseBinaryOp, MatrixBase::operator- + */ +template struct scalar_difference_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_difference_op) + EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a - b; } + template + EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const + { return internal::psub(a,b); } +}; +template +struct functor_traits > { + enum { + Cost = NumTraits::AddCost, + PacketAccess = packet_traits::HasSub + }; +}; + +/** \internal + * \brief Template functor to compute the quotient of two scalars + * + * \sa class CwiseBinaryOp, Cwise::operator/() + */ +template struct scalar_quotient_op { + enum { + // TODO vectorize mixed product + Vectorizable = is_same::value && packet_traits::HasDiv && packet_traits::HasDiv + }; + typedef typename scalar_product_traits::ReturnType result_type; + EIGEN_EMPTY_STRUCT_CTOR(scalar_quotient_op) + EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a / b; } + template + EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const + { return internal::pdiv(a,b); } +}; +template +struct functor_traits > { + enum { + Cost = (NumTraits::MulCost + NumTraits::MulCost), // rough estimate! + PacketAccess = scalar_quotient_op::Vectorizable + }; +}; + + + +/** \internal + * \brief Template functor to compute the and of two booleans + * + * \sa class CwiseBinaryOp, ArrayBase::operator&& + */ +struct scalar_boolean_and_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_boolean_and_op) + EIGEN_STRONG_INLINE bool operator() (const bool& a, const bool& b) const { return a && b; } +}; +template<> struct functor_traits { + enum { + Cost = NumTraits::AddCost, + PacketAccess = false + }; +}; + +/** \internal + * \brief Template functor to compute the or of two booleans + * + * \sa class CwiseBinaryOp, ArrayBase::operator|| + */ +struct scalar_boolean_or_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_boolean_or_op) + EIGEN_STRONG_INLINE bool operator() (const bool& a, const bool& b) const { return a || b; } +}; +template<> struct functor_traits { + enum { + Cost = NumTraits::AddCost, + PacketAccess = false + }; +}; + +/** \internal + * \brief Template functors for comparison of two scalars + * \todo Implement packet-comparisons + */ +template struct scalar_cmp_op; + +template +struct functor_traits > { + enum { + Cost = NumTraits::AddCost, + PacketAccess = false + }; +}; + +template +struct result_of(Scalar,Scalar)> { + typedef bool type; +}; + + +template struct scalar_cmp_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op) + EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return a==b;} +}; +template struct scalar_cmp_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op) + EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return a struct scalar_cmp_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op) + EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return a<=b;} +}; +template struct scalar_cmp_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op) + EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return !(a<=b || b<=a);} +}; +template struct scalar_cmp_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op) + EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return a!=b;} +}; + +// unary functors: + +/** \internal + * \brief Template functor to compute the opposite of a scalar + * + * \sa class CwiseUnaryOp, MatrixBase::operator- + */ +template struct scalar_opposite_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_opposite_op) + EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return -a; } + template + EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const + { return internal::pnegate(a); } +}; +template +struct functor_traits > +{ enum { + Cost = NumTraits::AddCost, + PacketAccess = packet_traits::HasNegate }; +}; + +/** \internal + * \brief Template functor to compute the absolute value of a scalar + * + * \sa class CwiseUnaryOp, Cwise::abs + */ +template struct scalar_abs_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_abs_op) + typedef typename NumTraits::Real result_type; + EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { using std::abs; return abs(a); } + template + EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const + { return internal::pabs(a); } +}; +template +struct functor_traits > +{ + enum { + Cost = NumTraits::AddCost, + PacketAccess = packet_traits::HasAbs + }; +}; + +/** \internal + * \brief Template functor to compute the squared absolute value of a scalar + * + * \sa class CwiseUnaryOp, Cwise::abs2 + */ +template struct scalar_abs2_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_abs2_op) + typedef typename NumTraits::Real result_type; + EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return numext::abs2(a); } + template + EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const + { return internal::pmul(a,a); } +}; +template +struct functor_traits > +{ enum { Cost = NumTraits::MulCost, PacketAccess = packet_traits::HasAbs2 }; }; + +/** \internal + * \brief Template functor to compute the conjugate of a complex value + * + * \sa class CwiseUnaryOp, MatrixBase::conjugate() + */ +template struct scalar_conjugate_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_conjugate_op) + EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { using numext::conj; return conj(a); } + template + EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const { return internal::pconj(a); } +}; +template +struct functor_traits > +{ + enum { + Cost = NumTraits::IsComplex ? NumTraits::AddCost : 0, + PacketAccess = packet_traits::HasConj + }; +}; + +/** \internal + * \brief Template functor to cast a scalar to another type + * + * \sa class CwiseUnaryOp, MatrixBase::cast() + */ +template +struct scalar_cast_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_cast_op) + typedef NewType result_type; + EIGEN_STRONG_INLINE const NewType operator() (const Scalar& a) const { return cast(a); } +}; +template +struct functor_traits > +{ enum { Cost = is_same::value ? 0 : NumTraits::AddCost, PacketAccess = false }; }; + +/** \internal + * \brief Template functor to extract the real part of a complex + * + * \sa class CwiseUnaryOp, MatrixBase::real() + */ +template +struct scalar_real_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_real_op) + typedef typename NumTraits::Real result_type; + EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return numext::real(a); } +}; +template +struct functor_traits > +{ enum { Cost = 0, PacketAccess = false }; }; + +/** \internal + * \brief Template functor to extract the imaginary part of a complex + * + * \sa class CwiseUnaryOp, MatrixBase::imag() + */ +template +struct scalar_imag_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_imag_op) + typedef typename NumTraits::Real result_type; + EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return numext::imag(a); } +}; +template +struct functor_traits > +{ enum { Cost = 0, PacketAccess = false }; }; + +/** \internal + * \brief Template functor to extract the real part of a complex as a reference + * + * \sa class CwiseUnaryOp, MatrixBase::real() + */ +template +struct scalar_real_ref_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_real_ref_op) + typedef typename NumTraits::Real result_type; + EIGEN_STRONG_INLINE result_type& operator() (const Scalar& a) const { return numext::real_ref(*const_cast(&a)); } +}; +template +struct functor_traits > +{ enum { Cost = 0, PacketAccess = false }; }; + +/** \internal + * \brief Template functor to extract the imaginary part of a complex as a reference + * + * \sa class CwiseUnaryOp, MatrixBase::imag() + */ +template +struct scalar_imag_ref_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_imag_ref_op) + typedef typename NumTraits::Real result_type; + EIGEN_STRONG_INLINE result_type& operator() (const Scalar& a) const { return numext::imag_ref(*const_cast(&a)); } +}; +template +struct functor_traits > +{ enum { Cost = 0, PacketAccess = false }; }; + +/** \internal + * + * \brief Template functor to compute the exponential of a scalar + * + * \sa class CwiseUnaryOp, Cwise::exp() + */ +template struct scalar_exp_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_exp_op) + inline const Scalar operator() (const Scalar& a) const { using std::exp; return exp(a); } + typedef typename packet_traits::type Packet; + inline Packet packetOp(const Packet& a) const { return internal::pexp(a); } +}; +template +struct functor_traits > +{ enum { Cost = 5 * NumTraits::MulCost, PacketAccess = packet_traits::HasExp }; }; + +/** \internal + * + * \brief Template functor to compute the logarithm of a scalar + * + * \sa class CwiseUnaryOp, Cwise::log() + */ +template struct scalar_log_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_log_op) + inline const Scalar operator() (const Scalar& a) const { using std::log; return log(a); } + typedef typename packet_traits::type Packet; + inline Packet packetOp(const Packet& a) const { return internal::plog(a); } +}; +template +struct functor_traits > +{ enum { Cost = 5 * NumTraits::MulCost, PacketAccess = packet_traits::HasLog }; }; + +/** \internal + * \brief Template functor to multiply a scalar by a fixed other one + * + * \sa class CwiseUnaryOp, MatrixBase::operator*, MatrixBase::operator/ + */ +/* NOTE why doing the pset1() in packetOp *is* an optimization ? + * indeed it seems better to declare m_other as a Packet and do the pset1() once + * in the constructor. However, in practice: + * - GCC does not like m_other as a Packet and generate a load every time it needs it + * - on the other hand GCC is able to moves the pset1() outside the loop :) + * - simpler code ;) + * (ICC and gcc 4.4 seems to perform well in both cases, the issue is visible with y = a*x + b*y) + */ +template +struct scalar_multiple_op { + typedef typename packet_traits::type Packet; + // FIXME default copy constructors seems bugged with std::complex<> + EIGEN_STRONG_INLINE scalar_multiple_op(const scalar_multiple_op& other) : m_other(other.m_other) { } + EIGEN_STRONG_INLINE scalar_multiple_op(const Scalar& other) : m_other(other) { } + EIGEN_STRONG_INLINE Scalar operator() (const Scalar& a) const { return a * m_other; } + EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const + { return internal::pmul(a, pset1(m_other)); } + typename add_const_on_value_type::Nested>::type m_other; +}; +template +struct functor_traits > +{ enum { Cost = NumTraits::MulCost, PacketAccess = packet_traits::HasMul }; }; + +template +struct scalar_multiple2_op { + typedef typename scalar_product_traits::ReturnType result_type; + EIGEN_STRONG_INLINE scalar_multiple2_op(const scalar_multiple2_op& other) : m_other(other.m_other) { } + EIGEN_STRONG_INLINE scalar_multiple2_op(const Scalar2& other) : m_other(other) { } + EIGEN_STRONG_INLINE result_type operator() (const Scalar1& a) const { return a * m_other; } + typename add_const_on_value_type::Nested>::type m_other; +}; +template +struct functor_traits > +{ enum { Cost = NumTraits::MulCost, PacketAccess = false }; }; + +/** \internal + * \brief Template functor to divide a scalar by a fixed other one + * + * This functor is used to implement the quotient of a matrix by + * a scalar where the scalar type is not necessarily a floating point type. + * + * \sa class CwiseUnaryOp, MatrixBase::operator/ + */ +template +struct scalar_quotient1_op { + typedef typename packet_traits::type Packet; + // FIXME default copy constructors seems bugged with std::complex<> + EIGEN_STRONG_INLINE scalar_quotient1_op(const scalar_quotient1_op& other) : m_other(other.m_other) { } + EIGEN_STRONG_INLINE scalar_quotient1_op(const Scalar& other) : m_other(other) {} + EIGEN_STRONG_INLINE Scalar operator() (const Scalar& a) const { return a / m_other; } + EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const + { return internal::pdiv(a, pset1(m_other)); } + typename add_const_on_value_type::Nested>::type m_other; +}; +template +struct functor_traits > +{ enum { Cost = 2 * NumTraits::MulCost, PacketAccess = packet_traits::HasDiv }; }; + +// nullary functors + +template +struct scalar_constant_op { + typedef typename packet_traits::type Packet; + EIGEN_STRONG_INLINE scalar_constant_op(const scalar_constant_op& other) : m_other(other.m_other) { } + EIGEN_STRONG_INLINE scalar_constant_op(const Scalar& other) : m_other(other) { } + template + EIGEN_STRONG_INLINE const Scalar operator() (Index, Index = 0) const { return m_other; } + template + EIGEN_STRONG_INLINE const Packet packetOp(Index, Index = 0) const { return internal::pset1(m_other); } + const Scalar m_other; +}; +template +struct functor_traits > +// FIXME replace this packet test by a safe one +{ enum { Cost = 1, PacketAccess = packet_traits::Vectorizable, IsRepeatable = true }; }; + +template struct scalar_identity_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_identity_op) + template + EIGEN_STRONG_INLINE const Scalar operator() (Index row, Index col) const { return row==col ? Scalar(1) : Scalar(0); } +}; +template +struct functor_traits > +{ enum { Cost = NumTraits::AddCost, PacketAccess = false, IsRepeatable = true }; }; + +template struct linspaced_op_impl; + +// linear access for packet ops: +// 1) initialization +// base = [low, ..., low] + ([step, ..., step] * [-size, ..., 0]) +// 2) each step (where size is 1 for coeff access or PacketSize for packet access) +// base += [size*step, ..., size*step] +// +// TODO: Perhaps it's better to initialize lazily (so not in the constructor but in packetOp) +// in order to avoid the padd() in operator() ? +template +struct linspaced_op_impl +{ + typedef typename packet_traits::type Packet; + + linspaced_op_impl(const Scalar& low, const Scalar& step) : + m_low(low), m_step(step), + m_packetStep(pset1(packet_traits::size*step)), + m_base(padd(pset1(low), pmul(pset1(step),plset(-packet_traits::size)))) {} + + template + EIGEN_STRONG_INLINE const Scalar operator() (Index i) const + { + m_base = padd(m_base, pset1(m_step)); + return m_low+Scalar(i)*m_step; + } + + template + EIGEN_STRONG_INLINE const Packet packetOp(Index) const { return m_base = padd(m_base,m_packetStep); } + + const Scalar m_low; + const Scalar m_step; + const Packet m_packetStep; + mutable Packet m_base; +}; + +// random access for packet ops: +// 1) each step +// [low, ..., low] + ( [step, ..., step] * ( [i, ..., i] + [0, ..., size] ) ) +template +struct linspaced_op_impl +{ + typedef typename packet_traits::type Packet; + + linspaced_op_impl(const Scalar& low, const Scalar& step) : + m_low(low), m_step(step), + m_lowPacket(pset1(m_low)), m_stepPacket(pset1(m_step)), m_interPacket(plset(0)) {} + + template + EIGEN_STRONG_INLINE const Scalar operator() (Index i) const { return m_low+i*m_step; } + + template + EIGEN_STRONG_INLINE const Packet packetOp(Index i) const + { return internal::padd(m_lowPacket, pmul(m_stepPacket, padd(pset1(Scalar(i)),m_interPacket))); } + + const Scalar m_low; + const Scalar m_step; + const Packet m_lowPacket; + const Packet m_stepPacket; + const Packet m_interPacket; +}; + +// ----- Linspace functor ---------------------------------------------------------------- + +// Forward declaration (we default to random access which does not really give +// us a speed gain when using packet access but it allows to use the functor in +// nested expressions). +template struct linspaced_op; +template struct functor_traits< linspaced_op > +{ enum { Cost = 1, PacketAccess = packet_traits::HasSetLinear, IsRepeatable = true }; }; +template struct linspaced_op +{ + typedef typename packet_traits::type Packet; + linspaced_op(const Scalar& low, const Scalar& high, DenseIndex num_steps) : impl((num_steps==1 ? high : low), (num_steps==1 ? Scalar() : (high-low)/Scalar(num_steps-1))) {} + + template + EIGEN_STRONG_INLINE const Scalar operator() (Index i) const { return impl(i); } + + // We need this function when assigning e.g. a RowVectorXd to a MatrixXd since + // there row==0 and col is used for the actual iteration. + template + EIGEN_STRONG_INLINE const Scalar operator() (Index row, Index col) const + { + eigen_assert(col==0 || row==0); + return impl(col + row); + } + + template + EIGEN_STRONG_INLINE const Packet packetOp(Index i) const { return impl.packetOp(i); } + + // We need this function when assigning e.g. a RowVectorXd to a MatrixXd since + // there row==0 and col is used for the actual iteration. + template + EIGEN_STRONG_INLINE const Packet packetOp(Index row, Index col) const + { + eigen_assert(col==0 || row==0); + return impl.packetOp(col + row); + } + + // This proxy object handles the actual required temporaries, the different + // implementations (random vs. sequential access) as well as the + // correct piping to size 2/4 packet operations. + const linspaced_op_impl impl; +}; + +// all functors allow linear access, except scalar_identity_op. So we fix here a quick meta +// to indicate whether a functor allows linear access, just always answering 'yes' except for +// scalar_identity_op. +// FIXME move this to functor_traits adding a functor_default +template struct functor_has_linear_access { enum { ret = 1 }; }; +template struct functor_has_linear_access > { enum { ret = 0 }; }; + +// In Eigen, any binary op (Product, CwiseBinaryOp) require the Lhs and Rhs to have the same scalar type, except for multiplication +// where the mixing of different types is handled by scalar_product_traits +// In particular, real * complex is allowed. +// FIXME move this to functor_traits adding a functor_default +template struct functor_is_product_like { enum { ret = 0 }; }; +template struct functor_is_product_like > { enum { ret = 1 }; }; +template struct functor_is_product_like > { enum { ret = 1 }; }; +template struct functor_is_product_like > { enum { ret = 1 }; }; + + +/** \internal + * \brief Template functor to add a scalar to a fixed other one + * \sa class CwiseUnaryOp, Array::operator+ + */ +/* If you wonder why doing the pset1() in packetOp() is an optimization check scalar_multiple_op */ +template +struct scalar_add_op { + typedef typename packet_traits::type Packet; + // FIXME default copy constructors seems bugged with std::complex<> + inline scalar_add_op(const scalar_add_op& other) : m_other(other.m_other) { } + inline scalar_add_op(const Scalar& other) : m_other(other) { } + inline Scalar operator() (const Scalar& a) const { return a + m_other; } + inline const Packet packetOp(const Packet& a) const + { return internal::padd(a, pset1(m_other)); } + const Scalar m_other; +}; +template +struct functor_traits > +{ enum { Cost = NumTraits::AddCost, PacketAccess = packet_traits::HasAdd }; }; + +/** \internal + * \brief Template functor to compute the square root of a scalar + * \sa class CwiseUnaryOp, Cwise::sqrt() + */ +template struct scalar_sqrt_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_sqrt_op) + inline const Scalar operator() (const Scalar& a) const { using std::sqrt; return sqrt(a); } + typedef typename packet_traits::type Packet; + inline Packet packetOp(const Packet& a) const { return internal::psqrt(a); } +}; +template +struct functor_traits > +{ enum { + Cost = 5 * NumTraits::MulCost, + PacketAccess = packet_traits::HasSqrt + }; +}; + +/** \internal + * \brief Template functor to compute the cosine of a scalar + * \sa class CwiseUnaryOp, ArrayBase::cos() + */ +template struct scalar_cos_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_cos_op) + inline Scalar operator() (const Scalar& a) const { using std::cos; return cos(a); } + typedef typename packet_traits::type Packet; + inline Packet packetOp(const Packet& a) const { return internal::pcos(a); } +}; +template +struct functor_traits > +{ + enum { + Cost = 5 * NumTraits::MulCost, + PacketAccess = packet_traits::HasCos + }; +}; + +/** \internal + * \brief Template functor to compute the sine of a scalar + * \sa class CwiseUnaryOp, ArrayBase::sin() + */ +template struct scalar_sin_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_sin_op) + inline const Scalar operator() (const Scalar& a) const { using std::sin; return sin(a); } + typedef typename packet_traits::type Packet; + inline Packet packetOp(const Packet& a) const { return internal::psin(a); } +}; +template +struct functor_traits > +{ + enum { + Cost = 5 * NumTraits::MulCost, + PacketAccess = packet_traits::HasSin + }; +}; + + +/** \internal + * \brief Template functor to compute the tan of a scalar + * \sa class CwiseUnaryOp, ArrayBase::tan() + */ +template struct scalar_tan_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_tan_op) + inline const Scalar operator() (const Scalar& a) const { using std::tan; return tan(a); } + typedef typename packet_traits::type Packet; + inline Packet packetOp(const Packet& a) const { return internal::ptan(a); } +}; +template +struct functor_traits > +{ + enum { + Cost = 5 * NumTraits::MulCost, + PacketAccess = packet_traits::HasTan + }; +}; + +/** \internal + * \brief Template functor to compute the arc cosine of a scalar + * \sa class CwiseUnaryOp, ArrayBase::acos() + */ +template struct scalar_acos_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_acos_op) + inline const Scalar operator() (const Scalar& a) const { using std::acos; return acos(a); } + typedef typename packet_traits::type Packet; + inline Packet packetOp(const Packet& a) const { return internal::pacos(a); } +}; +template +struct functor_traits > +{ + enum { + Cost = 5 * NumTraits::MulCost, + PacketAccess = packet_traits::HasACos + }; +}; + +/** \internal + * \brief Template functor to compute the arc sine of a scalar + * \sa class CwiseUnaryOp, ArrayBase::asin() + */ +template struct scalar_asin_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_asin_op) + inline const Scalar operator() (const Scalar& a) const { using std::asin; return asin(a); } + typedef typename packet_traits::type Packet; + inline Packet packetOp(const Packet& a) const { return internal::pasin(a); } +}; +template +struct functor_traits > +{ + enum { + Cost = 5 * NumTraits::MulCost, + PacketAccess = packet_traits::HasASin + }; +}; + +/** \internal + * \brief Template functor to raise a scalar to a power + * \sa class CwiseUnaryOp, Cwise::pow + */ +template +struct scalar_pow_op { + // FIXME default copy constructors seems bugged with std::complex<> + inline scalar_pow_op(const scalar_pow_op& other) : m_exponent(other.m_exponent) { } + inline scalar_pow_op(const Scalar& exponent) : m_exponent(exponent) {} + inline Scalar operator() (const Scalar& a) const { return numext::pow(a, m_exponent); } + const Scalar m_exponent; +}; +template +struct functor_traits > +{ enum { Cost = 5 * NumTraits::MulCost, PacketAccess = false }; }; + +/** \internal + * \brief Template functor to compute the quotient between a scalar and array entries. + * \sa class CwiseUnaryOp, Cwise::inverse() + */ +template +struct scalar_inverse_mult_op { + scalar_inverse_mult_op(const Scalar& other) : m_other(other) {} + inline Scalar operator() (const Scalar& a) const { return m_other / a; } + template + inline const Packet packetOp(const Packet& a) const + { return internal::pdiv(pset1(m_other),a); } + Scalar m_other; +}; + +/** \internal + * \brief Template functor to compute the inverse of a scalar + * \sa class CwiseUnaryOp, Cwise::inverse() + */ +template +struct scalar_inverse_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_inverse_op) + inline Scalar operator() (const Scalar& a) const { return Scalar(1)/a; } + template + inline const Packet packetOp(const Packet& a) const + { return internal::pdiv(pset1(Scalar(1)),a); } +}; +template +struct functor_traits > +{ enum { Cost = NumTraits::MulCost, PacketAccess = packet_traits::HasDiv }; }; + +/** \internal + * \brief Template functor to compute the square of a scalar + * \sa class CwiseUnaryOp, Cwise::square() + */ +template +struct scalar_square_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_square_op) + inline Scalar operator() (const Scalar& a) const { return a*a; } + template + inline const Packet packetOp(const Packet& a) const + { return internal::pmul(a,a); } +}; +template +struct functor_traits > +{ enum { Cost = NumTraits::MulCost, PacketAccess = packet_traits::HasMul }; }; + +/** \internal + * \brief Template functor to compute the cube of a scalar + * \sa class CwiseUnaryOp, Cwise::cube() + */ +template +struct scalar_cube_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_cube_op) + inline Scalar operator() (const Scalar& a) const { return a*a*a; } + template + inline const Packet packetOp(const Packet& a) const + { return internal::pmul(a,pmul(a,a)); } +}; +template +struct functor_traits > +{ enum { Cost = 2*NumTraits::MulCost, PacketAccess = packet_traits::HasMul }; }; + +// default functor traits for STL functors: + +template +struct functor_traits > +{ enum { Cost = NumTraits::MulCost, PacketAccess = false }; }; + +template +struct functor_traits > +{ enum { Cost = NumTraits::MulCost, PacketAccess = false }; }; + +template +struct functor_traits > +{ enum { Cost = NumTraits::AddCost, PacketAccess = false }; }; + +template +struct functor_traits > +{ enum { Cost = NumTraits::AddCost, PacketAccess = false }; }; + +template +struct functor_traits > +{ enum { Cost = NumTraits::AddCost, PacketAccess = false }; }; + +template +struct functor_traits > +{ enum { Cost = 1, PacketAccess = false }; }; + +template +struct functor_traits > +{ enum { Cost = 1, PacketAccess = false }; }; + +template +struct functor_traits > +{ enum { Cost = 1, PacketAccess = false }; }; + +template +struct functor_traits > +{ enum { Cost = 1, PacketAccess = false }; }; + +template +struct functor_traits > +{ enum { Cost = 1, PacketAccess = false }; }; + +template +struct functor_traits > +{ enum { Cost = 1, PacketAccess = false }; }; + +template +struct functor_traits > +{ enum { Cost = 1, PacketAccess = false }; }; + +template +struct functor_traits > +{ enum { Cost = 1, PacketAccess = false }; }; + +template +struct functor_traits > +{ enum { Cost = 1, PacketAccess = false }; }; + +template +struct functor_traits > +{ enum { Cost = functor_traits::Cost, PacketAccess = false }; }; + +template +struct functor_traits > +{ enum { Cost = functor_traits::Cost, PacketAccess = false }; }; + +template +struct functor_traits > +{ enum { Cost = 1 + functor_traits::Cost, PacketAccess = false }; }; + +template +struct functor_traits > +{ enum { Cost = 1 + functor_traits::Cost, PacketAccess = false }; }; + +#ifdef EIGEN_STDEXT_SUPPORT + +template +struct functor_traits > +{ enum { Cost = 0, PacketAccess = false }; }; + +template +struct functor_traits > +{ enum { Cost = 0, PacketAccess = false }; }; + +template +struct functor_traits > > +{ enum { Cost = 0, PacketAccess = false }; }; + +template +struct functor_traits > > +{ enum { Cost = 0, PacketAccess = false }; }; + +template +struct functor_traits > +{ enum { Cost = functor_traits::Cost + functor_traits::Cost, PacketAccess = false }; }; + +template +struct functor_traits > +{ enum { Cost = functor_traits::Cost + functor_traits::Cost + functor_traits::Cost, PacketAccess = false }; }; + +#endif // EIGEN_STDEXT_SUPPORT + +// allow to add new functors and specializations of functor_traits from outside Eigen. +// this macro is really needed because functor_traits must be specialized after it is declared but before it is used... +#ifdef EIGEN_FUNCTORS_PLUGIN +#include EIGEN_FUNCTORS_PLUGIN +#endif + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_FUNCTORS_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/Fuzzy.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/Fuzzy.h new file mode 100644 index 00000000..fe63bd29 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/Fuzzy.h @@ -0,0 +1,150 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2006-2008 Benoit Jacob +// Copyright (C) 2008 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_FUZZY_H +#define EIGEN_FUZZY_H + +namespace Eigen { + +namespace internal +{ + +template::IsInteger> +struct isApprox_selector +{ + static bool run(const Derived& x, const OtherDerived& y, const typename Derived::RealScalar& prec) + { + using std::min; + typename internal::nested::type nested(x); + typename internal::nested::type otherNested(y); + return (nested - otherNested).cwiseAbs2().sum() <= prec * prec * (min)(nested.cwiseAbs2().sum(), otherNested.cwiseAbs2().sum()); + } +}; + +template +struct isApprox_selector +{ + static bool run(const Derived& x, const OtherDerived& y, const typename Derived::RealScalar&) + { + return x.matrix() == y.matrix(); + } +}; + +template::IsInteger> +struct isMuchSmallerThan_object_selector +{ + static bool run(const Derived& x, const OtherDerived& y, const typename Derived::RealScalar& prec) + { + return x.cwiseAbs2().sum() <= numext::abs2(prec) * y.cwiseAbs2().sum(); + } +}; + +template +struct isMuchSmallerThan_object_selector +{ + static bool run(const Derived& x, const OtherDerived&, const typename Derived::RealScalar&) + { + return x.matrix() == Derived::Zero(x.rows(), x.cols()).matrix(); + } +}; + +template::IsInteger> +struct isMuchSmallerThan_scalar_selector +{ + static bool run(const Derived& x, const typename Derived::RealScalar& y, const typename Derived::RealScalar& prec) + { + return x.cwiseAbs2().sum() <= numext::abs2(prec * y); + } +}; + +template +struct isMuchSmallerThan_scalar_selector +{ + static bool run(const Derived& x, const typename Derived::RealScalar&, const typename Derived::RealScalar&) + { + return x.matrix() == Derived::Zero(x.rows(), x.cols()).matrix(); + } +}; + +} // end namespace internal + + +/** \returns \c true if \c *this is approximately equal to \a other, within the precision + * determined by \a prec. + * + * \note The fuzzy compares are done multiplicatively. Two vectors \f$ v \f$ and \f$ w \f$ + * are considered to be approximately equal within precision \f$ p \f$ if + * \f[ \Vert v - w \Vert \leqslant p\,\min(\Vert v\Vert, \Vert w\Vert). \f] + * For matrices, the comparison is done using the Hilbert-Schmidt norm (aka Frobenius norm + * L2 norm). + * + * \note Because of the multiplicativeness of this comparison, one can't use this function + * to check whether \c *this is approximately equal to the zero matrix or vector. + * Indeed, \c isApprox(zero) returns false unless \c *this itself is exactly the zero matrix + * or vector. If you want to test whether \c *this is zero, use internal::isMuchSmallerThan(const + * RealScalar&, RealScalar) instead. + * + * \sa internal::isMuchSmallerThan(const RealScalar&, RealScalar) const + */ +template +template +bool DenseBase::isApprox( + const DenseBase& other, + const RealScalar& prec +) const +{ + return internal::isApprox_selector::run(derived(), other.derived(), prec); +} + +/** \returns \c true if the norm of \c *this is much smaller than \a other, + * within the precision determined by \a prec. + * + * \note The fuzzy compares are done multiplicatively. A vector \f$ v \f$ is + * considered to be much smaller than \f$ x \f$ within precision \f$ p \f$ if + * \f[ \Vert v \Vert \leqslant p\,\vert x\vert. \f] + * + * For matrices, the comparison is done using the Hilbert-Schmidt norm. For this reason, + * the value of the reference scalar \a other should come from the Hilbert-Schmidt norm + * of a reference matrix of same dimensions. + * + * \sa isApprox(), isMuchSmallerThan(const DenseBase&, RealScalar) const + */ +template +bool DenseBase::isMuchSmallerThan( + const typename NumTraits::Real& other, + const RealScalar& prec +) const +{ + return internal::isMuchSmallerThan_scalar_selector::run(derived(), other, prec); +} + +/** \returns \c true if the norm of \c *this is much smaller than the norm of \a other, + * within the precision determined by \a prec. + * + * \note The fuzzy compares are done multiplicatively. A vector \f$ v \f$ is + * considered to be much smaller than a vector \f$ w \f$ within precision \f$ p \f$ if + * \f[ \Vert v \Vert \leqslant p\,\Vert w\Vert. \f] + * For matrices, the comparison is done using the Hilbert-Schmidt norm. + * + * \sa isApprox(), isMuchSmallerThan(const RealScalar&, RealScalar) const + */ +template +template +bool DenseBase::isMuchSmallerThan( + const DenseBase& other, + const RealScalar& prec +) const +{ + return internal::isMuchSmallerThan_object_selector::run(derived(), other.derived(), prec); +} + +} // end namespace Eigen + +#endif // EIGEN_FUZZY_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/GeneralProduct.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/GeneralProduct.h new file mode 100644 index 00000000..0eae5299 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/GeneralProduct.h @@ -0,0 +1,635 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2006-2008 Benoit Jacob +// Copyright (C) 2008-2011 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_GENERAL_PRODUCT_H +#define EIGEN_GENERAL_PRODUCT_H + +namespace Eigen { + +/** \class GeneralProduct + * \ingroup Core_Module + * + * \brief Expression of the product of two general matrices or vectors + * + * \param LhsNested the type used to store the left-hand side + * \param RhsNested the type used to store the right-hand side + * \param ProductMode the type of the product + * + * This class represents an expression of the product of two general matrices. + * We call a general matrix, a dense matrix with full storage. For instance, + * This excludes triangular, selfadjoint, and sparse matrices. + * It is the return type of the operator* between general matrices. Its template + * arguments are determined automatically by ProductReturnType. Therefore, + * GeneralProduct should never be used direclty. To determine the result type of a + * function which involves a matrix product, use ProductReturnType::Type. + * + * \sa ProductReturnType, MatrixBase::operator*(const MatrixBase&) + */ +template::value> +class GeneralProduct; + +enum { + Large = 2, + Small = 3 +}; + +namespace internal { + +template struct product_type_selector; + +template struct product_size_category +{ + enum { is_large = MaxSize == Dynamic || + Size >= EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD, + value = is_large ? Large + : Size == 1 ? 1 + : Small + }; +}; + +template struct product_type +{ + typedef typename remove_all::type _Lhs; + typedef typename remove_all::type _Rhs; + enum { + MaxRows = _Lhs::MaxRowsAtCompileTime, + Rows = _Lhs::RowsAtCompileTime, + MaxCols = _Rhs::MaxColsAtCompileTime, + Cols = _Rhs::ColsAtCompileTime, + MaxDepth = EIGEN_SIZE_MIN_PREFER_FIXED(_Lhs::MaxColsAtCompileTime, + _Rhs::MaxRowsAtCompileTime), + Depth = EIGEN_SIZE_MIN_PREFER_FIXED(_Lhs::ColsAtCompileTime, + _Rhs::RowsAtCompileTime), + LargeThreshold = EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD + }; + + // the splitting into different lines of code here, introducing the _select enums and the typedef below, + // is to work around an internal compiler error with gcc 4.1 and 4.2. +private: + enum { + rows_select = product_size_category::value, + cols_select = product_size_category::value, + depth_select = product_size_category::value + }; + typedef product_type_selector selector; + +public: + enum { + value = selector::ret + }; +#ifdef EIGEN_DEBUG_PRODUCT + static void debug() + { + EIGEN_DEBUG_VAR(Rows); + EIGEN_DEBUG_VAR(Cols); + EIGEN_DEBUG_VAR(Depth); + EIGEN_DEBUG_VAR(rows_select); + EIGEN_DEBUG_VAR(cols_select); + EIGEN_DEBUG_VAR(depth_select); + EIGEN_DEBUG_VAR(value); + } +#endif +}; + + +/* The following allows to select the kind of product at compile time + * based on the three dimensions of the product. + * This is a compile time mapping from {1,Small,Large}^3 -> {product types} */ +// FIXME I'm not sure the current mapping is the ideal one. +template struct product_type_selector { enum { ret = OuterProduct }; }; +template struct product_type_selector<1, 1, Depth> { enum { ret = InnerProduct }; }; +template<> struct product_type_selector<1, 1, 1> { enum { ret = InnerProduct }; }; +template<> struct product_type_selector { enum { ret = CoeffBasedProductMode }; }; +template<> struct product_type_selector<1, Small,Small> { enum { ret = CoeffBasedProductMode }; }; +template<> struct product_type_selector { enum { ret = CoeffBasedProductMode }; }; +template<> struct product_type_selector { enum { ret = LazyCoeffBasedProductMode }; }; +template<> struct product_type_selector { enum { ret = LazyCoeffBasedProductMode }; }; +template<> struct product_type_selector { enum { ret = LazyCoeffBasedProductMode }; }; +template<> struct product_type_selector<1, Large,Small> { enum { ret = CoeffBasedProductMode }; }; +template<> struct product_type_selector<1, Large,Large> { enum { ret = GemvProduct }; }; +template<> struct product_type_selector<1, Small,Large> { enum { ret = CoeffBasedProductMode }; }; +template<> struct product_type_selector { enum { ret = CoeffBasedProductMode }; }; +template<> struct product_type_selector { enum { ret = GemvProduct }; }; +template<> struct product_type_selector { enum { ret = CoeffBasedProductMode }; }; +template<> struct product_type_selector { enum { ret = GemmProduct }; }; +template<> struct product_type_selector { enum { ret = GemmProduct }; }; +template<> struct product_type_selector { enum { ret = GemmProduct }; }; +template<> struct product_type_selector { enum { ret = GemmProduct }; }; +template<> struct product_type_selector { enum { ret = GemmProduct }; }; +template<> struct product_type_selector { enum { ret = GemmProduct }; }; +template<> struct product_type_selector { enum { ret = GemmProduct }; }; + +} // end namespace internal + +/** \class ProductReturnType + * \ingroup Core_Module + * + * \brief Helper class to get the correct and optimized returned type of operator* + * + * \param Lhs the type of the left-hand side + * \param Rhs the type of the right-hand side + * \param ProductMode the type of the product (determined automatically by internal::product_mode) + * + * This class defines the typename Type representing the optimized product expression + * between two matrix expressions. In practice, using ProductReturnType::Type + * is the recommended way to define the result type of a function returning an expression + * which involve a matrix product. The class Product should never be + * used directly. + * + * \sa class Product, MatrixBase::operator*(const MatrixBase&) + */ +template +struct ProductReturnType +{ + // TODO use the nested type to reduce instanciations ???? +// typedef typename internal::nested::type LhsNested; +// typedef typename internal::nested::type RhsNested; + + typedef GeneralProduct Type; +}; + +template +struct ProductReturnType +{ + typedef typename internal::nested::type >::type LhsNested; + typedef typename internal::nested::type >::type RhsNested; + typedef CoeffBasedProduct Type; +}; + +template +struct ProductReturnType +{ + typedef typename internal::nested::type >::type LhsNested; + typedef typename internal::nested::type >::type RhsNested; + typedef CoeffBasedProduct Type; +}; + +// this is a workaround for sun CC +template +struct LazyProductReturnType : public ProductReturnType +{}; + +/*********************************************************************** +* Implementation of Inner Vector Vector Product +***********************************************************************/ + +// FIXME : maybe the "inner product" could return a Scalar +// instead of a 1x1 matrix ?? +// Pro: more natural for the user +// Cons: this could be a problem if in a meta unrolled algorithm a matrix-matrix +// product ends up to a row-vector times col-vector product... To tackle this use +// case, we could have a specialization for Block with: operator=(Scalar x); + +namespace internal { + +template +struct traits > + : traits::ReturnType,1,1> > +{}; + +} + +template +class GeneralProduct + : internal::no_assignment_operator, + public Matrix::ReturnType,1,1> +{ + typedef Matrix::ReturnType,1,1> Base; + public: + GeneralProduct(const Lhs& lhs, const Rhs& rhs) + { + EIGEN_STATIC_ASSERT((internal::is_same::value), + YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) + + Base::coeffRef(0,0) = (lhs.transpose().cwiseProduct(rhs)).sum(); + } + + /** Convertion to scalar */ + operator const typename Base::Scalar() const { + return Base::coeff(0,0); + } +}; + +/*********************************************************************** +* Implementation of Outer Vector Vector Product +***********************************************************************/ + +namespace internal { + +// Column major +template +EIGEN_DONT_INLINE void outer_product_selector_run(const ProductType& prod, Dest& dest, const Func& func, const false_type&) +{ + typedef typename Dest::Index Index; + // FIXME make sure lhs is sequentially stored + // FIXME not very good if rhs is real and lhs complex while alpha is real too + const Index cols = dest.cols(); + for (Index j=0; j +EIGEN_DONT_INLINE void outer_product_selector_run(const ProductType& prod, Dest& dest, const Func& func, const true_type&) { + typedef typename Dest::Index Index; + // FIXME make sure rhs is sequentially stored + // FIXME not very good if lhs is real and rhs complex while alpha is real too + const Index rows = dest.rows(); + for (Index i=0; i +struct traits > + : traits, Lhs, Rhs> > +{}; + +} + +template +class GeneralProduct + : public ProductBase, Lhs, Rhs> +{ + template struct is_row_major : internal::conditional<(int(T::Flags)&RowMajorBit), internal::true_type, internal::false_type>::type {}; + + public: + EIGEN_PRODUCT_PUBLIC_INTERFACE(GeneralProduct) + + GeneralProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs) + { + EIGEN_STATIC_ASSERT((internal::is_same::value), + YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) + } + + struct set { template void operator()(const Dst& dst, const Src& src) const { dst.const_cast_derived() = src; } }; + struct add { template void operator()(const Dst& dst, const Src& src) const { dst.const_cast_derived() += src; } }; + struct sub { template void operator()(const Dst& dst, const Src& src) const { dst.const_cast_derived() -= src; } }; + struct adds { + Scalar m_scale; + adds(const Scalar& s) : m_scale(s) {} + template void operator()(const Dst& dst, const Src& src) const { + dst.const_cast_derived() += m_scale * src; + } + }; + + template + inline void evalTo(Dest& dest) const { + internal::outer_product_selector_run(*this, dest, set(), is_row_major()); + } + + template + inline void addTo(Dest& dest) const { + internal::outer_product_selector_run(*this, dest, add(), is_row_major()); + } + + template + inline void subTo(Dest& dest) const { + internal::outer_product_selector_run(*this, dest, sub(), is_row_major()); + } + + template void scaleAndAddTo(Dest& dest, const Scalar& alpha) const + { + internal::outer_product_selector_run(*this, dest, adds(alpha), is_row_major()); + } +}; + +/*********************************************************************** +* Implementation of General Matrix Vector Product +***********************************************************************/ + +/* According to the shape/flags of the matrix we have to distinghish 3 different cases: + * 1 - the matrix is col-major, BLAS compatible and M is large => call fast BLAS-like colmajor routine + * 2 - the matrix is row-major, BLAS compatible and N is large => call fast BLAS-like rowmajor routine + * 3 - all other cases are handled using a simple loop along the outer-storage direction. + * Therefore we need a lower level meta selector. + * Furthermore, if the matrix is the rhs, then the product has to be transposed. + */ +namespace internal { + +template +struct traits > + : traits, Lhs, Rhs> > +{}; + +template +struct gemv_selector; + +} // end namespace internal + +template +class GeneralProduct + : public ProductBase, Lhs, Rhs> +{ + public: + EIGEN_PRODUCT_PUBLIC_INTERFACE(GeneralProduct) + + typedef typename Lhs::Scalar LhsScalar; + typedef typename Rhs::Scalar RhsScalar; + + GeneralProduct(const Lhs& a_lhs, const Rhs& a_rhs) : Base(a_lhs,a_rhs) + { +// EIGEN_STATIC_ASSERT((internal::is_same::value), +// YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) + } + + enum { Side = Lhs::IsVectorAtCompileTime ? OnTheLeft : OnTheRight }; + typedef typename internal::conditional::type MatrixType; + + template void scaleAndAddTo(Dest& dst, const Scalar& alpha) const + { + eigen_assert(m_lhs.rows() == dst.rows() && m_rhs.cols() == dst.cols()); + internal::gemv_selector::HasUsableDirectAccess)>::run(*this, dst, alpha); + } +}; + +namespace internal { + +// The vector is on the left => transposition +template +struct gemv_selector +{ + template + static void run(const ProductType& prod, Dest& dest, const typename ProductType::Scalar& alpha) + { + Transpose destT(dest); + enum { OtherStorageOrder = StorageOrder == RowMajor ? ColMajor : RowMajor }; + gemv_selector + ::run(GeneralProduct,Transpose, GemvProduct> + (prod.rhs().transpose(), prod.lhs().transpose()), destT, alpha); + } +}; + +template struct gemv_static_vector_if; + +template +struct gemv_static_vector_if +{ + EIGEN_STRONG_INLINE Scalar* data() { eigen_internal_assert(false && "should never be called"); return 0; } +}; + +template +struct gemv_static_vector_if +{ + EIGEN_STRONG_INLINE Scalar* data() { return 0; } +}; + +template +struct gemv_static_vector_if +{ + #if EIGEN_ALIGN_STATICALLY + internal::plain_array m_data; + EIGEN_STRONG_INLINE Scalar* data() { return m_data.array; } + #else + // Some architectures cannot align on the stack, + // => let's manually enforce alignment by allocating more data and return the address of the first aligned element. + enum { + ForceAlignment = internal::packet_traits::Vectorizable, + PacketSize = internal::packet_traits::size + }; + internal::plain_array m_data; + EIGEN_STRONG_INLINE Scalar* data() { + return ForceAlignment + ? reinterpret_cast((reinterpret_cast(m_data.array) & ~(size_t(15))) + 16) + : m_data.array; + } + #endif +}; + +template<> struct gemv_selector +{ + template + static inline void run(const ProductType& prod, Dest& dest, const typename ProductType::Scalar& alpha) + { + typedef typename ProductType::Index Index; + typedef typename ProductType::LhsScalar LhsScalar; + typedef typename ProductType::RhsScalar RhsScalar; + typedef typename ProductType::Scalar ResScalar; + typedef typename ProductType::RealScalar RealScalar; + typedef typename ProductType::ActualLhsType ActualLhsType; + typedef typename ProductType::ActualRhsType ActualRhsType; + typedef typename ProductType::LhsBlasTraits LhsBlasTraits; + typedef typename ProductType::RhsBlasTraits RhsBlasTraits; + typedef Map, Aligned> MappedDest; + + ActualLhsType actualLhs = LhsBlasTraits::extract(prod.lhs()); + ActualRhsType actualRhs = RhsBlasTraits::extract(prod.rhs()); + + ResScalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(prod.lhs()) + * RhsBlasTraits::extractScalarFactor(prod.rhs()); + + enum { + // FIXME find a way to allow an inner stride on the result if packet_traits::size==1 + // on, the other hand it is good for the cache to pack the vector anyways... + EvalToDestAtCompileTime = Dest::InnerStrideAtCompileTime==1, + ComplexByReal = (NumTraits::IsComplex) && (!NumTraits::IsComplex), + MightCannotUseDest = (Dest::InnerStrideAtCompileTime!=1) || ComplexByReal + }; + + gemv_static_vector_if static_dest; + + bool alphaIsCompatible = (!ComplexByReal) || (numext::imag(actualAlpha)==RealScalar(0)); + bool evalToDest = EvalToDestAtCompileTime && alphaIsCompatible; + + RhsScalar compatibleAlpha = get_factor::run(actualAlpha); + + ei_declare_aligned_stack_constructed_variable(ResScalar,actualDestPtr,dest.size(), + evalToDest ? dest.data() : static_dest.data()); + + if(!evalToDest) + { + #ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN + int size = dest.size(); + EIGEN_DENSE_STORAGE_CTOR_PLUGIN + #endif + if(!alphaIsCompatible) + { + MappedDest(actualDestPtr, dest.size()).setZero(); + compatibleAlpha = RhsScalar(1); + } + else + MappedDest(actualDestPtr, dest.size()) = dest; + } + + general_matrix_vector_product + ::run( + actualLhs.rows(), actualLhs.cols(), + actualLhs.data(), actualLhs.outerStride(), + actualRhs.data(), actualRhs.innerStride(), + actualDestPtr, 1, + compatibleAlpha); + + if (!evalToDest) + { + if(!alphaIsCompatible) + dest += actualAlpha * MappedDest(actualDestPtr, dest.size()); + else + dest = MappedDest(actualDestPtr, dest.size()); + } + } +}; + +template<> struct gemv_selector +{ + template + static void run(const ProductType& prod, Dest& dest, const typename ProductType::Scalar& alpha) + { + typedef typename ProductType::LhsScalar LhsScalar; + typedef typename ProductType::RhsScalar RhsScalar; + typedef typename ProductType::Scalar ResScalar; + typedef typename ProductType::Index Index; + typedef typename ProductType::ActualLhsType ActualLhsType; + typedef typename ProductType::ActualRhsType ActualRhsType; + typedef typename ProductType::_ActualRhsType _ActualRhsType; + typedef typename ProductType::LhsBlasTraits LhsBlasTraits; + typedef typename ProductType::RhsBlasTraits RhsBlasTraits; + + typename add_const::type actualLhs = LhsBlasTraits::extract(prod.lhs()); + typename add_const::type actualRhs = RhsBlasTraits::extract(prod.rhs()); + + ResScalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(prod.lhs()) + * RhsBlasTraits::extractScalarFactor(prod.rhs()); + + enum { + // FIXME find a way to allow an inner stride on the result if packet_traits::size==1 + // on, the other hand it is good for the cache to pack the vector anyways... + DirectlyUseRhs = _ActualRhsType::InnerStrideAtCompileTime==1 + }; + + gemv_static_vector_if static_rhs; + + ei_declare_aligned_stack_constructed_variable(RhsScalar,actualRhsPtr,actualRhs.size(), + DirectlyUseRhs ? const_cast(actualRhs.data()) : static_rhs.data()); + + if(!DirectlyUseRhs) + { + #ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN + int size = actualRhs.size(); + EIGEN_DENSE_STORAGE_CTOR_PLUGIN + #endif + Map(actualRhsPtr, actualRhs.size()) = actualRhs; + } + + general_matrix_vector_product + ::run( + actualLhs.rows(), actualLhs.cols(), + actualLhs.data(), actualLhs.outerStride(), + actualRhsPtr, 1, + dest.data(), dest.innerStride(), + actualAlpha); + } +}; + +template<> struct gemv_selector +{ + template + static void run(const ProductType& prod, Dest& dest, const typename ProductType::Scalar& alpha) + { + typedef typename Dest::Index Index; + // TODO makes sure dest is sequentially stored in memory, otherwise use a temp + const Index size = prod.rhs().rows(); + for(Index k=0; k struct gemv_selector +{ + template + static void run(const ProductType& prod, Dest& dest, const typename ProductType::Scalar& alpha) + { + typedef typename Dest::Index Index; + // TODO makes sure rhs is sequentially stored in memory, otherwise use a temp + const Index rows = prod.rows(); + for(Index i=0; i +template +inline const typename ProductReturnType::Type +MatrixBase::operator*(const MatrixBase &other) const +{ + // A note regarding the function declaration: In MSVC, this function will sometimes + // not be inlined since DenseStorage is an unwindable object for dynamic + // matrices and product types are holding a member to store the result. + // Thus it does not help tagging this function with EIGEN_STRONG_INLINE. + enum { + ProductIsValid = Derived::ColsAtCompileTime==Dynamic + || OtherDerived::RowsAtCompileTime==Dynamic + || int(Derived::ColsAtCompileTime)==int(OtherDerived::RowsAtCompileTime), + AreVectors = Derived::IsVectorAtCompileTime && OtherDerived::IsVectorAtCompileTime, + SameSizes = EIGEN_PREDICATE_SAME_MATRIX_SIZE(Derived,OtherDerived) + }; + // note to the lost user: + // * for a dot product use: v1.dot(v2) + // * for a coeff-wise product use: v1.cwiseProduct(v2) + EIGEN_STATIC_ASSERT(ProductIsValid || !(AreVectors && SameSizes), + INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS) + EIGEN_STATIC_ASSERT(ProductIsValid || !(SameSizes && !AreVectors), + INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION) + EIGEN_STATIC_ASSERT(ProductIsValid || SameSizes, INVALID_MATRIX_PRODUCT) +#ifdef EIGEN_DEBUG_PRODUCT + internal::product_type::debug(); +#endif + return typename ProductReturnType::Type(derived(), other.derived()); +} + +/** \returns an expression of the matrix product of \c *this and \a other without implicit evaluation. + * + * The returned product will behave like any other expressions: the coefficients of the product will be + * computed once at a time as requested. This might be useful in some extremely rare cases when only + * a small and no coherent fraction of the result's coefficients have to be computed. + * + * \warning This version of the matrix product can be much much slower. So use it only if you know + * what you are doing and that you measured a true speed improvement. + * + * \sa operator*(const MatrixBase&) + */ +template +template +const typename LazyProductReturnType::Type +MatrixBase::lazyProduct(const MatrixBase &other) const +{ + enum { + ProductIsValid = Derived::ColsAtCompileTime==Dynamic + || OtherDerived::RowsAtCompileTime==Dynamic + || int(Derived::ColsAtCompileTime)==int(OtherDerived::RowsAtCompileTime), + AreVectors = Derived::IsVectorAtCompileTime && OtherDerived::IsVectorAtCompileTime, + SameSizes = EIGEN_PREDICATE_SAME_MATRIX_SIZE(Derived,OtherDerived) + }; + // note to the lost user: + // * for a dot product use: v1.dot(v2) + // * for a coeff-wise product use: v1.cwiseProduct(v2) + EIGEN_STATIC_ASSERT(ProductIsValid || !(AreVectors && SameSizes), + INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS) + EIGEN_STATIC_ASSERT(ProductIsValid || !(SameSizes && !AreVectors), + INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION) + EIGEN_STATIC_ASSERT(ProductIsValid || SameSizes, INVALID_MATRIX_PRODUCT) + + return typename LazyProductReturnType::Type(derived(), other.derived()); +} + +} // end namespace Eigen + +#endif // EIGEN_PRODUCT_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/GenericPacketMath.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/GenericPacketMath.h new file mode 100644 index 00000000..5f783ebe --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/GenericPacketMath.h @@ -0,0 +1,350 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008 Gael Guennebaud +// Copyright (C) 2006-2008 Benoit Jacob +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_GENERIC_PACKET_MATH_H +#define EIGEN_GENERIC_PACKET_MATH_H + +namespace Eigen { + +namespace internal { + +/** \internal + * \file GenericPacketMath.h + * + * Default implementation for types not supported by the vectorization. + * In practice these functions are provided to make easier the writing + * of generic vectorized code. + */ + +#ifndef EIGEN_DEBUG_ALIGNED_LOAD +#define EIGEN_DEBUG_ALIGNED_LOAD +#endif + +#ifndef EIGEN_DEBUG_UNALIGNED_LOAD +#define EIGEN_DEBUG_UNALIGNED_LOAD +#endif + +#ifndef EIGEN_DEBUG_ALIGNED_STORE +#define EIGEN_DEBUG_ALIGNED_STORE +#endif + +#ifndef EIGEN_DEBUG_UNALIGNED_STORE +#define EIGEN_DEBUG_UNALIGNED_STORE +#endif + +struct default_packet_traits +{ + enum { + HasAdd = 1, + HasSub = 1, + HasMul = 1, + HasNegate = 1, + HasAbs = 1, + HasAbs2 = 1, + HasMin = 1, + HasMax = 1, + HasConj = 1, + HasSetLinear = 1, + + HasDiv = 0, + HasSqrt = 0, + HasExp = 0, + HasLog = 0, + HasPow = 0, + + HasSin = 0, + HasCos = 0, + HasTan = 0, + HasASin = 0, + HasACos = 0, + HasATan = 0 + }; +}; + +template struct packet_traits : default_packet_traits +{ + typedef T type; + enum { + Vectorizable = 0, + size = 1, + AlignedOnScalar = 0 + }; + enum { + HasAdd = 0, + HasSub = 0, + HasMul = 0, + HasNegate = 0, + HasAbs = 0, + HasAbs2 = 0, + HasMin = 0, + HasMax = 0, + HasConj = 0, + HasSetLinear = 0 + }; +}; + +/** \internal \returns a + b (coeff-wise) */ +template inline Packet +padd(const Packet& a, + const Packet& b) { return a+b; } + +/** \internal \returns a - b (coeff-wise) */ +template inline Packet +psub(const Packet& a, + const Packet& b) { return a-b; } + +/** \internal \returns -a (coeff-wise) */ +template inline Packet +pnegate(const Packet& a) { return -a; } + +/** \internal \returns conj(a) (coeff-wise) */ +template inline Packet +pconj(const Packet& a) { return numext::conj(a); } + +/** \internal \returns a * b (coeff-wise) */ +template inline Packet +pmul(const Packet& a, + const Packet& b) { return a*b; } + +/** \internal \returns a / b (coeff-wise) */ +template inline Packet +pdiv(const Packet& a, + const Packet& b) { return a/b; } + +/** \internal \returns the min of \a a and \a b (coeff-wise) */ +template inline Packet +pmin(const Packet& a, + const Packet& b) { using std::min; return (min)(a, b); } + +/** \internal \returns the max of \a a and \a b (coeff-wise) */ +template inline Packet +pmax(const Packet& a, + const Packet& b) { using std::max; return (max)(a, b); } + +/** \internal \returns the absolute value of \a a */ +template inline Packet +pabs(const Packet& a) { using std::abs; return abs(a); } + +/** \internal \returns the bitwise and of \a a and \a b */ +template inline Packet +pand(const Packet& a, const Packet& b) { return a & b; } + +/** \internal \returns the bitwise or of \a a and \a b */ +template inline Packet +por(const Packet& a, const Packet& b) { return a | b; } + +/** \internal \returns the bitwise xor of \a a and \a b */ +template inline Packet +pxor(const Packet& a, const Packet& b) { return a ^ b; } + +/** \internal \returns the bitwise andnot of \a a and \a b */ +template inline Packet +pandnot(const Packet& a, const Packet& b) { return a & (!b); } + +/** \internal \returns a packet version of \a *from, from must be 16 bytes aligned */ +template inline Packet +pload(const typename unpacket_traits::type* from) { return *from; } + +/** \internal \returns a packet version of \a *from, (un-aligned load) */ +template inline Packet +ploadu(const typename unpacket_traits::type* from) { return *from; } + +/** \internal \returns a packet with elements of \a *from duplicated. + * For instance, for a packet of 8 elements, 4 scalar will be read from \a *from and + * duplicated to form: {from[0],from[0],from[1],from[1],,from[2],from[2],,from[3],from[3]} + * Currently, this function is only used for scalar * complex products. + */ +template inline Packet +ploaddup(const typename unpacket_traits::type* from) { return *from; } + +/** \internal \returns a packet with constant coefficients \a a, e.g.: (a,a,a,a) */ +template inline Packet +pset1(const typename unpacket_traits::type& a) { return a; } + +/** \internal \brief Returns a packet with coefficients (a,a+1,...,a+packet_size-1). */ +template inline typename packet_traits::type +plset(const Scalar& a) { return a; } + +/** \internal copy the packet \a from to \a *to, \a to must be 16 bytes aligned */ +template inline void pstore(Scalar* to, const Packet& from) +{ (*to) = from; } + +/** \internal copy the packet \a from to \a *to, (un-aligned store) */ +template inline void pstoreu(Scalar* to, const Packet& from) +{ (*to) = from; } + +/** \internal tries to do cache prefetching of \a addr */ +template inline void prefetch(const Scalar* addr) +{ +#if !defined(_MSC_VER) +__builtin_prefetch(addr); +#endif +} + +/** \internal \returns the first element of a packet */ +template inline typename unpacket_traits::type pfirst(const Packet& a) +{ return a; } + +/** \internal \returns a packet where the element i contains the sum of the packet of \a vec[i] */ +template inline Packet +preduxp(const Packet* vecs) { return vecs[0]; } + +/** \internal \returns the sum of the elements of \a a*/ +template inline typename unpacket_traits::type predux(const Packet& a) +{ return a; } + +/** \internal \returns the product of the elements of \a a*/ +template inline typename unpacket_traits::type predux_mul(const Packet& a) +{ return a; } + +/** \internal \returns the min of the elements of \a a*/ +template inline typename unpacket_traits::type predux_min(const Packet& a) +{ return a; } + +/** \internal \returns the max of the elements of \a a*/ +template inline typename unpacket_traits::type predux_max(const Packet& a) +{ return a; } + +/** \internal \returns the reversed elements of \a a*/ +template inline Packet preverse(const Packet& a) +{ return a; } + + +/** \internal \returns \a a with real and imaginary part flipped (for complex type only) */ +template inline Packet pcplxflip(const Packet& a) +{ + // FIXME: uncomment the following in case we drop the internal imag and real functions. +// using std::imag; +// using std::real; + return Packet(imag(a),real(a)); +} + +/************************** +* Special math functions +***************************/ + +/** \internal \returns the sine of \a a (coeff-wise) */ +template EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS +Packet psin(const Packet& a) { using std::sin; return sin(a); } + +/** \internal \returns the cosine of \a a (coeff-wise) */ +template EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS +Packet pcos(const Packet& a) { using std::cos; return cos(a); } + +/** \internal \returns the tan of \a a (coeff-wise) */ +template EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS +Packet ptan(const Packet& a) { using std::tan; return tan(a); } + +/** \internal \returns the arc sine of \a a (coeff-wise) */ +template EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS +Packet pasin(const Packet& a) { using std::asin; return asin(a); } + +/** \internal \returns the arc cosine of \a a (coeff-wise) */ +template EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS +Packet pacos(const Packet& a) { using std::acos; return acos(a); } + +/** \internal \returns the exp of \a a (coeff-wise) */ +template EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS +Packet pexp(const Packet& a) { using std::exp; return exp(a); } + +/** \internal \returns the log of \a a (coeff-wise) */ +template EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS +Packet plog(const Packet& a) { using std::log; return log(a); } + +/** \internal \returns the square-root of \a a (coeff-wise) */ +template EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS +Packet psqrt(const Packet& a) { using std::sqrt; return sqrt(a); } + +/*************************************************************************** +* The following functions might not have to be overwritten for vectorized types +***************************************************************************/ + +/** \internal copy a packet with constant coeficient \a a (e.g., [a,a,a,a]) to \a *to. \a to must be 16 bytes aligned */ +// NOTE: this function must really be templated on the packet type (think about different packet types for the same scalar type) +template +inline void pstore1(typename unpacket_traits::type* to, const typename unpacket_traits::type& a) +{ + pstore(to, pset1(a)); +} + +/** \internal \returns a * b + c (coeff-wise) */ +template inline Packet +pmadd(const Packet& a, + const Packet& b, + const Packet& c) +{ return padd(pmul(a, b),c); } + +/** \internal \returns a packet version of \a *from. + * If LoadMode equals #Aligned, \a from must be 16 bytes aligned */ +template +inline Packet ploadt(const typename unpacket_traits::type* from) +{ + if(LoadMode == Aligned) + return pload(from); + else + return ploadu(from); +} + +/** \internal copy the packet \a from to \a *to. + * If StoreMode equals #Aligned, \a to must be 16 bytes aligned */ +template +inline void pstoret(Scalar* to, const Packet& from) +{ + if(LoadMode == Aligned) + pstore(to, from); + else + pstoreu(to, from); +} + +/** \internal default implementation of palign() allowing partial specialization */ +template +struct palign_impl +{ + // by default data are aligned, so there is nothing to be done :) + static inline void run(PacketType&, const PacketType&) {} +}; + +/** \internal update \a first using the concatenation of the packet_size minus \a Offset last elements + * of \a first and \a Offset first elements of \a second. + * + * This function is currently only used to optimize matrix-vector products on unligned matrices. + * It takes 2 packets that represent a contiguous memory array, and returns a packet starting + * at the position \a Offset. For instance, for packets of 4 elements, we have: + * Input: + * - first = {f0,f1,f2,f3} + * - second = {s0,s1,s2,s3} + * Output: + * - if Offset==0 then {f0,f1,f2,f3} + * - if Offset==1 then {f1,f2,f3,s0} + * - if Offset==2 then {f2,f3,s0,s1} + * - if Offset==3 then {f3,s0,s1,s3} + */ +template +inline void palign(PacketType& first, const PacketType& second) +{ + palign_impl::run(first,second); +} + +/*************************************************************************** +* Fast complex products (GCC generates a function call which is very slow) +***************************************************************************/ + +template<> inline std::complex pmul(const std::complex& a, const std::complex& b) +{ return std::complex(real(a)*real(b) - imag(a)*imag(b), imag(a)*real(b) + real(a)*imag(b)); } + +template<> inline std::complex pmul(const std::complex& a, const std::complex& b) +{ return std::complex(real(a)*real(b) - imag(a)*imag(b), imag(a)*real(b) + real(a)*imag(b)); } + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_GENERIC_PACKET_MATH_H + diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/GlobalFunctions.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/GlobalFunctions.h new file mode 100644 index 00000000..2acf9772 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/GlobalFunctions.h @@ -0,0 +1,92 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2010-2012 Gael Guennebaud +// Copyright (C) 2010 Benoit Jacob +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_GLOBAL_FUNCTIONS_H +#define EIGEN_GLOBAL_FUNCTIONS_H + +#define EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(NAME,FUNCTOR) \ + template \ + inline const Eigen::CwiseUnaryOp, const Derived> \ + NAME(const Eigen::ArrayBase& x) { \ + return x.derived(); \ + } + +#define EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(NAME,FUNCTOR) \ + \ + template \ + struct NAME##_retval > \ + { \ + typedef const Eigen::CwiseUnaryOp, const Derived> type; \ + }; \ + template \ + struct NAME##_impl > \ + { \ + static inline typename NAME##_retval >::type run(const Eigen::ArrayBase& x) \ + { \ + return x.derived(); \ + } \ + }; + + +namespace Eigen +{ + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(real,scalar_real_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(imag,scalar_imag_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(conj,scalar_conjugate_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(sin,scalar_sin_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(cos,scalar_cos_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(asin,scalar_asin_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(acos,scalar_acos_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(tan,scalar_tan_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(exp,scalar_exp_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(log,scalar_log_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(abs,scalar_abs_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(sqrt,scalar_sqrt_op) + + template + inline const Eigen::CwiseUnaryOp, const Derived> + pow(const Eigen::ArrayBase& x, const typename Derived::Scalar& exponent) { + return x.derived().pow(exponent); + } + + template + inline const Eigen::CwiseBinaryOp, const Derived, const Derived> + pow(const Eigen::ArrayBase& x, const Eigen::ArrayBase& exponents) + { + return Eigen::CwiseBinaryOp, const Derived, const Derived>( + x.derived(), + exponents.derived() + ); + } + + /** + * \brief Component-wise division of a scalar by array elements. + **/ + template + inline const Eigen::CwiseUnaryOp, const Derived> + operator/(const typename Derived::Scalar& s, const Eigen::ArrayBase& a) + { + return Eigen::CwiseUnaryOp, const Derived>( + a.derived(), + Eigen::internal::scalar_inverse_mult_op(s) + ); + } + + namespace internal + { + EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(real,scalar_real_op) + EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(imag,scalar_imag_op) + EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(abs2,scalar_abs2_op) + } +} + +// TODO: cleanly disable those functions that are not supported on Array (numext::real_ref, internal::random, internal::isApprox...) + +#endif // EIGEN_GLOBAL_FUNCTIONS_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/IO.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/IO.h new file mode 100644 index 00000000..8d4bc59e --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/IO.h @@ -0,0 +1,250 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2006-2008 Benoit Jacob +// Copyright (C) 2008 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_IO_H +#define EIGEN_IO_H + +namespace Eigen { + +enum { DontAlignCols = 1 }; +enum { StreamPrecision = -1, + FullPrecision = -2 }; + +namespace internal { +template +std::ostream & print_matrix(std::ostream & s, const Derived& _m, const IOFormat& fmt); +} + +/** \class IOFormat + * \ingroup Core_Module + * + * \brief Stores a set of parameters controlling the way matrices are printed + * + * List of available parameters: + * - \b precision number of digits for floating point values, or one of the special constants \c StreamPrecision and \c FullPrecision. + * The default is the special value \c StreamPrecision which means to use the + * stream's own precision setting, as set for instance using \c cout.precision(3). The other special value + * \c FullPrecision means that the number of digits will be computed to match the full precision of each floating-point + * type. + * - \b flags an OR-ed combination of flags, the default value is 0, the only currently available flag is \c DontAlignCols which + * allows to disable the alignment of columns, resulting in faster code. + * - \b coeffSeparator string printed between two coefficients of the same row + * - \b rowSeparator string printed between two rows + * - \b rowPrefix string printed at the beginning of each row + * - \b rowSuffix string printed at the end of each row + * - \b matPrefix string printed at the beginning of the matrix + * - \b matSuffix string printed at the end of the matrix + * + * Example: \include IOFormat.cpp + * Output: \verbinclude IOFormat.out + * + * \sa DenseBase::format(), class WithFormat + */ +struct IOFormat +{ + /** Default contructor, see class IOFormat for the meaning of the parameters */ + IOFormat(int _precision = StreamPrecision, int _flags = 0, + const std::string& _coeffSeparator = " ", + const std::string& _rowSeparator = "\n", const std::string& _rowPrefix="", const std::string& _rowSuffix="", + const std::string& _matPrefix="", const std::string& _matSuffix="") + : matPrefix(_matPrefix), matSuffix(_matSuffix), rowPrefix(_rowPrefix), rowSuffix(_rowSuffix), rowSeparator(_rowSeparator), + rowSpacer(""), coeffSeparator(_coeffSeparator), precision(_precision), flags(_flags) + { + int i = int(matSuffix.length())-1; + while (i>=0 && matSuffix[i]!='\n') + { + rowSpacer += ' '; + i--; + } + } + std::string matPrefix, matSuffix; + std::string rowPrefix, rowSuffix, rowSeparator, rowSpacer; + std::string coeffSeparator; + int precision; + int flags; +}; + +/** \class WithFormat + * \ingroup Core_Module + * + * \brief Pseudo expression providing matrix output with given format + * + * \param ExpressionType the type of the object on which IO stream operations are performed + * + * This class represents an expression with stream operators controlled by a given IOFormat. + * It is the return type of DenseBase::format() + * and most of the time this is the only way it is used. + * + * See class IOFormat for some examples. + * + * \sa DenseBase::format(), class IOFormat + */ +template +class WithFormat +{ + public: + + WithFormat(const ExpressionType& matrix, const IOFormat& format) + : m_matrix(matrix), m_format(format) + {} + + friend std::ostream & operator << (std::ostream & s, const WithFormat& wf) + { + return internal::print_matrix(s, wf.m_matrix.eval(), wf.m_format); + } + + protected: + const typename ExpressionType::Nested m_matrix; + IOFormat m_format; +}; + +/** \returns a WithFormat proxy object allowing to print a matrix the with given + * format \a fmt. + * + * See class IOFormat for some examples. + * + * \sa class IOFormat, class WithFormat + */ +template +inline const WithFormat +DenseBase::format(const IOFormat& fmt) const +{ + return WithFormat(derived(), fmt); +} + +namespace internal { + +template +struct significant_decimals_default_impl +{ + typedef typename NumTraits::Real RealScalar; + static inline int run() + { + using std::ceil; + using std::log; + return cast(ceil(-log(NumTraits::epsilon())/log(RealScalar(10)))); + } +}; + +template +struct significant_decimals_default_impl +{ + static inline int run() + { + return 0; + } +}; + +template +struct significant_decimals_impl + : significant_decimals_default_impl::IsInteger> +{}; + +/** \internal + * print the matrix \a _m to the output stream \a s using the output format \a fmt */ +template +std::ostream & print_matrix(std::ostream & s, const Derived& _m, const IOFormat& fmt) +{ + if(_m.size() == 0) + { + s << fmt.matPrefix << fmt.matSuffix; + return s; + } + + typename Derived::Nested m = _m; + typedef typename Derived::Scalar Scalar; + typedef typename Derived::Index Index; + + Index width = 0; + + std::streamsize explicit_precision; + if(fmt.precision == StreamPrecision) + { + explicit_precision = 0; + } + else if(fmt.precision == FullPrecision) + { + if (NumTraits::IsInteger) + { + explicit_precision = 0; + } + else + { + explicit_precision = significant_decimals_impl::run(); + } + } + else + { + explicit_precision = fmt.precision; + } + + std::streamsize old_precision = 0; + if(explicit_precision) old_precision = s.precision(explicit_precision); + + bool align_cols = !(fmt.flags & DontAlignCols); + if(align_cols) + { + // compute the largest width + for(Index j = 0; j < m.cols(); ++j) + for(Index i = 0; i < m.rows(); ++i) + { + std::stringstream sstr; + sstr.copyfmt(s); + sstr << m.coeff(i,j); + width = std::max(width, Index(sstr.str().length())); + } + } + s << fmt.matPrefix; + for(Index i = 0; i < m.rows(); ++i) + { + if (i) + s << fmt.rowSpacer; + s << fmt.rowPrefix; + if(width) s.width(width); + s << m.coeff(i, 0); + for(Index j = 1; j < m.cols(); ++j) + { + s << fmt.coeffSeparator; + if (width) s.width(width); + s << m.coeff(i, j); + } + s << fmt.rowSuffix; + if( i < m.rows() - 1) + s << fmt.rowSeparator; + } + s << fmt.matSuffix; + if(explicit_precision) s.precision(old_precision); + return s; +} + +} // end namespace internal + +/** \relates DenseBase + * + * Outputs the matrix, to the given stream. + * + * If you wish to print the matrix with a format different than the default, use DenseBase::format(). + * + * It is also possible to change the default format by defining EIGEN_DEFAULT_IO_FORMAT before including Eigen headers. + * If not defined, this will automatically be defined to Eigen::IOFormat(), that is the Eigen::IOFormat with default parameters. + * + * \sa DenseBase::format() + */ +template +std::ostream & operator << +(std::ostream & s, + const DenseBase & m) +{ + return internal::print_matrix(s, m.eval(), EIGEN_DEFAULT_IO_FORMAT); +} + +} // end namespace Eigen + +#endif // EIGEN_IO_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/Map.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/Map.h new file mode 100644 index 00000000..f804c89d --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/Map.h @@ -0,0 +1,192 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2007-2010 Benoit Jacob +// Copyright (C) 2008 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_MAP_H +#define EIGEN_MAP_H + +namespace Eigen { + +/** \class Map + * \ingroup Core_Module + * + * \brief A matrix or vector expression mapping an existing array of data. + * + * \tparam PlainObjectType the equivalent matrix type of the mapped data + * \tparam MapOptions specifies whether the pointer is \c #Aligned, or \c #Unaligned. + * The default is \c #Unaligned. + * \tparam StrideType optionally specifies strides. By default, Map assumes the memory layout + * of an ordinary, contiguous array. This can be overridden by specifying strides. + * The type passed here must be a specialization of the Stride template, see examples below. + * + * This class represents a matrix or vector expression mapping an existing array of data. + * It can be used to let Eigen interface without any overhead with non-Eigen data structures, + * such as plain C arrays or structures from other libraries. By default, it assumes that the + * data is laid out contiguously in memory. You can however override this by explicitly specifying + * inner and outer strides. + * + * Here's an example of simply mapping a contiguous array as a \ref TopicStorageOrders "column-major" matrix: + * \include Map_simple.cpp + * Output: \verbinclude Map_simple.out + * + * If you need to map non-contiguous arrays, you can do so by specifying strides: + * + * Here's an example of mapping an array as a vector, specifying an inner stride, that is, the pointer + * increment between two consecutive coefficients. Here, we're specifying the inner stride as a compile-time + * fixed value. + * \include Map_inner_stride.cpp + * Output: \verbinclude Map_inner_stride.out + * + * Here's an example of mapping an array while specifying an outer stride. Here, since we're mapping + * as a column-major matrix, 'outer stride' means the pointer increment between two consecutive columns. + * Here, we're specifying the outer stride as a runtime parameter. Note that here \c OuterStride<> is + * a short version of \c OuterStride because the default template parameter of OuterStride + * is \c Dynamic + * \include Map_outer_stride.cpp + * Output: \verbinclude Map_outer_stride.out + * + * For more details and for an example of specifying both an inner and an outer stride, see class Stride. + * + * \b Tip: to change the array of data mapped by a Map object, you can use the C++ + * placement new syntax: + * + * Example: \include Map_placement_new.cpp + * Output: \verbinclude Map_placement_new.out + * + * This class is the return type of PlainObjectBase::Map() but can also be used directly. + * + * \sa PlainObjectBase::Map(), \ref TopicStorageOrders + */ + +namespace internal { +template +struct traits > + : public traits +{ + typedef traits TraitsBase; + typedef typename PlainObjectType::Index Index; + typedef typename PlainObjectType::Scalar Scalar; + enum { + InnerStrideAtCompileTime = StrideType::InnerStrideAtCompileTime == 0 + ? int(PlainObjectType::InnerStrideAtCompileTime) + : int(StrideType::InnerStrideAtCompileTime), + OuterStrideAtCompileTime = StrideType::OuterStrideAtCompileTime == 0 + ? int(PlainObjectType::OuterStrideAtCompileTime) + : int(StrideType::OuterStrideAtCompileTime), + HasNoInnerStride = InnerStrideAtCompileTime == 1, + HasNoOuterStride = StrideType::OuterStrideAtCompileTime == 0, + HasNoStride = HasNoInnerStride && HasNoOuterStride, + IsAligned = bool(EIGEN_ALIGN) && ((int(MapOptions)&Aligned)==Aligned), + IsDynamicSize = PlainObjectType::SizeAtCompileTime==Dynamic, + KeepsPacketAccess = bool(HasNoInnerStride) + && ( bool(IsDynamicSize) + || HasNoOuterStride + || ( OuterStrideAtCompileTime!=Dynamic + && ((static_cast(sizeof(Scalar))*OuterStrideAtCompileTime)%16)==0 ) ), + Flags0 = TraitsBase::Flags & (~NestByRefBit), + Flags1 = IsAligned ? (int(Flags0) | AlignedBit) : (int(Flags0) & ~AlignedBit), + Flags2 = (bool(HasNoStride) || bool(PlainObjectType::IsVectorAtCompileTime)) + ? int(Flags1) : int(Flags1 & ~LinearAccessBit), + Flags3 = is_lvalue::value ? int(Flags2) : (int(Flags2) & ~LvalueBit), + Flags = KeepsPacketAccess ? int(Flags3) : (int(Flags3) & ~PacketAccessBit) + }; +private: + enum { Options }; // Expressions don't have Options +}; +} + +template class Map + : public MapBase > +{ + public: + + typedef MapBase Base; + EIGEN_DENSE_PUBLIC_INTERFACE(Map) + + typedef typename Base::PointerType PointerType; +#if EIGEN2_SUPPORT_STAGE <= STAGE30_FULL_EIGEN3_API + typedef const Scalar* PointerArgType; + inline PointerType cast_to_pointer_type(PointerArgType ptr) { return const_cast(ptr); } +#else + typedef PointerType PointerArgType; + inline PointerType cast_to_pointer_type(PointerArgType ptr) { return ptr; } +#endif + + inline Index innerStride() const + { + return StrideType::InnerStrideAtCompileTime != 0 ? m_stride.inner() : 1; + } + + inline Index outerStride() const + { + return StrideType::OuterStrideAtCompileTime != 0 ? m_stride.outer() + : IsVectorAtCompileTime ? this->size() + : int(Flags)&RowMajorBit ? this->cols() + : this->rows(); + } + + /** Constructor in the fixed-size case. + * + * \param dataPtr pointer to the array to map + * \param a_stride optional Stride object, passing the strides. + */ + inline Map(PointerArgType dataPtr, const StrideType& a_stride = StrideType()) + : Base(cast_to_pointer_type(dataPtr)), m_stride(a_stride) + { + PlainObjectType::Base::_check_template_params(); + } + + /** Constructor in the dynamic-size vector case. + * + * \param dataPtr pointer to the array to map + * \param a_size the size of the vector expression + * \param a_stride optional Stride object, passing the strides. + */ + inline Map(PointerArgType dataPtr, Index a_size, const StrideType& a_stride = StrideType()) + : Base(cast_to_pointer_type(dataPtr), a_size), m_stride(a_stride) + { + PlainObjectType::Base::_check_template_params(); + } + + /** Constructor in the dynamic-size matrix case. + * + * \param dataPtr pointer to the array to map + * \param nbRows the number of rows of the matrix expression + * \param nbCols the number of columns of the matrix expression + * \param a_stride optional Stride object, passing the strides. + */ + inline Map(PointerArgType dataPtr, Index nbRows, Index nbCols, const StrideType& a_stride = StrideType()) + : Base(cast_to_pointer_type(dataPtr), nbRows, nbCols), m_stride(a_stride) + { + PlainObjectType::Base::_check_template_params(); + } + + EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Map) + + protected: + StrideType m_stride; +}; + +template +inline Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> + ::Array(const Scalar *data) +{ + this->_set_noalias(Eigen::Map(data)); +} + +template +inline Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> + ::Matrix(const Scalar *data) +{ + this->_set_noalias(Eigen::Map(data)); +} + +} // end namespace Eigen + +#endif // EIGEN_MAP_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/MapBase.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/MapBase.h new file mode 100644 index 00000000..a9828f7f --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/MapBase.h @@ -0,0 +1,247 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2007-2010 Benoit Jacob +// Copyright (C) 2008 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_MAPBASE_H +#define EIGEN_MAPBASE_H + +#define EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived) \ + EIGEN_STATIC_ASSERT((int(internal::traits::Flags) & LinearAccessBit) || Derived::IsVectorAtCompileTime, \ + YOU_ARE_TRYING_TO_USE_AN_INDEX_BASED_ACCESSOR_ON_AN_EXPRESSION_THAT_DOES_NOT_SUPPORT_THAT) + +namespace Eigen { + +/** \class MapBase + * \ingroup Core_Module + * + * \brief Base class for Map and Block expression with direct access + * + * \sa class Map, class Block + */ +template class MapBase + : public internal::dense_xpr_base::type +{ + public: + + typedef typename internal::dense_xpr_base::type Base; + enum { + RowsAtCompileTime = internal::traits::RowsAtCompileTime, + ColsAtCompileTime = internal::traits::ColsAtCompileTime, + SizeAtCompileTime = Base::SizeAtCompileTime + }; + + typedef typename internal::traits::StorageKind StorageKind; + typedef typename internal::traits::Index Index; + typedef typename internal::traits::Scalar Scalar; + typedef typename internal::packet_traits::type PacketScalar; + typedef typename NumTraits::Real RealScalar; + typedef typename internal::conditional< + bool(internal::is_lvalue::value), + Scalar *, + const Scalar *>::type + PointerType; + + using Base::derived; +// using Base::RowsAtCompileTime; +// using Base::ColsAtCompileTime; +// using Base::SizeAtCompileTime; + using Base::MaxRowsAtCompileTime; + using Base::MaxColsAtCompileTime; + using Base::MaxSizeAtCompileTime; + using Base::IsVectorAtCompileTime; + using Base::Flags; + using Base::IsRowMajor; + + using Base::rows; + using Base::cols; + using Base::size; + using Base::coeff; + using Base::coeffRef; + using Base::lazyAssign; + using Base::eval; + + using Base::innerStride; + using Base::outerStride; + using Base::rowStride; + using Base::colStride; + + // bug 217 - compile error on ICC 11.1 + using Base::operator=; + + typedef typename Base::CoeffReturnType CoeffReturnType; + + inline Index rows() const { return m_rows.value(); } + inline Index cols() const { return m_cols.value(); } + + /** Returns a pointer to the first coefficient of the matrix or vector. + * + * \note When addressing this data, make sure to honor the strides returned by innerStride() and outerStride(). + * + * \sa innerStride(), outerStride() + */ + inline const Scalar* data() const { return m_data; } + + inline const Scalar& coeff(Index rowId, Index colId) const + { + return m_data[colId * colStride() + rowId * rowStride()]; + } + + inline const Scalar& coeff(Index index) const + { + EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived) + return m_data[index * innerStride()]; + } + + inline const Scalar& coeffRef(Index rowId, Index colId) const + { + return this->m_data[colId * colStride() + rowId * rowStride()]; + } + + inline const Scalar& coeffRef(Index index) const + { + EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived) + return this->m_data[index * innerStride()]; + } + + template + inline PacketScalar packet(Index rowId, Index colId) const + { + return internal::ploadt + (m_data + (colId * colStride() + rowId * rowStride())); + } + + template + inline PacketScalar packet(Index index) const + { + EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived) + return internal::ploadt(m_data + index * innerStride()); + } + + explicit inline MapBase(PointerType dataPtr) : m_data(dataPtr), m_rows(RowsAtCompileTime), m_cols(ColsAtCompileTime) + { + EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived) + checkSanity(); + } + + inline MapBase(PointerType dataPtr, Index vecSize) + : m_data(dataPtr), + m_rows(RowsAtCompileTime == Dynamic ? vecSize : Index(RowsAtCompileTime)), + m_cols(ColsAtCompileTime == Dynamic ? vecSize : Index(ColsAtCompileTime)) + { + EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) + eigen_assert(vecSize >= 0); + eigen_assert(dataPtr == 0 || SizeAtCompileTime == Dynamic || SizeAtCompileTime == vecSize); + checkSanity(); + } + + inline MapBase(PointerType dataPtr, Index nbRows, Index nbCols) + : m_data(dataPtr), m_rows(nbRows), m_cols(nbCols) + { + eigen_assert( (dataPtr == 0) + || ( nbRows >= 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == nbRows) + && nbCols >= 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == nbCols))); + checkSanity(); + } + + protected: + + void checkSanity() const + { + EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(internal::traits::Flags&PacketAccessBit, + internal::inner_stride_at_compile_time::ret==1), + PACKET_ACCESS_REQUIRES_TO_HAVE_INNER_STRIDE_FIXED_TO_1); + eigen_assert(EIGEN_IMPLIES(internal::traits::Flags&AlignedBit, (size_t(m_data) % 16) == 0) + && "input pointer is not aligned on a 16 byte boundary"); + } + + PointerType m_data; + const internal::variable_if_dynamic m_rows; + const internal::variable_if_dynamic m_cols; +}; + +template class MapBase + : public MapBase +{ + typedef MapBase ReadOnlyMapBase; + public: + + typedef MapBase Base; + + typedef typename Base::Scalar Scalar; + typedef typename Base::PacketScalar PacketScalar; + typedef typename Base::Index Index; + typedef typename Base::PointerType PointerType; + + using Base::derived; + using Base::rows; + using Base::cols; + using Base::size; + using Base::coeff; + using Base::coeffRef; + + using Base::innerStride; + using Base::outerStride; + using Base::rowStride; + using Base::colStride; + + typedef typename internal::conditional< + internal::is_lvalue::value, + Scalar, + const Scalar + >::type ScalarWithConstIfNotLvalue; + + inline const Scalar* data() const { return this->m_data; } + inline ScalarWithConstIfNotLvalue* data() { return this->m_data; } // no const-cast here so non-const-correct code will give a compile error + + inline ScalarWithConstIfNotLvalue& coeffRef(Index row, Index col) + { + return this->m_data[col * colStride() + row * rowStride()]; + } + + inline ScalarWithConstIfNotLvalue& coeffRef(Index index) + { + EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived) + return this->m_data[index * innerStride()]; + } + + template + inline void writePacket(Index row, Index col, const PacketScalar& val) + { + internal::pstoret + (this->m_data + (col * colStride() + row * rowStride()), val); + } + + template + inline void writePacket(Index index, const PacketScalar& val) + { + EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived) + internal::pstoret + (this->m_data + index * innerStride(), val); + } + + explicit inline MapBase(PointerType dataPtr) : Base(dataPtr) {} + inline MapBase(PointerType dataPtr, Index vecSize) : Base(dataPtr, vecSize) {} + inline MapBase(PointerType dataPtr, Index nbRows, Index nbCols) : Base(dataPtr, nbRows, nbCols) {} + + Derived& operator=(const MapBase& other) + { + ReadOnlyMapBase::Base::operator=(other); + return derived(); + } + + // In theory we could simply refer to Base:Base::operator=, but MSVC does not like Base::Base, + // see bugs 821 and 920. + using ReadOnlyMapBase::Base::operator=; +}; + +#undef EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS + +} // end namespace Eigen + +#endif // EIGEN_MAPBASE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/MathFunctions.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/MathFunctions.h new file mode 100644 index 00000000..adf2f9c5 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/MathFunctions.h @@ -0,0 +1,768 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2006-2010 Benoit Jacob +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_MATHFUNCTIONS_H +#define EIGEN_MATHFUNCTIONS_H + +namespace Eigen { + +namespace internal { + +/** \internal \struct global_math_functions_filtering_base + * + * What it does: + * Defines a typedef 'type' as follows: + * - if type T has a member typedef Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl, then + * global_math_functions_filtering_base::type is a typedef for it. + * - otherwise, global_math_functions_filtering_base::type is a typedef for T. + * + * How it's used: + * To allow to defined the global math functions (like sin...) in certain cases, like the Array expressions. + * When you do sin(array1+array2), the object array1+array2 has a complicated expression type, all what you want to know + * is that it inherits ArrayBase. So we implement a partial specialization of sin_impl for ArrayBase. + * So we must make sure to use sin_impl > and not sin_impl, otherwise our partial specialization + * won't be used. How does sin know that? That's exactly what global_math_functions_filtering_base tells it. + * + * How it's implemented: + * SFINAE in the style of enable_if. Highly susceptible of breaking compilers. With GCC, it sure does work, but if you replace + * the typename dummy by an integer template parameter, it doesn't work anymore! + */ + +template +struct global_math_functions_filtering_base +{ + typedef T type; +}; + +template struct always_void { typedef void type; }; + +template +struct global_math_functions_filtering_base + ::type + > +{ + typedef typename T::Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl type; +}; + +#define EIGEN_MATHFUNC_IMPL(func, scalar) Eigen::internal::func##_impl::type> +#define EIGEN_MATHFUNC_RETVAL(func, scalar) typename Eigen::internal::func##_retval::type>::type + +/**************************************************************************** +* Implementation of real * +****************************************************************************/ + +template::IsComplex> +struct real_default_impl +{ + typedef typename NumTraits::Real RealScalar; + static inline RealScalar run(const Scalar& x) + { + return x; + } +}; + +template +struct real_default_impl +{ + typedef typename NumTraits::Real RealScalar; + static inline RealScalar run(const Scalar& x) + { + using std::real; + return real(x); + } +}; + +template struct real_impl : real_default_impl {}; + +template +struct real_retval +{ + typedef typename NumTraits::Real type; +}; + + +/**************************************************************************** +* Implementation of imag * +****************************************************************************/ + +template::IsComplex> +struct imag_default_impl +{ + typedef typename NumTraits::Real RealScalar; + static inline RealScalar run(const Scalar&) + { + return RealScalar(0); + } +}; + +template +struct imag_default_impl +{ + typedef typename NumTraits::Real RealScalar; + static inline RealScalar run(const Scalar& x) + { + using std::imag; + return imag(x); + } +}; + +template struct imag_impl : imag_default_impl {}; + +template +struct imag_retval +{ + typedef typename NumTraits::Real type; +}; + +/**************************************************************************** +* Implementation of real_ref * +****************************************************************************/ + +template +struct real_ref_impl +{ + typedef typename NumTraits::Real RealScalar; + static inline RealScalar& run(Scalar& x) + { + return reinterpret_cast(&x)[0]; + } + static inline const RealScalar& run(const Scalar& x) + { + return reinterpret_cast(&x)[0]; + } +}; + +template +struct real_ref_retval +{ + typedef typename NumTraits::Real & type; +}; + +/**************************************************************************** +* Implementation of imag_ref * +****************************************************************************/ + +template +struct imag_ref_default_impl +{ + typedef typename NumTraits::Real RealScalar; + static inline RealScalar& run(Scalar& x) + { + return reinterpret_cast(&x)[1]; + } + static inline const RealScalar& run(const Scalar& x) + { + return reinterpret_cast(&x)[1]; + } +}; + +template +struct imag_ref_default_impl +{ + static inline Scalar run(Scalar&) + { + return Scalar(0); + } + static inline const Scalar run(const Scalar&) + { + return Scalar(0); + } +}; + +template +struct imag_ref_impl : imag_ref_default_impl::IsComplex> {}; + +template +struct imag_ref_retval +{ + typedef typename NumTraits::Real & type; +}; + +/**************************************************************************** +* Implementation of conj * +****************************************************************************/ + +template::IsComplex> +struct conj_impl +{ + static inline Scalar run(const Scalar& x) + { + return x; + } +}; + +template +struct conj_impl +{ + static inline Scalar run(const Scalar& x) + { + using std::conj; + return conj(x); + } +}; + +template +struct conj_retval +{ + typedef Scalar type; +}; + +/**************************************************************************** +* Implementation of abs2 * +****************************************************************************/ + +template +struct abs2_impl +{ + typedef typename NumTraits::Real RealScalar; + static inline RealScalar run(const Scalar& x) + { + return x*x; + } +}; + +template +struct abs2_impl > +{ + static inline RealScalar run(const std::complex& x) + { + return real(x)*real(x) + imag(x)*imag(x); + } +}; + +template +struct abs2_retval +{ + typedef typename NumTraits::Real type; +}; + +/**************************************************************************** +* Implementation of norm1 * +****************************************************************************/ + +template +struct norm1_default_impl +{ + typedef typename NumTraits::Real RealScalar; + static inline RealScalar run(const Scalar& x) + { + using std::abs; + return abs(real(x)) + abs(imag(x)); + } +}; + +template +struct norm1_default_impl +{ + static inline Scalar run(const Scalar& x) + { + using std::abs; + return abs(x); + } +}; + +template +struct norm1_impl : norm1_default_impl::IsComplex> {}; + +template +struct norm1_retval +{ + typedef typename NumTraits::Real type; +}; + +/**************************************************************************** +* Implementation of hypot * +****************************************************************************/ + +template +struct hypot_impl +{ + typedef typename NumTraits::Real RealScalar; + static inline RealScalar run(const Scalar& x, const Scalar& y) + { + using std::max; + using std::min; + using std::abs; + using std::sqrt; + RealScalar _x = abs(x); + RealScalar _y = abs(y); + RealScalar p = (max)(_x, _y); + if(p==RealScalar(0)) return RealScalar(0); + RealScalar q = (min)(_x, _y); + RealScalar qp = q/p; + return p * sqrt(RealScalar(1) + qp*qp); + } +}; + +template +struct hypot_retval +{ + typedef typename NumTraits::Real type; +}; + +/**************************************************************************** +* Implementation of cast * +****************************************************************************/ + +template +struct cast_impl +{ + static inline NewType run(const OldType& x) + { + return static_cast(x); + } +}; + +// here, for once, we're plainly returning NewType: we don't want cast to do weird things. + +template +inline NewType cast(const OldType& x) +{ + return cast_impl::run(x); +} + +/**************************************************************************** +* Implementation of atanh2 * +****************************************************************************/ + +template +struct atanh2_default_impl +{ + typedef Scalar retval; + typedef typename NumTraits::Real RealScalar; + static inline Scalar run(const Scalar& x, const Scalar& y) + { + using std::abs; + using std::log; + using std::sqrt; + Scalar z = x / y; + if (y == Scalar(0) || abs(z) > sqrt(NumTraits::epsilon())) + return RealScalar(0.5) * log((y + x) / (y - x)); + else + return z + z*z*z / RealScalar(3); + } +}; + +template +struct atanh2_default_impl +{ + static inline Scalar run(const Scalar&, const Scalar&) + { + EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar) + return Scalar(0); + } +}; + +template +struct atanh2_impl : atanh2_default_impl::IsInteger> {}; + +template +struct atanh2_retval +{ + typedef Scalar type; +}; + +/**************************************************************************** +* Implementation of pow * +****************************************************************************/ + +template +struct pow_default_impl +{ + typedef Scalar retval; + static inline Scalar run(const Scalar& x, const Scalar& y) + { + using std::pow; + return pow(x, y); + } +}; + +template +struct pow_default_impl +{ + static inline Scalar run(Scalar x, Scalar y) + { + Scalar res(1); + eigen_assert(!NumTraits::IsSigned || y >= 0); + if(y & 1) res *= x; + y >>= 1; + while(y) + { + x *= x; + if(y&1) res *= x; + y >>= 1; + } + return res; + } +}; + +template +struct pow_impl : pow_default_impl::IsInteger> {}; + +template +struct pow_retval +{ + typedef Scalar type; +}; + +/**************************************************************************** +* Implementation of random * +****************************************************************************/ + +template +struct random_default_impl {}; + +template +struct random_impl : random_default_impl::IsComplex, NumTraits::IsInteger> {}; + +template +struct random_retval +{ + typedef Scalar type; +}; + +template inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random(const Scalar& x, const Scalar& y); +template inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random(); + +template +struct random_default_impl +{ + static inline Scalar run(const Scalar& x, const Scalar& y) + { + return x + (y-x) * Scalar(std::rand()) / Scalar(RAND_MAX); + } + static inline Scalar run() + { + return run(Scalar(NumTraits::IsSigned ? -1 : 0), Scalar(1)); + } +}; + +enum { + floor_log2_terminate, + floor_log2_move_up, + floor_log2_move_down, + floor_log2_bogus +}; + +template struct floor_log2_selector +{ + enum { middle = (lower + upper) / 2, + value = (upper <= lower + 1) ? int(floor_log2_terminate) + : (n < (1 << middle)) ? int(floor_log2_move_down) + : (n==0) ? int(floor_log2_bogus) + : int(floor_log2_move_up) + }; +}; + +template::value> +struct floor_log2 {}; + +template +struct floor_log2 +{ + enum { value = floor_log2::middle>::value }; +}; + +template +struct floor_log2 +{ + enum { value = floor_log2::middle, upper>::value }; +}; + +template +struct floor_log2 +{ + enum { value = (n >= ((unsigned int)(1) << (lower+1))) ? lower+1 : lower }; +}; + +template +struct floor_log2 +{ + // no value, error at compile time +}; + +template +struct random_default_impl +{ + typedef typename NumTraits::NonInteger NonInteger; + + static inline Scalar run(const Scalar& x, const Scalar& y) + { + return x + Scalar((NonInteger(y)-x+1) * std::rand() / (RAND_MAX + NonInteger(1))); + } + + static inline Scalar run() + { +#ifdef EIGEN_MAKING_DOCS + return run(Scalar(NumTraits::IsSigned ? -10 : 0), Scalar(10)); +#else + enum { rand_bits = floor_log2<(unsigned int)(RAND_MAX)+1>::value, + scalar_bits = sizeof(Scalar) * CHAR_BIT, + shift = EIGEN_PLAIN_ENUM_MAX(0, int(rand_bits) - int(scalar_bits)), + offset = NumTraits::IsSigned ? (1 << (EIGEN_PLAIN_ENUM_MIN(rand_bits,scalar_bits)-1)) : 0 + }; + return Scalar((std::rand() >> shift) - offset); +#endif + } +}; + +template +struct random_default_impl +{ + static inline Scalar run(const Scalar& x, const Scalar& y) + { + return Scalar(random(real(x), real(y)), + random(imag(x), imag(y))); + } + static inline Scalar run() + { + typedef typename NumTraits::Real RealScalar; + return Scalar(random(), random()); + } +}; + +template +inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random(const Scalar& x, const Scalar& y) +{ + return EIGEN_MATHFUNC_IMPL(random, Scalar)::run(x, y); +} + +template +inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random() +{ + return EIGEN_MATHFUNC_IMPL(random, Scalar)::run(); +} + +} // end namespace internal + +/**************************************************************************** +* Generic math function * +****************************************************************************/ + +namespace numext { + +template +inline EIGEN_MATHFUNC_RETVAL(real, Scalar) real(const Scalar& x) +{ + return EIGEN_MATHFUNC_IMPL(real, Scalar)::run(x); +} + +template +inline typename internal::add_const_on_value_type< EIGEN_MATHFUNC_RETVAL(real_ref, Scalar) >::type real_ref(const Scalar& x) +{ + return internal::real_ref_impl::run(x); +} + +template +inline EIGEN_MATHFUNC_RETVAL(real_ref, Scalar) real_ref(Scalar& x) +{ + return EIGEN_MATHFUNC_IMPL(real_ref, Scalar)::run(x); +} + +template +inline EIGEN_MATHFUNC_RETVAL(imag, Scalar) imag(const Scalar& x) +{ + return EIGEN_MATHFUNC_IMPL(imag, Scalar)::run(x); +} + +template +inline typename internal::add_const_on_value_type< EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) >::type imag_ref(const Scalar& x) +{ + return internal::imag_ref_impl::run(x); +} + +template +inline EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) imag_ref(Scalar& x) +{ + return EIGEN_MATHFUNC_IMPL(imag_ref, Scalar)::run(x); +} + +template +inline EIGEN_MATHFUNC_RETVAL(conj, Scalar) conj(const Scalar& x) +{ + return EIGEN_MATHFUNC_IMPL(conj, Scalar)::run(x); +} + +template +inline EIGEN_MATHFUNC_RETVAL(abs2, Scalar) abs2(const Scalar& x) +{ + return EIGEN_MATHFUNC_IMPL(abs2, Scalar)::run(x); +} + +template +inline EIGEN_MATHFUNC_RETVAL(norm1, Scalar) norm1(const Scalar& x) +{ + return EIGEN_MATHFUNC_IMPL(norm1, Scalar)::run(x); +} + +template +inline EIGEN_MATHFUNC_RETVAL(hypot, Scalar) hypot(const Scalar& x, const Scalar& y) +{ + return EIGEN_MATHFUNC_IMPL(hypot, Scalar)::run(x, y); +} + +template +inline EIGEN_MATHFUNC_RETVAL(atanh2, Scalar) atanh2(const Scalar& x, const Scalar& y) +{ + return EIGEN_MATHFUNC_IMPL(atanh2, Scalar)::run(x, y); +} + +template +inline EIGEN_MATHFUNC_RETVAL(pow, Scalar) pow(const Scalar& x, const Scalar& y) +{ + return EIGEN_MATHFUNC_IMPL(pow, Scalar)::run(x, y); +} + +// std::isfinite is non standard, so let's define our own version, +// even though it is not very efficient. +template bool (isfinite)(const T& x) +{ + return x::highest() && x>NumTraits::lowest(); +} + +} // end namespace numext + +namespace internal { + +/**************************************************************************** +* Implementation of fuzzy comparisons * +****************************************************************************/ + +template +struct scalar_fuzzy_default_impl {}; + +template +struct scalar_fuzzy_default_impl +{ + typedef typename NumTraits::Real RealScalar; + template + static inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y, const RealScalar& prec) + { + using std::abs; + return abs(x) <= abs(y) * prec; + } + static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar& prec) + { + using std::min; + using std::abs; + return abs(x - y) <= (min)(abs(x), abs(y)) * prec; + } + static inline bool isApproxOrLessThan(const Scalar& x, const Scalar& y, const RealScalar& prec) + { + return x <= y || isApprox(x, y, prec); + } +}; + +template +struct scalar_fuzzy_default_impl +{ + typedef typename NumTraits::Real RealScalar; + template + static inline bool isMuchSmallerThan(const Scalar& x, const Scalar&, const RealScalar&) + { + return x == Scalar(0); + } + static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar&) + { + return x == y; + } + static inline bool isApproxOrLessThan(const Scalar& x, const Scalar& y, const RealScalar&) + { + return x <= y; + } +}; + +template +struct scalar_fuzzy_default_impl +{ + typedef typename NumTraits::Real RealScalar; + template + static inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y, const RealScalar& prec) + { + return numext::abs2(x) <= numext::abs2(y) * prec * prec; + } + static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar& prec) + { + using std::min; + return numext::abs2(x - y) <= (min)(numext::abs2(x), numext::abs2(y)) * prec * prec; + } +}; + +template +struct scalar_fuzzy_impl : scalar_fuzzy_default_impl::IsComplex, NumTraits::IsInteger> {}; + +template +inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y, + typename NumTraits::Real precision = NumTraits::dummy_precision()) +{ + return scalar_fuzzy_impl::template isMuchSmallerThan(x, y, precision); +} + +template +inline bool isApprox(const Scalar& x, const Scalar& y, + typename NumTraits::Real precision = NumTraits::dummy_precision()) +{ + return scalar_fuzzy_impl::isApprox(x, y, precision); +} + +template +inline bool isApproxOrLessThan(const Scalar& x, const Scalar& y, + typename NumTraits::Real precision = NumTraits::dummy_precision()) +{ + return scalar_fuzzy_impl::isApproxOrLessThan(x, y, precision); +} + +/****************************************** +*** The special case of the bool type *** +******************************************/ + +template<> struct random_impl +{ + static inline bool run() + { + return random(0,1)==0 ? false : true; + } +}; + +template<> struct scalar_fuzzy_impl +{ + typedef bool RealScalar; + + template + static inline bool isMuchSmallerThan(const bool& x, const bool&, const bool&) + { + return !x; + } + + static inline bool isApprox(bool x, bool y, bool) + { + return x == y; + } + + static inline bool isApproxOrLessThan(const bool& x, const bool& y, const bool&) + { + return (!x) || y; + } + +}; + + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_MATHFUNCTIONS_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/Matrix.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/Matrix.h new file mode 100644 index 00000000..02be142d --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/Matrix.h @@ -0,0 +1,420 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2006-2010 Benoit Jacob +// Copyright (C) 2008-2009 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_MATRIX_H +#define EIGEN_MATRIX_H + +namespace Eigen { + +/** \class Matrix + * \ingroup Core_Module + * + * \brief The matrix class, also used for vectors and row-vectors + * + * The %Matrix class is the work-horse for all \em dense (\ref dense "note") matrices and vectors within Eigen. + * Vectors are matrices with one column, and row-vectors are matrices with one row. + * + * The %Matrix class encompasses \em both fixed-size and dynamic-size objects (\ref fixedsize "note"). + * + * The first three template parameters are required: + * \tparam _Scalar \anchor matrix_tparam_scalar Numeric type, e.g. float, double, int or std::complex. + * User defined sclar types are supported as well (see \ref user_defined_scalars "here"). + * \tparam _Rows Number of rows, or \b Dynamic + * \tparam _Cols Number of columns, or \b Dynamic + * + * The remaining template parameters are optional -- in most cases you don't have to worry about them. + * \tparam _Options \anchor matrix_tparam_options A combination of either \b #RowMajor or \b #ColMajor, and of either + * \b #AutoAlign or \b #DontAlign. + * The former controls \ref TopicStorageOrders "storage order", and defaults to column-major. The latter controls alignment, which is required + * for vectorization. It defaults to aligning matrices except for fixed sizes that aren't a multiple of the packet size. + * \tparam _MaxRows Maximum number of rows. Defaults to \a _Rows (\ref maxrows "note"). + * \tparam _MaxCols Maximum number of columns. Defaults to \a _Cols (\ref maxrows "note"). + * + * Eigen provides a number of typedefs covering the usual cases. Here are some examples: + * + * \li \c Matrix2d is a 2x2 square matrix of doubles (\c Matrix) + * \li \c Vector4f is a vector of 4 floats (\c Matrix) + * \li \c RowVector3i is a row-vector of 3 ints (\c Matrix) + * + * \li \c MatrixXf is a dynamic-size matrix of floats (\c Matrix) + * \li \c VectorXf is a dynamic-size vector of floats (\c Matrix) + * + * \li \c Matrix2Xf is a partially fixed-size (dynamic-size) matrix of floats (\c Matrix) + * \li \c MatrixX3d is a partially dynamic-size (fixed-size) matrix of double (\c Matrix) + * + * See \link matrixtypedefs this page \endlink for a complete list of predefined \em %Matrix and \em Vector typedefs. + * + * You can access elements of vectors and matrices using normal subscripting: + * + * \code + * Eigen::VectorXd v(10); + * v[0] = 0.1; + * v[1] = 0.2; + * v(0) = 0.3; + * v(1) = 0.4; + * + * Eigen::MatrixXi m(10, 10); + * m(0, 1) = 1; + * m(0, 2) = 2; + * m(0, 3) = 3; + * \endcode + * + * This class can be extended with the help of the plugin mechanism described on the page + * \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_MATRIX_PLUGIN. + * + * Some notes: + * + *

+ *
\anchor dense Dense versus sparse:
+ *
This %Matrix class handles dense, not sparse matrices and vectors. For sparse matrices and vectors, see the Sparse module. + * + * Dense matrices and vectors are plain usual arrays of coefficients. All the coefficients are stored, in an ordinary contiguous array. + * This is unlike Sparse matrices and vectors where the coefficients are stored as a list of nonzero coefficients.
+ * + *
\anchor fixedsize Fixed-size versus dynamic-size:
+ *
Fixed-size means that the numbers of rows and columns are known are compile-time. In this case, Eigen allocates the array + * of coefficients as a fixed-size array, as a class member. This makes sense for very small matrices, typically up to 4x4, sometimes up + * to 16x16. Larger matrices should be declared as dynamic-size even if one happens to know their size at compile-time. + * + * Dynamic-size means that the numbers of rows or columns are not necessarily known at compile-time. In this case they are runtime + * variables, and the array of coefficients is allocated dynamically on the heap. + * + * Note that \em dense matrices, be they Fixed-size or Dynamic-size, do not expand dynamically in the sense of a std::map. + * If you want this behavior, see the Sparse module.
+ * + *
\anchor maxrows _MaxRows and _MaxCols:
+ *
In most cases, one just leaves these parameters to the default values. + * These parameters mean the maximum size of rows and columns that the matrix may have. They are useful in cases + * when the exact numbers of rows and columns are not known are compile-time, but it is known at compile-time that they cannot + * exceed a certain value. This happens when taking dynamic-size blocks inside fixed-size matrices: in this case _MaxRows and _MaxCols + * are the dimensions of the original matrix, while _Rows and _Cols are Dynamic.
+ *
+ * + * \see MatrixBase for the majority of the API methods for matrices, \ref TopicClassHierarchy, + * \ref TopicStorageOrders + */ + +namespace internal { +template +struct traits > +{ + typedef _Scalar Scalar; + typedef Dense StorageKind; + typedef DenseIndex Index; + typedef MatrixXpr XprKind; + enum { + RowsAtCompileTime = _Rows, + ColsAtCompileTime = _Cols, + MaxRowsAtCompileTime = _MaxRows, + MaxColsAtCompileTime = _MaxCols, + Flags = compute_matrix_flags<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::ret, + CoeffReadCost = NumTraits::ReadCost, + Options = _Options, + InnerStrideAtCompileTime = 1, + OuterStrideAtCompileTime = (Options&RowMajor) ? ColsAtCompileTime : RowsAtCompileTime + }; +}; +} + +template +class Matrix + : public PlainObjectBase > +{ + public: + + /** \brief Base class typedef. + * \sa PlainObjectBase + */ + typedef PlainObjectBase Base; + + enum { Options = _Options }; + + EIGEN_DENSE_PUBLIC_INTERFACE(Matrix) + + typedef typename Base::PlainObject PlainObject; + + using Base::base; + using Base::coeffRef; + + /** + * \brief Assigns matrices to each other. + * + * \note This is a special case of the templated operator=. Its purpose is + * to prevent a default operator= from hiding the templated operator=. + * + * \callgraph + */ + EIGEN_STRONG_INLINE Matrix& operator=(const Matrix& other) + { + return Base::_set(other); + } + + /** \internal + * \brief Copies the value of the expression \a other into \c *this with automatic resizing. + * + * *this might be resized to match the dimensions of \a other. If *this was a null matrix (not already initialized), + * it will be initialized. + * + * Note that copying a row-vector into a vector (and conversely) is allowed. + * The resizing, if any, is then done in the appropriate way so that row-vectors + * remain row-vectors and vectors remain vectors. + */ + template + EIGEN_STRONG_INLINE Matrix& operator=(const MatrixBase& other) + { + return Base::_set(other); + } + + /* Here, doxygen failed to copy the brief information when using \copydoc */ + + /** + * \brief Copies the generic expression \a other into *this. + * \copydetails DenseBase::operator=(const EigenBase &other) + */ + template + EIGEN_STRONG_INLINE Matrix& operator=(const EigenBase &other) + { + return Base::operator=(other); + } + + template + EIGEN_STRONG_INLINE Matrix& operator=(const ReturnByValue& func) + { + return Base::operator=(func); + } + + /** \brief Default constructor. + * + * For fixed-size matrices, does nothing. + * + * For dynamic-size matrices, creates an empty matrix of size 0. Does not allocate any array. Such a matrix + * is called a null matrix. This constructor is the unique way to create null matrices: resizing + * a matrix to 0 is not supported. + * + * \sa resize(Index,Index) + */ + EIGEN_STRONG_INLINE Matrix() : Base() + { + Base::_check_template_params(); + EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED + } + + // FIXME is it still needed + Matrix(internal::constructor_without_unaligned_array_assert) + : Base(internal::constructor_without_unaligned_array_assert()) + { Base::_check_template_params(); EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED } + +#ifdef EIGEN_HAVE_RVALUE_REFERENCES + Matrix(Matrix&& other) + : Base(std::move(other)) + { + Base::_check_template_params(); + if (RowsAtCompileTime!=Dynamic && ColsAtCompileTime!=Dynamic) + Base::_set_noalias(other); + } + Matrix& operator=(Matrix&& other) + { + other.swap(*this); + return *this; + } +#endif + + /** \brief Constructs a vector or row-vector with given dimension. \only_for_vectors + * + * Note that this is only useful for dynamic-size vectors. For fixed-size vectors, + * it is redundant to pass the dimension here, so it makes more sense to use the default + * constructor Matrix() instead. + */ + EIGEN_STRONG_INLINE explicit Matrix(Index dim) + : Base(dim, RowsAtCompileTime == 1 ? 1 : dim, ColsAtCompileTime == 1 ? 1 : dim) + { + Base::_check_template_params(); + EIGEN_STATIC_ASSERT_VECTOR_ONLY(Matrix) + eigen_assert(dim >= 0); + eigen_assert(SizeAtCompileTime == Dynamic || SizeAtCompileTime == dim); + EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED + } + + #ifndef EIGEN_PARSED_BY_DOXYGEN + template + EIGEN_STRONG_INLINE Matrix(const T0& x, const T1& y) + { + Base::_check_template_params(); + Base::template _init2(x, y); + } + #else + /** \brief Constructs an uninitialized matrix with \a rows rows and \a cols columns. + * + * This is useful for dynamic-size matrices. For fixed-size matrices, + * it is redundant to pass these parameters, so one should use the default constructor + * Matrix() instead. */ + Matrix(Index rows, Index cols); + /** \brief Constructs an initialized 2D vector with given coefficients */ + Matrix(const Scalar& x, const Scalar& y); + #endif + + /** \brief Constructs an initialized 3D vector with given coefficients */ + EIGEN_STRONG_INLINE Matrix(const Scalar& x, const Scalar& y, const Scalar& z) + { + Base::_check_template_params(); + EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Matrix, 3) + m_storage.data()[0] = x; + m_storage.data()[1] = y; + m_storage.data()[2] = z; + } + /** \brief Constructs an initialized 4D vector with given coefficients */ + EIGEN_STRONG_INLINE Matrix(const Scalar& x, const Scalar& y, const Scalar& z, const Scalar& w) + { + Base::_check_template_params(); + EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Matrix, 4) + m_storage.data()[0] = x; + m_storage.data()[1] = y; + m_storage.data()[2] = z; + m_storage.data()[3] = w; + } + + explicit Matrix(const Scalar *data); + + /** \brief Constructor copying the value of the expression \a other */ + template + EIGEN_STRONG_INLINE Matrix(const MatrixBase& other) + : Base(other.rows() * other.cols(), other.rows(), other.cols()) + { + // This test resides here, to bring the error messages closer to the user. Normally, these checks + // are performed deeply within the library, thus causing long and scary error traces. + EIGEN_STATIC_ASSERT((internal::is_same::value), + YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) + + Base::_check_template_params(); + Base::_set_noalias(other); + } + /** \brief Copy constructor */ + EIGEN_STRONG_INLINE Matrix(const Matrix& other) + : Base(other.rows() * other.cols(), other.rows(), other.cols()) + { + Base::_check_template_params(); + Base::_set_noalias(other); + } + /** \brief Copy constructor with in-place evaluation */ + template + EIGEN_STRONG_INLINE Matrix(const ReturnByValue& other) + { + Base::_check_template_params(); + Base::resize(other.rows(), other.cols()); + other.evalTo(*this); + } + + /** \brief Copy constructor for generic expressions. + * \sa MatrixBase::operator=(const EigenBase&) + */ + template + EIGEN_STRONG_INLINE Matrix(const EigenBase &other) + : Base(other.derived().rows() * other.derived().cols(), other.derived().rows(), other.derived().cols()) + { + Base::_check_template_params(); + Base::_resize_to_match(other); + // FIXME/CHECK: isn't *this = other.derived() more efficient. it allows to + // go for pure _set() implementations, right? + *this = other; + } + + /** \internal + * \brief Override MatrixBase::swap() since for dynamic-sized matrices + * of same type it is enough to swap the data pointers. + */ + template + void swap(MatrixBase const & other) + { this->_swap(other.derived()); } + + inline Index innerStride() const { return 1; } + inline Index outerStride() const { return this->innerSize(); } + + /////////// Geometry module /////////// + + template + explicit Matrix(const RotationBase& r); + template + Matrix& operator=(const RotationBase& r); + + #ifdef EIGEN2_SUPPORT + template + explicit Matrix(const eigen2_RotationBase& r); + template + Matrix& operator=(const eigen2_RotationBase& r); + #endif + + // allow to extend Matrix outside Eigen + #ifdef EIGEN_MATRIX_PLUGIN + #include EIGEN_MATRIX_PLUGIN + #endif + + protected: + template + friend struct internal::conservative_resize_like_impl; + + using Base::m_storage; +}; + +/** \defgroup matrixtypedefs Global matrix typedefs + * + * \ingroup Core_Module + * + * Eigen defines several typedef shortcuts for most common matrix and vector types. + * + * The general patterns are the following: + * + * \c MatrixSizeType where \c Size can be \c 2,\c 3,\c 4 for fixed size square matrices or \c X for dynamic size, + * and where \c Type can be \c i for integer, \c f for float, \c d for double, \c cf for complex float, \c cd + * for complex double. + * + * For example, \c Matrix3d is a fixed-size 3x3 matrix type of doubles, and \c MatrixXf is a dynamic-size matrix of floats. + * + * There are also \c VectorSizeType and \c RowVectorSizeType which are self-explanatory. For example, \c Vector4cf is + * a fixed-size vector of 4 complex floats. + * + * \sa class Matrix + */ + +#define EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, Size, SizeSuffix) \ +/** \ingroup matrixtypedefs */ \ +typedef Matrix Matrix##SizeSuffix##TypeSuffix; \ +/** \ingroup matrixtypedefs */ \ +typedef Matrix Vector##SizeSuffix##TypeSuffix; \ +/** \ingroup matrixtypedefs */ \ +typedef Matrix RowVector##SizeSuffix##TypeSuffix; + +#define EIGEN_MAKE_FIXED_TYPEDEFS(Type, TypeSuffix, Size) \ +/** \ingroup matrixtypedefs */ \ +typedef Matrix Matrix##Size##X##TypeSuffix; \ +/** \ingroup matrixtypedefs */ \ +typedef Matrix Matrix##X##Size##TypeSuffix; + +#define EIGEN_MAKE_TYPEDEFS_ALL_SIZES(Type, TypeSuffix) \ +EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, 2, 2) \ +EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, 3, 3) \ +EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, 4, 4) \ +EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, Dynamic, X) \ +EIGEN_MAKE_FIXED_TYPEDEFS(Type, TypeSuffix, 2) \ +EIGEN_MAKE_FIXED_TYPEDEFS(Type, TypeSuffix, 3) \ +EIGEN_MAKE_FIXED_TYPEDEFS(Type, TypeSuffix, 4) + +EIGEN_MAKE_TYPEDEFS_ALL_SIZES(int, i) +EIGEN_MAKE_TYPEDEFS_ALL_SIZES(float, f) +EIGEN_MAKE_TYPEDEFS_ALL_SIZES(double, d) +EIGEN_MAKE_TYPEDEFS_ALL_SIZES(std::complex, cf) +EIGEN_MAKE_TYPEDEFS_ALL_SIZES(std::complex, cd) + +#undef EIGEN_MAKE_TYPEDEFS_ALL_SIZES +#undef EIGEN_MAKE_TYPEDEFS +#undef EIGEN_MAKE_FIXED_TYPEDEFS + +} // end namespace Eigen + +#endif // EIGEN_MATRIX_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/MatrixBase.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/MatrixBase.h new file mode 100644 index 00000000..e83ef4dc --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/MatrixBase.h @@ -0,0 +1,563 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2006-2009 Benoit Jacob +// Copyright (C) 2008 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_MATRIXBASE_H +#define EIGEN_MATRIXBASE_H + +namespace Eigen { + +/** \class MatrixBase + * \ingroup Core_Module + * + * \brief Base class for all dense matrices, vectors, and expressions + * + * This class is the base that is inherited by all matrix, vector, and related expression + * types. Most of the Eigen API is contained in this class, and its base classes. Other important + * classes for the Eigen API are Matrix, and VectorwiseOp. + * + * Note that some methods are defined in other modules such as the \ref LU_Module LU module + * for all functions related to matrix inversions. + * + * \tparam Derived is the derived type, e.g. a matrix type, or an expression, etc. + * + * When writing a function taking Eigen objects as argument, if you want your function + * to take as argument any matrix, vector, or expression, just let it take a + * MatrixBase argument. As an example, here is a function printFirstRow which, given + * a matrix, vector, or expression \a x, prints the first row of \a x. + * + * \code + template + void printFirstRow(const Eigen::MatrixBase& x) + { + cout << x.row(0) << endl; + } + * \endcode + * + * This class can be extended with the help of the plugin mechanism described on the page + * \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_MATRIXBASE_PLUGIN. + * + * \sa \ref TopicClassHierarchy + */ +template class MatrixBase + : public DenseBase +{ + public: +#ifndef EIGEN_PARSED_BY_DOXYGEN + typedef MatrixBase StorageBaseType; + typedef typename internal::traits::StorageKind StorageKind; + typedef typename internal::traits::Index Index; + typedef typename internal::traits::Scalar Scalar; + typedef typename internal::packet_traits::type PacketScalar; + typedef typename NumTraits::Real RealScalar; + + typedef DenseBase Base; + using Base::RowsAtCompileTime; + using Base::ColsAtCompileTime; + using Base::SizeAtCompileTime; + using Base::MaxRowsAtCompileTime; + using Base::MaxColsAtCompileTime; + using Base::MaxSizeAtCompileTime; + using Base::IsVectorAtCompileTime; + using Base::Flags; + using Base::CoeffReadCost; + + using Base::derived; + using Base::const_cast_derived; + using Base::rows; + using Base::cols; + using Base::size; + using Base::coeff; + using Base::coeffRef; + using Base::lazyAssign; + using Base::eval; + using Base::operator+=; + using Base::operator-=; + using Base::operator*=; + using Base::operator/=; + + typedef typename Base::CoeffReturnType CoeffReturnType; + typedef typename Base::ConstTransposeReturnType ConstTransposeReturnType; + typedef typename Base::RowXpr RowXpr; + typedef typename Base::ColXpr ColXpr; +#endif // not EIGEN_PARSED_BY_DOXYGEN + + + +#ifndef EIGEN_PARSED_BY_DOXYGEN + /** type of the equivalent square matrix */ + typedef Matrix SquareMatrixType; +#endif // not EIGEN_PARSED_BY_DOXYGEN + + /** \returns the size of the main diagonal, which is min(rows(),cols()). + * \sa rows(), cols(), SizeAtCompileTime. */ + inline Index diagonalSize() const { return (std::min)(rows(),cols()); } + + /** \brief The plain matrix type corresponding to this expression. + * + * This is not necessarily exactly the return type of eval(). In the case of plain matrices, + * the return type of eval() is a const reference to a matrix, not a matrix! It is however guaranteed + * that the return type of eval() is either PlainObject or const PlainObject&. + */ + typedef Matrix::Scalar, + internal::traits::RowsAtCompileTime, + internal::traits::ColsAtCompileTime, + AutoAlign | (internal::traits::Flags&RowMajorBit ? RowMajor : ColMajor), + internal::traits::MaxRowsAtCompileTime, + internal::traits::MaxColsAtCompileTime + > PlainObject; + +#ifndef EIGEN_PARSED_BY_DOXYGEN + /** \internal Represents a matrix with all coefficients equal to one another*/ + typedef CwiseNullaryOp,Derived> ConstantReturnType; + /** \internal the return type of MatrixBase::adjoint() */ + typedef typename internal::conditional::IsComplex, + CwiseUnaryOp, ConstTransposeReturnType>, + ConstTransposeReturnType + >::type AdjointReturnType; + /** \internal Return type of eigenvalues() */ + typedef Matrix, internal::traits::ColsAtCompileTime, 1, ColMajor> EigenvaluesReturnType; + /** \internal the return type of identity */ + typedef CwiseNullaryOp,Derived> IdentityReturnType; + /** \internal the return type of unit vectors */ + typedef Block, SquareMatrixType>, + internal::traits::RowsAtCompileTime, + internal::traits::ColsAtCompileTime> BasisReturnType; +#endif // not EIGEN_PARSED_BY_DOXYGEN + +#define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::MatrixBase +# include "../plugins/CommonCwiseUnaryOps.h" +# include "../plugins/CommonCwiseBinaryOps.h" +# include "../plugins/MatrixCwiseUnaryOps.h" +# include "../plugins/MatrixCwiseBinaryOps.h" +# ifdef EIGEN_MATRIXBASE_PLUGIN +# include EIGEN_MATRIXBASE_PLUGIN +# endif +#undef EIGEN_CURRENT_STORAGE_BASE_CLASS + + /** Special case of the template operator=, in order to prevent the compiler + * from generating a default operator= (issue hit with g++ 4.1) + */ + Derived& operator=(const MatrixBase& other); + + // We cannot inherit here via Base::operator= since it is causing + // trouble with MSVC. + + template + Derived& operator=(const DenseBase& other); + + template + Derived& operator=(const EigenBase& other); + + template + Derived& operator=(const ReturnByValue& other); + + template + Derived& lazyAssign(const ProductBase& other); + + template + Derived& lazyAssign(const MatrixPowerProduct& other); + + template + Derived& operator+=(const MatrixBase& other); + template + Derived& operator-=(const MatrixBase& other); + + template + const typename ProductReturnType::Type + operator*(const MatrixBase &other) const; + + template + const typename LazyProductReturnType::Type + lazyProduct(const MatrixBase &other) const; + + template + Derived& operator*=(const EigenBase& other); + + template + void applyOnTheLeft(const EigenBase& other); + + template + void applyOnTheRight(const EigenBase& other); + + template + const DiagonalProduct + operator*(const DiagonalBase &diagonal) const; + + template + typename internal::scalar_product_traits::Scalar,typename internal::traits::Scalar>::ReturnType + dot(const MatrixBase& other) const; + + #ifdef EIGEN2_SUPPORT + template + Scalar eigen2_dot(const MatrixBase& other) const; + #endif + + RealScalar squaredNorm() const; + RealScalar norm() const; + RealScalar stableNorm() const; + RealScalar blueNorm() const; + RealScalar hypotNorm() const; + const PlainObject normalized() const; + void normalize(); + + const AdjointReturnType adjoint() const; + void adjointInPlace(); + + typedef Diagonal DiagonalReturnType; + DiagonalReturnType diagonal(); + typedef typename internal::add_const >::type ConstDiagonalReturnType; + ConstDiagonalReturnType diagonal() const; + + template struct DiagonalIndexReturnType { typedef Diagonal Type; }; + template struct ConstDiagonalIndexReturnType { typedef const Diagonal Type; }; + + template typename DiagonalIndexReturnType::Type diagonal(); + template typename ConstDiagonalIndexReturnType::Type diagonal() const; + + typedef Diagonal DiagonalDynamicIndexReturnType; + typedef typename internal::add_const >::type ConstDiagonalDynamicIndexReturnType; + + DiagonalDynamicIndexReturnType diagonal(Index index); + ConstDiagonalDynamicIndexReturnType diagonal(Index index) const; + + #ifdef EIGEN2_SUPPORT + template typename internal::eigen2_part_return_type::type part(); + template const typename internal::eigen2_part_return_type::type part() const; + + // huuuge hack. make Eigen2's matrix.part() work in eigen3. Problem: Diagonal is now a class template instead + // of an integer constant. Solution: overload the part() method template wrt template parameters list. + template class U> + const DiagonalWrapper part() const + { return diagonal().asDiagonal(); } + #endif // EIGEN2_SUPPORT + + template struct TriangularViewReturnType { typedef TriangularView Type; }; + template struct ConstTriangularViewReturnType { typedef const TriangularView Type; }; + + template typename TriangularViewReturnType::Type triangularView(); + template typename ConstTriangularViewReturnType::Type triangularView() const; + + template struct SelfAdjointViewReturnType { typedef SelfAdjointView Type; }; + template struct ConstSelfAdjointViewReturnType { typedef const SelfAdjointView Type; }; + + template typename SelfAdjointViewReturnType::Type selfadjointView(); + template typename ConstSelfAdjointViewReturnType::Type selfadjointView() const; + + const SparseView sparseView(const Scalar& m_reference = Scalar(0), + const typename NumTraits::Real& m_epsilon = NumTraits::dummy_precision()) const; + static const IdentityReturnType Identity(); + static const IdentityReturnType Identity(Index rows, Index cols); + static const BasisReturnType Unit(Index size, Index i); + static const BasisReturnType Unit(Index i); + static const BasisReturnType UnitX(); + static const BasisReturnType UnitY(); + static const BasisReturnType UnitZ(); + static const BasisReturnType UnitW(); + + const DiagonalWrapper asDiagonal() const; + const PermutationWrapper asPermutation() const; + + Derived& setIdentity(); + Derived& setIdentity(Index rows, Index cols); + + bool isIdentity(const RealScalar& prec = NumTraits::dummy_precision()) const; + bool isDiagonal(const RealScalar& prec = NumTraits::dummy_precision()) const; + + bool isUpperTriangular(const RealScalar& prec = NumTraits::dummy_precision()) const; + bool isLowerTriangular(const RealScalar& prec = NumTraits::dummy_precision()) const; + + template + bool isOrthogonal(const MatrixBase& other, + const RealScalar& prec = NumTraits::dummy_precision()) const; + bool isUnitary(const RealScalar& prec = NumTraits::dummy_precision()) const; + + /** \returns true if each coefficients of \c *this and \a other are all exactly equal. + * \warning When using floating point scalar values you probably should rather use a + * fuzzy comparison such as isApprox() + * \sa isApprox(), operator!= */ + template + inline bool operator==(const MatrixBase& other) const + { return cwiseEqual(other).all(); } + + /** \returns true if at least one pair of coefficients of \c *this and \a other are not exactly equal to each other. + * \warning When using floating point scalar values you probably should rather use a + * fuzzy comparison such as isApprox() + * \sa isApprox(), operator== */ + template + inline bool operator!=(const MatrixBase& other) const + { return cwiseNotEqual(other).any(); } + + NoAlias noalias(); + + inline const ForceAlignedAccess forceAlignedAccess() const; + inline ForceAlignedAccess forceAlignedAccess(); + template inline typename internal::add_const_on_value_type,Derived&>::type>::type forceAlignedAccessIf() const; + template inline typename internal::conditional,Derived&>::type forceAlignedAccessIf(); + + Scalar trace() const; + +/////////// Array module /////////// + + template RealScalar lpNorm() const; + + MatrixBase& matrix() { return *this; } + const MatrixBase& matrix() const { return *this; } + + /** \returns an \link Eigen::ArrayBase Array \endlink expression of this matrix + * \sa ArrayBase::matrix() */ + ArrayWrapper array() { return derived(); } + const ArrayWrapper array() const { return derived(); } + +/////////// LU module /////////// + + const FullPivLU fullPivLu() const; + const PartialPivLU partialPivLu() const; + + #if EIGEN2_SUPPORT_STAGE < STAGE20_RESOLVE_API_CONFLICTS + const LU lu() const; + #endif + + #ifdef EIGEN2_SUPPORT + const LU eigen2_lu() const; + #endif + + #if EIGEN2_SUPPORT_STAGE > STAGE20_RESOLVE_API_CONFLICTS + const PartialPivLU lu() const; + #endif + + #ifdef EIGEN2_SUPPORT + template + void computeInverse(MatrixBase *result) const { + *result = this->inverse(); + } + #endif + + const internal::inverse_impl inverse() const; + template + void computeInverseAndDetWithCheck( + ResultType& inverse, + typename ResultType::Scalar& determinant, + bool& invertible, + const RealScalar& absDeterminantThreshold = NumTraits::dummy_precision() + ) const; + template + void computeInverseWithCheck( + ResultType& inverse, + bool& invertible, + const RealScalar& absDeterminantThreshold = NumTraits::dummy_precision() + ) const; + Scalar determinant() const; + +/////////// Cholesky module /////////// + + const LLT llt() const; + const LDLT ldlt() const; + +/////////// QR module /////////// + + const HouseholderQR householderQr() const; + const ColPivHouseholderQR colPivHouseholderQr() const; + const FullPivHouseholderQR fullPivHouseholderQr() const; + + #ifdef EIGEN2_SUPPORT + const QR qr() const; + #endif + + EigenvaluesReturnType eigenvalues() const; + RealScalar operatorNorm() const; + +/////////// SVD module /////////// + + JacobiSVD jacobiSvd(unsigned int computationOptions = 0) const; + + #ifdef EIGEN2_SUPPORT + SVD svd() const; + #endif + +/////////// Geometry module /////////// + + #ifndef EIGEN_PARSED_BY_DOXYGEN + /// \internal helper struct to form the return type of the cross product + template struct cross_product_return_type { + typedef typename internal::scalar_product_traits::Scalar,typename internal::traits::Scalar>::ReturnType Scalar; + typedef Matrix type; + }; + #endif // EIGEN_PARSED_BY_DOXYGEN + template + typename cross_product_return_type::type + cross(const MatrixBase& other) const; + template + PlainObject cross3(const MatrixBase& other) const; + PlainObject unitOrthogonal(void) const; + Matrix eulerAngles(Index a0, Index a1, Index a2) const; + + #if EIGEN2_SUPPORT_STAGE > STAGE20_RESOLVE_API_CONFLICTS + ScalarMultipleReturnType operator*(const UniformScaling& s) const; + // put this as separate enum value to work around possible GCC 4.3 bug (?) + enum { HomogeneousReturnTypeDirection = ColsAtCompileTime==1?Vertical:Horizontal }; + typedef Homogeneous HomogeneousReturnType; + HomogeneousReturnType homogeneous() const; + #endif + + enum { + SizeMinusOne = SizeAtCompileTime==Dynamic ? Dynamic : SizeAtCompileTime-1 + }; + typedef Block::ColsAtCompileTime==1 ? SizeMinusOne : 1, + internal::traits::ColsAtCompileTime==1 ? 1 : SizeMinusOne> ConstStartMinusOne; + typedef CwiseUnaryOp::Scalar>, + const ConstStartMinusOne > HNormalizedReturnType; + + const HNormalizedReturnType hnormalized() const; + +////////// Householder module /////////// + + void makeHouseholderInPlace(Scalar& tau, RealScalar& beta); + template + void makeHouseholder(EssentialPart& essential, + Scalar& tau, RealScalar& beta) const; + template + void applyHouseholderOnTheLeft(const EssentialPart& essential, + const Scalar& tau, + Scalar* workspace); + template + void applyHouseholderOnTheRight(const EssentialPart& essential, + const Scalar& tau, + Scalar* workspace); + +///////// Jacobi module ///////// + + template + void applyOnTheLeft(Index p, Index q, const JacobiRotation& j); + template + void applyOnTheRight(Index p, Index q, const JacobiRotation& j); + +///////// SparseCore module ///////// + + template + EIGEN_STRONG_INLINE const typename SparseMatrixBase::template CwiseProductDenseReturnType::Type + cwiseProduct(const SparseMatrixBase &other) const + { + return other.cwiseProduct(derived()); + } + +///////// MatrixFunctions module ///////// + + typedef typename internal::stem_function::type StemFunction; + const MatrixExponentialReturnValue exp() const; + const MatrixFunctionReturnValue matrixFunction(StemFunction f) const; + const MatrixFunctionReturnValue cosh() const; + const MatrixFunctionReturnValue sinh() const; + const MatrixFunctionReturnValue cos() const; + const MatrixFunctionReturnValue sin() const; + const MatrixSquareRootReturnValue sqrt() const; + const MatrixLogarithmReturnValue log() const; + const MatrixPowerReturnValue pow(const RealScalar& p) const; + +#ifdef EIGEN2_SUPPORT + template + Derived& operator+=(const Flagged, 0, + EvalBeforeAssigningBit>& other); + + template + Derived& operator-=(const Flagged, 0, + EvalBeforeAssigningBit>& other); + + /** \deprecated because .lazy() is deprecated + * Overloaded for cache friendly product evaluation */ + template + Derived& lazyAssign(const Flagged& other) + { return lazyAssign(other._expression()); } + + template + const Flagged marked() const; + const Flagged lazy() const; + + inline const Cwise cwise() const; + inline Cwise cwise(); + + VectorBlock start(Index size); + const VectorBlock start(Index size) const; + VectorBlock end(Index size); + const VectorBlock end(Index size) const; + template VectorBlock start(); + template const VectorBlock start() const; + template VectorBlock end(); + template const VectorBlock end() const; + + Minor minor(Index row, Index col); + const Minor minor(Index row, Index col) const; +#endif + + protected: + MatrixBase() : Base() {} + + private: + explicit MatrixBase(int); + MatrixBase(int,int); + template explicit MatrixBase(const MatrixBase&); + protected: + // mixing arrays and matrices is not legal + template Derived& operator+=(const ArrayBase& ) + {EIGEN_STATIC_ASSERT(std::ptrdiff_t(sizeof(typename OtherDerived::Scalar))==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES); return *this;} + // mixing arrays and matrices is not legal + template Derived& operator-=(const ArrayBase& ) + {EIGEN_STATIC_ASSERT(std::ptrdiff_t(sizeof(typename OtherDerived::Scalar))==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES); return *this;} +}; + + +/*************************************************************************** +* Implementation of matrix base methods +***************************************************************************/ + +/** replaces \c *this by \c *this * \a other. + * + * \returns a reference to \c *this + * + * Example: \include MatrixBase_applyOnTheRight.cpp + * Output: \verbinclude MatrixBase_applyOnTheRight.out + */ +template +template +inline Derived& +MatrixBase::operator*=(const EigenBase &other) +{ + other.derived().applyThisOnTheRight(derived()); + return derived(); +} + +/** replaces \c *this by \c *this * \a other. It is equivalent to MatrixBase::operator*=(). + * + * Example: \include MatrixBase_applyOnTheRight.cpp + * Output: \verbinclude MatrixBase_applyOnTheRight.out + */ +template +template +inline void MatrixBase::applyOnTheRight(const EigenBase &other) +{ + other.derived().applyThisOnTheRight(derived()); +} + +/** replaces \c *this by \a other * \c *this. + * + * Example: \include MatrixBase_applyOnTheLeft.cpp + * Output: \verbinclude MatrixBase_applyOnTheLeft.out + */ +template +template +inline void MatrixBase::applyOnTheLeft(const EigenBase &other) +{ + other.derived().applyThisOnTheLeft(derived()); +} + +} // end namespace Eigen + +#endif // EIGEN_MATRIXBASE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/NestByValue.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/NestByValue.h new file mode 100644 index 00000000..a893b176 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/NestByValue.h @@ -0,0 +1,111 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008 Gael Guennebaud +// Copyright (C) 2006-2008 Benoit Jacob +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_NESTBYVALUE_H +#define EIGEN_NESTBYVALUE_H + +namespace Eigen { + +/** \class NestByValue + * \ingroup Core_Module + * + * \brief Expression which must be nested by value + * + * \param ExpressionType the type of the object of which we are requiring nesting-by-value + * + * This class is the return type of MatrixBase::nestByValue() + * and most of the time this is the only way it is used. + * + * \sa MatrixBase::nestByValue() + */ + +namespace internal { +template +struct traits > : public traits +{}; +} + +template class NestByValue + : public internal::dense_xpr_base< NestByValue >::type +{ + public: + + typedef typename internal::dense_xpr_base::type Base; + EIGEN_DENSE_PUBLIC_INTERFACE(NestByValue) + + inline NestByValue(const ExpressionType& matrix) : m_expression(matrix) {} + + inline Index rows() const { return m_expression.rows(); } + inline Index cols() const { return m_expression.cols(); } + inline Index outerStride() const { return m_expression.outerStride(); } + inline Index innerStride() const { return m_expression.innerStride(); } + + inline const CoeffReturnType coeff(Index row, Index col) const + { + return m_expression.coeff(row, col); + } + + inline Scalar& coeffRef(Index row, Index col) + { + return m_expression.const_cast_derived().coeffRef(row, col); + } + + inline const CoeffReturnType coeff(Index index) const + { + return m_expression.coeff(index); + } + + inline Scalar& coeffRef(Index index) + { + return m_expression.const_cast_derived().coeffRef(index); + } + + template + inline const PacketScalar packet(Index row, Index col) const + { + return m_expression.template packet(row, col); + } + + template + inline void writePacket(Index row, Index col, const PacketScalar& x) + { + m_expression.const_cast_derived().template writePacket(row, col, x); + } + + template + inline const PacketScalar packet(Index index) const + { + return m_expression.template packet(index); + } + + template + inline void writePacket(Index index, const PacketScalar& x) + { + m_expression.const_cast_derived().template writePacket(index, x); + } + + operator const ExpressionType&() const { return m_expression; } + + protected: + const ExpressionType m_expression; +}; + +/** \returns an expression of the temporary version of *this. + */ +template +inline const NestByValue +DenseBase::nestByValue() const +{ + return NestByValue(derived()); +} + +} // end namespace Eigen + +#endif // EIGEN_NESTBYVALUE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/NoAlias.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/NoAlias.h new file mode 100644 index 00000000..768bfb18 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/NoAlias.h @@ -0,0 +1,134 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2009 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_NOALIAS_H +#define EIGEN_NOALIAS_H + +namespace Eigen { + +/** \class NoAlias + * \ingroup Core_Module + * + * \brief Pseudo expression providing an operator = assuming no aliasing + * + * \param ExpressionType the type of the object on which to do the lazy assignment + * + * This class represents an expression with special assignment operators + * assuming no aliasing between the target expression and the source expression. + * More precisely it alloas to bypass the EvalBeforeAssignBit flag of the source expression. + * It is the return type of MatrixBase::noalias() + * and most of the time this is the only way it is used. + * + * \sa MatrixBase::noalias() + */ +template class StorageBase> +class NoAlias +{ + typedef typename ExpressionType::Scalar Scalar; + public: + NoAlias(ExpressionType& expression) : m_expression(expression) {} + + /** Behaves like MatrixBase::lazyAssign(other) + * \sa MatrixBase::lazyAssign() */ + template + EIGEN_STRONG_INLINE ExpressionType& operator=(const StorageBase& other) + { return internal::assign_selector::run(m_expression,other.derived()); } + + /** \sa MatrixBase::operator+= */ + template + EIGEN_STRONG_INLINE ExpressionType& operator+=(const StorageBase& other) + { + typedef SelfCwiseBinaryOp, ExpressionType, OtherDerived> SelfAdder; + SelfAdder tmp(m_expression); + typedef typename internal::nested::type OtherDerivedNested; + typedef typename internal::remove_all::type _OtherDerivedNested; + internal::assign_selector::run(tmp,OtherDerivedNested(other.derived())); + return m_expression; + } + + /** \sa MatrixBase::operator-= */ + template + EIGEN_STRONG_INLINE ExpressionType& operator-=(const StorageBase& other) + { + typedef SelfCwiseBinaryOp, ExpressionType, OtherDerived> SelfAdder; + SelfAdder tmp(m_expression); + typedef typename internal::nested::type OtherDerivedNested; + typedef typename internal::remove_all::type _OtherDerivedNested; + internal::assign_selector::run(tmp,OtherDerivedNested(other.derived())); + return m_expression; + } + +#ifndef EIGEN_PARSED_BY_DOXYGEN + template + EIGEN_STRONG_INLINE ExpressionType& operator+=(const ProductBase& other) + { other.derived().addTo(m_expression); return m_expression; } + + template + EIGEN_STRONG_INLINE ExpressionType& operator-=(const ProductBase& other) + { other.derived().subTo(m_expression); return m_expression; } + + template + EIGEN_STRONG_INLINE ExpressionType& operator+=(const CoeffBasedProduct& other) + { return m_expression.derived() += CoeffBasedProduct(other.lhs(), other.rhs()); } + + template + EIGEN_STRONG_INLINE ExpressionType& operator-=(const CoeffBasedProduct& other) + { return m_expression.derived() -= CoeffBasedProduct(other.lhs(), other.rhs()); } + + template + ExpressionType& operator=(const ReturnByValue& func) + { return m_expression = func; } +#endif + + ExpressionType& expression() const + { + return m_expression; + } + + protected: + ExpressionType& m_expression; +}; + +/** \returns a pseudo expression of \c *this with an operator= assuming + * no aliasing between \c *this and the source expression. + * + * More precisely, noalias() allows to bypass the EvalBeforeAssignBit flag. + * Currently, even though several expressions may alias, only product + * expressions have this flag. Therefore, noalias() is only usefull when + * the source expression contains a matrix product. + * + * Here are some examples where noalias is usefull: + * \code + * D.noalias() = A * B; + * D.noalias() += A.transpose() * B; + * D.noalias() -= 2 * A * B.adjoint(); + * \endcode + * + * On the other hand the following example will lead to a \b wrong result: + * \code + * A.noalias() = A * B; + * \endcode + * because the result matrix A is also an operand of the matrix product. Therefore, + * there is no alternative than evaluating A * B in a temporary, that is the default + * behavior when you write: + * \code + * A = A * B; + * \endcode + * + * \sa class NoAlias + */ +template +NoAlias MatrixBase::noalias() +{ + return derived(); +} + +} // end namespace Eigen + +#endif // EIGEN_NOALIAS_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/NumTraits.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/NumTraits.h new file mode 100644 index 00000000..bac9e50b --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/NumTraits.h @@ -0,0 +1,150 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2006-2010 Benoit Jacob +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_NUMTRAITS_H +#define EIGEN_NUMTRAITS_H + +namespace Eigen { + +/** \class NumTraits + * \ingroup Core_Module + * + * \brief Holds information about the various numeric (i.e. scalar) types allowed by Eigen. + * + * \param T the numeric type at hand + * + * This class stores enums, typedefs and static methods giving information about a numeric type. + * + * The provided data consists of: + * \li A typedef \a Real, giving the "real part" type of \a T. If \a T is already real, + * then \a Real is just a typedef to \a T. If \a T is \c std::complex then \a Real + * is a typedef to \a U. + * \li A typedef \a NonInteger, giving the type that should be used for operations producing non-integral values, + * such as quotients, square roots, etc. If \a T is a floating-point type, then this typedef just gives + * \a T again. Note however that many Eigen functions such as internal::sqrt simply refuse to + * take integers. Outside of a few cases, Eigen doesn't do automatic type promotion. Thus, this typedef is + * only intended as a helper for code that needs to explicitly promote types. + * \li A typedef \a Nested giving the type to use to nest a value inside of the expression tree. If you don't know what + * this means, just use \a T here. + * \li An enum value \a IsComplex. It is equal to 1 if \a T is a \c std::complex + * type, and to 0 otherwise. + * \li An enum value \a IsInteger. It is equal to \c 1 if \a T is an integer type such as \c int, + * and to \c 0 otherwise. + * \li Enum values ReadCost, AddCost and MulCost representing a rough estimate of the number of CPU cycles needed + * to by move / add / mul instructions respectively, assuming the data is already stored in CPU registers. + * Stay vague here. No need to do architecture-specific stuff. + * \li An enum value \a IsSigned. It is equal to \c 1 if \a T is a signed type and to 0 if \a T is unsigned. + * \li An enum value \a RequireInitialization. It is equal to \c 1 if the constructor of the numeric type \a T must + * be called, and to 0 if it is safe not to call it. Default is 0 if \a T is an arithmetic type, and 1 otherwise. + * \li An epsilon() function which, unlike std::numeric_limits::epsilon(), returns a \a Real instead of a \a T. + * \li A dummy_precision() function returning a weak epsilon value. It is mainly used as a default + * value by the fuzzy comparison operators. + * \li highest() and lowest() functions returning the highest and lowest possible values respectively. + */ + +template struct GenericNumTraits +{ + enum { + IsInteger = std::numeric_limits::is_integer, + IsSigned = std::numeric_limits::is_signed, + IsComplex = 0, + RequireInitialization = internal::is_arithmetic::value ? 0 : 1, + ReadCost = 1, + AddCost = 1, + MulCost = 1 + }; + + typedef T Real; + typedef typename internal::conditional< + IsInteger, + typename internal::conditional::type, + T + >::type NonInteger; + typedef T Nested; + + static inline Real epsilon() { return std::numeric_limits::epsilon(); } + static inline Real dummy_precision() + { + // make sure to override this for floating-point types + return Real(0); + } + static inline T highest() { return (std::numeric_limits::max)(); } + static inline T lowest() { return IsInteger ? (std::numeric_limits::min)() : (-(std::numeric_limits::max)()); } + +#ifdef EIGEN2_SUPPORT + enum { + HasFloatingPoint = !IsInteger + }; + typedef NonInteger FloatingPoint; +#endif +}; + +template struct NumTraits : GenericNumTraits +{}; + +template<> struct NumTraits + : GenericNumTraits +{ + static inline float dummy_precision() { return 1e-5f; } +}; + +template<> struct NumTraits : GenericNumTraits +{ + static inline double dummy_precision() { return 1e-12; } +}; + +template<> struct NumTraits + : GenericNumTraits +{ + static inline long double dummy_precision() { return 1e-15l; } +}; + +template struct NumTraits > + : GenericNumTraits > +{ + typedef _Real Real; + enum { + IsComplex = 1, + RequireInitialization = NumTraits<_Real>::RequireInitialization, + ReadCost = 2 * NumTraits<_Real>::ReadCost, + AddCost = 2 * NumTraits::AddCost, + MulCost = 4 * NumTraits::MulCost + 2 * NumTraits::AddCost + }; + + static inline Real epsilon() { return NumTraits::epsilon(); } + static inline Real dummy_precision() { return NumTraits::dummy_precision(); } +}; + +template +struct NumTraits > +{ + typedef Array ArrayType; + typedef typename NumTraits::Real RealScalar; + typedef Array Real; + typedef typename NumTraits::NonInteger NonIntegerScalar; + typedef Array NonInteger; + typedef ArrayType & Nested; + + enum { + IsComplex = NumTraits::IsComplex, + IsInteger = NumTraits::IsInteger, + IsSigned = NumTraits::IsSigned, + RequireInitialization = 1, + ReadCost = ArrayType::SizeAtCompileTime==Dynamic ? Dynamic : ArrayType::SizeAtCompileTime * NumTraits::ReadCost, + AddCost = ArrayType::SizeAtCompileTime==Dynamic ? Dynamic : ArrayType::SizeAtCompileTime * NumTraits::AddCost, + MulCost = ArrayType::SizeAtCompileTime==Dynamic ? Dynamic : ArrayType::SizeAtCompileTime * NumTraits::MulCost + }; + + static inline RealScalar epsilon() { return NumTraits::epsilon(); } + static inline RealScalar dummy_precision() { return NumTraits::dummy_precision(); } +}; + +} // end namespace Eigen + +#endif // EIGEN_NUMTRAITS_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/PermutationMatrix.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/PermutationMatrix.h new file mode 100644 index 00000000..85ffae26 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/PermutationMatrix.h @@ -0,0 +1,721 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2009 Benoit Jacob +// Copyright (C) 2009-2011 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_PERMUTATIONMATRIX_H +#define EIGEN_PERMUTATIONMATRIX_H + +namespace Eigen { + +template class PermutedImpl; + +/** \class PermutationBase + * \ingroup Core_Module + * + * \brief Base class for permutations + * + * \param Derived the derived class + * + * This class is the base class for all expressions representing a permutation matrix, + * internally stored as a vector of integers. + * The convention followed here is that if \f$ \sigma \f$ is a permutation, the corresponding permutation matrix + * \f$ P_\sigma \f$ is such that if \f$ (e_1,\ldots,e_p) \f$ is the canonical basis, we have: + * \f[ P_\sigma(e_i) = e_{\sigma(i)}. \f] + * This convention ensures that for any two permutations \f$ \sigma, \tau \f$, we have: + * \f[ P_{\sigma\circ\tau} = P_\sigma P_\tau. \f] + * + * Permutation matrices are square and invertible. + * + * Notice that in addition to the member functions and operators listed here, there also are non-member + * operator* to multiply any kind of permutation object with any kind of matrix expression (MatrixBase) + * on either side. + * + * \sa class PermutationMatrix, class PermutationWrapper + */ + +namespace internal { + +template +struct permut_matrix_product_retval; +template +struct permut_sparsematrix_product_retval; +enum PermPermProduct_t {PermPermProduct}; + +} // end namespace internal + +template +class PermutationBase : public EigenBase +{ + typedef internal::traits Traits; + typedef EigenBase Base; + public: + + #ifndef EIGEN_PARSED_BY_DOXYGEN + typedef typename Traits::IndicesType IndicesType; + enum { + Flags = Traits::Flags, + CoeffReadCost = Traits::CoeffReadCost, + RowsAtCompileTime = Traits::RowsAtCompileTime, + ColsAtCompileTime = Traits::ColsAtCompileTime, + MaxRowsAtCompileTime = Traits::MaxRowsAtCompileTime, + MaxColsAtCompileTime = Traits::MaxColsAtCompileTime + }; + typedef typename Traits::Scalar Scalar; + typedef typename Traits::Index Index; + typedef Matrix + DenseMatrixType; + typedef PermutationMatrix + PlainPermutationType; + using Base::derived; + #endif + + /** Copies the other permutation into *this */ + template + Derived& operator=(const PermutationBase& other) + { + indices() = other.indices(); + return derived(); + } + + /** Assignment from the Transpositions \a tr */ + template + Derived& operator=(const TranspositionsBase& tr) + { + setIdentity(tr.size()); + for(Index k=size()-1; k>=0; --k) + applyTranspositionOnTheRight(k,tr.coeff(k)); + return derived(); + } + + #ifndef EIGEN_PARSED_BY_DOXYGEN + /** This is a special case of the templated operator=. Its purpose is to + * prevent a default operator= from hiding the templated operator=. + */ + Derived& operator=(const PermutationBase& other) + { + indices() = other.indices(); + return derived(); + } + #endif + + /** \returns the number of rows */ + inline Index rows() const { return Index(indices().size()); } + + /** \returns the number of columns */ + inline Index cols() const { return Index(indices().size()); } + + /** \returns the size of a side of the respective square matrix, i.e., the number of indices */ + inline Index size() const { return Index(indices().size()); } + + #ifndef EIGEN_PARSED_BY_DOXYGEN + template + void evalTo(MatrixBase& other) const + { + other.setZero(); + for (int i=0; i=0 && j>=0 && i=0 && j>=0 && i inverse() const + { return derived(); } + /** \returns the tranpose permutation matrix. + * + * \note \note_try_to_help_rvo + */ + inline Transpose transpose() const + { return derived(); } + + /**** multiplication helpers to hopefully get RVO ****/ + + +#ifndef EIGEN_PARSED_BY_DOXYGEN + protected: + template + void assignTranspose(const PermutationBase& other) + { + for (int i=0; i + void assignProduct(const Lhs& lhs, const Rhs& rhs) + { + eigen_assert(lhs.cols() == rhs.rows()); + for (int i=0; i + inline PlainPermutationType operator*(const PermutationBase& other) const + { return PlainPermutationType(internal::PermPermProduct, derived(), other.derived()); } + + /** \returns the product of a permutation with another inverse permutation. + * + * \note \note_try_to_help_rvo + */ + template + inline PlainPermutationType operator*(const Transpose >& other) const + { return PlainPermutationType(internal::PermPermProduct, *this, other.eval()); } + + /** \returns the product of an inverse permutation with another permutation. + * + * \note \note_try_to_help_rvo + */ + template friend + inline PlainPermutationType operator*(const Transpose >& other, const PermutationBase& perm) + { return PlainPermutationType(internal::PermPermProduct, other.eval(), perm); } + + /** \returns the determinant of the permutation matrix, which is either 1 or -1 depending on the parity of the permutation. + * + * This function is O(\c n) procedure allocating a buffer of \c n booleans. + */ + Index determinant() const + { + Index res = 1; + Index n = size(); + Matrix mask(n); + mask.fill(false); + Index r = 0; + while(r < n) + { + // search for the next seed + while(r=n) + break; + // we got one, let's follow it until we are back to the seed + Index k0 = r++; + mask.coeffRef(k0) = true; + for(Index k=indices().coeff(k0); k!=k0; k=indices().coeff(k)) + { + mask.coeffRef(k) = true; + res = -res; + } + } + return res; + } + + protected: + +}; + +/** \class PermutationMatrix + * \ingroup Core_Module + * + * \brief Permutation matrix + * + * \param SizeAtCompileTime the number of rows/cols, or Dynamic + * \param MaxSizeAtCompileTime the maximum number of rows/cols, or Dynamic. This optional parameter defaults to SizeAtCompileTime. Most of the time, you should not have to specify it. + * \param IndexType the interger type of the indices + * + * This class represents a permutation matrix, internally stored as a vector of integers. + * + * \sa class PermutationBase, class PermutationWrapper, class DiagonalMatrix + */ + +namespace internal { +template +struct traits > + : traits > +{ + typedef IndexType Index; + typedef Matrix IndicesType; +}; +} + +template +class PermutationMatrix : public PermutationBase > +{ + typedef PermutationBase Base; + typedef internal::traits Traits; + public: + + #ifndef EIGEN_PARSED_BY_DOXYGEN + typedef typename Traits::IndicesType IndicesType; + #endif + + inline PermutationMatrix() + {} + + /** Constructs an uninitialized permutation matrix of given size. + */ + inline PermutationMatrix(int size) : m_indices(size) + {} + + /** Copy constructor. */ + template + inline PermutationMatrix(const PermutationBase& other) + : m_indices(other.indices()) {} + + #ifndef EIGEN_PARSED_BY_DOXYGEN + /** Standard copy constructor. Defined only to prevent a default copy constructor + * from hiding the other templated constructor */ + inline PermutationMatrix(const PermutationMatrix& other) : m_indices(other.indices()) {} + #endif + + /** Generic constructor from expression of the indices. The indices + * array has the meaning that the permutations sends each integer i to indices[i]. + * + * \warning It is your responsibility to check that the indices array that you passes actually + * describes a permutation, i.e., each value between 0 and n-1 occurs exactly once, where n is the + * array's size. + */ + template + explicit inline PermutationMatrix(const MatrixBase& a_indices) : m_indices(a_indices) + {} + + /** Convert the Transpositions \a tr to a permutation matrix */ + template + explicit PermutationMatrix(const TranspositionsBase& tr) + : m_indices(tr.size()) + { + *this = tr; + } + + /** Copies the other permutation into *this */ + template + PermutationMatrix& operator=(const PermutationBase& other) + { + m_indices = other.indices(); + return *this; + } + + /** Assignment from the Transpositions \a tr */ + template + PermutationMatrix& operator=(const TranspositionsBase& tr) + { + return Base::operator=(tr.derived()); + } + + #ifndef EIGEN_PARSED_BY_DOXYGEN + /** This is a special case of the templated operator=. Its purpose is to + * prevent a default operator= from hiding the templated operator=. + */ + PermutationMatrix& operator=(const PermutationMatrix& other) + { + m_indices = other.m_indices; + return *this; + } + #endif + + /** const version of indices(). */ + const IndicesType& indices() const { return m_indices; } + /** \returns a reference to the stored array representing the permutation. */ + IndicesType& indices() { return m_indices; } + + + /**** multiplication helpers to hopefully get RVO ****/ + +#ifndef EIGEN_PARSED_BY_DOXYGEN + template + PermutationMatrix(const Transpose >& other) + : m_indices(other.nestedPermutation().size()) + { + for (int i=0; i + PermutationMatrix(internal::PermPermProduct_t, const Lhs& lhs, const Rhs& rhs) + : m_indices(lhs.indices().size()) + { + Base::assignProduct(lhs,rhs); + } +#endif + + protected: + + IndicesType m_indices; +}; + + +namespace internal { +template +struct traits,_PacketAccess> > + : traits > +{ + typedef IndexType Index; + typedef Map, _PacketAccess> IndicesType; +}; +} + +template +class Map,_PacketAccess> + : public PermutationBase,_PacketAccess> > +{ + typedef PermutationBase Base; + typedef internal::traits Traits; + public: + + #ifndef EIGEN_PARSED_BY_DOXYGEN + typedef typename Traits::IndicesType IndicesType; + typedef typename IndicesType::Scalar Index; + #endif + + inline Map(const Index* indicesPtr) + : m_indices(indicesPtr) + {} + + inline Map(const Index* indicesPtr, Index size) + : m_indices(indicesPtr,size) + {} + + /** Copies the other permutation into *this */ + template + Map& operator=(const PermutationBase& other) + { return Base::operator=(other.derived()); } + + /** Assignment from the Transpositions \a tr */ + template + Map& operator=(const TranspositionsBase& tr) + { return Base::operator=(tr.derived()); } + + #ifndef EIGEN_PARSED_BY_DOXYGEN + /** This is a special case of the templated operator=. Its purpose is to + * prevent a default operator= from hiding the templated operator=. + */ + Map& operator=(const Map& other) + { + m_indices = other.m_indices; + return *this; + } + #endif + + /** const version of indices(). */ + const IndicesType& indices() const { return m_indices; } + /** \returns a reference to the stored array representing the permutation. */ + IndicesType& indices() { return m_indices; } + + protected: + + IndicesType m_indices; +}; + +/** \class PermutationWrapper + * \ingroup Core_Module + * + * \brief Class to view a vector of integers as a permutation matrix + * + * \param _IndicesType the type of the vector of integer (can be any compatible expression) + * + * This class allows to view any vector expression of integers as a permutation matrix. + * + * \sa class PermutationBase, class PermutationMatrix + */ + +struct PermutationStorage {}; + +template class TranspositionsWrapper; +namespace internal { +template +struct traits > +{ + typedef PermutationStorage StorageKind; + typedef typename _IndicesType::Scalar Scalar; + typedef typename _IndicesType::Scalar Index; + typedef _IndicesType IndicesType; + enum { + RowsAtCompileTime = _IndicesType::SizeAtCompileTime, + ColsAtCompileTime = _IndicesType::SizeAtCompileTime, + MaxRowsAtCompileTime = IndicesType::MaxRowsAtCompileTime, + MaxColsAtCompileTime = IndicesType::MaxColsAtCompileTime, + Flags = 0, + CoeffReadCost = _IndicesType::CoeffReadCost + }; +}; +} + +template +class PermutationWrapper : public PermutationBase > +{ + typedef PermutationBase Base; + typedef internal::traits Traits; + public: + + #ifndef EIGEN_PARSED_BY_DOXYGEN + typedef typename Traits::IndicesType IndicesType; + #endif + + inline PermutationWrapper(const IndicesType& a_indices) + : m_indices(a_indices) + {} + + /** const version of indices(). */ + const typename internal::remove_all::type& + indices() const { return m_indices; } + + protected: + + typename IndicesType::Nested m_indices; +}; + +/** \returns the matrix with the permutation applied to the columns. + */ +template +inline const internal::permut_matrix_product_retval +operator*(const MatrixBase& matrix, + const PermutationBase &permutation) +{ + return internal::permut_matrix_product_retval + + (permutation.derived(), matrix.derived()); +} + +/** \returns the matrix with the permutation applied to the rows. + */ +template +inline const internal::permut_matrix_product_retval + +operator*(const PermutationBase &permutation, + const MatrixBase& matrix) +{ + return internal::permut_matrix_product_retval + + (permutation.derived(), matrix.derived()); +} + +namespace internal { + +template +struct traits > +{ + typedef typename MatrixType::PlainObject ReturnType; +}; + +template +struct permut_matrix_product_retval + : public ReturnByValue > +{ + typedef typename remove_all::type MatrixTypeNestedCleaned; + typedef typename MatrixType::Index Index; + + permut_matrix_product_retval(const PermutationType& perm, const MatrixType& matrix) + : m_permutation(perm), m_matrix(matrix) + {} + + inline Index rows() const { return m_matrix.rows(); } + inline Index cols() const { return m_matrix.cols(); } + + template inline void evalTo(Dest& dst) const + { + const Index n = Side==OnTheLeft ? rows() : cols(); + // FIXME we need an is_same for expression that is not sensitive to constness. For instance + // is_same_xpr, Block >::value should be true. + if( is_same::value + && blas_traits::HasUsableDirectAccess + && blas_traits::HasUsableDirectAccess + && extract_data(dst) == extract_data(m_matrix)) + { + // apply the permutation inplace + Matrix mask(m_permutation.size()); + mask.fill(false); + Index r = 0; + while(r < m_permutation.size()) + { + // search for the next seed + while(r=m_permutation.size()) + break; + // we got one, let's follow it until we are back to the seed + Index k0 = r++; + Index kPrev = k0; + mask.coeffRef(k0) = true; + for(Index k=m_permutation.indices().coeff(k0); k!=k0; k=m_permutation.indices().coeff(k)) + { + Block(dst, k) + .swap(Block + (dst,((Side==OnTheLeft) ^ Transposed) ? k0 : kPrev)); + + mask.coeffRef(k) = true; + kPrev = k; + } + } + } + else + { + for(int i = 0; i < n; ++i) + { + Block + (dst, ((Side==OnTheLeft) ^ Transposed) ? m_permutation.indices().coeff(i) : i) + + = + + Block + (m_matrix, ((Side==OnTheRight) ^ Transposed) ? m_permutation.indices().coeff(i) : i); + } + } + } + + protected: + const PermutationType& m_permutation; + typename MatrixType::Nested m_matrix; +}; + +/* Template partial specialization for transposed/inverse permutations */ + +template +struct traits > > + : traits +{}; + +} // end namespace internal + +template +class Transpose > + : public EigenBase > > +{ + typedef Derived PermutationType; + typedef typename PermutationType::IndicesType IndicesType; + typedef typename PermutationType::PlainPermutationType PlainPermutationType; + public: + + #ifndef EIGEN_PARSED_BY_DOXYGEN + typedef internal::traits Traits; + typedef typename Derived::DenseMatrixType DenseMatrixType; + enum { + Flags = Traits::Flags, + CoeffReadCost = Traits::CoeffReadCost, + RowsAtCompileTime = Traits::RowsAtCompileTime, + ColsAtCompileTime = Traits::ColsAtCompileTime, + MaxRowsAtCompileTime = Traits::MaxRowsAtCompileTime, + MaxColsAtCompileTime = Traits::MaxColsAtCompileTime + }; + typedef typename Traits::Scalar Scalar; + #endif + + Transpose(const PermutationType& p) : m_permutation(p) {} + + inline int rows() const { return m_permutation.rows(); } + inline int cols() const { return m_permutation.cols(); } + + #ifndef EIGEN_PARSED_BY_DOXYGEN + template + void evalTo(MatrixBase& other) const + { + other.setZero(); + for (int i=0; i friend + inline const internal::permut_matrix_product_retval + operator*(const MatrixBase& matrix, const Transpose& trPerm) + { + return internal::permut_matrix_product_retval(trPerm.m_permutation, matrix.derived()); + } + + /** \returns the matrix with the inverse permutation applied to the rows. + */ + template + inline const internal::permut_matrix_product_retval + operator*(const MatrixBase& matrix) const + { + return internal::permut_matrix_product_retval(m_permutation, matrix.derived()); + } + + const PermutationType& nestedPermutation() const { return m_permutation; } + + protected: + const PermutationType& m_permutation; +}; + +template +const PermutationWrapper MatrixBase::asPermutation() const +{ + return derived(); +} + +} // end namespace Eigen + +#endif // EIGEN_PERMUTATIONMATRIX_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/PlainObjectBase.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/PlainObjectBase.h new file mode 100644 index 00000000..a4e4af4a --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/PlainObjectBase.h @@ -0,0 +1,822 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008-2009 Gael Guennebaud +// Copyright (C) 2006-2008 Benoit Jacob +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_DENSESTORAGEBASE_H +#define EIGEN_DENSESTORAGEBASE_H + +#if defined(EIGEN_INITIALIZE_MATRICES_BY_ZERO) +# define EIGEN_INITIALIZE_COEFFS +# define EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED for(int i=0;i::quiet_NaN(); +#else +# undef EIGEN_INITIALIZE_COEFFS +# define EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED +#endif + +namespace Eigen { + +namespace internal { + +template struct check_rows_cols_for_overflow { + template + static EIGEN_ALWAYS_INLINE void run(Index, Index) + { + } +}; + +template<> struct check_rows_cols_for_overflow { + template + static EIGEN_ALWAYS_INLINE void run(Index rows, Index cols) + { + // http://hg.mozilla.org/mozilla-central/file/6c8a909977d3/xpcom/ds/CheckedInt.h#l242 + // we assume Index is signed + Index max_index = (size_t(1) << (8 * sizeof(Index) - 1)) - 1; // assume Index is signed + bool error = (rows == 0 || cols == 0) ? false + : (rows > max_index / cols); + if (error) + throw_std_bad_alloc(); + } +}; + +template +struct conservative_resize_like_impl; + +template struct matrix_swap_impl; + +} // end namespace internal + +/** \class PlainObjectBase + * \brief %Dense storage base class for matrices and arrays. + * + * This class can be extended with the help of the plugin mechanism described on the page + * \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_PLAINOBJECTBASE_PLUGIN. + * + * \sa \ref TopicClassHierarchy + */ +#ifdef EIGEN_PARSED_BY_DOXYGEN +namespace internal { + +// this is a warkaround to doxygen not being able to understand the inheritence logic +// when it is hidden by the dense_xpr_base helper struct. +template struct dense_xpr_base_dispatcher_for_doxygen;// : public MatrixBase {}; +/** This class is just a workaround for Doxygen and it does not not actually exist. */ +template +struct dense_xpr_base_dispatcher_for_doxygen > + : public MatrixBase > {}; +/** This class is just a workaround for Doxygen and it does not not actually exist. */ +template +struct dense_xpr_base_dispatcher_for_doxygen > + : public ArrayBase > {}; + +} // namespace internal + +template +class PlainObjectBase : public internal::dense_xpr_base_dispatcher_for_doxygen +#else +template +class PlainObjectBase : public internal::dense_xpr_base::type +#endif +{ + public: + enum { Options = internal::traits::Options }; + typedef typename internal::dense_xpr_base::type Base; + + typedef typename internal::traits::StorageKind StorageKind; + typedef typename internal::traits::Index Index; + typedef typename internal::traits::Scalar Scalar; + typedef typename internal::packet_traits::type PacketScalar; + typedef typename NumTraits::Real RealScalar; + typedef Derived DenseType; + + using Base::RowsAtCompileTime; + using Base::ColsAtCompileTime; + using Base::SizeAtCompileTime; + using Base::MaxRowsAtCompileTime; + using Base::MaxColsAtCompileTime; + using Base::MaxSizeAtCompileTime; + using Base::IsVectorAtCompileTime; + using Base::Flags; + + template friend class Eigen::Map; + friend class Eigen::Map; + typedef Eigen::Map MapType; + friend class Eigen::Map; + typedef const Eigen::Map ConstMapType; + friend class Eigen::Map; + typedef Eigen::Map AlignedMapType; + friend class Eigen::Map; + typedef const Eigen::Map ConstAlignedMapType; + template struct StridedMapType { typedef Eigen::Map type; }; + template struct StridedConstMapType { typedef Eigen::Map type; }; + template struct StridedAlignedMapType { typedef Eigen::Map type; }; + template struct StridedConstAlignedMapType { typedef Eigen::Map type; }; + + protected: + DenseStorage m_storage; + + public: + enum { NeedsToAlign = SizeAtCompileTime != Dynamic && (internal::traits::Flags & AlignedBit) != 0 }; + EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign) + + Base& base() { return *static_cast(this); } + const Base& base() const { return *static_cast(this); } + + EIGEN_STRONG_INLINE Index rows() const { return m_storage.rows(); } + EIGEN_STRONG_INLINE Index cols() const { return m_storage.cols(); } + + EIGEN_STRONG_INLINE const Scalar& coeff(Index rowId, Index colId) const + { + if(Flags & RowMajorBit) + return m_storage.data()[colId + rowId * m_storage.cols()]; + else // column-major + return m_storage.data()[rowId + colId * m_storage.rows()]; + } + + EIGEN_STRONG_INLINE const Scalar& coeff(Index index) const + { + return m_storage.data()[index]; + } + + EIGEN_STRONG_INLINE Scalar& coeffRef(Index rowId, Index colId) + { + if(Flags & RowMajorBit) + return m_storage.data()[colId + rowId * m_storage.cols()]; + else // column-major + return m_storage.data()[rowId + colId * m_storage.rows()]; + } + + EIGEN_STRONG_INLINE Scalar& coeffRef(Index index) + { + return m_storage.data()[index]; + } + + EIGEN_STRONG_INLINE const Scalar& coeffRef(Index rowId, Index colId) const + { + if(Flags & RowMajorBit) + return m_storage.data()[colId + rowId * m_storage.cols()]; + else // column-major + return m_storage.data()[rowId + colId * m_storage.rows()]; + } + + EIGEN_STRONG_INLINE const Scalar& coeffRef(Index index) const + { + return m_storage.data()[index]; + } + + /** \internal */ + template + EIGEN_STRONG_INLINE PacketScalar packet(Index rowId, Index colId) const + { + return internal::ploadt + (m_storage.data() + (Flags & RowMajorBit + ? colId + rowId * m_storage.cols() + : rowId + colId * m_storage.rows())); + } + + /** \internal */ + template + EIGEN_STRONG_INLINE PacketScalar packet(Index index) const + { + return internal::ploadt(m_storage.data() + index); + } + + /** \internal */ + template + EIGEN_STRONG_INLINE void writePacket(Index rowId, Index colId, const PacketScalar& val) + { + internal::pstoret + (m_storage.data() + (Flags & RowMajorBit + ? colId + rowId * m_storage.cols() + : rowId + colId * m_storage.rows()), val); + } + + /** \internal */ + template + EIGEN_STRONG_INLINE void writePacket(Index index, const PacketScalar& val) + { + internal::pstoret(m_storage.data() + index, val); + } + + /** \returns a const pointer to the data array of this matrix */ + EIGEN_STRONG_INLINE const Scalar *data() const + { return m_storage.data(); } + + /** \returns a pointer to the data array of this matrix */ + EIGEN_STRONG_INLINE Scalar *data() + { return m_storage.data(); } + + /** Resizes \c *this to a \a rows x \a cols matrix. + * + * This method is intended for dynamic-size matrices, although it is legal to call it on any + * matrix as long as fixed dimensions are left unchanged. If you only want to change the number + * of rows and/or of columns, you can use resize(NoChange_t, Index), resize(Index, NoChange_t). + * + * If the current number of coefficients of \c *this exactly matches the + * product \a rows * \a cols, then no memory allocation is performed and + * the current values are left unchanged. In all other cases, including + * shrinking, the data is reallocated and all previous values are lost. + * + * Example: \include Matrix_resize_int_int.cpp + * Output: \verbinclude Matrix_resize_int_int.out + * + * \sa resize(Index) for vectors, resize(NoChange_t, Index), resize(Index, NoChange_t) + */ + EIGEN_STRONG_INLINE void resize(Index nbRows, Index nbCols) + { + eigen_assert( EIGEN_IMPLIES(RowsAtCompileTime!=Dynamic,nbRows==RowsAtCompileTime) + && EIGEN_IMPLIES(ColsAtCompileTime!=Dynamic,nbCols==ColsAtCompileTime) + && EIGEN_IMPLIES(RowsAtCompileTime==Dynamic && MaxRowsAtCompileTime!=Dynamic,nbRows<=MaxRowsAtCompileTime) + && EIGEN_IMPLIES(ColsAtCompileTime==Dynamic && MaxColsAtCompileTime!=Dynamic,nbCols<=MaxColsAtCompileTime) + && nbRows>=0 && nbCols>=0 && "Invalid sizes when resizing a matrix or array."); + internal::check_rows_cols_for_overflow::run(nbRows, nbCols); + #ifdef EIGEN_INITIALIZE_COEFFS + Index size = nbRows*nbCols; + bool size_changed = size != this->size(); + m_storage.resize(size, nbRows, nbCols); + if(size_changed) EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED + #else + internal::check_rows_cols_for_overflow::run(nbRows, nbCols); + m_storage.resize(nbRows*nbCols, nbRows, nbCols); + #endif + } + + /** Resizes \c *this to a vector of length \a size + * + * \only_for_vectors. This method does not work for + * partially dynamic matrices when the static dimension is anything other + * than 1. For example it will not work with Matrix. + * + * Example: \include Matrix_resize_int.cpp + * Output: \verbinclude Matrix_resize_int.out + * + * \sa resize(Index,Index), resize(NoChange_t, Index), resize(Index, NoChange_t) + */ + inline void resize(Index size) + { + EIGEN_STATIC_ASSERT_VECTOR_ONLY(PlainObjectBase) + eigen_assert(((SizeAtCompileTime == Dynamic && (MaxSizeAtCompileTime==Dynamic || size<=MaxSizeAtCompileTime)) || SizeAtCompileTime == size) && size>=0); + #ifdef EIGEN_INITIALIZE_COEFFS + bool size_changed = size != this->size(); + #endif + if(RowsAtCompileTime == 1) + m_storage.resize(size, 1, size); + else + m_storage.resize(size, size, 1); + #ifdef EIGEN_INITIALIZE_COEFFS + if(size_changed) EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED + #endif + } + + /** Resizes the matrix, changing only the number of columns. For the parameter of type NoChange_t, just pass the special value \c NoChange + * as in the example below. + * + * Example: \include Matrix_resize_NoChange_int.cpp + * Output: \verbinclude Matrix_resize_NoChange_int.out + * + * \sa resize(Index,Index) + */ + inline void resize(NoChange_t, Index nbCols) + { + resize(rows(), nbCols); + } + + /** Resizes the matrix, changing only the number of rows. For the parameter of type NoChange_t, just pass the special value \c NoChange + * as in the example below. + * + * Example: \include Matrix_resize_int_NoChange.cpp + * Output: \verbinclude Matrix_resize_int_NoChange.out + * + * \sa resize(Index,Index) + */ + inline void resize(Index nbRows, NoChange_t) + { + resize(nbRows, cols()); + } + + /** Resizes \c *this to have the same dimensions as \a other. + * Takes care of doing all the checking that's needed. + * + * Note that copying a row-vector into a vector (and conversely) is allowed. + * The resizing, if any, is then done in the appropriate way so that row-vectors + * remain row-vectors and vectors remain vectors. + */ + template + EIGEN_STRONG_INLINE void resizeLike(const EigenBase& _other) + { + const OtherDerived& other = _other.derived(); + internal::check_rows_cols_for_overflow::run(other.rows(), other.cols()); + const Index othersize = other.rows()*other.cols(); + if(RowsAtCompileTime == 1) + { + eigen_assert(other.rows() == 1 || other.cols() == 1); + resize(1, othersize); + } + else if(ColsAtCompileTime == 1) + { + eigen_assert(other.rows() == 1 || other.cols() == 1); + resize(othersize, 1); + } + else resize(other.rows(), other.cols()); + } + + /** Resizes the matrix to \a rows x \a cols while leaving old values untouched. + * + * The method is intended for matrices of dynamic size. If you only want to change the number + * of rows and/or of columns, you can use conservativeResize(NoChange_t, Index) or + * conservativeResize(Index, NoChange_t). + * + * Matrices are resized relative to the top-left element. In case values need to be + * appended to the matrix they will be uninitialized. + */ + EIGEN_STRONG_INLINE void conservativeResize(Index nbRows, Index nbCols) + { + internal::conservative_resize_like_impl::run(*this, nbRows, nbCols); + } + + /** Resizes the matrix to \a rows x \a cols while leaving old values untouched. + * + * As opposed to conservativeResize(Index rows, Index cols), this version leaves + * the number of columns unchanged. + * + * In case the matrix is growing, new rows will be uninitialized. + */ + EIGEN_STRONG_INLINE void conservativeResize(Index nbRows, NoChange_t) + { + // Note: see the comment in conservativeResize(Index,Index) + conservativeResize(nbRows, cols()); + } + + /** Resizes the matrix to \a rows x \a cols while leaving old values untouched. + * + * As opposed to conservativeResize(Index rows, Index cols), this version leaves + * the number of rows unchanged. + * + * In case the matrix is growing, new columns will be uninitialized. + */ + EIGEN_STRONG_INLINE void conservativeResize(NoChange_t, Index nbCols) + { + // Note: see the comment in conservativeResize(Index,Index) + conservativeResize(rows(), nbCols); + } + + /** Resizes the vector to \a size while retaining old values. + * + * \only_for_vectors. This method does not work for + * partially dynamic matrices when the static dimension is anything other + * than 1. For example it will not work with Matrix. + * + * When values are appended, they will be uninitialized. + */ + EIGEN_STRONG_INLINE void conservativeResize(Index size) + { + internal::conservative_resize_like_impl::run(*this, size); + } + + /** Resizes the matrix to \a rows x \a cols of \c other, while leaving old values untouched. + * + * The method is intended for matrices of dynamic size. If you only want to change the number + * of rows and/or of columns, you can use conservativeResize(NoChange_t, Index) or + * conservativeResize(Index, NoChange_t). + * + * Matrices are resized relative to the top-left element. In case values need to be + * appended to the matrix they will copied from \c other. + */ + template + EIGEN_STRONG_INLINE void conservativeResizeLike(const DenseBase& other) + { + internal::conservative_resize_like_impl::run(*this, other); + } + + /** This is a special case of the templated operator=. Its purpose is to + * prevent a default operator= from hiding the templated operator=. + */ + EIGEN_STRONG_INLINE Derived& operator=(const PlainObjectBase& other) + { + return _set(other); + } + + /** \sa MatrixBase::lazyAssign() */ + template + EIGEN_STRONG_INLINE Derived& lazyAssign(const DenseBase& other) + { + _resize_to_match(other); + return Base::lazyAssign(other.derived()); + } + + template + EIGEN_STRONG_INLINE Derived& operator=(const ReturnByValue& func) + { + resize(func.rows(), func.cols()); + return Base::operator=(func); + } + + EIGEN_STRONG_INLINE PlainObjectBase() : m_storage() + { +// _check_template_params(); +// EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED + } + +#ifndef EIGEN_PARSED_BY_DOXYGEN + // FIXME is it still needed ? + /** \internal */ + PlainObjectBase(internal::constructor_without_unaligned_array_assert) + : m_storage(internal::constructor_without_unaligned_array_assert()) + { +// _check_template_params(); EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED + } +#endif + +#ifdef EIGEN_HAVE_RVALUE_REFERENCES + PlainObjectBase(PlainObjectBase&& other) + : m_storage( std::move(other.m_storage) ) + { + } + + PlainObjectBase& operator=(PlainObjectBase&& other) + { + using std::swap; + swap(m_storage, other.m_storage); + return *this; + } +#endif + + /** Copy constructor */ + EIGEN_STRONG_INLINE PlainObjectBase(const PlainObjectBase& other) + : m_storage() + { + _check_template_params(); + lazyAssign(other); + } + + template + EIGEN_STRONG_INLINE PlainObjectBase(const DenseBase &other) + : m_storage() + { + _check_template_params(); + lazyAssign(other); + } + + EIGEN_STRONG_INLINE PlainObjectBase(Index a_size, Index nbRows, Index nbCols) + : m_storage(a_size, nbRows, nbCols) + { +// _check_template_params(); +// EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED + } + + /** \copydoc MatrixBase::operator=(const EigenBase&) + */ + template + EIGEN_STRONG_INLINE Derived& operator=(const EigenBase &other) + { + _resize_to_match(other); + Base::operator=(other.derived()); + return this->derived(); + } + + /** \sa MatrixBase::operator=(const EigenBase&) */ + template + EIGEN_STRONG_INLINE PlainObjectBase(const EigenBase &other) + : m_storage(other.derived().rows() * other.derived().cols(), other.derived().rows(), other.derived().cols()) + { + _check_template_params(); + internal::check_rows_cols_for_overflow::run(other.derived().rows(), other.derived().cols()); + Base::operator=(other.derived()); + } + + /** \name Map + * These are convenience functions returning Map objects. The Map() static functions return unaligned Map objects, + * while the AlignedMap() functions return aligned Map objects and thus should be called only with 16-byte-aligned + * \a data pointers. + * + * \see class Map + */ + //@{ + static inline ConstMapType Map(const Scalar* data) + { return ConstMapType(data); } + static inline MapType Map(Scalar* data) + { return MapType(data); } + static inline ConstMapType Map(const Scalar* data, Index size) + { return ConstMapType(data, size); } + static inline MapType Map(Scalar* data, Index size) + { return MapType(data, size); } + static inline ConstMapType Map(const Scalar* data, Index rows, Index cols) + { return ConstMapType(data, rows, cols); } + static inline MapType Map(Scalar* data, Index rows, Index cols) + { return MapType(data, rows, cols); } + + static inline ConstAlignedMapType MapAligned(const Scalar* data) + { return ConstAlignedMapType(data); } + static inline AlignedMapType MapAligned(Scalar* data) + { return AlignedMapType(data); } + static inline ConstAlignedMapType MapAligned(const Scalar* data, Index size) + { return ConstAlignedMapType(data, size); } + static inline AlignedMapType MapAligned(Scalar* data, Index size) + { return AlignedMapType(data, size); } + static inline ConstAlignedMapType MapAligned(const Scalar* data, Index rows, Index cols) + { return ConstAlignedMapType(data, rows, cols); } + static inline AlignedMapType MapAligned(Scalar* data, Index rows, Index cols) + { return AlignedMapType(data, rows, cols); } + + template + static inline typename StridedConstMapType >::type Map(const Scalar* data, const Stride& stride) + { return typename StridedConstMapType >::type(data, stride); } + template + static inline typename StridedMapType >::type Map(Scalar* data, const Stride& stride) + { return typename StridedMapType >::type(data, stride); } + template + static inline typename StridedConstMapType >::type Map(const Scalar* data, Index size, const Stride& stride) + { return typename StridedConstMapType >::type(data, size, stride); } + template + static inline typename StridedMapType >::type Map(Scalar* data, Index size, const Stride& stride) + { return typename StridedMapType >::type(data, size, stride); } + template + static inline typename StridedConstMapType >::type Map(const Scalar* data, Index rows, Index cols, const Stride& stride) + { return typename StridedConstMapType >::type(data, rows, cols, stride); } + template + static inline typename StridedMapType >::type Map(Scalar* data, Index rows, Index cols, const Stride& stride) + { return typename StridedMapType >::type(data, rows, cols, stride); } + + template + static inline typename StridedConstAlignedMapType >::type MapAligned(const Scalar* data, const Stride& stride) + { return typename StridedConstAlignedMapType >::type(data, stride); } + template + static inline typename StridedAlignedMapType >::type MapAligned(Scalar* data, const Stride& stride) + { return typename StridedAlignedMapType >::type(data, stride); } + template + static inline typename StridedConstAlignedMapType >::type MapAligned(const Scalar* data, Index size, const Stride& stride) + { return typename StridedConstAlignedMapType >::type(data, size, stride); } + template + static inline typename StridedAlignedMapType >::type MapAligned(Scalar* data, Index size, const Stride& stride) + { return typename StridedAlignedMapType >::type(data, size, stride); } + template + static inline typename StridedConstAlignedMapType >::type MapAligned(const Scalar* data, Index rows, Index cols, const Stride& stride) + { return typename StridedConstAlignedMapType >::type(data, rows, cols, stride); } + template + static inline typename StridedAlignedMapType >::type MapAligned(Scalar* data, Index rows, Index cols, const Stride& stride) + { return typename StridedAlignedMapType >::type(data, rows, cols, stride); } + //@} + + using Base::setConstant; + Derived& setConstant(Index size, const Scalar& value); + Derived& setConstant(Index rows, Index cols, const Scalar& value); + + using Base::setZero; + Derived& setZero(Index size); + Derived& setZero(Index rows, Index cols); + + using Base::setOnes; + Derived& setOnes(Index size); + Derived& setOnes(Index rows, Index cols); + + using Base::setRandom; + Derived& setRandom(Index size); + Derived& setRandom(Index rows, Index cols); + + #ifdef EIGEN_PLAINOBJECTBASE_PLUGIN + #include EIGEN_PLAINOBJECTBASE_PLUGIN + #endif + + protected: + /** \internal Resizes *this in preparation for assigning \a other to it. + * Takes care of doing all the checking that's needed. + * + * Note that copying a row-vector into a vector (and conversely) is allowed. + * The resizing, if any, is then done in the appropriate way so that row-vectors + * remain row-vectors and vectors remain vectors. + */ + template + EIGEN_STRONG_INLINE void _resize_to_match(const EigenBase& other) + { + #ifdef EIGEN_NO_AUTOMATIC_RESIZING + eigen_assert((this->size()==0 || (IsVectorAtCompileTime ? (this->size() == other.size()) + : (rows() == other.rows() && cols() == other.cols()))) + && "Size mismatch. Automatic resizing is disabled because EIGEN_NO_AUTOMATIC_RESIZING is defined"); + EIGEN_ONLY_USED_FOR_DEBUG(other); + if(this->size()==0) + resizeLike(other); + #else + resizeLike(other); + #endif + } + + /** + * \brief Copies the value of the expression \a other into \c *this with automatic resizing. + * + * *this might be resized to match the dimensions of \a other. If *this was a null matrix (not already initialized), + * it will be initialized. + * + * Note that copying a row-vector into a vector (and conversely) is allowed. + * The resizing, if any, is then done in the appropriate way so that row-vectors + * remain row-vectors and vectors remain vectors. + * + * \sa operator=(const MatrixBase&), _set_noalias() + * + * \internal + */ + template + EIGEN_STRONG_INLINE Derived& _set(const DenseBase& other) + { + _set_selector(other.derived(), typename internal::conditional(int(OtherDerived::Flags) & EvalBeforeAssigningBit), internal::true_type, internal::false_type>::type()); + return this->derived(); + } + + template + EIGEN_STRONG_INLINE void _set_selector(const OtherDerived& other, const internal::true_type&) { _set_noalias(other.eval()); } + + template + EIGEN_STRONG_INLINE void _set_selector(const OtherDerived& other, const internal::false_type&) { _set_noalias(other); } + + /** \internal Like _set() but additionally makes the assumption that no aliasing effect can happen (which + * is the case when creating a new matrix) so one can enforce lazy evaluation. + * + * \sa operator=(const MatrixBase&), _set() + */ + template + EIGEN_STRONG_INLINE Derived& _set_noalias(const DenseBase& other) + { + // I don't think we need this resize call since the lazyAssign will anyways resize + // and lazyAssign will be called by the assign selector. + //_resize_to_match(other); + // the 'false' below means to enforce lazy evaluation. We don't use lazyAssign() because + // it wouldn't allow to copy a row-vector into a column-vector. + return internal::assign_selector::run(this->derived(), other.derived()); + } + + template + EIGEN_STRONG_INLINE void _init2(Index nbRows, Index nbCols, typename internal::enable_if::type* = 0) + { + EIGEN_STATIC_ASSERT(bool(NumTraits::IsInteger) && + bool(NumTraits::IsInteger), + FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED) + resize(nbRows,nbCols); + } + template + EIGEN_STRONG_INLINE void _init2(const Scalar& val0, const Scalar& val1, typename internal::enable_if::type* = 0) + { + EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 2) + m_storage.data()[0] = val0; + m_storage.data()[1] = val1; + } + + template + friend struct internal::matrix_swap_impl; + + /** \internal generic implementation of swap for dense storage since for dynamic-sized matrices of same type it is enough to swap the + * data pointers. + */ + template + void _swap(DenseBase const & other) + { + enum { SwapPointers = internal::is_same::value && Base::SizeAtCompileTime==Dynamic }; + internal::matrix_swap_impl::run(this->derived(), other.const_cast_derived()); + } + + public: +#ifndef EIGEN_PARSED_BY_DOXYGEN + static EIGEN_STRONG_INLINE void _check_template_params() + { + EIGEN_STATIC_ASSERT((EIGEN_IMPLIES(MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1, (Options&RowMajor)==RowMajor) + && EIGEN_IMPLIES(MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1, (Options&RowMajor)==0) + && ((RowsAtCompileTime == Dynamic) || (RowsAtCompileTime >= 0)) + && ((ColsAtCompileTime == Dynamic) || (ColsAtCompileTime >= 0)) + && ((MaxRowsAtCompileTime == Dynamic) || (MaxRowsAtCompileTime >= 0)) + && ((MaxColsAtCompileTime == Dynamic) || (MaxColsAtCompileTime >= 0)) + && (MaxRowsAtCompileTime == RowsAtCompileTime || RowsAtCompileTime==Dynamic) + && (MaxColsAtCompileTime == ColsAtCompileTime || ColsAtCompileTime==Dynamic) + && (Options & (DontAlign|RowMajor)) == Options), + INVALID_MATRIX_TEMPLATE_PARAMETERS) + } +#endif + +private: + enum { ThisConstantIsPrivateInPlainObjectBase }; +}; + +namespace internal { + +template +struct conservative_resize_like_impl +{ + typedef typename Derived::Index Index; + static void run(DenseBase& _this, Index rows, Index cols) + { + if (_this.rows() == rows && _this.cols() == cols) return; + EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived) + + if ( ( Derived::IsRowMajor && _this.cols() == cols) || // row-major and we change only the number of rows + (!Derived::IsRowMajor && _this.rows() == rows) ) // column-major and we change only the number of columns + { + internal::check_rows_cols_for_overflow::run(rows, cols); + _this.derived().m_storage.conservativeResize(rows*cols,rows,cols); + } + else + { + // The storage order does not allow us to use reallocation. + typename Derived::PlainObject tmp(rows,cols); + const Index common_rows = (std::min)(rows, _this.rows()); + const Index common_cols = (std::min)(cols, _this.cols()); + tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols); + _this.derived().swap(tmp); + } + } + + static void run(DenseBase& _this, const DenseBase& other) + { + if (_this.rows() == other.rows() && _this.cols() == other.cols()) return; + + // Note: Here is space for improvement. Basically, for conservativeResize(Index,Index), + // neither RowsAtCompileTime or ColsAtCompileTime must be Dynamic. If only one of the + // dimensions is dynamic, one could use either conservativeResize(Index rows, NoChange_t) or + // conservativeResize(NoChange_t, Index cols). For these methods new static asserts like + // EIGEN_STATIC_ASSERT_DYNAMIC_ROWS and EIGEN_STATIC_ASSERT_DYNAMIC_COLS would be good. + EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived) + EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(OtherDerived) + + if ( ( Derived::IsRowMajor && _this.cols() == other.cols()) || // row-major and we change only the number of rows + (!Derived::IsRowMajor && _this.rows() == other.rows()) ) // column-major and we change only the number of columns + { + const Index new_rows = other.rows() - _this.rows(); + const Index new_cols = other.cols() - _this.cols(); + _this.derived().m_storage.conservativeResize(other.size(),other.rows(),other.cols()); + if (new_rows>0) + _this.bottomRightCorner(new_rows, other.cols()) = other.bottomRows(new_rows); + else if (new_cols>0) + _this.bottomRightCorner(other.rows(), new_cols) = other.rightCols(new_cols); + } + else + { + // The storage order does not allow us to use reallocation. + typename Derived::PlainObject tmp(other); + const Index common_rows = (std::min)(tmp.rows(), _this.rows()); + const Index common_cols = (std::min)(tmp.cols(), _this.cols()); + tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols); + _this.derived().swap(tmp); + } + } +}; + +// Here, the specialization for vectors inherits from the general matrix case +// to allow calling .conservativeResize(rows,cols) on vectors. +template +struct conservative_resize_like_impl + : conservative_resize_like_impl +{ + using conservative_resize_like_impl::run; + + typedef typename Derived::Index Index; + static void run(DenseBase& _this, Index size) + { + const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : size; + const Index new_cols = Derived::RowsAtCompileTime==1 ? size : 1; + _this.derived().m_storage.conservativeResize(size,new_rows,new_cols); + } + + static void run(DenseBase& _this, const DenseBase& other) + { + if (_this.rows() == other.rows() && _this.cols() == other.cols()) return; + + const Index num_new_elements = other.size() - _this.size(); + + const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : other.rows(); + const Index new_cols = Derived::RowsAtCompileTime==1 ? other.cols() : 1; + _this.derived().m_storage.conservativeResize(other.size(),new_rows,new_cols); + + if (num_new_elements > 0) + _this.tail(num_new_elements) = other.tail(num_new_elements); + } +}; + +template +struct matrix_swap_impl +{ + static inline void run(MatrixTypeA& a, MatrixTypeB& b) + { + a.base().swap(b); + } +}; + +template +struct matrix_swap_impl +{ + static inline void run(MatrixTypeA& a, MatrixTypeB& b) + { + static_cast(a).m_storage.swap(static_cast(b).m_storage); + } +}; + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_DENSESTORAGEBASE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/ProductBase.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/ProductBase.h new file mode 100644 index 00000000..cf74470a --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/ProductBase.h @@ -0,0 +1,290 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2009-2010 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_PRODUCTBASE_H +#define EIGEN_PRODUCTBASE_H + +namespace Eigen { + +/** \class ProductBase + * \ingroup Core_Module + * + */ + +namespace internal { +template +struct traits > +{ + typedef MatrixXpr XprKind; + typedef typename remove_all<_Lhs>::type Lhs; + typedef typename remove_all<_Rhs>::type Rhs; + typedef typename scalar_product_traits::ReturnType Scalar; + typedef typename promote_storage_type::StorageKind, + typename traits::StorageKind>::ret StorageKind; + typedef typename promote_index_type::Index, + typename traits::Index>::type Index; + enum { + RowsAtCompileTime = traits::RowsAtCompileTime, + ColsAtCompileTime = traits::ColsAtCompileTime, + MaxRowsAtCompileTime = traits::MaxRowsAtCompileTime, + MaxColsAtCompileTime = traits::MaxColsAtCompileTime, + Flags = (MaxRowsAtCompileTime==1 ? RowMajorBit : 0) + | EvalBeforeNestingBit | EvalBeforeAssigningBit | NestByRefBit, + // Note that EvalBeforeNestingBit and NestByRefBit + // are not used in practice because nested is overloaded for products + CoeffReadCost = 0 // FIXME why is it needed ? + }; +}; +} + +#define EIGEN_PRODUCT_PUBLIC_INTERFACE(Derived) \ + typedef ProductBase Base; \ + EIGEN_DENSE_PUBLIC_INTERFACE(Derived) \ + typedef typename Base::LhsNested LhsNested; \ + typedef typename Base::_LhsNested _LhsNested; \ + typedef typename Base::LhsBlasTraits LhsBlasTraits; \ + typedef typename Base::ActualLhsType ActualLhsType; \ + typedef typename Base::_ActualLhsType _ActualLhsType; \ + typedef typename Base::RhsNested RhsNested; \ + typedef typename Base::_RhsNested _RhsNested; \ + typedef typename Base::RhsBlasTraits RhsBlasTraits; \ + typedef typename Base::ActualRhsType ActualRhsType; \ + typedef typename Base::_ActualRhsType _ActualRhsType; \ + using Base::m_lhs; \ + using Base::m_rhs; + +template +class ProductBase : public MatrixBase +{ + public: + typedef MatrixBase Base; + EIGEN_DENSE_PUBLIC_INTERFACE(ProductBase) + + typedef typename Lhs::Nested LhsNested; + typedef typename internal::remove_all::type _LhsNested; + typedef internal::blas_traits<_LhsNested> LhsBlasTraits; + typedef typename LhsBlasTraits::DirectLinearAccessType ActualLhsType; + typedef typename internal::remove_all::type _ActualLhsType; + typedef typename internal::traits::Scalar LhsScalar; + + typedef typename Rhs::Nested RhsNested; + typedef typename internal::remove_all::type _RhsNested; + typedef internal::blas_traits<_RhsNested> RhsBlasTraits; + typedef typename RhsBlasTraits::DirectLinearAccessType ActualRhsType; + typedef typename internal::remove_all::type _ActualRhsType; + typedef typename internal::traits::Scalar RhsScalar; + + // Diagonal of a product: no need to evaluate the arguments because they are going to be evaluated only once + typedef CoeffBasedProduct FullyLazyCoeffBaseProductType; + + public: + +#ifndef EIGEN_NO_MALLOC + typedef typename Base::PlainObject BasePlainObject; + typedef Matrix DynPlainObject; + typedef typename internal::conditional<(BasePlainObject::SizeAtCompileTime==Dynamic) || (BasePlainObject::SizeAtCompileTime*int(sizeof(Scalar)) < int(EIGEN_STACK_ALLOCATION_LIMIT)), + BasePlainObject, DynPlainObject>::type PlainObject; +#else + typedef typename Base::PlainObject PlainObject; +#endif + + ProductBase(const Lhs& a_lhs, const Rhs& a_rhs) + : m_lhs(a_lhs), m_rhs(a_rhs) + { + eigen_assert(a_lhs.cols() == a_rhs.rows() + && "invalid matrix product" + && "if you wanted a coeff-wise or a dot product use the respective explicit functions"); + } + + inline Index rows() const { return m_lhs.rows(); } + inline Index cols() const { return m_rhs.cols(); } + + template + inline void evalTo(Dest& dst) const { dst.setZero(); scaleAndAddTo(dst,Scalar(1)); } + + template + inline void addTo(Dest& dst) const { scaleAndAddTo(dst,Scalar(1)); } + + template + inline void subTo(Dest& dst) const { scaleAndAddTo(dst,Scalar(-1)); } + + template + inline void scaleAndAddTo(Dest& dst, const Scalar& alpha) const { derived().scaleAndAddTo(dst,alpha); } + + const _LhsNested& lhs() const { return m_lhs; } + const _RhsNested& rhs() const { return m_rhs; } + + // Implicit conversion to the nested type (trigger the evaluation of the product) + operator const PlainObject& () const + { + m_result.resize(m_lhs.rows(), m_rhs.cols()); + derived().evalTo(m_result); + return m_result; + } + + const Diagonal diagonal() const + { return FullyLazyCoeffBaseProductType(m_lhs, m_rhs); } + + template + const Diagonal diagonal() const + { return FullyLazyCoeffBaseProductType(m_lhs, m_rhs); } + + const Diagonal diagonal(Index index) const + { return FullyLazyCoeffBaseProductType(m_lhs, m_rhs).diagonal(index); } + + // restrict coeff accessors to 1x1 expressions. No need to care about mutators here since this isnt a Lvalue expression + typename Base::CoeffReturnType coeff(Index row, Index col) const + { +#ifdef EIGEN2_SUPPORT + return lhs().row(row).cwiseProduct(rhs().col(col).transpose()).sum(); +#else + EIGEN_STATIC_ASSERT_SIZE_1x1(Derived) + eigen_assert(this->rows() == 1 && this->cols() == 1); + Matrix result = *this; + return result.coeff(row,col); +#endif + } + + typename Base::CoeffReturnType coeff(Index i) const + { + EIGEN_STATIC_ASSERT_SIZE_1x1(Derived) + eigen_assert(this->rows() == 1 && this->cols() == 1); + Matrix result = *this; + return result.coeff(i); + } + + const Scalar& coeffRef(Index row, Index col) const + { + EIGEN_STATIC_ASSERT_SIZE_1x1(Derived) + eigen_assert(this->rows() == 1 && this->cols() == 1); + return derived().coeffRef(row,col); + } + + const Scalar& coeffRef(Index i) const + { + EIGEN_STATIC_ASSERT_SIZE_1x1(Derived) + eigen_assert(this->rows() == 1 && this->cols() == 1); + return derived().coeffRef(i); + } + + protected: + + LhsNested m_lhs; + RhsNested m_rhs; + + mutable PlainObject m_result; +}; + +// here we need to overload the nested rule for products +// such that the nested type is a const reference to a plain matrix +namespace internal { +template +struct nested, N, PlainObject> +{ + typedef typename GeneralProduct::PlainObject const& type; +}; +template +struct nested, N, PlainObject> +{ + typedef typename GeneralProduct::PlainObject const& type; +}; +} + +template +class ScaledProduct; + +// Note that these two operator* functions are not defined as member +// functions of ProductBase, because, otherwise we would have to +// define all overloads defined in MatrixBase. Furthermore, Using +// "using Base::operator*" would not work with MSVC. +// +// Also note that here we accept any compatible scalar types +template +const ScaledProduct +operator*(const ProductBase& prod, const typename Derived::Scalar& x) +{ return ScaledProduct(prod.derived(), x); } + +template +typename internal::enable_if::value, + const ScaledProduct >::type +operator*(const ProductBase& prod, const typename Derived::RealScalar& x) +{ return ScaledProduct(prod.derived(), x); } + + +template +const ScaledProduct +operator*(const typename Derived::Scalar& x,const ProductBase& prod) +{ return ScaledProduct(prod.derived(), x); } + +template +typename internal::enable_if::value, + const ScaledProduct >::type +operator*(const typename Derived::RealScalar& x,const ProductBase& prod) +{ return ScaledProduct(prod.derived(), x); } + +namespace internal { +template +struct traits > + : traits, + typename NestedProduct::_LhsNested, + typename NestedProduct::_RhsNested> > +{ + typedef typename traits::StorageKind StorageKind; +}; +} + +template +class ScaledProduct + : public ProductBase, + typename NestedProduct::_LhsNested, + typename NestedProduct::_RhsNested> +{ + public: + typedef ProductBase, + typename NestedProduct::_LhsNested, + typename NestedProduct::_RhsNested> Base; + typedef typename Base::Scalar Scalar; + typedef typename Base::PlainObject PlainObject; +// EIGEN_PRODUCT_PUBLIC_INTERFACE(ScaledProduct) + + ScaledProduct(const NestedProduct& prod, const Scalar& x) + : Base(prod.lhs(),prod.rhs()), m_prod(prod), m_alpha(x) {} + + template + inline void evalTo(Dest& dst) const { dst.setZero(); scaleAndAddTo(dst, Scalar(1)); } + + template + inline void addTo(Dest& dst) const { scaleAndAddTo(dst, Scalar(1)); } + + template + inline void subTo(Dest& dst) const { scaleAndAddTo(dst, Scalar(-1)); } + + template + inline void scaleAndAddTo(Dest& dst, const Scalar& a_alpha) const { m_prod.derived().scaleAndAddTo(dst,a_alpha * m_alpha); } + + const Scalar& alpha() const { return m_alpha; } + + protected: + const NestedProduct& m_prod; + Scalar m_alpha; +}; + +/** \internal + * Overloaded to perform an efficient C = (A*B).lazy() */ +template +template +Derived& MatrixBase::lazyAssign(const ProductBase& other) +{ + other.derived().evalTo(derived()); + return derived(); +} + +} // end namespace Eigen + +#endif // EIGEN_PRODUCTBASE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/Random.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/Random.h new file mode 100644 index 00000000..480fea40 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/Random.h @@ -0,0 +1,152 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_RANDOM_H +#define EIGEN_RANDOM_H + +namespace Eigen { + +namespace internal { + +template struct scalar_random_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_random_op) + template + inline const Scalar operator() (Index, Index = 0) const { return random(); } +}; + +template +struct functor_traits > +{ enum { Cost = 5 * NumTraits::MulCost, PacketAccess = false, IsRepeatable = false }; }; + +} // end namespace internal + +/** \returns a random matrix expression + * + * The parameters \a rows and \a cols are the number of rows and of columns of + * the returned matrix. Must be compatible with this MatrixBase type. + * + * This variant is meant to be used for dynamic-size matrix types. For fixed-size types, + * it is redundant to pass \a rows and \a cols as arguments, so Random() should be used + * instead. + * + * Example: \include MatrixBase_random_int_int.cpp + * Output: \verbinclude MatrixBase_random_int_int.out + * + * This expression has the "evaluate before nesting" flag so that it will be evaluated into + * a temporary matrix whenever it is nested in a larger expression. This prevents unexpected + * behavior with expressions involving random matrices. + * + * \sa MatrixBase::setRandom(), MatrixBase::Random(Index), MatrixBase::Random() + */ +template +inline const CwiseNullaryOp::Scalar>, Derived> +DenseBase::Random(Index rows, Index cols) +{ + return NullaryExpr(rows, cols, internal::scalar_random_op()); +} + +/** \returns a random vector expression + * + * The parameter \a size is the size of the returned vector. + * Must be compatible with this MatrixBase type. + * + * \only_for_vectors + * + * This variant is meant to be used for dynamic-size vector types. For fixed-size types, + * it is redundant to pass \a size as argument, so Random() should be used + * instead. + * + * Example: \include MatrixBase_random_int.cpp + * Output: \verbinclude MatrixBase_random_int.out + * + * This expression has the "evaluate before nesting" flag so that it will be evaluated into + * a temporary vector whenever it is nested in a larger expression. This prevents unexpected + * behavior with expressions involving random matrices. + * + * \sa MatrixBase::setRandom(), MatrixBase::Random(Index,Index), MatrixBase::Random() + */ +template +inline const CwiseNullaryOp::Scalar>, Derived> +DenseBase::Random(Index size) +{ + return NullaryExpr(size, internal::scalar_random_op()); +} + +/** \returns a fixed-size random matrix or vector expression + * + * This variant is only for fixed-size MatrixBase types. For dynamic-size types, you + * need to use the variants taking size arguments. + * + * Example: \include MatrixBase_random.cpp + * Output: \verbinclude MatrixBase_random.out + * + * This expression has the "evaluate before nesting" flag so that it will be evaluated into + * a temporary matrix whenever it is nested in a larger expression. This prevents unexpected + * behavior with expressions involving random matrices. + * + * \sa MatrixBase::setRandom(), MatrixBase::Random(Index,Index), MatrixBase::Random(Index) + */ +template +inline const CwiseNullaryOp::Scalar>, Derived> +DenseBase::Random() +{ + return NullaryExpr(RowsAtCompileTime, ColsAtCompileTime, internal::scalar_random_op()); +} + +/** Sets all coefficients in this expression to random values. + * + * Example: \include MatrixBase_setRandom.cpp + * Output: \verbinclude MatrixBase_setRandom.out + * + * \sa class CwiseNullaryOp, setRandom(Index), setRandom(Index,Index) + */ +template +inline Derived& DenseBase::setRandom() +{ + return *this = Random(rows(), cols()); +} + +/** Resizes to the given \a newSize, and sets all coefficients in this expression to random values. + * + * \only_for_vectors + * + * Example: \include Matrix_setRandom_int.cpp + * Output: \verbinclude Matrix_setRandom_int.out + * + * \sa MatrixBase::setRandom(), setRandom(Index,Index), class CwiseNullaryOp, MatrixBase::Random() + */ +template +EIGEN_STRONG_INLINE Derived& +PlainObjectBase::setRandom(Index newSize) +{ + resize(newSize); + return setRandom(); +} + +/** Resizes to the given size, and sets all coefficients in this expression to random values. + * + * \param nbRows the new number of rows + * \param nbCols the new number of columns + * + * Example: \include Matrix_setRandom_int_int.cpp + * Output: \verbinclude Matrix_setRandom_int_int.out + * + * \sa MatrixBase::setRandom(), setRandom(Index), class CwiseNullaryOp, MatrixBase::Random() + */ +template +EIGEN_STRONG_INLINE Derived& +PlainObjectBase::setRandom(Index nbRows, Index nbCols) +{ + resize(nbRows, nbCols); + return setRandom(); +} + +} // end namespace Eigen + +#endif // EIGEN_RANDOM_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/Redux.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/Redux.h new file mode 100644 index 00000000..9b8662a6 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/Redux.h @@ -0,0 +1,409 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008 Gael Guennebaud +// Copyright (C) 2006-2008 Benoit Jacob +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_REDUX_H +#define EIGEN_REDUX_H + +namespace Eigen { + +namespace internal { + +// TODO +// * implement other kind of vectorization +// * factorize code + +/*************************************************************************** +* Part 1 : the logic deciding a strategy for vectorization and unrolling +***************************************************************************/ + +template +struct redux_traits +{ +public: + enum { + PacketSize = packet_traits::size, + InnerMaxSize = int(Derived::IsRowMajor) + ? Derived::MaxColsAtCompileTime + : Derived::MaxRowsAtCompileTime + }; + + enum { + MightVectorize = (int(Derived::Flags)&ActualPacketAccessBit) + && (functor_traits::PacketAccess), + MayLinearVectorize = MightVectorize && (int(Derived::Flags)&LinearAccessBit), + MaySliceVectorize = MightVectorize && int(InnerMaxSize)>=3*PacketSize + }; + +public: + enum { + Traversal = int(MayLinearVectorize) ? int(LinearVectorizedTraversal) + : int(MaySliceVectorize) ? int(SliceVectorizedTraversal) + : int(DefaultTraversal) + }; + +public: + enum { + Cost = ( Derived::SizeAtCompileTime == Dynamic + || Derived::CoeffReadCost == Dynamic + || (Derived::SizeAtCompileTime!=1 && functor_traits::Cost == Dynamic) + ) ? Dynamic + : Derived::SizeAtCompileTime * Derived::CoeffReadCost + + (Derived::SizeAtCompileTime-1) * functor_traits::Cost, + UnrollingLimit = EIGEN_UNROLLING_LIMIT * (int(Traversal) == int(DefaultTraversal) ? 1 : int(PacketSize)) + }; + +public: + enum { + Unrolling = Cost != Dynamic && Cost <= UnrollingLimit + ? CompleteUnrolling + : NoUnrolling + }; +}; + +/*************************************************************************** +* Part 2 : unrollers +***************************************************************************/ + +/*** no vectorization ***/ + +template +struct redux_novec_unroller +{ + enum { + HalfLength = Length/2 + }; + + typedef typename Derived::Scalar Scalar; + + static EIGEN_STRONG_INLINE Scalar run(const Derived &mat, const Func& func) + { + return func(redux_novec_unroller::run(mat,func), + redux_novec_unroller::run(mat,func)); + } +}; + +template +struct redux_novec_unroller +{ + enum { + outer = Start / Derived::InnerSizeAtCompileTime, + inner = Start % Derived::InnerSizeAtCompileTime + }; + + typedef typename Derived::Scalar Scalar; + + static EIGEN_STRONG_INLINE Scalar run(const Derived &mat, const Func&) + { + return mat.coeffByOuterInner(outer, inner); + } +}; + +// This is actually dead code and will never be called. It is required +// to prevent false warnings regarding failed inlining though +// for 0 length run() will never be called at all. +template +struct redux_novec_unroller +{ + typedef typename Derived::Scalar Scalar; + static EIGEN_STRONG_INLINE Scalar run(const Derived&, const Func&) { return Scalar(); } +}; + +/*** vectorization ***/ + +template +struct redux_vec_unroller +{ + enum { + PacketSize = packet_traits::size, + HalfLength = Length/2 + }; + + typedef typename Derived::Scalar Scalar; + typedef typename packet_traits::type PacketScalar; + + static EIGEN_STRONG_INLINE PacketScalar run(const Derived &mat, const Func& func) + { + return func.packetOp( + redux_vec_unroller::run(mat,func), + redux_vec_unroller::run(mat,func) ); + } +}; + +template +struct redux_vec_unroller +{ + enum { + index = Start * packet_traits::size, + outer = index / int(Derived::InnerSizeAtCompileTime), + inner = index % int(Derived::InnerSizeAtCompileTime), + alignment = (Derived::Flags & AlignedBit) ? Aligned : Unaligned + }; + + typedef typename Derived::Scalar Scalar; + typedef typename packet_traits::type PacketScalar; + + static EIGEN_STRONG_INLINE PacketScalar run(const Derived &mat, const Func&) + { + return mat.template packetByOuterInner(outer, inner); + } +}; + +/*************************************************************************** +* Part 3 : implementation of all cases +***************************************************************************/ + +template::Traversal, + int Unrolling = redux_traits::Unrolling +> +struct redux_impl; + +template +struct redux_impl +{ + typedef typename Derived::Scalar Scalar; + typedef typename Derived::Index Index; + static EIGEN_STRONG_INLINE Scalar run(const Derived& mat, const Func& func) + { + eigen_assert(mat.rows()>0 && mat.cols()>0 && "you are using an empty matrix"); + Scalar res; + res = mat.coeffByOuterInner(0, 0); + for(Index i = 1; i < mat.innerSize(); ++i) + res = func(res, mat.coeffByOuterInner(0, i)); + for(Index i = 1; i < mat.outerSize(); ++i) + for(Index j = 0; j < mat.innerSize(); ++j) + res = func(res, mat.coeffByOuterInner(i, j)); + return res; + } +}; + +template +struct redux_impl + : public redux_novec_unroller +{}; + +template +struct redux_impl +{ + typedef typename Derived::Scalar Scalar; + typedef typename packet_traits::type PacketScalar; + typedef typename Derived::Index Index; + + static Scalar run(const Derived& mat, const Func& func) + { + const Index size = mat.size(); + eigen_assert(size && "you are using an empty matrix"); + const Index packetSize = packet_traits::size; + const Index alignedStart = internal::first_aligned(mat); + enum { + alignment = bool(Derived::Flags & DirectAccessBit) || bool(Derived::Flags & AlignedBit) + ? Aligned : Unaligned + }; + const Index alignedSize2 = ((size-alignedStart)/(2*packetSize))*(2*packetSize); + const Index alignedSize = ((size-alignedStart)/(packetSize))*(packetSize); + const Index alignedEnd2 = alignedStart + alignedSize2; + const Index alignedEnd = alignedStart + alignedSize; + Scalar res; + if(alignedSize) + { + PacketScalar packet_res0 = mat.template packet(alignedStart); + if(alignedSize>packetSize) // we have at least two packets to partly unroll the loop + { + PacketScalar packet_res1 = mat.template packet(alignedStart+packetSize); + for(Index index = alignedStart + 2*packetSize; index < alignedEnd2; index += 2*packetSize) + { + packet_res0 = func.packetOp(packet_res0, mat.template packet(index)); + packet_res1 = func.packetOp(packet_res1, mat.template packet(index+packetSize)); + } + + packet_res0 = func.packetOp(packet_res0,packet_res1); + if(alignedEnd>alignedEnd2) + packet_res0 = func.packetOp(packet_res0, mat.template packet(alignedEnd2)); + } + res = func.predux(packet_res0); + + for(Index index = 0; index < alignedStart; ++index) + res = func(res,mat.coeff(index)); + + for(Index index = alignedEnd; index < size; ++index) + res = func(res,mat.coeff(index)); + } + else // too small to vectorize anything. + // since this is dynamic-size hence inefficient anyway for such small sizes, don't try to optimize. + { + res = mat.coeff(0); + for(Index index = 1; index < size; ++index) + res = func(res,mat.coeff(index)); + } + + return res; + } +}; + +// NOTE: for SliceVectorizedTraversal we simply bypass unrolling +template +struct redux_impl +{ + typedef typename Derived::Scalar Scalar; + typedef typename packet_traits::type PacketScalar; + typedef typename Derived::Index Index; + + static Scalar run(const Derived& mat, const Func& func) + { + eigen_assert(mat.rows()>0 && mat.cols()>0 && "you are using an empty matrix"); + const Index innerSize = mat.innerSize(); + const Index outerSize = mat.outerSize(); + enum { + packetSize = packet_traits::size + }; + const Index packetedInnerSize = ((innerSize)/packetSize)*packetSize; + Scalar res; + if(packetedInnerSize) + { + PacketScalar packet_res = mat.template packet(0,0); + for(Index j=0; j(j,i)); + + res = func.predux(packet_res); + for(Index j=0; j::run(mat, func); + } + + return res; + } +}; + +template +struct redux_impl +{ + typedef typename Derived::Scalar Scalar; + typedef typename packet_traits::type PacketScalar; + enum { + PacketSize = packet_traits::size, + Size = Derived::SizeAtCompileTime, + VectorizedSize = (Size / PacketSize) * PacketSize + }; + static EIGEN_STRONG_INLINE Scalar run(const Derived& mat, const Func& func) + { + eigen_assert(mat.rows()>0 && mat.cols()>0 && "you are using an empty matrix"); + Scalar res = func.predux(redux_vec_unroller::run(mat,func)); + if (VectorizedSize != Size) + res = func(res,redux_novec_unroller::run(mat,func)); + return res; + } +}; + +} // end namespace internal + +/*************************************************************************** +* Part 4 : public API +***************************************************************************/ + + +/** \returns the result of a full redux operation on the whole matrix or vector using \a func + * + * The template parameter \a BinaryOp is the type of the functor \a func which must be + * an associative operator. Both current STL and TR1 functor styles are handled. + * + * \sa DenseBase::sum(), DenseBase::minCoeff(), DenseBase::maxCoeff(), MatrixBase::colwise(), MatrixBase::rowwise() + */ +template +template +EIGEN_STRONG_INLINE typename internal::result_of::Scalar)>::type +DenseBase::redux(const Func& func) const +{ + typedef typename internal::remove_all::type ThisNested; + return internal::redux_impl + ::run(derived(), func); +} + +/** \returns the minimum of all coefficients of \c *this. + * \warning the result is undefined if \c *this contains NaN. + */ +template +EIGEN_STRONG_INLINE typename internal::traits::Scalar +DenseBase::minCoeff() const +{ + return this->redux(Eigen::internal::scalar_min_op()); +} + +/** \returns the maximum of all coefficients of \c *this. + * \warning the result is undefined if \c *this contains NaN. + */ +template +EIGEN_STRONG_INLINE typename internal::traits::Scalar +DenseBase::maxCoeff() const +{ + return this->redux(Eigen::internal::scalar_max_op()); +} + +/** \returns the sum of all coefficients of *this + * + * \sa trace(), prod(), mean() + */ +template +EIGEN_STRONG_INLINE typename internal::traits::Scalar +DenseBase::sum() const +{ + if(SizeAtCompileTime==0 || (SizeAtCompileTime==Dynamic && size()==0)) + return Scalar(0); + return this->redux(Eigen::internal::scalar_sum_op()); +} + +/** \returns the mean of all coefficients of *this +* +* \sa trace(), prod(), sum() +*/ +template +EIGEN_STRONG_INLINE typename internal::traits::Scalar +DenseBase::mean() const +{ + return Scalar(this->redux(Eigen::internal::scalar_sum_op())) / Scalar(this->size()); +} + +/** \returns the product of all coefficients of *this + * + * Example: \include MatrixBase_prod.cpp + * Output: \verbinclude MatrixBase_prod.out + * + * \sa sum(), mean(), trace() + */ +template +EIGEN_STRONG_INLINE typename internal::traits::Scalar +DenseBase::prod() const +{ + if(SizeAtCompileTime==0 || (SizeAtCompileTime==Dynamic && size()==0)) + return Scalar(1); + return this->redux(Eigen::internal::scalar_product_op()); +} + +/** \returns the trace of \c *this, i.e. the sum of the coefficients on the main diagonal. + * + * \c *this can be any matrix, not necessarily square. + * + * \sa diagonal(), sum() + */ +template +EIGEN_STRONG_INLINE typename internal::traits::Scalar +MatrixBase::trace() const +{ + return derived().diagonal().sum(); +} + +} // end namespace Eigen + +#endif // EIGEN_REDUX_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/Ref.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/Ref.h new file mode 100644 index 00000000..7a3becaf --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/Ref.h @@ -0,0 +1,278 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2012 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_REF_H +#define EIGEN_REF_H + +namespace Eigen { + +template class RefBase; +template,OuterStride<> >::type > class Ref; + +/** \class Ref + * \ingroup Core_Module + * + * \brief A matrix or vector expression mapping an existing expressions + * + * \tparam PlainObjectType the equivalent matrix type of the mapped data + * \tparam Options specifies whether the pointer is \c #Aligned, or \c #Unaligned. + * The default is \c #Unaligned. + * \tparam StrideType optionally specifies strides. By default, Ref implies a contiguous storage along the inner dimension (inner stride==1), + * but accept a variable outer stride (leading dimension). + * This can be overridden by specifying strides. + * The type passed here must be a specialization of the Stride template, see examples below. + * + * This class permits to write non template functions taking Eigen's object as parameters while limiting the number of copies. + * A Ref<> object can represent either a const expression or a l-value: + * \code + * // in-out argument: + * void foo1(Ref x); + * + * // read-only const argument: + * void foo2(const Ref& x); + * \endcode + * + * In the in-out case, the input argument must satisfies the constraints of the actual Ref<> type, otherwise a compilation issue will be triggered. + * By default, a Ref can reference any dense vector expression of float having a contiguous memory layout. + * Likewise, a Ref can reference any column major dense matrix expression of float whose column's elements are contiguously stored with + * the possibility to have a constant space inbetween each column, i.e.: the inner stride mmust be equal to 1, but the outer-stride (or leading dimension), + * can be greater than the number of rows. + * + * In the const case, if the input expression does not match the above requirement, then it is evaluated into a temporary before being passed to the function. + * Here are some examples: + * \code + * MatrixXf A; + * VectorXf a; + * foo1(a.head()); // OK + * foo1(A.col()); // OK + * foo1(A.row()); // compilation error because here innerstride!=1 + * foo2(A.row()); // The row is copied into a contiguous temporary + * foo2(2*a); // The expression is evaluated into a temporary + * foo2(A.col().segment(2,4)); // No temporary + * \endcode + * + * The range of inputs that can be referenced without temporary can be enlarged using the last two template parameter. + * Here is an example accepting an innerstride!=1: + * \code + * // in-out argument: + * void foo3(Ref > x); + * foo3(A.row()); // OK + * \endcode + * The downside here is that the function foo3 might be significantly slower than foo1 because it won't be able to exploit vectorization, and will involved more + * expensive address computations even if the input is contiguously stored in memory. To overcome this issue, one might propose to overloads internally calling a + * template function, e.g.: + * \code + * // in the .h: + * void foo(const Ref& A); + * void foo(const Ref >& A); + * + * // in the .cpp: + * template void foo_impl(const TypeOfA& A) { + * ... // crazy code goes here + * } + * void foo(const Ref& A) { foo_impl(A); } + * void foo(const Ref >& A) { foo_impl(A); } + * \endcode + * + * + * \sa PlainObjectBase::Map(), \ref TopicStorageOrders + */ + +namespace internal { + +template +struct traits > + : public traits > +{ + typedef _PlainObjectType PlainObjectType; + typedef _StrideType StrideType; + enum { + Options = _Options, + Flags = traits >::Flags | NestByRefBit + }; + + template struct match { + enum { + HasDirectAccess = internal::has_direct_access::ret, + StorageOrderMatch = PlainObjectType::IsVectorAtCompileTime || Derived::IsVectorAtCompileTime || ((PlainObjectType::Flags&RowMajorBit)==(Derived::Flags&RowMajorBit)), + InnerStrideMatch = int(StrideType::InnerStrideAtCompileTime)==int(Dynamic) + || int(StrideType::InnerStrideAtCompileTime)==int(Derived::InnerStrideAtCompileTime) + || (int(StrideType::InnerStrideAtCompileTime)==0 && int(Derived::InnerStrideAtCompileTime)==1), + OuterStrideMatch = Derived::IsVectorAtCompileTime + || int(StrideType::OuterStrideAtCompileTime)==int(Dynamic) || int(StrideType::OuterStrideAtCompileTime)==int(Derived::OuterStrideAtCompileTime), + AlignmentMatch = (_Options!=Aligned) || ((PlainObjectType::Flags&AlignedBit)==0) || ((traits::Flags&AlignedBit)==AlignedBit), + ScalarTypeMatch = internal::is_same::value, + MatchAtCompileTime = HasDirectAccess && StorageOrderMatch && InnerStrideMatch && OuterStrideMatch && AlignmentMatch && ScalarTypeMatch + }; + typedef typename internal::conditional::type type; + }; + +}; + +template +struct traits > : public traits {}; + +} + +template class RefBase + : public MapBase +{ + typedef typename internal::traits::PlainObjectType PlainObjectType; + typedef typename internal::traits::StrideType StrideType; + +public: + + typedef MapBase Base; + EIGEN_DENSE_PUBLIC_INTERFACE(RefBase) + + inline Index innerStride() const + { + return StrideType::InnerStrideAtCompileTime != 0 ? m_stride.inner() : 1; + } + + inline Index outerStride() const + { + return StrideType::OuterStrideAtCompileTime != 0 ? m_stride.outer() + : IsVectorAtCompileTime ? this->size() + : int(Flags)&RowMajorBit ? this->cols() + : this->rows(); + } + + RefBase() + : Base(0,RowsAtCompileTime==Dynamic?0:RowsAtCompileTime,ColsAtCompileTime==Dynamic?0:ColsAtCompileTime), + // Stride<> does not allow default ctor for Dynamic strides, so let' initialize it with dummy values: + m_stride(StrideType::OuterStrideAtCompileTime==Dynamic?0:StrideType::OuterStrideAtCompileTime, + StrideType::InnerStrideAtCompileTime==Dynamic?0:StrideType::InnerStrideAtCompileTime) + {} + + EIGEN_INHERIT_ASSIGNMENT_OPERATORS(RefBase) + +protected: + + typedef Stride StrideBase; + + template + void construct(Expression& expr) + { + if(PlainObjectType::RowsAtCompileTime==1) + { + eigen_assert(expr.rows()==1 || expr.cols()==1); + ::new (static_cast(this)) Base(expr.data(), 1, expr.size()); + } + else if(PlainObjectType::ColsAtCompileTime==1) + { + eigen_assert(expr.rows()==1 || expr.cols()==1); + ::new (static_cast(this)) Base(expr.data(), expr.size(), 1); + } + else + ::new (static_cast(this)) Base(expr.data(), expr.rows(), expr.cols()); + + if(Expression::IsVectorAtCompileTime && (!PlainObjectType::IsVectorAtCompileTime) && ((Expression::Flags&RowMajorBit)!=(PlainObjectType::Flags&RowMajorBit))) + ::new (&m_stride) StrideBase(expr.innerStride(), StrideType::InnerStrideAtCompileTime==0?0:1); + else + ::new (&m_stride) StrideBase(StrideType::OuterStrideAtCompileTime==0?0:expr.outerStride(), + StrideType::InnerStrideAtCompileTime==0?0:expr.innerStride()); + } + + StrideBase m_stride; +}; + + +template class Ref + : public RefBase > +{ + private: + typedef internal::traits Traits; + template + inline Ref(const PlainObjectBase& expr, + typename internal::enable_if::MatchAtCompileTime),Derived>::type* = 0); + public: + + typedef RefBase Base; + EIGEN_DENSE_PUBLIC_INTERFACE(Ref) + + + #ifndef EIGEN_PARSED_BY_DOXYGEN + template + inline Ref(PlainObjectBase& expr, + typename internal::enable_if::MatchAtCompileTime),Derived>::type* = 0) + { + EIGEN_STATIC_ASSERT(static_cast(Traits::template match::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH); + Base::construct(expr.derived()); + } + template + inline Ref(const DenseBase& expr, + typename internal::enable_if::MatchAtCompileTime),Derived>::type* = 0) + #else + template + inline Ref(DenseBase& expr) + #endif + { + EIGEN_STATIC_ASSERT(static_cast(internal::is_lvalue::value), THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY); + EIGEN_STATIC_ASSERT(static_cast(Traits::template match::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH); + enum { THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY = Derived::ThisConstantIsPrivateInPlainObjectBase}; + Base::construct(expr.const_cast_derived()); + } + + EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Ref) + +}; + +// this is the const ref version +template class Ref + : public RefBase > +{ + typedef internal::traits Traits; + public: + + typedef RefBase Base; + EIGEN_DENSE_PUBLIC_INTERFACE(Ref) + + template + inline Ref(const DenseBase& expr, + typename internal::enable_if::ScalarTypeMatch),Derived>::type* = 0) + { +// std::cout << match_helper::HasDirectAccess << "," << match_helper::OuterStrideMatch << "," << match_helper::InnerStrideMatch << "\n"; +// std::cout << int(StrideType::OuterStrideAtCompileTime) << " - " << int(Derived::OuterStrideAtCompileTime) << "\n"; +// std::cout << int(StrideType::InnerStrideAtCompileTime) << " - " << int(Derived::InnerStrideAtCompileTime) << "\n"; + construct(expr.derived(), typename Traits::template match::type()); + } + + inline Ref(const Ref& other) : Base(other) { + // copy constructor shall not copy the m_object, to avoid unnecessary malloc and copy + } + + template + inline Ref(const RefBase& other) { + construct(other.derived(), typename Traits::template match::type()); + } + + protected: + + template + void construct(const Expression& expr,internal::true_type) + { + Base::construct(expr); + } + + template + void construct(const Expression& expr, internal::false_type) + { + m_object.lazyAssign(expr); + Base::construct(m_object); + } + + protected: + TPlainObjectType m_object; +}; + +} // end namespace Eigen + +#endif // EIGEN_REF_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/Replicate.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/Replicate.h new file mode 100644 index 00000000..ac4537c1 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/Replicate.h @@ -0,0 +1,177 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2009-2010 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_REPLICATE_H +#define EIGEN_REPLICATE_H + +namespace Eigen { + +/** + * \class Replicate + * \ingroup Core_Module + * + * \brief Expression of the multiple replication of a matrix or vector + * + * \param MatrixType the type of the object we are replicating + * + * This class represents an expression of the multiple replication of a matrix or vector. + * It is the return type of DenseBase::replicate() and most of the time + * this is the only way it is used. + * + * \sa DenseBase::replicate() + */ + +namespace internal { +template +struct traits > + : traits +{ + typedef typename MatrixType::Scalar Scalar; + typedef typename traits::StorageKind StorageKind; + typedef typename traits::XprKind XprKind; + enum { + Factor = (RowFactor==Dynamic || ColFactor==Dynamic) ? Dynamic : RowFactor*ColFactor + }; + typedef typename nested::type MatrixTypeNested; + typedef typename remove_reference::type _MatrixTypeNested; + enum { + RowsAtCompileTime = RowFactor==Dynamic || int(MatrixType::RowsAtCompileTime)==Dynamic + ? Dynamic + : RowFactor * MatrixType::RowsAtCompileTime, + ColsAtCompileTime = ColFactor==Dynamic || int(MatrixType::ColsAtCompileTime)==Dynamic + ? Dynamic + : ColFactor * MatrixType::ColsAtCompileTime, + //FIXME we don't propagate the max sizes !!! + MaxRowsAtCompileTime = RowsAtCompileTime, + MaxColsAtCompileTime = ColsAtCompileTime, + IsRowMajor = MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1 ? 1 + : MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1 ? 0 + : (MatrixType::Flags & RowMajorBit) ? 1 : 0, + Flags = (_MatrixTypeNested::Flags & HereditaryBits & ~RowMajorBit) | (IsRowMajor ? RowMajorBit : 0), + CoeffReadCost = _MatrixTypeNested::CoeffReadCost + }; +}; +} + +template class Replicate + : public internal::dense_xpr_base< Replicate >::type +{ + typedef typename internal::traits::MatrixTypeNested MatrixTypeNested; + typedef typename internal::traits::_MatrixTypeNested _MatrixTypeNested; + public: + + typedef typename internal::dense_xpr_base::type Base; + EIGEN_DENSE_PUBLIC_INTERFACE(Replicate) + + template + inline explicit Replicate(const OriginalMatrixType& a_matrix) + : m_matrix(a_matrix), m_rowFactor(RowFactor), m_colFactor(ColFactor) + { + EIGEN_STATIC_ASSERT((internal::is_same::type,OriginalMatrixType>::value), + THE_MATRIX_OR_EXPRESSION_THAT_YOU_PASSED_DOES_NOT_HAVE_THE_EXPECTED_TYPE) + eigen_assert(RowFactor!=Dynamic && ColFactor!=Dynamic); + } + + template + inline Replicate(const OriginalMatrixType& a_matrix, Index rowFactor, Index colFactor) + : m_matrix(a_matrix), m_rowFactor(rowFactor), m_colFactor(colFactor) + { + EIGEN_STATIC_ASSERT((internal::is_same::type,OriginalMatrixType>::value), + THE_MATRIX_OR_EXPRESSION_THAT_YOU_PASSED_DOES_NOT_HAVE_THE_EXPECTED_TYPE) + } + + inline Index rows() const { return m_matrix.rows() * m_rowFactor.value(); } + inline Index cols() const { return m_matrix.cols() * m_colFactor.value(); } + + inline Scalar coeff(Index rowId, Index colId) const + { + // try to avoid using modulo; this is a pure optimization strategy + const Index actual_row = internal::traits::RowsAtCompileTime==1 ? 0 + : RowFactor==1 ? rowId + : rowId%m_matrix.rows(); + const Index actual_col = internal::traits::ColsAtCompileTime==1 ? 0 + : ColFactor==1 ? colId + : colId%m_matrix.cols(); + + return m_matrix.coeff(actual_row, actual_col); + } + template + inline PacketScalar packet(Index rowId, Index colId) const + { + const Index actual_row = internal::traits::RowsAtCompileTime==1 ? 0 + : RowFactor==1 ? rowId + : rowId%m_matrix.rows(); + const Index actual_col = internal::traits::ColsAtCompileTime==1 ? 0 + : ColFactor==1 ? colId + : colId%m_matrix.cols(); + + return m_matrix.template packet(actual_row, actual_col); + } + + const _MatrixTypeNested& nestedExpression() const + { + return m_matrix; + } + + protected: + MatrixTypeNested m_matrix; + const internal::variable_if_dynamic m_rowFactor; + const internal::variable_if_dynamic m_colFactor; +}; + +/** + * \return an expression of the replication of \c *this + * + * Example: \include MatrixBase_replicate.cpp + * Output: \verbinclude MatrixBase_replicate.out + * + * \sa VectorwiseOp::replicate(), DenseBase::replicate(Index,Index), class Replicate + */ +template +template +const Replicate +DenseBase::replicate() const +{ + return Replicate(derived()); +} + +/** + * \return an expression of the replication of \c *this + * + * Example: \include MatrixBase_replicate_int_int.cpp + * Output: \verbinclude MatrixBase_replicate_int_int.out + * + * \sa VectorwiseOp::replicate(), DenseBase::replicate(), class Replicate + */ +template +const typename DenseBase::ReplicateReturnType +DenseBase::replicate(Index rowFactor,Index colFactor) const +{ + return Replicate(derived(),rowFactor,colFactor); +} + +/** + * \return an expression of the replication of each column (or row) of \c *this + * + * Example: \include DirectionWise_replicate_int.cpp + * Output: \verbinclude DirectionWise_replicate_int.out + * + * \sa VectorwiseOp::replicate(), DenseBase::replicate(), class Replicate + */ +template +const typename VectorwiseOp::ReplicateReturnType +VectorwiseOp::replicate(Index factor) const +{ + return typename VectorwiseOp::ReplicateReturnType + (_expression(),Direction==Vertical?factor:1,Direction==Horizontal?factor:1); +} + +} // end namespace Eigen + +#endif // EIGEN_REPLICATE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/ReturnByValue.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/ReturnByValue.h new file mode 100644 index 00000000..f635598d --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/ReturnByValue.h @@ -0,0 +1,99 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2009-2010 Gael Guennebaud +// Copyright (C) 2009-2010 Benoit Jacob +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_RETURNBYVALUE_H +#define EIGEN_RETURNBYVALUE_H + +namespace Eigen { + +/** \class ReturnByValue + * \ingroup Core_Module + * + */ + +namespace internal { + +template +struct traits > + : public traits::ReturnType> +{ + enum { + // We're disabling the DirectAccess because e.g. the constructor of + // the Block-with-DirectAccess expression requires to have a coeffRef method. + // Also, we don't want to have to implement the stride stuff. + Flags = (traits::ReturnType>::Flags + | EvalBeforeNestingBit) & ~DirectAccessBit + }; +}; + +/* The ReturnByValue object doesn't even have a coeff() method. + * So the only way that nesting it in an expression can work, is by evaluating it into a plain matrix. + * So internal::nested always gives the plain return matrix type. + * + * FIXME: I don't understand why we need this specialization: isn't this taken care of by the EvalBeforeNestingBit ?? + */ +template +struct nested, n, PlainObject> +{ + typedef typename traits::ReturnType type; +}; + +} // end namespace internal + +template class ReturnByValue + : internal::no_assignment_operator, public internal::dense_xpr_base< ReturnByValue >::type +{ + public: + typedef typename internal::traits::ReturnType ReturnType; + + typedef typename internal::dense_xpr_base::type Base; + EIGEN_DENSE_PUBLIC_INTERFACE(ReturnByValue) + + template + inline void evalTo(Dest& dst) const + { static_cast(this)->evalTo(dst); } + inline Index rows() const { return static_cast(this)->rows(); } + inline Index cols() const { return static_cast(this)->cols(); } + +#ifndef EIGEN_PARSED_BY_DOXYGEN +#define Unusable YOU_ARE_TRYING_TO_ACCESS_A_SINGLE_COEFFICIENT_IN_A_SPECIAL_EXPRESSION_WHERE_THAT_IS_NOT_ALLOWED_BECAUSE_THAT_WOULD_BE_INEFFICIENT + class Unusable{ + Unusable(const Unusable&) {} + Unusable& operator=(const Unusable&) {return *this;} + }; + const Unusable& coeff(Index) const { return *reinterpret_cast(this); } + const Unusable& coeff(Index,Index) const { return *reinterpret_cast(this); } + Unusable& coeffRef(Index) { return *reinterpret_cast(this); } + Unusable& coeffRef(Index,Index) { return *reinterpret_cast(this); } + template Unusable& packet(Index) const; + template Unusable& packet(Index, Index) const; +#endif +}; + +template +template +Derived& DenseBase::operator=(const ReturnByValue& other) +{ + other.evalTo(derived()); + return derived(); +} + +template +template +Derived& DenseBase::lazyAssign(const ReturnByValue& other) +{ + other.evalTo(derived()); + return derived(); +} + + +} // end namespace Eigen + +#endif // EIGEN_RETURNBYVALUE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/Reverse.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/Reverse.h new file mode 100644 index 00000000..e30ae3d2 --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/Reverse.h @@ -0,0 +1,224 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2006-2008 Benoit Jacob +// Copyright (C) 2009 Ricard Marxer +// Copyright (C) 2009-2010 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_REVERSE_H +#define EIGEN_REVERSE_H + +namespace Eigen { + +/** \class Reverse + * \ingroup Core_Module + * + * \brief Expression of the reverse of a vector or matrix + * + * \param MatrixType the type of the object of which we are taking the reverse + * + * This class represents an expression of the reverse of a vector. + * It is the return type of MatrixBase::reverse() and VectorwiseOp::reverse() + * and most of the time this is the only way it is used. + * + * \sa MatrixBase::reverse(), VectorwiseOp::reverse() + */ + +namespace internal { + +template +struct traits > + : traits +{ + typedef typename MatrixType::Scalar Scalar; + typedef typename traits::StorageKind StorageKind; + typedef typename traits::XprKind XprKind; + typedef typename nested::type MatrixTypeNested; + typedef typename remove_reference::type _MatrixTypeNested; + enum { + RowsAtCompileTime = MatrixType::RowsAtCompileTime, + ColsAtCompileTime = MatrixType::ColsAtCompileTime, + MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime, + MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime, + + // let's enable LinearAccess only with vectorization because of the product overhead + LinearAccess = ( (Direction==BothDirections) && (int(_MatrixTypeNested::Flags)&PacketAccessBit) ) + ? LinearAccessBit : 0, + + Flags = int(_MatrixTypeNested::Flags) & (HereditaryBits | LvalueBit | PacketAccessBit | LinearAccess), + + CoeffReadCost = _MatrixTypeNested::CoeffReadCost + }; +}; + +template struct reverse_packet_cond +{ + static inline PacketScalar run(const PacketScalar& x) { return preverse(x); } +}; + +template struct reverse_packet_cond +{ + static inline PacketScalar run(const PacketScalar& x) { return x; } +}; + +} // end namespace internal + +template class Reverse + : public internal::dense_xpr_base< Reverse >::type +{ + public: + + typedef typename internal::dense_xpr_base::type Base; + EIGEN_DENSE_PUBLIC_INTERFACE(Reverse) + using Base::IsRowMajor; + + // next line is necessary because otherwise const version of operator() + // is hidden by non-const version defined in this file + using Base::operator(); + + protected: + enum { + PacketSize = internal::packet_traits::size, + IsColMajor = !IsRowMajor, + ReverseRow = (Direction == Vertical) || (Direction == BothDirections), + ReverseCol = (Direction == Horizontal) || (Direction == BothDirections), + OffsetRow = ReverseRow && IsColMajor ? PacketSize : 1, + OffsetCol = ReverseCol && IsRowMajor ? PacketSize : 1, + ReversePacket = (Direction == BothDirections) + || ((Direction == Vertical) && IsColMajor) + || ((Direction == Horizontal) && IsRowMajor) + }; + typedef internal::reverse_packet_cond reverse_packet; + public: + + inline Reverse(const MatrixType& matrix) : m_matrix(matrix) { } + + EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Reverse) + + inline Index rows() const { return m_matrix.rows(); } + inline Index cols() const { return m_matrix.cols(); } + + inline Index innerStride() const + { + return -m_matrix.innerStride(); + } + + inline Scalar& operator()(Index row, Index col) + { + eigen_assert(row >= 0 && row < rows() && col >= 0 && col < cols()); + return coeffRef(row, col); + } + + inline Scalar& coeffRef(Index row, Index col) + { + return m_matrix.const_cast_derived().coeffRef(ReverseRow ? m_matrix.rows() - row - 1 : row, + ReverseCol ? m_matrix.cols() - col - 1 : col); + } + + inline CoeffReturnType coeff(Index row, Index col) const + { + return m_matrix.coeff(ReverseRow ? m_matrix.rows() - row - 1 : row, + ReverseCol ? m_matrix.cols() - col - 1 : col); + } + + inline CoeffReturnType coeff(Index index) const + { + return m_matrix.coeff(m_matrix.size() - index - 1); + } + + inline Scalar& coeffRef(Index index) + { + return m_matrix.const_cast_derived().coeffRef(m_matrix.size() - index - 1); + } + + inline Scalar& operator()(Index index) + { + eigen_assert(index >= 0 && index < m_matrix.size()); + return coeffRef(index); + } + + template + inline const PacketScalar packet(Index row, Index col) const + { + return reverse_packet::run(m_matrix.template packet( + ReverseRow ? m_matrix.rows() - row - OffsetRow : row, + ReverseCol ? m_matrix.cols() - col - OffsetCol : col)); + } + + template + inline void writePacket(Index row, Index col, const PacketScalar& x) + { + m_matrix.const_cast_derived().template writePacket( + ReverseRow ? m_matrix.rows() - row - OffsetRow : row, + ReverseCol ? m_matrix.cols() - col - OffsetCol : col, + reverse_packet::run(x)); + } + + template + inline const PacketScalar packet(Index index) const + { + return internal::preverse(m_matrix.template packet( m_matrix.size() - index - PacketSize )); + } + + template + inline void writePacket(Index index, const PacketScalar& x) + { + m_matrix.const_cast_derived().template writePacket(m_matrix.size() - index - PacketSize, internal::preverse(x)); + } + + const typename internal::remove_all::type& + nestedExpression() const + { + return m_matrix; + } + + protected: + typename MatrixType::Nested m_matrix; +}; + +/** \returns an expression of the reverse of *this. + * + * Example: \include MatrixBase_reverse.cpp + * Output: \verbinclude MatrixBase_reverse.out + * + */ +template +inline typename DenseBase::ReverseReturnType +DenseBase::reverse() +{ + return derived(); +} + +/** This is the const version of reverse(). */ +template +inline const typename DenseBase::ConstReverseReturnType +DenseBase::reverse() const +{ + return derived(); +} + +/** This is the "in place" version of reverse: it reverses \c *this. + * + * In most cases it is probably better to simply use the reversed expression + * of a matrix. However, when reversing the matrix data itself is really needed, + * then this "in-place" version is probably the right choice because it provides + * the following additional features: + * - less error prone: doing the same operation with .reverse() requires special care: + * \code m = m.reverse().eval(); \endcode + * - this API allows to avoid creating a temporary (the current implementation creates a temporary, but that could be avoided using swap) + * - it allows future optimizations (cache friendliness, etc.) + * + * \sa reverse() */ +template +inline void DenseBase::reverseInPlace() +{ + derived() = derived().reverse().eval(); +} + +} // end namespace Eigen + +#endif // EIGEN_REVERSE_H diff --git a/thirdparty/eigen-3.2.7/Eigen/src/Core/Select.h b/thirdparty/eigen-3.2.7/Eigen/src/Core/Select.h new file mode 100644 index 00000000..87993bbb --- /dev/null +++ b/thirdparty/eigen-3.2.7/Eigen/src/Core/Select.h @@ -0,0 +1,162 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008-2010 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_SELECT_H +#define EIGEN_SELECT_H + +namespace Eigen { + +/** \class Select + * \ingroup Core_Module + * + * \brief Expression of a coefficient wise version of the C++ ternary operator ?: + * + * \param ConditionMatrixType the type of the \em condition expression which must be a boolean matrix + * \param ThenMatrixType the type of the \em then expression + * \param ElseMatrixType the type of the \em else expression + * + * This class represents an expression of a coefficient wise version of the C++ ternary operator ?:. + * It is the return type of DenseBase::select() and most of the time this is the only way it is used. + * + * \sa DenseBase::select(const DenseBase&, const DenseBase&) const + */ + +namespace internal { +template +struct traits > + : traits +{ + typedef typename traits::Scalar Scalar; + typedef Dense StorageKind; + typedef typename traits::XprKind XprKind; + typedef typename ConditionMatrixType::Nested ConditionMatrixNested; + typedef typename ThenMatrixType::Nested ThenMatrixNested; + typedef typename ElseMatrixType::Nested ElseMatrixNested; + enum { + RowsAtCompileTime = ConditionMatrixType::RowsAtCompileTime, + ColsAtCompileTime = ConditionMatrixType::ColsAtCompileTime, + MaxRowsAtCompileTime = ConditionMatrixType::MaxRowsAtCompileTime, + MaxColsAtCompileTime = ConditionMatrixType::MaxColsAtCompileTime, + Flags = (unsigned int)ThenMatrixType::Flags & ElseMatrixType::Flags & HereditaryBits, + CoeffReadCost = traits::type>::CoeffReadCost + + EIGEN_SIZE_MAX(traits::type>::CoeffReadCost, + traits::type>::CoeffReadCost) + }; +}; +} + +template +class Select : internal::no_assignment_operator, + public internal::dense_xpr_base< Select >::type +{ + public: + + typedef typename internal::dense_xpr_base