Disabled external gits
This commit is contained in:
		
							
								
								
									
										390
									
								
								cs440-acg/ext/eigen/test/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										390
									
								
								cs440-acg/ext/eigen/test/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,390 @@
 | 
			
		||||
# generate split test header file only if it does not yet exist
 | 
			
		||||
# in order to prevent a rebuild everytime cmake is configured
 | 
			
		||||
if(NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/split_test_helper.h)  
 | 
			
		||||
  file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/split_test_helper.h "")
 | 
			
		||||
  foreach(i RANGE 1 999)
 | 
			
		||||
    file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/split_test_helper.h
 | 
			
		||||
      "#ifdef EIGEN_TEST_PART_${i}\n"
 | 
			
		||||
      "#define CALL_SUBTEST_${i}(FUNC) CALL_SUBTEST(FUNC)\n"
 | 
			
		||||
      "#else\n"
 | 
			
		||||
      "#define CALL_SUBTEST_${i}(FUNC)\n"
 | 
			
		||||
      "#endif\n\n"
 | 
			
		||||
    )
 | 
			
		||||
  endforeach()
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
# check if we have a Fortran compiler
 | 
			
		||||
include("../cmake/language_support.cmake")
 | 
			
		||||
 | 
			
		||||
workaround_9220(Fortran EIGEN_Fortran_COMPILER_WORKS)
 | 
			
		||||
 | 
			
		||||
if(EIGEN_Fortran_COMPILER_WORKS)
 | 
			
		||||
  enable_language(Fortran OPTIONAL)
 | 
			
		||||
  if(NOT CMAKE_Fortran_COMPILER)
 | 
			
		||||
    set(EIGEN_Fortran_COMPILER_WORKS OFF)
 | 
			
		||||
  endif()
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
if(NOT EIGEN_Fortran_COMPILER_WORKS)
 | 
			
		||||
  # search for a default Lapack library to complete Eigen's one
 | 
			
		||||
  find_package(LAPACK QUIET)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
# configure blas/lapack (use Eigen's ones)
 | 
			
		||||
set(EIGEN_BLAS_LIBRARIES eigen_blas)
 | 
			
		||||
set(EIGEN_LAPACK_LIBRARIES eigen_lapack)
 | 
			
		||||
 | 
			
		||||
set(EIGEN_TEST_MATRIX_DIR "" CACHE STRING "Enable testing of realword sparse matrices contained in the specified path")
 | 
			
		||||
if(EIGEN_TEST_MATRIX_DIR)
 | 
			
		||||
  if(NOT WIN32)
 | 
			
		||||
    message(STATUS "Test realworld sparse matrices: ${EIGEN_TEST_MATRIX_DIR}")
 | 
			
		||||
    add_definitions( -DTEST_REAL_CASES="${EIGEN_TEST_MATRIX_DIR}" )
 | 
			
		||||
  else(NOT WIN32)
 | 
			
		||||
    message(STATUS "REAL CASES CAN NOT BE CURRENTLY TESTED ON WIN32")
 | 
			
		||||
  endif(NOT WIN32)
 | 
			
		||||
endif(EIGEN_TEST_MATRIX_DIR)
 | 
			
		||||
 | 
			
		||||
set(SPARSE_LIBS " ")
 | 
			
		||||
 | 
			
		||||
find_package(Cholmod)
 | 
			
		||||
if(CHOLMOD_FOUND)
 | 
			
		||||
  add_definitions("-DEIGEN_CHOLMOD_SUPPORT")
 | 
			
		||||
  include_directories(${CHOLMOD_INCLUDES})
 | 
			
		||||
  set(SPARSE_LIBS ${SPARSE_LIBS} ${CHOLMOD_LIBRARIES} ${EIGEN_BLAS_LIBRARIES} ${EIGEN_LAPACK_LIBRARIES})
 | 
			
		||||
  set(CHOLMOD_ALL_LIBS  ${CHOLMOD_LIBRARIES} ${EIGEN_BLAS_LIBRARIES} ${EIGEN_LAPACK_LIBRARIES})
 | 
			
		||||
  ei_add_property(EIGEN_TESTED_BACKENDS "Cholmod, ")
 | 
			
		||||
else()
 | 
			
		||||
  ei_add_property(EIGEN_MISSING_BACKENDS "Cholmod, ")
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
find_package(Umfpack)
 | 
			
		||||
if(UMFPACK_FOUND)
 | 
			
		||||
  add_definitions("-DEIGEN_UMFPACK_SUPPORT")
 | 
			
		||||
  include_directories(${UMFPACK_INCLUDES})
 | 
			
		||||
  set(SPARSE_LIBS ${SPARSE_LIBS} ${UMFPACK_LIBRARIES} ${EIGEN_BLAS_LIBRARIES})
 | 
			
		||||
  set(UMFPACK_ALL_LIBS ${UMFPACK_LIBRARIES} ${EIGEN_BLAS_LIBRARIES})
 | 
			
		||||
  ei_add_property(EIGEN_TESTED_BACKENDS "UmfPack, ")
 | 
			
		||||
else()
 | 
			
		||||
  ei_add_property(EIGEN_MISSING_BACKENDS "UmfPack, ")
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
find_package(SuperLU 4.0)
 | 
			
		||||
if(SUPERLU_FOUND)
 | 
			
		||||
  add_definitions("-DEIGEN_SUPERLU_SUPPORT")
 | 
			
		||||
  include_directories(${SUPERLU_INCLUDES})
 | 
			
		||||
  set(SPARSE_LIBS ${SPARSE_LIBS} ${SUPERLU_LIBRARIES} ${EIGEN_BLAS_LIBRARIES})
 | 
			
		||||
  set(SUPERLU_ALL_LIBS ${SUPERLU_LIBRARIES} ${EIGEN_BLAS_LIBRARIES})
 | 
			
		||||
  ei_add_property(EIGEN_TESTED_BACKENDS  "SuperLU, ")
 | 
			
		||||
else()
 | 
			
		||||
  ei_add_property(EIGEN_MISSING_BACKENDS  "SuperLU, ")
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
find_package(PASTIX QUIET COMPONENTS METIS SCOTCH)
 | 
			
		||||
# check that the PASTIX found is a version without MPI
 | 
			
		||||
find_path(PASTIX_pastix_nompi.h_INCLUDE_DIRS
 | 
			
		||||
  NAMES pastix_nompi.h
 | 
			
		||||
  HINTS ${PASTIX_INCLUDE_DIRS}
 | 
			
		||||
)
 | 
			
		||||
if (NOT PASTIX_pastix_nompi.h_INCLUDE_DIRS)
 | 
			
		||||
  message(STATUS "A version of Pastix has been found but pastix_nompi.h does not exist in the include directory."
 | 
			
		||||
                 " Because Eigen tests require a version without MPI, we disable the Pastix backend.")
 | 
			
		||||
endif()
 | 
			
		||||
if(PASTIX_FOUND AND PASTIX_pastix_nompi.h_INCLUDE_DIRS)
 | 
			
		||||
  add_definitions("-DEIGEN_PASTIX_SUPPORT")
 | 
			
		||||
  include_directories(${PASTIX_INCLUDE_DIRS_DEP})
 | 
			
		||||
  if(SCOTCH_FOUND)
 | 
			
		||||
    include_directories(${SCOTCH_INCLUDE_DIRS})
 | 
			
		||||
    set(PASTIX_LIBRARIES ${PASTIX_LIBRARIES} ${SCOTCH_LIBRARIES})
 | 
			
		||||
  elseif(METIS_FOUND)
 | 
			
		||||
    include_directories(${METIS_INCLUDE_DIRS})
 | 
			
		||||
    set(PASTIX_LIBRARIES ${PASTIX_LIBRARIES} ${METIS_LIBRARIES})
 | 
			
		||||
  else(SCOTCH_FOUND)
 | 
			
		||||
    ei_add_property(EIGEN_MISSING_BACKENDS  "PaStiX, ")
 | 
			
		||||
  endif(SCOTCH_FOUND)
 | 
			
		||||
  set(SPARSE_LIBS ${SPARSE_LIBS} ${PASTIX_LIBRARIES_DEP} ${ORDERING_LIBRARIES})
 | 
			
		||||
  set(PASTIX_ALL_LIBS ${PASTIX_LIBRARIES_DEP})
 | 
			
		||||
  ei_add_property(EIGEN_TESTED_BACKENDS  "PaStiX, ")
 | 
			
		||||
else()
 | 
			
		||||
  ei_add_property(EIGEN_MISSING_BACKENDS  "PaStiX, ")
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
if(METIS_FOUND)
 | 
			
		||||
  add_definitions("-DEIGEN_METIS_SUPPORT")
 | 
			
		||||
  include_directories(${METIS_INCLUDE_DIRS})
 | 
			
		||||
  ei_add_property(EIGEN_TESTED_BACKENDS "METIS, ")
 | 
			
		||||
else()
 | 
			
		||||
  ei_add_property(EIGEN_MISSING_BACKENDS "METIS, ")
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
find_package(SPQR)
 | 
			
		||||
if(SPQR_FOUND AND CHOLMOD_FOUND AND (EIGEN_Fortran_COMPILER_WORKS OR LAPACK_FOUND) )
 | 
			
		||||
  add_definitions("-DEIGEN_SPQR_SUPPORT")
 | 
			
		||||
  include_directories(${SPQR_INCLUDES})
 | 
			
		||||
  set(SPQR_ALL_LIBS ${SPQR_LIBRARIES} ${CHOLMOD_LIBRARIES} ${EIGEN_LAPACK_LIBRARIES} ${EIGEN_BLAS_LIBRARIES} ${LAPACK_LIBRARIES})
 | 
			
		||||
  set(SPARSE_LIBS ${SPARSE_LIBS} ${SPQR_ALL_LIBS})
 | 
			
		||||
  ei_add_property(EIGEN_TESTED_BACKENDS "SPQR, ")
 | 
			
		||||
else()
 | 
			
		||||
  ei_add_property(EIGEN_MISSING_BACKENDS "SPQR, ")
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
option(EIGEN_TEST_NOQT "Disable Qt support in unit tests" OFF)
 | 
			
		||||
if(NOT EIGEN_TEST_NOQT)
 | 
			
		||||
  find_package(Qt4)
 | 
			
		||||
  if(QT4_FOUND)
 | 
			
		||||
    include(${QT_USE_FILE})
 | 
			
		||||
    ei_add_property(EIGEN_TESTED_BACKENDS  "Qt4 support, ")
 | 
			
		||||
  else()
 | 
			
		||||
    ei_add_property(EIGEN_MISSING_BACKENDS  "Qt4 support, ")
 | 
			
		||||
  endif()
 | 
			
		||||
endif(NOT EIGEN_TEST_NOQT)
 | 
			
		||||
 | 
			
		||||
if(TEST_LIB)
 | 
			
		||||
  add_definitions("-DEIGEN_EXTERN_INSTANTIATIONS=1")
 | 
			
		||||
endif(TEST_LIB)
 | 
			
		||||
 | 
			
		||||
set_property(GLOBAL PROPERTY EIGEN_CURRENT_SUBPROJECT "Official")
 | 
			
		||||
add_custom_target(BuildOfficial)
 | 
			
		||||
 | 
			
		||||
ei_add_test(rand)
 | 
			
		||||
ei_add_test(meta)
 | 
			
		||||
ei_add_test(numext)
 | 
			
		||||
ei_add_test(sizeof)
 | 
			
		||||
ei_add_test(dynalloc)
 | 
			
		||||
ei_add_test(nomalloc)
 | 
			
		||||
ei_add_test(first_aligned)
 | 
			
		||||
ei_add_test(nullary)
 | 
			
		||||
ei_add_test(mixingtypes)
 | 
			
		||||
ei_add_test(packetmath "-DEIGEN_FAST_MATH=1")
 | 
			
		||||
ei_add_test(unalignedassert)
 | 
			
		||||
ei_add_test(vectorization_logic)
 | 
			
		||||
ei_add_test(basicstuff)
 | 
			
		||||
ei_add_test(constructor)
 | 
			
		||||
ei_add_test(linearstructure)
 | 
			
		||||
ei_add_test(integer_types)
 | 
			
		||||
ei_add_test(unalignedcount)
 | 
			
		||||
if(NOT EIGEN_TEST_NO_EXCEPTIONS AND NOT EIGEN_TEST_OPENMP)
 | 
			
		||||
  ei_add_test(exceptions)
 | 
			
		||||
endif()
 | 
			
		||||
ei_add_test(redux)
 | 
			
		||||
ei_add_test(visitor)
 | 
			
		||||
ei_add_test(block)
 | 
			
		||||
ei_add_test(corners)
 | 
			
		||||
ei_add_test(swap)
 | 
			
		||||
ei_add_test(resize)
 | 
			
		||||
ei_add_test(conservative_resize)
 | 
			
		||||
ei_add_test(product_small)
 | 
			
		||||
ei_add_test(product_large)
 | 
			
		||||
ei_add_test(product_extra)
 | 
			
		||||
ei_add_test(diagonalmatrices)
 | 
			
		||||
ei_add_test(adjoint)
 | 
			
		||||
ei_add_test(diagonal)
 | 
			
		||||
ei_add_test(miscmatrices)
 | 
			
		||||
ei_add_test(commainitializer)
 | 
			
		||||
ei_add_test(smallvectors)
 | 
			
		||||
ei_add_test(mapped_matrix)
 | 
			
		||||
ei_add_test(mapstride)
 | 
			
		||||
ei_add_test(mapstaticmethods)
 | 
			
		||||
ei_add_test(array_cwise)
 | 
			
		||||
ei_add_test(array_for_matrix)
 | 
			
		||||
ei_add_test(array_replicate)
 | 
			
		||||
ei_add_test(array_reverse)
 | 
			
		||||
ei_add_test(ref)
 | 
			
		||||
ei_add_test(is_same_dense)
 | 
			
		||||
ei_add_test(triangular)
 | 
			
		||||
ei_add_test(selfadjoint)
 | 
			
		||||
ei_add_test(product_selfadjoint)
 | 
			
		||||
ei_add_test(product_symm)
 | 
			
		||||
ei_add_test(product_syrk)
 | 
			
		||||
ei_add_test(product_trmv)
 | 
			
		||||
ei_add_test(product_trmm)
 | 
			
		||||
ei_add_test(product_trsolve)
 | 
			
		||||
ei_add_test(product_mmtr)
 | 
			
		||||
ei_add_test(product_notemporary)
 | 
			
		||||
ei_add_test(stable_norm)
 | 
			
		||||
ei_add_test(permutationmatrices)
 | 
			
		||||
ei_add_test(bandmatrix)
 | 
			
		||||
ei_add_test(cholesky)
 | 
			
		||||
ei_add_test(lu)
 | 
			
		||||
ei_add_test(determinant)
 | 
			
		||||
ei_add_test(inverse)
 | 
			
		||||
ei_add_test(qr)
 | 
			
		||||
ei_add_test(qr_colpivoting)
 | 
			
		||||
ei_add_test(qr_fullpivoting)
 | 
			
		||||
ei_add_test(upperbidiagonalization)
 | 
			
		||||
ei_add_test(hessenberg)
 | 
			
		||||
ei_add_test(schur_real)
 | 
			
		||||
ei_add_test(schur_complex)
 | 
			
		||||
ei_add_test(eigensolver_selfadjoint)
 | 
			
		||||
ei_add_test(eigensolver_generic)
 | 
			
		||||
ei_add_test(eigensolver_complex)
 | 
			
		||||
ei_add_test(real_qz)
 | 
			
		||||
ei_add_test(eigensolver_generalized_real)
 | 
			
		||||
ei_add_test(jacobi)
 | 
			
		||||
ei_add_test(jacobisvd)
 | 
			
		||||
ei_add_test(bdcsvd)
 | 
			
		||||
ei_add_test(householder)
 | 
			
		||||
ei_add_test(geo_orthomethods)
 | 
			
		||||
ei_add_test(geo_quaternion)
 | 
			
		||||
ei_add_test(geo_eulerangles)
 | 
			
		||||
ei_add_test(geo_parametrizedline)
 | 
			
		||||
ei_add_test(geo_alignedbox)
 | 
			
		||||
ei_add_test(geo_hyperplane)
 | 
			
		||||
ei_add_test(geo_transformations)
 | 
			
		||||
ei_add_test(geo_homogeneous)
 | 
			
		||||
ei_add_test(stdvector)
 | 
			
		||||
ei_add_test(stdvector_overload)
 | 
			
		||||
ei_add_test(stdlist)
 | 
			
		||||
ei_add_test(stdlist_overload)
 | 
			
		||||
ei_add_test(stddeque)
 | 
			
		||||
ei_add_test(stddeque_overload)
 | 
			
		||||
ei_add_test(sparse_basic)
 | 
			
		||||
ei_add_test(sparse_block)
 | 
			
		||||
ei_add_test(sparse_vector)
 | 
			
		||||
ei_add_test(sparse_product)
 | 
			
		||||
ei_add_test(sparse_ref)
 | 
			
		||||
ei_add_test(sparse_solvers)
 | 
			
		||||
ei_add_test(sparse_permutations)
 | 
			
		||||
ei_add_test(simplicial_cholesky)
 | 
			
		||||
ei_add_test(conjugate_gradient)
 | 
			
		||||
ei_add_test(incomplete_cholesky)
 | 
			
		||||
ei_add_test(bicgstab)
 | 
			
		||||
ei_add_test(lscg)
 | 
			
		||||
ei_add_test(sparselu)
 | 
			
		||||
ei_add_test(sparseqr)
 | 
			
		||||
ei_add_test(umeyama)
 | 
			
		||||
ei_add_test(nesting_ops "${CMAKE_CXX_FLAGS_DEBUG}")
 | 
			
		||||
ei_add_test(zerosized)
 | 
			
		||||
ei_add_test(dontalign)
 | 
			
		||||
ei_add_test(evaluators)
 | 
			
		||||
if(NOT EIGEN_TEST_NO_EXCEPTIONS)
 | 
			
		||||
  ei_add_test(sizeoverflow)
 | 
			
		||||
endif()
 | 
			
		||||
ei_add_test(prec_inverse_4x4)
 | 
			
		||||
ei_add_test(vectorwiseop)
 | 
			
		||||
ei_add_test(special_numbers)
 | 
			
		||||
ei_add_test(rvalue_types)
 | 
			
		||||
ei_add_test(dense_storage)
 | 
			
		||||
ei_add_test(ctorleak)
 | 
			
		||||
ei_add_test(mpl2only)
 | 
			
		||||
ei_add_test(inplace_decomposition)
 | 
			
		||||
ei_add_test(half_float)
 | 
			
		||||
ei_add_test(array_of_string)
 | 
			
		||||
 | 
			
		||||
add_executable(bug1213 bug1213.cpp bug1213_main.cpp)
 | 
			
		||||
 | 
			
		||||
check_cxx_compiler_flag("-ffast-math" COMPILER_SUPPORT_FASTMATH)
 | 
			
		||||
if(COMPILER_SUPPORT_FASTMATH)
 | 
			
		||||
  set(EIGEN_FASTMATH_FLAGS "-ffast-math")
 | 
			
		||||
else()
 | 
			
		||||
  check_cxx_compiler_flag("/fp:fast" COMPILER_SUPPORT_FPFAST)
 | 
			
		||||
  if(COMPILER_SUPPORT_FPFAST)
 | 
			
		||||
    set(EIGEN_FASTMATH_FLAGS "/fp:fast")
 | 
			
		||||
  endif()
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
ei_add_test(fastmath " ${EIGEN_FASTMATH_FLAGS} ")
 | 
			
		||||
 | 
			
		||||
# # ei_add_test(denseLM)
 | 
			
		||||
 | 
			
		||||
if(QT4_FOUND)
 | 
			
		||||
  ei_add_test(qtvector "" "${QT_QTCORE_LIBRARY}")
 | 
			
		||||
endif(QT4_FOUND)
 | 
			
		||||
 | 
			
		||||
if(UMFPACK_FOUND)
 | 
			
		||||
  ei_add_test(umfpack_support "" "${UMFPACK_ALL_LIBS}")
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
if(SUPERLU_FOUND)
 | 
			
		||||
  ei_add_test(superlu_support "" "${SUPERLU_ALL_LIBS}")
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
if(CHOLMOD_FOUND)
 | 
			
		||||
  ei_add_test(cholmod_support "" "${CHOLMOD_ALL_LIBS}")
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
if(PARDISO_FOUND)
 | 
			
		||||
  ei_add_test(pardiso_support "" "${PARDISO_ALL_LIBS}")
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
if(PASTIX_FOUND AND (SCOTCH_FOUND OR METIS_FOUND))
 | 
			
		||||
  ei_add_test(pastix_support "" "${PASTIX_ALL_LIBS}")
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
if(SPQR_FOUND AND CHOLMOD_FOUND)
 | 
			
		||||
  ei_add_test(spqr_support "" "${SPQR_ALL_LIBS}")
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
if(METIS_FOUND)
 | 
			
		||||
ei_add_test(metis_support "" "${METIS_LIBRARIES}")
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
string(TOLOWER "${CMAKE_CXX_COMPILER}" cmake_cxx_compiler_tolower)
 | 
			
		||||
if(cmake_cxx_compiler_tolower MATCHES "qcc")
 | 
			
		||||
  set(CXX_IS_QCC "ON")
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
ei_add_property(EIGEN_TESTING_SUMMARY "CXX:               ${CMAKE_CXX_COMPILER}\n")
 | 
			
		||||
if(CMAKE_COMPILER_IS_GNUCXX AND NOT CXX_IS_QCC)
 | 
			
		||||
  execute_process(COMMAND ${CMAKE_CXX_COMPILER} --version COMMAND head -n 1 OUTPUT_VARIABLE EIGEN_CXX_VERSION_STRING OUTPUT_STRIP_TRAILING_WHITESPACE)
 | 
			
		||||
  ei_add_property(EIGEN_TESTING_SUMMARY "CXX_VERSION:       ${EIGEN_CXX_VERSION_STRING}\n")
 | 
			
		||||
endif()
 | 
			
		||||
ei_add_property(EIGEN_TESTING_SUMMARY "CXX_FLAGS:         ${CMAKE_CXX_FLAGS}\n")
 | 
			
		||||
ei_add_property(EIGEN_TESTING_SUMMARY "Sparse lib flags:  ${SPARSE_LIBS}\n")
 | 
			
		||||
 | 
			
		||||
option(EIGEN_TEST_EIGEN2 "Run whole Eigen2 test suite against EIGEN2_SUPPORT" OFF)
 | 
			
		||||
mark_as_advanced(EIGEN_TEST_EIGEN2)
 | 
			
		||||
if(EIGEN_TEST_EIGEN2)
 | 
			
		||||
  message(WARNING "The Eigen2 test suite has been removed")
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
# boost MP unit test
 | 
			
		||||
find_package(Boost)
 | 
			
		||||
if(Boost_FOUND)
 | 
			
		||||
  include_directories(${Boost_INCLUDE_DIRS})
 | 
			
		||||
  ei_add_test(boostmultiprec "" "${Boost_LIBRARIES}")
 | 
			
		||||
  ei_add_property(EIGEN_TESTED_BACKENDS "Boost.Multiprecision, ")
 | 
			
		||||
else()
 | 
			
		||||
  ei_add_property(EIGEN_MISSING_BACKENDS "Boost.Multiprecision, ")
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# CUDA unit tests
 | 
			
		||||
option(EIGEN_TEST_CUDA "Enable CUDA support in unit tests" OFF)
 | 
			
		||||
option(EIGEN_TEST_CUDA_CLANG "Use clang instead of nvcc to compile the CUDA tests" OFF)
 | 
			
		||||
 | 
			
		||||
if(EIGEN_TEST_CUDA_CLANG AND NOT CMAKE_CXX_COMPILER MATCHES "clang")
 | 
			
		||||
  message(WARNING "EIGEN_TEST_CUDA_CLANG is set, but CMAKE_CXX_COMPILER does not appear to be clang.")
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
if(EIGEN_TEST_CUDA)
 | 
			
		||||
 | 
			
		||||
find_package(CUDA 5.0)
 | 
			
		||||
if(CUDA_FOUND)
 | 
			
		||||
  
 | 
			
		||||
  set(CUDA_PROPAGATE_HOST_FLAGS OFF)
 | 
			
		||||
  if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") 
 | 
			
		||||
    set(CUDA_NVCC_FLAGS "-ccbin ${CMAKE_C_COMPILER}" CACHE STRING "nvcc flags" FORCE)
 | 
			
		||||
  endif()
 | 
			
		||||
  if(EIGEN_TEST_CUDA_CLANG)
 | 
			
		||||
   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 --cuda-gpu-arch=sm_30")
 | 
			
		||||
  endif()
 | 
			
		||||
  cuda_include_directories(${CMAKE_CURRENT_BINARY_DIR})
 | 
			
		||||
  set(EIGEN_ADD_TEST_FILENAME_EXTENSION  "cu")
 | 
			
		||||
  
 | 
			
		||||
  ei_add_test(cuda_basic)
 | 
			
		||||
  
 | 
			
		||||
  unset(EIGEN_ADD_TEST_FILENAME_EXTENSION)
 | 
			
		||||
 | 
			
		||||
endif(CUDA_FOUND)
 | 
			
		||||
 | 
			
		||||
endif(EIGEN_TEST_CUDA)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/failtests)    
 | 
			
		||||
add_test(NAME failtests WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/failtests COMMAND ${CMAKE_COMMAND} ${Eigen_SOURCE_DIR} -G "${CMAKE_GENERATOR}" -DEIGEN_FAILTEST=ON)
 | 
			
		||||
 | 
			
		||||
option(EIGEN_TEST_BUILD_DOCUMENTATION "Test building the doxygen documentation" OFF)
 | 
			
		||||
IF(EIGEN_TEST_BUILD_DOCUMENTATION)
 | 
			
		||||
  add_dependencies(buildtests doc)
 | 
			
		||||
ENDIF()
 | 
			
		||||
							
								
								
									
										199
									
								
								cs440-acg/ext/eigen/test/adjoint.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										199
									
								
								cs440-acg/ext/eigen/test/adjoint.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,199 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#define EIGEN_NO_STATIC_ASSERT
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
 | 
			
		||||
template<bool IsInteger> struct adjoint_specific;
 | 
			
		||||
 | 
			
		||||
template<> struct adjoint_specific<true> {
 | 
			
		||||
  template<typename Vec, typename Mat, typename Scalar>
 | 
			
		||||
  static void run(const Vec& v1, const Vec& v2, Vec& v3, const Mat& square, Scalar s1, Scalar s2) {
 | 
			
		||||
    VERIFY(test_isApproxWithRef((s1 * v1 + s2 * v2).dot(v3),     numext::conj(s1) * v1.dot(v3) + numext::conj(s2) * v2.dot(v3), 0));
 | 
			
		||||
    VERIFY(test_isApproxWithRef(v3.dot(s1 * v1 + s2 * v2),       s1*v3.dot(v1)+s2*v3.dot(v2), 0));
 | 
			
		||||
    
 | 
			
		||||
    // check compatibility of dot and adjoint
 | 
			
		||||
    VERIFY(test_isApproxWithRef(v1.dot(square * v2), (square.adjoint() * v1).dot(v2), 0));
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<> struct adjoint_specific<false> {
 | 
			
		||||
  template<typename Vec, typename Mat, typename Scalar>
 | 
			
		||||
  static void run(const Vec& v1, const Vec& v2, Vec& v3, const Mat& square, Scalar s1, Scalar s2) {
 | 
			
		||||
    typedef typename NumTraits<Scalar>::Real RealScalar;
 | 
			
		||||
    using std::abs;
 | 
			
		||||
    
 | 
			
		||||
    RealScalar ref = NumTraits<Scalar>::IsInteger ? RealScalar(0) : (std::max)((s1 * v1 + s2 * v2).norm(),v3.norm());
 | 
			
		||||
    VERIFY(test_isApproxWithRef((s1 * v1 + s2 * v2).dot(v3),     numext::conj(s1) * v1.dot(v3) + numext::conj(s2) * v2.dot(v3), ref));
 | 
			
		||||
    VERIFY(test_isApproxWithRef(v3.dot(s1 * v1 + s2 * v2),       s1*v3.dot(v1)+s2*v3.dot(v2), ref));
 | 
			
		||||
  
 | 
			
		||||
    VERIFY_IS_APPROX(v1.squaredNorm(),                v1.norm() * v1.norm());
 | 
			
		||||
    // check normalized() and normalize()
 | 
			
		||||
    VERIFY_IS_APPROX(v1, v1.norm() * v1.normalized());
 | 
			
		||||
    v3 = v1;
 | 
			
		||||
    v3.normalize();
 | 
			
		||||
    VERIFY_IS_APPROX(v1, v1.norm() * v3);
 | 
			
		||||
    VERIFY_IS_APPROX(v3, v1.normalized());
 | 
			
		||||
    VERIFY_IS_APPROX(v3.norm(), RealScalar(1));
 | 
			
		||||
 | 
			
		||||
    // check null inputs
 | 
			
		||||
    VERIFY_IS_APPROX((v1*0).normalized(), (v1*0));
 | 
			
		||||
#if (!EIGEN_ARCH_i386) || defined(EIGEN_VECTORIZE)
 | 
			
		||||
    RealScalar very_small = (std::numeric_limits<RealScalar>::min)();
 | 
			
		||||
    VERIFY( (v1*very_small).norm() == 0 );
 | 
			
		||||
    VERIFY_IS_APPROX((v1*very_small).normalized(), (v1*very_small));
 | 
			
		||||
    v3 = v1*very_small;
 | 
			
		||||
    v3.normalize();
 | 
			
		||||
    VERIFY_IS_APPROX(v3, (v1*very_small));
 | 
			
		||||
#endif
 | 
			
		||||
    
 | 
			
		||||
    // check compatibility of dot and adjoint
 | 
			
		||||
    ref = NumTraits<Scalar>::IsInteger ? 0 : (std::max)((std::max)(v1.norm(),v2.norm()),(std::max)((square * v2).norm(),(square.adjoint() * v1).norm()));
 | 
			
		||||
    VERIFY(internal::isMuchSmallerThan(abs(v1.dot(square * v2) - (square.adjoint() * v1).dot(v2)), ref, test_precision<Scalar>()));
 | 
			
		||||
    
 | 
			
		||||
    // check that Random().normalized() works: tricky as the random xpr must be evaluated by
 | 
			
		||||
    // normalized() in order to produce a consistent result.
 | 
			
		||||
    VERIFY_IS_APPROX(Vec::Random(v1.size()).normalized().norm(), RealScalar(1));
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void adjoint(const MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  /* this test covers the following files:
 | 
			
		||||
     Transpose.h Conjugate.h Dot.h
 | 
			
		||||
  */
 | 
			
		||||
  using std::abs;
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
  typedef typename NumTraits<Scalar>::Real RealScalar;
 | 
			
		||||
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;
 | 
			
		||||
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> SquareMatrixType;
 | 
			
		||||
  const Index PacketSize = internal::packet_traits<Scalar>::size;
 | 
			
		||||
  
 | 
			
		||||
  Index rows = m.rows();
 | 
			
		||||
  Index cols = m.cols();
 | 
			
		||||
 | 
			
		||||
  MatrixType m1 = MatrixType::Random(rows, cols),
 | 
			
		||||
             m2 = MatrixType::Random(rows, cols),
 | 
			
		||||
             m3(rows, cols),
 | 
			
		||||
             square = SquareMatrixType::Random(rows, rows);
 | 
			
		||||
  VectorType v1 = VectorType::Random(rows),
 | 
			
		||||
             v2 = VectorType::Random(rows),
 | 
			
		||||
             v3 = VectorType::Random(rows),
 | 
			
		||||
             vzero = VectorType::Zero(rows);
 | 
			
		||||
 | 
			
		||||
  Scalar s1 = internal::random<Scalar>(),
 | 
			
		||||
         s2 = internal::random<Scalar>();
 | 
			
		||||
 | 
			
		||||
  // check basic compatibility of adjoint, transpose, conjugate
 | 
			
		||||
  VERIFY_IS_APPROX(m1.transpose().conjugate().adjoint(),    m1);
 | 
			
		||||
  VERIFY_IS_APPROX(m1.adjoint().conjugate().transpose(),    m1);
 | 
			
		||||
 | 
			
		||||
  // check multiplicative behavior
 | 
			
		||||
  VERIFY_IS_APPROX((m1.adjoint() * m2).adjoint(),           m2.adjoint() * m1);
 | 
			
		||||
  VERIFY_IS_APPROX((s1 * m1).adjoint(),                     numext::conj(s1) * m1.adjoint());
 | 
			
		||||
 | 
			
		||||
  // check basic properties of dot, squaredNorm
 | 
			
		||||
  VERIFY_IS_APPROX(numext::conj(v1.dot(v2)),               v2.dot(v1));
 | 
			
		||||
  VERIFY_IS_APPROX(numext::real(v1.dot(v1)),               v1.squaredNorm());
 | 
			
		||||
  
 | 
			
		||||
  adjoint_specific<NumTraits<Scalar>::IsInteger>::run(v1, v2, v3, square, s1, s2);
 | 
			
		||||
  
 | 
			
		||||
  VERIFY_IS_MUCH_SMALLER_THAN(abs(vzero.dot(v1)),  static_cast<RealScalar>(1));
 | 
			
		||||
  
 | 
			
		||||
  // like in testBasicStuff, test operator() to check const-qualification
 | 
			
		||||
  Index r = internal::random<Index>(0, rows-1),
 | 
			
		||||
      c = internal::random<Index>(0, cols-1);
 | 
			
		||||
  VERIFY_IS_APPROX(m1.conjugate()(r,c), numext::conj(m1(r,c)));
 | 
			
		||||
  VERIFY_IS_APPROX(m1.adjoint()(c,r), numext::conj(m1(r,c)));
 | 
			
		||||
 | 
			
		||||
  // check inplace transpose
 | 
			
		||||
  m3 = m1;
 | 
			
		||||
  m3.transposeInPlace();
 | 
			
		||||
  VERIFY_IS_APPROX(m3,m1.transpose());
 | 
			
		||||
  m3.transposeInPlace();
 | 
			
		||||
  VERIFY_IS_APPROX(m3,m1);
 | 
			
		||||
  
 | 
			
		||||
  if(PacketSize<m3.rows() && PacketSize<m3.cols())
 | 
			
		||||
  {
 | 
			
		||||
    m3 = m1;
 | 
			
		||||
    Index i = internal::random<Index>(0,m3.rows()-PacketSize);
 | 
			
		||||
    Index j = internal::random<Index>(0,m3.cols()-PacketSize);
 | 
			
		||||
    m3.template block<PacketSize,PacketSize>(i,j).transposeInPlace();
 | 
			
		||||
    VERIFY_IS_APPROX( (m3.template block<PacketSize,PacketSize>(i,j)), (m1.template block<PacketSize,PacketSize>(i,j).transpose()) );
 | 
			
		||||
    m3.template block<PacketSize,PacketSize>(i,j).transposeInPlace();
 | 
			
		||||
    VERIFY_IS_APPROX(m3,m1);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // check inplace adjoint
 | 
			
		||||
  m3 = m1;
 | 
			
		||||
  m3.adjointInPlace();
 | 
			
		||||
  VERIFY_IS_APPROX(m3,m1.adjoint());
 | 
			
		||||
  m3.transposeInPlace();
 | 
			
		||||
  VERIFY_IS_APPROX(m3,m1.conjugate());
 | 
			
		||||
 | 
			
		||||
  // check mixed dot product
 | 
			
		||||
  typedef Matrix<RealScalar, MatrixType::RowsAtCompileTime, 1> RealVectorType;
 | 
			
		||||
  RealVectorType rv1 = RealVectorType::Random(rows);
 | 
			
		||||
  VERIFY_IS_APPROX(v1.dot(rv1.template cast<Scalar>()), v1.dot(rv1));
 | 
			
		||||
  VERIFY_IS_APPROX(rv1.template cast<Scalar>().dot(v1), rv1.dot(v1));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_adjoint()
 | 
			
		||||
{
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_1( adjoint(Matrix<float, 1, 1>()) );
 | 
			
		||||
    CALL_SUBTEST_2( adjoint(Matrix3d()) );
 | 
			
		||||
    CALL_SUBTEST_3( adjoint(Matrix4f()) );
 | 
			
		||||
    
 | 
			
		||||
    CALL_SUBTEST_4( adjoint(MatrixXcf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2), internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2))) );
 | 
			
		||||
    CALL_SUBTEST_5( adjoint(MatrixXi(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
    CALL_SUBTEST_6( adjoint(MatrixXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
    
 | 
			
		||||
    // Complement for 128 bits vectorization:
 | 
			
		||||
    CALL_SUBTEST_8( adjoint(Matrix2d()) );
 | 
			
		||||
    CALL_SUBTEST_9( adjoint(Matrix<int,4,4>()) );
 | 
			
		||||
    
 | 
			
		||||
    // 256 bits vectorization:
 | 
			
		||||
    CALL_SUBTEST_10( adjoint(Matrix<float,8,8>()) );
 | 
			
		||||
    CALL_SUBTEST_11( adjoint(Matrix<double,4,4>()) );
 | 
			
		||||
    CALL_SUBTEST_12( adjoint(Matrix<int,8,8>()) );
 | 
			
		||||
  }
 | 
			
		||||
  // test a large static matrix only once
 | 
			
		||||
  CALL_SUBTEST_7( adjoint(Matrix<float, 100, 100>()) );
 | 
			
		||||
 | 
			
		||||
#ifdef EIGEN_TEST_PART_13
 | 
			
		||||
  {
 | 
			
		||||
    MatrixXcf a(10,10), b(10,10);
 | 
			
		||||
    VERIFY_RAISES_ASSERT(a = a.transpose());
 | 
			
		||||
    VERIFY_RAISES_ASSERT(a = a.transpose() + b);
 | 
			
		||||
    VERIFY_RAISES_ASSERT(a = b + a.transpose());
 | 
			
		||||
    VERIFY_RAISES_ASSERT(a = a.conjugate().transpose());
 | 
			
		||||
    VERIFY_RAISES_ASSERT(a = a.adjoint());
 | 
			
		||||
    VERIFY_RAISES_ASSERT(a = a.adjoint() + b);
 | 
			
		||||
    VERIFY_RAISES_ASSERT(a = b + a.adjoint());
 | 
			
		||||
 | 
			
		||||
    // no assertion should be triggered for these cases:
 | 
			
		||||
    a.transpose() = a.transpose();
 | 
			
		||||
    a.transpose() += a.transpose();
 | 
			
		||||
    a.transpose() += a.transpose() + b;
 | 
			
		||||
    a.transpose() = a.adjoint();
 | 
			
		||||
    a.transpose() += a.adjoint();
 | 
			
		||||
    a.transpose() += a.adjoint() + b;
 | 
			
		||||
 | 
			
		||||
    // regression tests for check_for_aliasing
 | 
			
		||||
    MatrixXd c(10,10);
 | 
			
		||||
    c = 1.0 * MatrixXd::Ones(10,10) + c;
 | 
			
		||||
    c = MatrixXd::Ones(10,10) * 1.0 + c;
 | 
			
		||||
    c = c + MatrixXd::Ones(10,10) .cwiseProduct( MatrixXd::Zero(10,10) );
 | 
			
		||||
    c = MatrixXd::Ones(10,10) * MatrixXd::Zero(10,10);
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										490
									
								
								cs440-acg/ext/eigen/test/array_cwise.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										490
									
								
								cs440-acg/ext/eigen/test/array_cwise.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,490 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
 | 
			
		||||
template<typename ArrayType> void array(const ArrayType& m)
 | 
			
		||||
{
 | 
			
		||||
  typedef typename ArrayType::Scalar Scalar;
 | 
			
		||||
  typedef typename ArrayType::RealScalar RealScalar;
 | 
			
		||||
  typedef Array<Scalar, ArrayType::RowsAtCompileTime, 1> ColVectorType;
 | 
			
		||||
  typedef Array<Scalar, 1, ArrayType::ColsAtCompileTime> RowVectorType;
 | 
			
		||||
 | 
			
		||||
  Index rows = m.rows();
 | 
			
		||||
  Index cols = m.cols(); 
 | 
			
		||||
 | 
			
		||||
  ArrayType m1 = ArrayType::Random(rows, cols),
 | 
			
		||||
             m2 = ArrayType::Random(rows, cols),
 | 
			
		||||
             m3(rows, cols);
 | 
			
		||||
  ArrayType m4 = m1; // copy constructor
 | 
			
		||||
  VERIFY_IS_APPROX(m1, m4);
 | 
			
		||||
 | 
			
		||||
  ColVectorType cv1 = ColVectorType::Random(rows);
 | 
			
		||||
  RowVectorType rv1 = RowVectorType::Random(cols);
 | 
			
		||||
 | 
			
		||||
  Scalar  s1 = internal::random<Scalar>(),
 | 
			
		||||
          s2 = internal::random<Scalar>();
 | 
			
		||||
 | 
			
		||||
  // scalar addition
 | 
			
		||||
  VERIFY_IS_APPROX(m1 + s1, s1 + m1);
 | 
			
		||||
  VERIFY_IS_APPROX(m1 + s1, ArrayType::Constant(rows,cols,s1) + m1);
 | 
			
		||||
  VERIFY_IS_APPROX(s1 - m1, (-m1)+s1 );
 | 
			
		||||
  VERIFY_IS_APPROX(m1 - s1, m1 - ArrayType::Constant(rows,cols,s1));
 | 
			
		||||
  VERIFY_IS_APPROX(s1 - m1, ArrayType::Constant(rows,cols,s1) - m1);
 | 
			
		||||
  VERIFY_IS_APPROX((m1*Scalar(2)) - s2, (m1+m1) - ArrayType::Constant(rows,cols,s2) );
 | 
			
		||||
  m3 = m1;
 | 
			
		||||
  m3 += s2;
 | 
			
		||||
  VERIFY_IS_APPROX(m3, m1 + s2);
 | 
			
		||||
  m3 = m1;
 | 
			
		||||
  m3 -= s1;
 | 
			
		||||
  VERIFY_IS_APPROX(m3, m1 - s1);  
 | 
			
		||||
  
 | 
			
		||||
  // scalar operators via Maps
 | 
			
		||||
  m3 = m1;
 | 
			
		||||
  ArrayType::Map(m1.data(), m1.rows(), m1.cols()) -= ArrayType::Map(m2.data(), m2.rows(), m2.cols());
 | 
			
		||||
  VERIFY_IS_APPROX(m1, m3 - m2);
 | 
			
		||||
  
 | 
			
		||||
  m3 = m1;
 | 
			
		||||
  ArrayType::Map(m1.data(), m1.rows(), m1.cols()) += ArrayType::Map(m2.data(), m2.rows(), m2.cols());
 | 
			
		||||
  VERIFY_IS_APPROX(m1, m3 + m2);
 | 
			
		||||
  
 | 
			
		||||
  m3 = m1;
 | 
			
		||||
  ArrayType::Map(m1.data(), m1.rows(), m1.cols()) *= ArrayType::Map(m2.data(), m2.rows(), m2.cols());
 | 
			
		||||
  VERIFY_IS_APPROX(m1, m3 * m2);
 | 
			
		||||
  
 | 
			
		||||
  m3 = m1;
 | 
			
		||||
  m2 = ArrayType::Random(rows,cols);
 | 
			
		||||
  m2 = (m2==0).select(1,m2);
 | 
			
		||||
  ArrayType::Map(m1.data(), m1.rows(), m1.cols()) /= ArrayType::Map(m2.data(), m2.rows(), m2.cols());  
 | 
			
		||||
  VERIFY_IS_APPROX(m1, m3 / m2);
 | 
			
		||||
 | 
			
		||||
  // reductions
 | 
			
		||||
  VERIFY_IS_APPROX(m1.abs().colwise().sum().sum(), m1.abs().sum());
 | 
			
		||||
  VERIFY_IS_APPROX(m1.abs().rowwise().sum().sum(), m1.abs().sum());
 | 
			
		||||
  using std::abs;
 | 
			
		||||
  VERIFY_IS_MUCH_SMALLER_THAN(abs(m1.colwise().sum().sum() - m1.sum()), m1.abs().sum());
 | 
			
		||||
  VERIFY_IS_MUCH_SMALLER_THAN(abs(m1.rowwise().sum().sum() - m1.sum()), m1.abs().sum());
 | 
			
		||||
  if (!internal::isMuchSmallerThan(abs(m1.sum() - (m1+m2).sum()), m1.abs().sum(), test_precision<Scalar>()))
 | 
			
		||||
      VERIFY_IS_NOT_APPROX(((m1+m2).rowwise().sum()).sum(), m1.sum());
 | 
			
		||||
  VERIFY_IS_APPROX(m1.colwise().sum(), m1.colwise().redux(internal::scalar_sum_op<Scalar,Scalar>()));
 | 
			
		||||
 | 
			
		||||
  // vector-wise ops
 | 
			
		||||
  m3 = m1;
 | 
			
		||||
  VERIFY_IS_APPROX(m3.colwise() += cv1, m1.colwise() + cv1);
 | 
			
		||||
  m3 = m1;
 | 
			
		||||
  VERIFY_IS_APPROX(m3.colwise() -= cv1, m1.colwise() - cv1);
 | 
			
		||||
  m3 = m1;
 | 
			
		||||
  VERIFY_IS_APPROX(m3.rowwise() += rv1, m1.rowwise() + rv1);
 | 
			
		||||
  m3 = m1;
 | 
			
		||||
  VERIFY_IS_APPROX(m3.rowwise() -= rv1, m1.rowwise() - rv1);
 | 
			
		||||
  
 | 
			
		||||
  // Conversion from scalar
 | 
			
		||||
  VERIFY_IS_APPROX((m3 = s1), ArrayType::Constant(rows,cols,s1));
 | 
			
		||||
  VERIFY_IS_APPROX((m3 = 1),  ArrayType::Constant(rows,cols,1));
 | 
			
		||||
  VERIFY_IS_APPROX((m3.topLeftCorner(rows,cols) = 1),  ArrayType::Constant(rows,cols,1));
 | 
			
		||||
  typedef Array<Scalar,
 | 
			
		||||
                ArrayType::RowsAtCompileTime==Dynamic?2:ArrayType::RowsAtCompileTime,
 | 
			
		||||
                ArrayType::ColsAtCompileTime==Dynamic?2:ArrayType::ColsAtCompileTime,
 | 
			
		||||
                ArrayType::Options> FixedArrayType;
 | 
			
		||||
  FixedArrayType f1(s1);
 | 
			
		||||
  VERIFY_IS_APPROX(f1, FixedArrayType::Constant(s1));
 | 
			
		||||
  FixedArrayType f2(numext::real(s1));
 | 
			
		||||
  VERIFY_IS_APPROX(f2, FixedArrayType::Constant(numext::real(s1)));
 | 
			
		||||
  FixedArrayType f3((int)100*numext::real(s1));
 | 
			
		||||
  VERIFY_IS_APPROX(f3, FixedArrayType::Constant((int)100*numext::real(s1)));
 | 
			
		||||
  f1.setRandom();
 | 
			
		||||
  FixedArrayType f4(f1.data());
 | 
			
		||||
  VERIFY_IS_APPROX(f4, f1);
 | 
			
		||||
  
 | 
			
		||||
  // pow
 | 
			
		||||
  VERIFY_IS_APPROX(m1.pow(2), m1.square());
 | 
			
		||||
  VERIFY_IS_APPROX(pow(m1,2), m1.square());
 | 
			
		||||
  VERIFY_IS_APPROX(m1.pow(3), m1.cube());
 | 
			
		||||
  VERIFY_IS_APPROX(pow(m1,3), m1.cube());
 | 
			
		||||
  VERIFY_IS_APPROX((-m1).pow(3), -m1.cube());
 | 
			
		||||
  VERIFY_IS_APPROX(pow(2*m1,3), 8*m1.cube());
 | 
			
		||||
  ArrayType exponents = ArrayType::Constant(rows, cols, RealScalar(2));
 | 
			
		||||
  VERIFY_IS_APPROX(Eigen::pow(m1,exponents), m1.square());
 | 
			
		||||
  VERIFY_IS_APPROX(m1.pow(exponents), m1.square());
 | 
			
		||||
  VERIFY_IS_APPROX(Eigen::pow(2*m1,exponents), 4*m1.square());
 | 
			
		||||
  VERIFY_IS_APPROX((2*m1).pow(exponents), 4*m1.square());
 | 
			
		||||
  VERIFY_IS_APPROX(Eigen::pow(m1,2*exponents), m1.square().square());
 | 
			
		||||
  VERIFY_IS_APPROX(m1.pow(2*exponents), m1.square().square());
 | 
			
		||||
  VERIFY_IS_APPROX(Eigen::pow(m1(0,0), exponents), ArrayType::Constant(rows,cols,m1(0,0)*m1(0,0)));
 | 
			
		||||
 | 
			
		||||
  // Check possible conflicts with 1D ctor
 | 
			
		||||
  typedef Array<Scalar, Dynamic, 1> OneDArrayType;
 | 
			
		||||
  OneDArrayType o1(rows);
 | 
			
		||||
  VERIFY(o1.size()==rows);
 | 
			
		||||
  OneDArrayType o4((int)rows);
 | 
			
		||||
  VERIFY(o4.size()==rows);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename ArrayType> void comparisons(const ArrayType& m)
 | 
			
		||||
{
 | 
			
		||||
  using std::abs;
 | 
			
		||||
  typedef typename ArrayType::Scalar Scalar;
 | 
			
		||||
  typedef typename NumTraits<Scalar>::Real RealScalar;
 | 
			
		||||
 | 
			
		||||
  Index rows = m.rows();
 | 
			
		||||
  Index cols = m.cols();
 | 
			
		||||
 | 
			
		||||
  Index r = internal::random<Index>(0, rows-1),
 | 
			
		||||
        c = internal::random<Index>(0, cols-1);
 | 
			
		||||
 | 
			
		||||
  ArrayType m1 = ArrayType::Random(rows, cols),
 | 
			
		||||
            m2 = ArrayType::Random(rows, cols),
 | 
			
		||||
            m3(rows, cols),
 | 
			
		||||
            m4 = m1;
 | 
			
		||||
  
 | 
			
		||||
  m4 = (m4.abs()==Scalar(0)).select(1,m4);
 | 
			
		||||
 | 
			
		||||
  VERIFY(((m1 + Scalar(1)) > m1).all());
 | 
			
		||||
  VERIFY(((m1 - Scalar(1)) < m1).all());
 | 
			
		||||
  if (rows*cols>1)
 | 
			
		||||
  {
 | 
			
		||||
    m3 = m1;
 | 
			
		||||
    m3(r,c) += 1;
 | 
			
		||||
    VERIFY(! (m1 < m3).all() );
 | 
			
		||||
    VERIFY(! (m1 > m3).all() );
 | 
			
		||||
  }
 | 
			
		||||
  VERIFY(!(m1 > m2 && m1 < m2).any());
 | 
			
		||||
  VERIFY((m1 <= m2 || m1 >= m2).all());
 | 
			
		||||
 | 
			
		||||
  // comparisons array to scalar
 | 
			
		||||
  VERIFY( (m1 != (m1(r,c)+1) ).any() );
 | 
			
		||||
  VERIFY( (m1 >  (m1(r,c)-1) ).any() );
 | 
			
		||||
  VERIFY( (m1 <  (m1(r,c)+1) ).any() );
 | 
			
		||||
  VERIFY( (m1 ==  m1(r,c)    ).any() );
 | 
			
		||||
 | 
			
		||||
  // comparisons scalar to array
 | 
			
		||||
  VERIFY( ( (m1(r,c)+1) != m1).any() );
 | 
			
		||||
  VERIFY( ( (m1(r,c)-1) <  m1).any() );
 | 
			
		||||
  VERIFY( ( (m1(r,c)+1) >  m1).any() );
 | 
			
		||||
  VERIFY( (  m1(r,c)    == m1).any() );
 | 
			
		||||
 | 
			
		||||
  // test Select
 | 
			
		||||
  VERIFY_IS_APPROX( (m1<m2).select(m1,m2), m1.cwiseMin(m2) );
 | 
			
		||||
  VERIFY_IS_APPROX( (m1>m2).select(m1,m2), m1.cwiseMax(m2) );
 | 
			
		||||
  Scalar mid = (m1.cwiseAbs().minCoeff() + m1.cwiseAbs().maxCoeff())/Scalar(2);
 | 
			
		||||
  for (int j=0; j<cols; ++j)
 | 
			
		||||
  for (int i=0; i<rows; ++i)
 | 
			
		||||
    m3(i,j) = abs(m1(i,j))<mid ? 0 : m1(i,j);
 | 
			
		||||
  VERIFY_IS_APPROX( (m1.abs()<ArrayType::Constant(rows,cols,mid))
 | 
			
		||||
                        .select(ArrayType::Zero(rows,cols),m1), m3);
 | 
			
		||||
  // shorter versions:
 | 
			
		||||
  VERIFY_IS_APPROX( (m1.abs()<ArrayType::Constant(rows,cols,mid))
 | 
			
		||||
                        .select(0,m1), m3);
 | 
			
		||||
  VERIFY_IS_APPROX( (m1.abs()>=ArrayType::Constant(rows,cols,mid))
 | 
			
		||||
                        .select(m1,0), m3);
 | 
			
		||||
  // even shorter version:
 | 
			
		||||
  VERIFY_IS_APPROX( (m1.abs()<mid).select(0,m1), m3);
 | 
			
		||||
 | 
			
		||||
  // count
 | 
			
		||||
  VERIFY(((m1.abs()+1)>RealScalar(0.1)).count() == rows*cols);
 | 
			
		||||
 | 
			
		||||
  // and/or
 | 
			
		||||
  VERIFY( (m1<RealScalar(0) && m1>RealScalar(0)).count() == 0);
 | 
			
		||||
  VERIFY( (m1<RealScalar(0) || m1>=RealScalar(0)).count() == rows*cols);
 | 
			
		||||
  RealScalar a = m1.abs().mean();
 | 
			
		||||
  VERIFY( (m1<-a || m1>a).count() == (m1.abs()>a).count());
 | 
			
		||||
 | 
			
		||||
  typedef Array<typename ArrayType::Index, Dynamic, 1> ArrayOfIndices;
 | 
			
		||||
 | 
			
		||||
  // TODO allows colwise/rowwise for array
 | 
			
		||||
  VERIFY_IS_APPROX(((m1.abs()+1)>RealScalar(0.1)).colwise().count(), ArrayOfIndices::Constant(cols,rows).transpose());
 | 
			
		||||
  VERIFY_IS_APPROX(((m1.abs()+1)>RealScalar(0.1)).rowwise().count(), ArrayOfIndices::Constant(rows, cols));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename ArrayType> void array_real(const ArrayType& m)
 | 
			
		||||
{
 | 
			
		||||
  using std::abs;
 | 
			
		||||
  using std::sqrt;
 | 
			
		||||
  typedef typename ArrayType::Scalar Scalar;
 | 
			
		||||
  typedef typename NumTraits<Scalar>::Real RealScalar;
 | 
			
		||||
 | 
			
		||||
  Index rows = m.rows();
 | 
			
		||||
  Index cols = m.cols();
 | 
			
		||||
 | 
			
		||||
  ArrayType m1 = ArrayType::Random(rows, cols),
 | 
			
		||||
            m2 = ArrayType::Random(rows, cols),
 | 
			
		||||
            m3(rows, cols),
 | 
			
		||||
            m4 = m1;
 | 
			
		||||
 | 
			
		||||
  m4 = (m4.abs()==Scalar(0)).select(1,m4);
 | 
			
		||||
 | 
			
		||||
  Scalar  s1 = internal::random<Scalar>();
 | 
			
		||||
 | 
			
		||||
  // these tests are mostly to check possible compilation issues with free-functions.
 | 
			
		||||
  VERIFY_IS_APPROX(m1.sin(), sin(m1));
 | 
			
		||||
  VERIFY_IS_APPROX(m1.cos(), cos(m1));
 | 
			
		||||
  VERIFY_IS_APPROX(m1.tan(), tan(m1));
 | 
			
		||||
  VERIFY_IS_APPROX(m1.asin(), asin(m1));
 | 
			
		||||
  VERIFY_IS_APPROX(m1.acos(), acos(m1));
 | 
			
		||||
  VERIFY_IS_APPROX(m1.atan(), atan(m1));
 | 
			
		||||
  VERIFY_IS_APPROX(m1.sinh(), sinh(m1));
 | 
			
		||||
  VERIFY_IS_APPROX(m1.cosh(), cosh(m1));
 | 
			
		||||
  VERIFY_IS_APPROX(m1.tanh(), tanh(m1));
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(m1.arg(), arg(m1));
 | 
			
		||||
  VERIFY_IS_APPROX(m1.round(), round(m1));
 | 
			
		||||
  VERIFY_IS_APPROX(m1.floor(), floor(m1));
 | 
			
		||||
  VERIFY_IS_APPROX(m1.ceil(), ceil(m1));
 | 
			
		||||
  VERIFY((m1.isNaN() == (Eigen::isnan)(m1)).all());
 | 
			
		||||
  VERIFY((m1.isInf() == (Eigen::isinf)(m1)).all());
 | 
			
		||||
  VERIFY((m1.isFinite() == (Eigen::isfinite)(m1)).all());
 | 
			
		||||
  VERIFY_IS_APPROX(m1.inverse(), inverse(m1));
 | 
			
		||||
  VERIFY_IS_APPROX(m1.abs(), abs(m1));
 | 
			
		||||
  VERIFY_IS_APPROX(m1.abs2(), abs2(m1));
 | 
			
		||||
  VERIFY_IS_APPROX(m1.square(), square(m1));
 | 
			
		||||
  VERIFY_IS_APPROX(m1.cube(), cube(m1));
 | 
			
		||||
  VERIFY_IS_APPROX(cos(m1+RealScalar(3)*m2), cos((m1+RealScalar(3)*m2).eval()));
 | 
			
		||||
  VERIFY_IS_APPROX(m1.sign(), sign(m1));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  // avoid NaNs with abs() so verification doesn't fail
 | 
			
		||||
  m3 = m1.abs();
 | 
			
		||||
  VERIFY_IS_APPROX(m3.sqrt(), sqrt(abs(m1)));
 | 
			
		||||
  VERIFY_IS_APPROX(m3.rsqrt(), Scalar(1)/sqrt(abs(m1)));
 | 
			
		||||
  VERIFY_IS_APPROX(rsqrt(m3), Scalar(1)/sqrt(abs(m1)));
 | 
			
		||||
  VERIFY_IS_APPROX(m3.log(), log(m3));
 | 
			
		||||
  VERIFY_IS_APPROX(m3.log1p(), log1p(m3));
 | 
			
		||||
  VERIFY_IS_APPROX(m3.log10(), log10(m3));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  VERIFY((!(m1>m2) == (m1<=m2)).all());
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(sin(m1.asin()), m1);
 | 
			
		||||
  VERIFY_IS_APPROX(cos(m1.acos()), m1);
 | 
			
		||||
  VERIFY_IS_APPROX(tan(m1.atan()), m1);
 | 
			
		||||
  VERIFY_IS_APPROX(sinh(m1), 0.5*(exp(m1)-exp(-m1)));
 | 
			
		||||
  VERIFY_IS_APPROX(cosh(m1), 0.5*(exp(m1)+exp(-m1)));
 | 
			
		||||
  VERIFY_IS_APPROX(tanh(m1), (0.5*(exp(m1)-exp(-m1)))/(0.5*(exp(m1)+exp(-m1))));
 | 
			
		||||
  VERIFY_IS_APPROX(arg(m1), ((m1<0).template cast<Scalar>())*std::acos(-1.0));
 | 
			
		||||
  VERIFY((round(m1) <= ceil(m1) && round(m1) >= floor(m1)).all());
 | 
			
		||||
  VERIFY((Eigen::isnan)((m1*0.0)/0.0).all());
 | 
			
		||||
  VERIFY((Eigen::isinf)(m4/0.0).all());
 | 
			
		||||
  VERIFY(((Eigen::isfinite)(m1) && (!(Eigen::isfinite)(m1*0.0/0.0)) && (!(Eigen::isfinite)(m4/0.0))).all());
 | 
			
		||||
  VERIFY_IS_APPROX(inverse(inverse(m1)),m1);
 | 
			
		||||
  VERIFY((abs(m1) == m1 || abs(m1) == -m1).all());
 | 
			
		||||
  VERIFY_IS_APPROX(m3, sqrt(abs2(m1)));
 | 
			
		||||
  VERIFY_IS_APPROX( m1.sign(), -(-m1).sign() );
 | 
			
		||||
  VERIFY_IS_APPROX( m1*m1.sign(),m1.abs());
 | 
			
		||||
  VERIFY_IS_APPROX(m1.sign() * m1.abs(), m1);
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(numext::abs2(numext::real(m1)) + numext::abs2(numext::imag(m1)), numext::abs2(m1));
 | 
			
		||||
  VERIFY_IS_APPROX(numext::abs2(Eigen::real(m1)) + numext::abs2(Eigen::imag(m1)), numext::abs2(m1));
 | 
			
		||||
  if(!NumTraits<Scalar>::IsComplex)
 | 
			
		||||
    VERIFY_IS_APPROX(numext::real(m1), m1);
 | 
			
		||||
 | 
			
		||||
  // shift argument of logarithm so that it is not zero
 | 
			
		||||
  Scalar smallNumber = NumTraits<Scalar>::dummy_precision();
 | 
			
		||||
  VERIFY_IS_APPROX((m3 + smallNumber).log() , log(abs(m1) + smallNumber));
 | 
			
		||||
  VERIFY_IS_APPROX((m3 + smallNumber + 1).log() , log1p(abs(m1) + smallNumber));
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(m1.exp() * m2.exp(), exp(m1+m2));
 | 
			
		||||
  VERIFY_IS_APPROX(m1.exp(), exp(m1));
 | 
			
		||||
  VERIFY_IS_APPROX(m1.exp() / m2.exp(),(m1-m2).exp());
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(m3.pow(RealScalar(0.5)), m3.sqrt());
 | 
			
		||||
  VERIFY_IS_APPROX(pow(m3,RealScalar(0.5)), m3.sqrt());
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(m3.pow(RealScalar(-0.5)), m3.rsqrt());
 | 
			
		||||
  VERIFY_IS_APPROX(pow(m3,RealScalar(-0.5)), m3.rsqrt());
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(log10(m3), log(m3)/log(10));
 | 
			
		||||
 | 
			
		||||
  // scalar by array division
 | 
			
		||||
  const RealScalar tiny = sqrt(std::numeric_limits<RealScalar>::epsilon());
 | 
			
		||||
  s1 += Scalar(tiny);
 | 
			
		||||
  m1 += ArrayType::Constant(rows,cols,Scalar(tiny));
 | 
			
		||||
  VERIFY_IS_APPROX(s1/m1, s1 * m1.inverse());
 | 
			
		||||
 | 
			
		||||
  // check inplace transpose
 | 
			
		||||
  m3 = m1;
 | 
			
		||||
  m3.transposeInPlace();
 | 
			
		||||
  VERIFY_IS_APPROX(m3, m1.transpose());
 | 
			
		||||
  m3.transposeInPlace();
 | 
			
		||||
  VERIFY_IS_APPROX(m3, m1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename ArrayType> void array_complex(const ArrayType& m)
 | 
			
		||||
{
 | 
			
		||||
  typedef typename ArrayType::Scalar Scalar;
 | 
			
		||||
  typedef typename NumTraits<Scalar>::Real RealScalar;
 | 
			
		||||
 | 
			
		||||
  Index rows = m.rows();
 | 
			
		||||
  Index cols = m.cols();
 | 
			
		||||
 | 
			
		||||
  ArrayType m1 = ArrayType::Random(rows, cols),
 | 
			
		||||
            m2(rows, cols),
 | 
			
		||||
            m4 = m1;
 | 
			
		||||
  
 | 
			
		||||
  m4.real() = (m4.real().abs()==RealScalar(0)).select(RealScalar(1),m4.real());
 | 
			
		||||
  m4.imag() = (m4.imag().abs()==RealScalar(0)).select(RealScalar(1),m4.imag());
 | 
			
		||||
 | 
			
		||||
  Array<RealScalar, -1, -1> m3(rows, cols);
 | 
			
		||||
 | 
			
		||||
  for (Index i = 0; i < m.rows(); ++i)
 | 
			
		||||
    for (Index j = 0; j < m.cols(); ++j)
 | 
			
		||||
      m2(i,j) = sqrt(m1(i,j));
 | 
			
		||||
 | 
			
		||||
  // these tests are mostly to check possible compilation issues with free-functions.
 | 
			
		||||
  VERIFY_IS_APPROX(m1.sin(), sin(m1));
 | 
			
		||||
  VERIFY_IS_APPROX(m1.cos(), cos(m1));
 | 
			
		||||
  VERIFY_IS_APPROX(m1.tan(), tan(m1));
 | 
			
		||||
  VERIFY_IS_APPROX(m1.sinh(), sinh(m1));
 | 
			
		||||
  VERIFY_IS_APPROX(m1.cosh(), cosh(m1));
 | 
			
		||||
  VERIFY_IS_APPROX(m1.tanh(), tanh(m1));
 | 
			
		||||
  VERIFY_IS_APPROX(m1.arg(), arg(m1));
 | 
			
		||||
  VERIFY((m1.isNaN() == (Eigen::isnan)(m1)).all());
 | 
			
		||||
  VERIFY((m1.isInf() == (Eigen::isinf)(m1)).all());
 | 
			
		||||
  VERIFY((m1.isFinite() == (Eigen::isfinite)(m1)).all());
 | 
			
		||||
  VERIFY_IS_APPROX(m1.inverse(), inverse(m1));
 | 
			
		||||
  VERIFY_IS_APPROX(m1.log(), log(m1));
 | 
			
		||||
  VERIFY_IS_APPROX(m1.log10(), log10(m1));
 | 
			
		||||
  VERIFY_IS_APPROX(m1.abs(), abs(m1));
 | 
			
		||||
  VERIFY_IS_APPROX(m1.abs2(), abs2(m1));
 | 
			
		||||
  VERIFY_IS_APPROX(m1.sqrt(), sqrt(m1));
 | 
			
		||||
  VERIFY_IS_APPROX(m1.square(), square(m1));
 | 
			
		||||
  VERIFY_IS_APPROX(m1.cube(), cube(m1));
 | 
			
		||||
  VERIFY_IS_APPROX(cos(m1+RealScalar(3)*m2), cos((m1+RealScalar(3)*m2).eval()));
 | 
			
		||||
  VERIFY_IS_APPROX(m1.sign(), sign(m1));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(m1.exp() * m2.exp(), exp(m1+m2));
 | 
			
		||||
  VERIFY_IS_APPROX(m1.exp(), exp(m1));
 | 
			
		||||
  VERIFY_IS_APPROX(m1.exp() / m2.exp(),(m1-m2).exp());
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(sinh(m1), 0.5*(exp(m1)-exp(-m1)));
 | 
			
		||||
  VERIFY_IS_APPROX(cosh(m1), 0.5*(exp(m1)+exp(-m1)));
 | 
			
		||||
  VERIFY_IS_APPROX(tanh(m1), (0.5*(exp(m1)-exp(-m1)))/(0.5*(exp(m1)+exp(-m1))));
 | 
			
		||||
 | 
			
		||||
  for (Index i = 0; i < m.rows(); ++i)
 | 
			
		||||
    for (Index j = 0; j < m.cols(); ++j)
 | 
			
		||||
      m3(i,j) = std::atan2(m1(i,j).imag(), m1(i,j).real());
 | 
			
		||||
  VERIFY_IS_APPROX(arg(m1), m3);
 | 
			
		||||
 | 
			
		||||
  std::complex<RealScalar> zero(0.0,0.0);
 | 
			
		||||
  VERIFY((Eigen::isnan)(m1*zero/zero).all());
 | 
			
		||||
#if EIGEN_COMP_MSVC
 | 
			
		||||
  // msvc complex division is not robust
 | 
			
		||||
  VERIFY((Eigen::isinf)(m4/RealScalar(0)).all());
 | 
			
		||||
#else
 | 
			
		||||
#if EIGEN_COMP_CLANG
 | 
			
		||||
  // clang's complex division is notoriously broken too
 | 
			
		||||
  if((numext::isinf)(m4(0,0)/RealScalar(0))) {
 | 
			
		||||
#endif
 | 
			
		||||
    VERIFY((Eigen::isinf)(m4/zero).all());
 | 
			
		||||
#if EIGEN_COMP_CLANG
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    VERIFY((Eigen::isinf)(m4.real()/zero.real()).all());
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
#endif // MSVC
 | 
			
		||||
 | 
			
		||||
  VERIFY(((Eigen::isfinite)(m1) && (!(Eigen::isfinite)(m1*zero/zero)) && (!(Eigen::isfinite)(m1/zero))).all());
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(inverse(inverse(m1)),m1);
 | 
			
		||||
  VERIFY_IS_APPROX(conj(m1.conjugate()), m1);
 | 
			
		||||
  VERIFY_IS_APPROX(abs(m1), sqrt(square(m1.real())+square(m1.imag())));
 | 
			
		||||
  VERIFY_IS_APPROX(abs(m1), sqrt(abs2(m1)));
 | 
			
		||||
  VERIFY_IS_APPROX(log10(m1), log(m1)/log(10));
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX( m1.sign(), -(-m1).sign() );
 | 
			
		||||
  VERIFY_IS_APPROX( m1.sign() * m1.abs(), m1);
 | 
			
		||||
 | 
			
		||||
  // scalar by array division
 | 
			
		||||
  Scalar  s1 = internal::random<Scalar>();
 | 
			
		||||
  const RealScalar tiny = std::sqrt(std::numeric_limits<RealScalar>::epsilon());
 | 
			
		||||
  s1 += Scalar(tiny);
 | 
			
		||||
  m1 += ArrayType::Constant(rows,cols,Scalar(tiny));
 | 
			
		||||
  VERIFY_IS_APPROX(s1/m1, s1 * m1.inverse());
 | 
			
		||||
 | 
			
		||||
  // check inplace transpose
 | 
			
		||||
  m2 = m1;
 | 
			
		||||
  m2.transposeInPlace();
 | 
			
		||||
  VERIFY_IS_APPROX(m2, m1.transpose());
 | 
			
		||||
  m2.transposeInPlace();
 | 
			
		||||
  VERIFY_IS_APPROX(m2, m1);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename ArrayType> void min_max(const ArrayType& m)
 | 
			
		||||
{
 | 
			
		||||
  typedef typename ArrayType::Scalar Scalar;
 | 
			
		||||
 | 
			
		||||
  Index rows = m.rows();
 | 
			
		||||
  Index cols = m.cols();
 | 
			
		||||
 | 
			
		||||
  ArrayType m1 = ArrayType::Random(rows, cols);
 | 
			
		||||
 | 
			
		||||
  // min/max with array
 | 
			
		||||
  Scalar maxM1 = m1.maxCoeff();
 | 
			
		||||
  Scalar minM1 = m1.minCoeff();
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(ArrayType::Constant(rows,cols, minM1), (m1.min)(ArrayType::Constant(rows,cols, minM1)));
 | 
			
		||||
  VERIFY_IS_APPROX(m1, (m1.min)(ArrayType::Constant(rows,cols, maxM1)));
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(ArrayType::Constant(rows,cols, maxM1), (m1.max)(ArrayType::Constant(rows,cols, maxM1)));
 | 
			
		||||
  VERIFY_IS_APPROX(m1, (m1.max)(ArrayType::Constant(rows,cols, minM1)));
 | 
			
		||||
 | 
			
		||||
  // min/max with scalar input
 | 
			
		||||
  VERIFY_IS_APPROX(ArrayType::Constant(rows,cols, minM1), (m1.min)( minM1));
 | 
			
		||||
  VERIFY_IS_APPROX(m1, (m1.min)( maxM1));
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(ArrayType::Constant(rows,cols, maxM1), (m1.max)( maxM1));
 | 
			
		||||
  VERIFY_IS_APPROX(m1, (m1.max)( minM1));
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_array_cwise()
 | 
			
		||||
{
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_1( array(Array<float, 1, 1>()) );
 | 
			
		||||
    CALL_SUBTEST_2( array(Array22f()) );
 | 
			
		||||
    CALL_SUBTEST_3( array(Array44d()) );
 | 
			
		||||
    CALL_SUBTEST_4( array(ArrayXXcf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
    CALL_SUBTEST_5( array(ArrayXXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
    CALL_SUBTEST_6( array(ArrayXXi(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
  }
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_1( comparisons(Array<float, 1, 1>()) );
 | 
			
		||||
    CALL_SUBTEST_2( comparisons(Array22f()) );
 | 
			
		||||
    CALL_SUBTEST_3( comparisons(Array44d()) );
 | 
			
		||||
    CALL_SUBTEST_5( comparisons(ArrayXXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
    CALL_SUBTEST_6( comparisons(ArrayXXi(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
  }
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_1( min_max(Array<float, 1, 1>()) );
 | 
			
		||||
    CALL_SUBTEST_2( min_max(Array22f()) );
 | 
			
		||||
    CALL_SUBTEST_3( min_max(Array44d()) );
 | 
			
		||||
    CALL_SUBTEST_5( min_max(ArrayXXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
    CALL_SUBTEST_6( min_max(ArrayXXi(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
  }
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_1( array_real(Array<float, 1, 1>()) );
 | 
			
		||||
    CALL_SUBTEST_2( array_real(Array22f()) );
 | 
			
		||||
    CALL_SUBTEST_3( array_real(Array44d()) );
 | 
			
		||||
    CALL_SUBTEST_5( array_real(ArrayXXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
  }
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_4( array_complex(ArrayXXcf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  VERIFY((internal::is_same< internal::global_math_functions_filtering_base<int>::type, int >::value));
 | 
			
		||||
  VERIFY((internal::is_same< internal::global_math_functions_filtering_base<float>::type, float >::value));
 | 
			
		||||
  VERIFY((internal::is_same< internal::global_math_functions_filtering_base<Array2i>::type, ArrayBase<Array2i> >::value));
 | 
			
		||||
  typedef CwiseUnaryOp<internal::scalar_abs_op<double>, ArrayXd > Xpr;
 | 
			
		||||
  VERIFY((internal::is_same< internal::global_math_functions_filtering_base<Xpr>::type,
 | 
			
		||||
                           ArrayBase<Xpr>
 | 
			
		||||
                         >::value));
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										300
									
								
								cs440-acg/ext/eigen/test/array_for_matrix.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										300
									
								
								cs440-acg/ext/eigen/test/array_for_matrix.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,300 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void array_for_matrix(const MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> ColVectorType;
 | 
			
		||||
  typedef Matrix<Scalar, 1, MatrixType::ColsAtCompileTime> RowVectorType; 
 | 
			
		||||
 | 
			
		||||
  Index rows = m.rows();
 | 
			
		||||
  Index cols = m.cols();
 | 
			
		||||
 | 
			
		||||
  MatrixType m1 = MatrixType::Random(rows, cols),
 | 
			
		||||
             m2 = MatrixType::Random(rows, cols),
 | 
			
		||||
             m3(rows, cols);
 | 
			
		||||
 | 
			
		||||
  ColVectorType cv1 = ColVectorType::Random(rows);
 | 
			
		||||
  RowVectorType rv1 = RowVectorType::Random(cols);
 | 
			
		||||
  
 | 
			
		||||
  Scalar  s1 = internal::random<Scalar>(),
 | 
			
		||||
          s2 = internal::random<Scalar>();
 | 
			
		||||
          
 | 
			
		||||
  // scalar addition
 | 
			
		||||
  VERIFY_IS_APPROX(m1.array() + s1, s1 + m1.array());
 | 
			
		||||
  VERIFY_IS_APPROX((m1.array() + s1).matrix(), MatrixType::Constant(rows,cols,s1) + m1);
 | 
			
		||||
  VERIFY_IS_APPROX(((m1*Scalar(2)).array() - s2).matrix(), (m1+m1) - MatrixType::Constant(rows,cols,s2) );
 | 
			
		||||
  m3 = m1;
 | 
			
		||||
  m3.array() += s2;
 | 
			
		||||
  VERIFY_IS_APPROX(m3, (m1.array() + s2).matrix());
 | 
			
		||||
  m3 = m1;
 | 
			
		||||
  m3.array() -= s1;
 | 
			
		||||
  VERIFY_IS_APPROX(m3, (m1.array() - s1).matrix());
 | 
			
		||||
 | 
			
		||||
  // reductions
 | 
			
		||||
  VERIFY_IS_MUCH_SMALLER_THAN(m1.colwise().sum().sum() - m1.sum(), m1.squaredNorm());
 | 
			
		||||
  VERIFY_IS_MUCH_SMALLER_THAN(m1.rowwise().sum().sum() - m1.sum(), m1.squaredNorm());
 | 
			
		||||
  VERIFY_IS_MUCH_SMALLER_THAN(m1.colwise().sum() + m2.colwise().sum() - (m1+m2).colwise().sum(), (m1+m2).squaredNorm());
 | 
			
		||||
  VERIFY_IS_MUCH_SMALLER_THAN(m1.rowwise().sum() - m2.rowwise().sum() - (m1-m2).rowwise().sum(), (m1-m2).squaredNorm());
 | 
			
		||||
  VERIFY_IS_APPROX(m1.colwise().sum(), m1.colwise().redux(internal::scalar_sum_op<Scalar,Scalar>()));
 | 
			
		||||
 | 
			
		||||
  // vector-wise ops
 | 
			
		||||
  m3 = m1;
 | 
			
		||||
  VERIFY_IS_APPROX(m3.colwise() += cv1, m1.colwise() + cv1);
 | 
			
		||||
  m3 = m1;
 | 
			
		||||
  VERIFY_IS_APPROX(m3.colwise() -= cv1, m1.colwise() - cv1);
 | 
			
		||||
  m3 = m1;
 | 
			
		||||
  VERIFY_IS_APPROX(m3.rowwise() += rv1, m1.rowwise() + rv1);
 | 
			
		||||
  m3 = m1;
 | 
			
		||||
  VERIFY_IS_APPROX(m3.rowwise() -= rv1, m1.rowwise() - rv1);
 | 
			
		||||
  
 | 
			
		||||
  // empty objects
 | 
			
		||||
  VERIFY_IS_APPROX(m1.block(0,0,0,cols).colwise().sum(),  RowVectorType::Zero(cols));
 | 
			
		||||
  VERIFY_IS_APPROX(m1.block(0,0,rows,0).rowwise().prod(), ColVectorType::Ones(rows));
 | 
			
		||||
  
 | 
			
		||||
  // verify the const accessors exist
 | 
			
		||||
  const Scalar& ref_m1 = m.matrix().array().coeffRef(0);
 | 
			
		||||
  const Scalar& ref_m2 = m.matrix().array().coeffRef(0,0);
 | 
			
		||||
  const Scalar& ref_a1 = m.array().matrix().coeffRef(0);
 | 
			
		||||
  const Scalar& ref_a2 = m.array().matrix().coeffRef(0,0);
 | 
			
		||||
  VERIFY(&ref_a1 == &ref_m1);
 | 
			
		||||
  VERIFY(&ref_a2 == &ref_m2);
 | 
			
		||||
 | 
			
		||||
  // Check write accessors:
 | 
			
		||||
  m1.array().coeffRef(0,0) = 1;
 | 
			
		||||
  VERIFY_IS_APPROX(m1(0,0),Scalar(1));
 | 
			
		||||
  m1.array()(0,0) = 2;
 | 
			
		||||
  VERIFY_IS_APPROX(m1(0,0),Scalar(2));
 | 
			
		||||
  m1.array().matrix().coeffRef(0,0) = 3;
 | 
			
		||||
  VERIFY_IS_APPROX(m1(0,0),Scalar(3));
 | 
			
		||||
  m1.array().matrix()(0,0) = 4;
 | 
			
		||||
  VERIFY_IS_APPROX(m1(0,0),Scalar(4));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void comparisons(const MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  using std::abs;
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
  typedef typename NumTraits<Scalar>::Real RealScalar;
 | 
			
		||||
 | 
			
		||||
  Index rows = m.rows();
 | 
			
		||||
  Index cols = m.cols();
 | 
			
		||||
 | 
			
		||||
  Index r = internal::random<Index>(0, rows-1),
 | 
			
		||||
        c = internal::random<Index>(0, cols-1);
 | 
			
		||||
 | 
			
		||||
  MatrixType m1 = MatrixType::Random(rows, cols),
 | 
			
		||||
             m2 = MatrixType::Random(rows, cols),
 | 
			
		||||
             m3(rows, cols);
 | 
			
		||||
 | 
			
		||||
  VERIFY(((m1.array() + Scalar(1)) > m1.array()).all());
 | 
			
		||||
  VERIFY(((m1.array() - Scalar(1)) < m1.array()).all());
 | 
			
		||||
  if (rows*cols>1)
 | 
			
		||||
  {
 | 
			
		||||
    m3 = m1;
 | 
			
		||||
    m3(r,c) += 1;
 | 
			
		||||
    VERIFY(! (m1.array() < m3.array()).all() );
 | 
			
		||||
    VERIFY(! (m1.array() > m3.array()).all() );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // comparisons to scalar
 | 
			
		||||
  VERIFY( (m1.array() != (m1(r,c)+1) ).any() );
 | 
			
		||||
  VERIFY( (m1.array() > (m1(r,c)-1) ).any() );
 | 
			
		||||
  VERIFY( (m1.array() < (m1(r,c)+1) ).any() );
 | 
			
		||||
  VERIFY( (m1.array() == m1(r,c) ).any() );
 | 
			
		||||
  VERIFY( m1.cwiseEqual(m1(r,c)).any() );
 | 
			
		||||
 | 
			
		||||
  // test Select
 | 
			
		||||
  VERIFY_IS_APPROX( (m1.array()<m2.array()).select(m1,m2), m1.cwiseMin(m2) );
 | 
			
		||||
  VERIFY_IS_APPROX( (m1.array()>m2.array()).select(m1,m2), m1.cwiseMax(m2) );
 | 
			
		||||
  Scalar mid = (m1.cwiseAbs().minCoeff() + m1.cwiseAbs().maxCoeff())/Scalar(2);
 | 
			
		||||
  for (int j=0; j<cols; ++j)
 | 
			
		||||
  for (int i=0; i<rows; ++i)
 | 
			
		||||
    m3(i,j) = abs(m1(i,j))<mid ? 0 : m1(i,j);
 | 
			
		||||
  VERIFY_IS_APPROX( (m1.array().abs()<MatrixType::Constant(rows,cols,mid).array())
 | 
			
		||||
                        .select(MatrixType::Zero(rows,cols),m1), m3);
 | 
			
		||||
  // shorter versions:
 | 
			
		||||
  VERIFY_IS_APPROX( (m1.array().abs()<MatrixType::Constant(rows,cols,mid).array())
 | 
			
		||||
                        .select(0,m1), m3);
 | 
			
		||||
  VERIFY_IS_APPROX( (m1.array().abs()>=MatrixType::Constant(rows,cols,mid).array())
 | 
			
		||||
                        .select(m1,0), m3);
 | 
			
		||||
  // even shorter version:
 | 
			
		||||
  VERIFY_IS_APPROX( (m1.array().abs()<mid).select(0,m1), m3);
 | 
			
		||||
 | 
			
		||||
  // count
 | 
			
		||||
  VERIFY(((m1.array().abs()+1)>RealScalar(0.1)).count() == rows*cols);
 | 
			
		||||
 | 
			
		||||
  // and/or
 | 
			
		||||
  VERIFY( ((m1.array()<RealScalar(0)).matrix() && (m1.array()>RealScalar(0)).matrix()).count() == 0);
 | 
			
		||||
  VERIFY( ((m1.array()<RealScalar(0)).matrix() || (m1.array()>=RealScalar(0)).matrix()).count() == rows*cols);
 | 
			
		||||
  RealScalar a = m1.cwiseAbs().mean();
 | 
			
		||||
  VERIFY( ((m1.array()<-a).matrix() || (m1.array()>a).matrix()).count() == (m1.cwiseAbs().array()>a).count());
 | 
			
		||||
 | 
			
		||||
  typedef Matrix<typename MatrixType::Index, Dynamic, 1> VectorOfIndices;
 | 
			
		||||
 | 
			
		||||
  // TODO allows colwise/rowwise for array
 | 
			
		||||
  VERIFY_IS_APPROX(((m1.array().abs()+1)>RealScalar(0.1)).matrix().colwise().count(), VectorOfIndices::Constant(cols,rows).transpose());
 | 
			
		||||
  VERIFY_IS_APPROX(((m1.array().abs()+1)>RealScalar(0.1)).matrix().rowwise().count(), VectorOfIndices::Constant(rows, cols));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename VectorType> void lpNorm(const VectorType& v)
 | 
			
		||||
{
 | 
			
		||||
  using std::sqrt;
 | 
			
		||||
  typedef typename VectorType::RealScalar RealScalar;
 | 
			
		||||
  VectorType u = VectorType::Random(v.size());
 | 
			
		||||
 | 
			
		||||
  if(v.size()==0)
 | 
			
		||||
  {
 | 
			
		||||
    VERIFY_IS_APPROX(u.template lpNorm<Infinity>(), RealScalar(0));
 | 
			
		||||
    VERIFY_IS_APPROX(u.template lpNorm<1>(), RealScalar(0));
 | 
			
		||||
    VERIFY_IS_APPROX(u.template lpNorm<2>(), RealScalar(0));
 | 
			
		||||
    VERIFY_IS_APPROX(u.template lpNorm<5>(), RealScalar(0));
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    VERIFY_IS_APPROX(u.template lpNorm<Infinity>(), u.cwiseAbs().maxCoeff());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(u.template lpNorm<1>(), u.cwiseAbs().sum());
 | 
			
		||||
  VERIFY_IS_APPROX(u.template lpNorm<2>(), sqrt(u.array().abs().square().sum()));
 | 
			
		||||
  VERIFY_IS_APPROX(numext::pow(u.template lpNorm<5>(), typename VectorType::RealScalar(5)), u.array().abs().pow(5).sum());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void cwise_min_max(const MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
 | 
			
		||||
  Index rows = m.rows();
 | 
			
		||||
  Index cols = m.cols();
 | 
			
		||||
 | 
			
		||||
  MatrixType m1 = MatrixType::Random(rows, cols);
 | 
			
		||||
 | 
			
		||||
  // min/max with array
 | 
			
		||||
  Scalar maxM1 = m1.maxCoeff();
 | 
			
		||||
  Scalar minM1 = m1.minCoeff();
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(MatrixType::Constant(rows,cols, minM1), m1.cwiseMin(MatrixType::Constant(rows,cols, minM1)));
 | 
			
		||||
  VERIFY_IS_APPROX(m1, m1.cwiseMin(MatrixType::Constant(rows,cols, maxM1)));
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(MatrixType::Constant(rows,cols, maxM1), m1.cwiseMax(MatrixType::Constant(rows,cols, maxM1)));
 | 
			
		||||
  VERIFY_IS_APPROX(m1, m1.cwiseMax(MatrixType::Constant(rows,cols, minM1)));
 | 
			
		||||
 | 
			
		||||
  // min/max with scalar input
 | 
			
		||||
  VERIFY_IS_APPROX(MatrixType::Constant(rows,cols, minM1), m1.cwiseMin( minM1));
 | 
			
		||||
  VERIFY_IS_APPROX(m1, m1.cwiseMin(maxM1));
 | 
			
		||||
  VERIFY_IS_APPROX(-m1, (-m1).cwiseMin(-minM1));
 | 
			
		||||
  VERIFY_IS_APPROX(-m1.array(), ((-m1).array().min)( -minM1));
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(MatrixType::Constant(rows,cols, maxM1), m1.cwiseMax( maxM1));
 | 
			
		||||
  VERIFY_IS_APPROX(m1, m1.cwiseMax(minM1));
 | 
			
		||||
  VERIFY_IS_APPROX(-m1, (-m1).cwiseMax(-maxM1));
 | 
			
		||||
  VERIFY_IS_APPROX(-m1.array(), ((-m1).array().max)(-maxM1));
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(MatrixType::Constant(rows,cols, minM1).array(), (m1.array().min)( minM1));
 | 
			
		||||
  VERIFY_IS_APPROX(m1.array(), (m1.array().min)( maxM1));
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(MatrixType::Constant(rows,cols, maxM1).array(), (m1.array().max)( maxM1));
 | 
			
		||||
  VERIFY_IS_APPROX(m1.array(), (m1.array().max)( minM1));
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename MatrixTraits> void resize(const MatrixTraits& t)
 | 
			
		||||
{
 | 
			
		||||
  typedef typename MatrixTraits::Scalar Scalar;
 | 
			
		||||
  typedef Matrix<Scalar,Dynamic,Dynamic> MatrixType;
 | 
			
		||||
  typedef Array<Scalar,Dynamic,Dynamic> Array2DType;
 | 
			
		||||
  typedef Matrix<Scalar,Dynamic,1> VectorType;
 | 
			
		||||
  typedef Array<Scalar,Dynamic,1> Array1DType;
 | 
			
		||||
 | 
			
		||||
  Index rows = t.rows(), cols = t.cols();
 | 
			
		||||
 | 
			
		||||
  MatrixType m(rows,cols);
 | 
			
		||||
  VectorType v(rows);
 | 
			
		||||
  Array2DType a2(rows,cols);
 | 
			
		||||
  Array1DType a1(rows);
 | 
			
		||||
 | 
			
		||||
  m.array().resize(rows+1,cols+1);
 | 
			
		||||
  VERIFY(m.rows()==rows+1 && m.cols()==cols+1);
 | 
			
		||||
  a2.matrix().resize(rows+1,cols+1);
 | 
			
		||||
  VERIFY(a2.rows()==rows+1 && a2.cols()==cols+1);
 | 
			
		||||
  v.array().resize(cols);
 | 
			
		||||
  VERIFY(v.size()==cols);
 | 
			
		||||
  a1.matrix().resize(cols);
 | 
			
		||||
  VERIFY(a1.size()==cols);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<int>
 | 
			
		||||
void regression_bug_654()
 | 
			
		||||
{
 | 
			
		||||
  ArrayXf a = RowVectorXf(3);
 | 
			
		||||
  VectorXf v = Array<float,1,Dynamic>(3);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Check propagation of LvalueBit through Array/Matrix-Wrapper
 | 
			
		||||
template<int>
 | 
			
		||||
void regrrssion_bug_1410()
 | 
			
		||||
{
 | 
			
		||||
  const Matrix4i M;
 | 
			
		||||
  const Array4i A;
 | 
			
		||||
  ArrayWrapper<const Matrix4i> MA = M.array();
 | 
			
		||||
  MA.row(0);
 | 
			
		||||
  MatrixWrapper<const Array4i> AM = A.matrix();
 | 
			
		||||
  AM.row(0);
 | 
			
		||||
 | 
			
		||||
  VERIFY((internal::traits<ArrayWrapper<const Matrix4i> >::Flags&LvalueBit)==0);
 | 
			
		||||
  VERIFY((internal::traits<MatrixWrapper<const Array4i> >::Flags&LvalueBit)==0);
 | 
			
		||||
 | 
			
		||||
  VERIFY((internal::traits<ArrayWrapper<Matrix4i> >::Flags&LvalueBit)==LvalueBit);
 | 
			
		||||
  VERIFY((internal::traits<MatrixWrapper<Array4i> >::Flags&LvalueBit)==LvalueBit);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_array_for_matrix()
 | 
			
		||||
{
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_1( array_for_matrix(Matrix<float, 1, 1>()) );
 | 
			
		||||
    CALL_SUBTEST_2( array_for_matrix(Matrix2f()) );
 | 
			
		||||
    CALL_SUBTEST_3( array_for_matrix(Matrix4d()) );
 | 
			
		||||
    CALL_SUBTEST_4( array_for_matrix(MatrixXcf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
    CALL_SUBTEST_5( array_for_matrix(MatrixXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
    CALL_SUBTEST_6( array_for_matrix(MatrixXi(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
  }
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_1( comparisons(Matrix<float, 1, 1>()) );
 | 
			
		||||
    CALL_SUBTEST_2( comparisons(Matrix2f()) );
 | 
			
		||||
    CALL_SUBTEST_3( comparisons(Matrix4d()) );
 | 
			
		||||
    CALL_SUBTEST_5( comparisons(MatrixXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
    CALL_SUBTEST_6( comparisons(MatrixXi(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
  }
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_1( cwise_min_max(Matrix<float, 1, 1>()) );
 | 
			
		||||
    CALL_SUBTEST_2( cwise_min_max(Matrix2f()) );
 | 
			
		||||
    CALL_SUBTEST_3( cwise_min_max(Matrix4d()) );
 | 
			
		||||
    CALL_SUBTEST_5( cwise_min_max(MatrixXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
    CALL_SUBTEST_6( cwise_min_max(MatrixXi(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
  }
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_1( lpNorm(Matrix<float, 1, 1>()) );
 | 
			
		||||
    CALL_SUBTEST_2( lpNorm(Vector2f()) );
 | 
			
		||||
    CALL_SUBTEST_7( lpNorm(Vector3d()) );
 | 
			
		||||
    CALL_SUBTEST_8( lpNorm(Vector4f()) );
 | 
			
		||||
    CALL_SUBTEST_5( lpNorm(VectorXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
    CALL_SUBTEST_4( lpNorm(VectorXcf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
  }
 | 
			
		||||
  CALL_SUBTEST_5( lpNorm(VectorXf(0)) );
 | 
			
		||||
  CALL_SUBTEST_4( lpNorm(VectorXcf(0)) );
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_4( resize(MatrixXcf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
    CALL_SUBTEST_5( resize(MatrixXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
    CALL_SUBTEST_6( resize(MatrixXi(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
  }
 | 
			
		||||
  CALL_SUBTEST_6( regression_bug_654<0>() );
 | 
			
		||||
  CALL_SUBTEST_6( regrrssion_bug_1410<0>() );
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										32
									
								
								cs440-acg/ext/eigen/test/array_of_string.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								cs440-acg/ext/eigen/test/array_of_string.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,32 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2016 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
 | 
			
		||||
void test_array_of_string()
 | 
			
		||||
{
 | 
			
		||||
  typedef Array<std::string,1,Dynamic> ArrayXs;
 | 
			
		||||
  ArrayXs a1(3), a2(3), a3(3), a3ref(3);
 | 
			
		||||
  a1 << "one", "two", "three";
 | 
			
		||||
  a2 << "1", "2", "3";
 | 
			
		||||
  a3ref << "one (1)", "two (2)", "three (3)";
 | 
			
		||||
  std::stringstream s1;
 | 
			
		||||
  s1 << a1;
 | 
			
		||||
  VERIFY_IS_EQUAL(s1.str(), std::string("  one    two  three"));
 | 
			
		||||
  a3 = a1 + std::string(" (") + a2 + std::string(")");
 | 
			
		||||
  VERIFY((a3==a3ref).all());
 | 
			
		||||
 | 
			
		||||
  a3 = a1;
 | 
			
		||||
  a3 += std::string(" (") + a2 + std::string(")");
 | 
			
		||||
  VERIFY((a3==a3ref).all());
 | 
			
		||||
 | 
			
		||||
  a1.swap(a3);
 | 
			
		||||
  VERIFY((a1==a3ref).all());
 | 
			
		||||
  VERIFY((a3!=a3ref).all());
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										81
									
								
								cs440-acg/ext/eigen/test/array_replicate.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								cs440-acg/ext/eigen/test/array_replicate.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,81 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void replicate(const MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  /* this test covers the following files:
 | 
			
		||||
     Replicate.cpp
 | 
			
		||||
  */
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;
 | 
			
		||||
  typedef Matrix<Scalar, Dynamic, Dynamic> MatrixX;
 | 
			
		||||
  typedef Matrix<Scalar, Dynamic, 1> VectorX;
 | 
			
		||||
 | 
			
		||||
  Index rows = m.rows();
 | 
			
		||||
  Index cols = m.cols();
 | 
			
		||||
 | 
			
		||||
  MatrixType m1 = MatrixType::Random(rows, cols),
 | 
			
		||||
             m2 = MatrixType::Random(rows, cols);
 | 
			
		||||
 | 
			
		||||
  VectorType v1 = VectorType::Random(rows);
 | 
			
		||||
 | 
			
		||||
  MatrixX x1, x2;
 | 
			
		||||
  VectorX vx1;
 | 
			
		||||
 | 
			
		||||
  int  f1 = internal::random<int>(1,10),
 | 
			
		||||
       f2 = internal::random<int>(1,10);
 | 
			
		||||
 | 
			
		||||
  x1.resize(rows*f1,cols*f2);
 | 
			
		||||
  for(int j=0; j<f2; j++)
 | 
			
		||||
  for(int i=0; i<f1; i++)
 | 
			
		||||
    x1.block(i*rows,j*cols,rows,cols) = m1;
 | 
			
		||||
  VERIFY_IS_APPROX(x1, m1.replicate(f1,f2));
 | 
			
		||||
 | 
			
		||||
  x2.resize(2*rows,3*cols);
 | 
			
		||||
  x2 << m2, m2, m2,
 | 
			
		||||
        m2, m2, m2;
 | 
			
		||||
  VERIFY_IS_APPROX(x2, (m2.template replicate<2,3>()));
 | 
			
		||||
  
 | 
			
		||||
  x2.resize(rows,3*cols);
 | 
			
		||||
  x2 << m2, m2, m2;
 | 
			
		||||
  VERIFY_IS_APPROX(x2, (m2.template replicate<1,3>()));
 | 
			
		||||
  
 | 
			
		||||
  vx1.resize(3*rows,cols);
 | 
			
		||||
  vx1 << m2, m2, m2;
 | 
			
		||||
  VERIFY_IS_APPROX(vx1+vx1, vx1+(m2.template replicate<3,1>()));
 | 
			
		||||
  
 | 
			
		||||
  vx1=m2+(m2.colwise().replicate(1));
 | 
			
		||||
  
 | 
			
		||||
  if(m2.cols()==1)
 | 
			
		||||
    VERIFY_IS_APPROX(m2.coeff(0), (m2.template replicate<3,1>().coeff(m2.rows())));
 | 
			
		||||
 | 
			
		||||
  x2.resize(rows,f1);
 | 
			
		||||
  for (int j=0; j<f1; ++j)
 | 
			
		||||
    x2.col(j) = v1;
 | 
			
		||||
  VERIFY_IS_APPROX(x2, v1.rowwise().replicate(f1));
 | 
			
		||||
 | 
			
		||||
  vx1.resize(rows*f2);
 | 
			
		||||
  for (int j=0; j<f2; ++j)
 | 
			
		||||
    vx1.segment(j*rows,rows) = v1;
 | 
			
		||||
  VERIFY_IS_APPROX(vx1, v1.colwise().replicate(f2));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_array_replicate()
 | 
			
		||||
{
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_1( replicate(Matrix<float, 1, 1>()) );
 | 
			
		||||
    CALL_SUBTEST_2( replicate(Vector2f()) );
 | 
			
		||||
    CALL_SUBTEST_3( replicate(Vector3d()) );
 | 
			
		||||
    CALL_SUBTEST_4( replicate(Vector4f()) );
 | 
			
		||||
    CALL_SUBTEST_5( replicate(VectorXf(16)) );
 | 
			
		||||
    CALL_SUBTEST_6( replicate(VectorXcd(10)) );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										145
									
								
								cs440-acg/ext/eigen/test/array_reverse.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								cs440-acg/ext/eigen/test/array_reverse.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,145 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
 | 
			
		||||
// Copyright (C) 2009 Ricard Marxer <email@ricardmarxer.com>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
#include <iostream>
 | 
			
		||||
 | 
			
		||||
using namespace std;
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void reverse(const MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;
 | 
			
		||||
 | 
			
		||||
  Index rows = m.rows();
 | 
			
		||||
  Index cols = m.cols();
 | 
			
		||||
 | 
			
		||||
  // this test relies a lot on Random.h, and there's not much more that we can do
 | 
			
		||||
  // to test it, hence I consider that we will have tested Random.h
 | 
			
		||||
  MatrixType m1 = MatrixType::Random(rows, cols), m2;
 | 
			
		||||
  VectorType v1 = VectorType::Random(rows);
 | 
			
		||||
 | 
			
		||||
  MatrixType m1_r = m1.reverse();
 | 
			
		||||
  // Verify that MatrixBase::reverse() works
 | 
			
		||||
  for ( int i = 0; i < rows; i++ ) {
 | 
			
		||||
    for ( int j = 0; j < cols; j++ ) {
 | 
			
		||||
      VERIFY_IS_APPROX(m1_r(i, j), m1(rows - 1 - i, cols - 1 - j));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Reverse<MatrixType> m1_rd(m1);
 | 
			
		||||
  // Verify that a Reverse default (in both directions) of an expression works
 | 
			
		||||
  for ( int i = 0; i < rows; i++ ) {
 | 
			
		||||
    for ( int j = 0; j < cols; j++ ) {
 | 
			
		||||
      VERIFY_IS_APPROX(m1_rd(i, j), m1(rows - 1 - i, cols - 1 - j));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Reverse<MatrixType, BothDirections> m1_rb(m1);
 | 
			
		||||
  // Verify that a Reverse in both directions of an expression works
 | 
			
		||||
  for ( int i = 0; i < rows; i++ ) {
 | 
			
		||||
    for ( int j = 0; j < cols; j++ ) {
 | 
			
		||||
      VERIFY_IS_APPROX(m1_rb(i, j), m1(rows - 1 - i, cols - 1 - j));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Reverse<MatrixType, Vertical> m1_rv(m1);
 | 
			
		||||
  // Verify that a Reverse in the vertical directions of an expression works
 | 
			
		||||
  for ( int i = 0; i < rows; i++ ) {
 | 
			
		||||
    for ( int j = 0; j < cols; j++ ) {
 | 
			
		||||
      VERIFY_IS_APPROX(m1_rv(i, j), m1(rows - 1 - i, j));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Reverse<MatrixType, Horizontal> m1_rh(m1);
 | 
			
		||||
  // Verify that a Reverse in the horizontal directions of an expression works
 | 
			
		||||
  for ( int i = 0; i < rows; i++ ) {
 | 
			
		||||
    for ( int j = 0; j < cols; j++ ) {
 | 
			
		||||
      VERIFY_IS_APPROX(m1_rh(i, j), m1(i, cols - 1 - j));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  VectorType v1_r = v1.reverse();
 | 
			
		||||
  // Verify that a VectorType::reverse() of an expression works
 | 
			
		||||
  for ( int i = 0; i < rows; i++ ) {
 | 
			
		||||
    VERIFY_IS_APPROX(v1_r(i), v1(rows - 1 - i));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  MatrixType m1_cr = m1.colwise().reverse();
 | 
			
		||||
  // Verify that PartialRedux::reverse() works (for colwise())
 | 
			
		||||
  for ( int i = 0; i < rows; i++ ) {
 | 
			
		||||
    for ( int j = 0; j < cols; j++ ) {
 | 
			
		||||
      VERIFY_IS_APPROX(m1_cr(i, j), m1(rows - 1 - i, j));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  MatrixType m1_rr = m1.rowwise().reverse();
 | 
			
		||||
  // Verify that PartialRedux::reverse() works (for rowwise())
 | 
			
		||||
  for ( int i = 0; i < rows; i++ ) {
 | 
			
		||||
    for ( int j = 0; j < cols; j++ ) {
 | 
			
		||||
      VERIFY_IS_APPROX(m1_rr(i, j), m1(i, cols - 1 - j));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Scalar x = internal::random<Scalar>();
 | 
			
		||||
 | 
			
		||||
  Index r = internal::random<Index>(0, rows-1),
 | 
			
		||||
        c = internal::random<Index>(0, cols-1);
 | 
			
		||||
 | 
			
		||||
  m1.reverse()(r, c) = x;
 | 
			
		||||
  VERIFY_IS_APPROX(x, m1(rows - 1 - r, cols - 1 - c));
 | 
			
		||||
  
 | 
			
		||||
  m2 = m1;
 | 
			
		||||
  m2.reverseInPlace();
 | 
			
		||||
  VERIFY_IS_APPROX(m2,m1.reverse().eval());
 | 
			
		||||
  
 | 
			
		||||
  m2 = m1;
 | 
			
		||||
  m2.col(0).reverseInPlace();
 | 
			
		||||
  VERIFY_IS_APPROX(m2.col(0),m1.col(0).reverse().eval());
 | 
			
		||||
  
 | 
			
		||||
  m2 = m1;
 | 
			
		||||
  m2.row(0).reverseInPlace();
 | 
			
		||||
  VERIFY_IS_APPROX(m2.row(0),m1.row(0).reverse().eval());
 | 
			
		||||
  
 | 
			
		||||
  m2 = m1;
 | 
			
		||||
  m2.rowwise().reverseInPlace();
 | 
			
		||||
  VERIFY_IS_APPROX(m2,m1.rowwise().reverse().eval());
 | 
			
		||||
  
 | 
			
		||||
  m2 = m1;
 | 
			
		||||
  m2.colwise().reverseInPlace();
 | 
			
		||||
  VERIFY_IS_APPROX(m2,m1.colwise().reverse().eval());
 | 
			
		||||
 | 
			
		||||
  m1.colwise().reverse()(r, c) = x;
 | 
			
		||||
  VERIFY_IS_APPROX(x, m1(rows - 1 - r, c));
 | 
			
		||||
 | 
			
		||||
  m1.rowwise().reverse()(r, c) = x;
 | 
			
		||||
  VERIFY_IS_APPROX(x, m1(r, cols - 1 - c));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_array_reverse()
 | 
			
		||||
{
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_1( reverse(Matrix<float, 1, 1>()) );
 | 
			
		||||
    CALL_SUBTEST_2( reverse(Matrix2f()) );
 | 
			
		||||
    CALL_SUBTEST_3( reverse(Matrix4f()) );
 | 
			
		||||
    CALL_SUBTEST_4( reverse(Matrix4d()) );
 | 
			
		||||
    CALL_SUBTEST_5( reverse(MatrixXcf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
    CALL_SUBTEST_6( reverse(MatrixXi(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
    CALL_SUBTEST_7( reverse(MatrixXcd(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
    CALL_SUBTEST_8( reverse(Matrix<float, 100, 100>()) );
 | 
			
		||||
    CALL_SUBTEST_9( reverse(Matrix<float,Dynamic,Dynamic,RowMajor>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
  }
 | 
			
		||||
#ifdef EIGEN_TEST_PART_3
 | 
			
		||||
  Vector4f x; x << 1, 2, 3, 4;
 | 
			
		||||
  Vector4f y; y << 4, 3, 2, 1;
 | 
			
		||||
  VERIFY(x.reverse()[1] == 3);
 | 
			
		||||
  VERIFY(x.reverse() == y);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										71
									
								
								cs440-acg/ext/eigen/test/bandmatrix.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								cs440-acg/ext/eigen/test/bandmatrix.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,71 @@
 | 
			
		||||
// This file is triangularView of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void bandmatrix(const MatrixType& _m)
 | 
			
		||||
{
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
  typedef typename NumTraits<Scalar>::Real RealScalar;
 | 
			
		||||
  typedef Matrix<Scalar,Dynamic,Dynamic> DenseMatrixType;
 | 
			
		||||
 | 
			
		||||
  Index rows = _m.rows();
 | 
			
		||||
  Index cols = _m.cols();
 | 
			
		||||
  Index supers = _m.supers();
 | 
			
		||||
  Index subs = _m.subs();
 | 
			
		||||
 | 
			
		||||
  MatrixType m(rows,cols,supers,subs);
 | 
			
		||||
 | 
			
		||||
  DenseMatrixType dm1(rows,cols);
 | 
			
		||||
  dm1.setZero();
 | 
			
		||||
 | 
			
		||||
  m.diagonal().setConstant(123);
 | 
			
		||||
  dm1.diagonal().setConstant(123);
 | 
			
		||||
  for (int i=1; i<=m.supers();++i)
 | 
			
		||||
  {
 | 
			
		||||
    m.diagonal(i).setConstant(static_cast<RealScalar>(i));
 | 
			
		||||
    dm1.diagonal(i).setConstant(static_cast<RealScalar>(i));
 | 
			
		||||
  }
 | 
			
		||||
  for (int i=1; i<=m.subs();++i)
 | 
			
		||||
  {
 | 
			
		||||
    m.diagonal(-i).setConstant(-static_cast<RealScalar>(i));
 | 
			
		||||
    dm1.diagonal(-i).setConstant(-static_cast<RealScalar>(i));
 | 
			
		||||
  }
 | 
			
		||||
  //std::cerr << m.m_data << "\n\n" << m.toDense() << "\n\n" << dm1 << "\n\n\n\n";
 | 
			
		||||
  VERIFY_IS_APPROX(dm1,m.toDenseMatrix());
 | 
			
		||||
 | 
			
		||||
  for (int i=0; i<cols; ++i)
 | 
			
		||||
  {
 | 
			
		||||
    m.col(i).setConstant(static_cast<RealScalar>(i+1));
 | 
			
		||||
    dm1.col(i).setConstant(static_cast<RealScalar>(i+1));
 | 
			
		||||
  }
 | 
			
		||||
  Index d = (std::min)(rows,cols);
 | 
			
		||||
  Index a = std::max<Index>(0,cols-d-supers);
 | 
			
		||||
  Index b = std::max<Index>(0,rows-d-subs);
 | 
			
		||||
  if(a>0) dm1.block(0,d+supers,rows,a).setZero();
 | 
			
		||||
  dm1.block(0,supers+1,cols-supers-1-a,cols-supers-1-a).template triangularView<Upper>().setZero();
 | 
			
		||||
  dm1.block(subs+1,0,rows-subs-1-b,rows-subs-1-b).template triangularView<Lower>().setZero();
 | 
			
		||||
  if(b>0) dm1.block(d+subs,0,b,cols).setZero();
 | 
			
		||||
  //std::cerr << m.m_data << "\n\n" << m.toDense() << "\n\n" << dm1 << "\n\n";
 | 
			
		||||
  VERIFY_IS_APPROX(dm1,m.toDenseMatrix());
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
using Eigen::internal::BandMatrix;
 | 
			
		||||
 | 
			
		||||
void test_bandmatrix()
 | 
			
		||||
{
 | 
			
		||||
  for(int i = 0; i < 10*g_repeat ; i++) {
 | 
			
		||||
    Index rows = internal::random<Index>(1,10);
 | 
			
		||||
    Index cols = internal::random<Index>(1,10);
 | 
			
		||||
    Index sups = internal::random<Index>(0,cols-1);
 | 
			
		||||
    Index subs = internal::random<Index>(0,rows-1);
 | 
			
		||||
    CALL_SUBTEST(bandmatrix(BandMatrix<float>(rows,cols,sups,subs)) );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										278
									
								
								cs440-acg/ext/eigen/test/basicstuff.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										278
									
								
								cs440-acg/ext/eigen/test/basicstuff.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,278 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#define EIGEN_NO_STATIC_ASSERT
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void basicStuff(const MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;
 | 
			
		||||
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> SquareMatrixType;
 | 
			
		||||
 | 
			
		||||
  Index rows = m.rows();
 | 
			
		||||
  Index cols = m.cols();
 | 
			
		||||
 | 
			
		||||
  // this test relies a lot on Random.h, and there's not much more that we can do
 | 
			
		||||
  // to test it, hence I consider that we will have tested Random.h
 | 
			
		||||
  MatrixType m1 = MatrixType::Random(rows, cols),
 | 
			
		||||
             m2 = MatrixType::Random(rows, cols),
 | 
			
		||||
             m3(rows, cols),
 | 
			
		||||
             mzero = MatrixType::Zero(rows, cols),
 | 
			
		||||
             square = Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime>::Random(rows, rows);
 | 
			
		||||
  VectorType v1 = VectorType::Random(rows),
 | 
			
		||||
             vzero = VectorType::Zero(rows);
 | 
			
		||||
  SquareMatrixType sm1 = SquareMatrixType::Random(rows,rows), sm2(rows,rows);
 | 
			
		||||
 | 
			
		||||
  Scalar x = 0;
 | 
			
		||||
  while(x == Scalar(0)) x = internal::random<Scalar>();
 | 
			
		||||
 | 
			
		||||
  Index r = internal::random<Index>(0, rows-1),
 | 
			
		||||
        c = internal::random<Index>(0, cols-1);
 | 
			
		||||
 | 
			
		||||
  m1.coeffRef(r,c) = x;
 | 
			
		||||
  VERIFY_IS_APPROX(x, m1.coeff(r,c));
 | 
			
		||||
  m1(r,c) = x;
 | 
			
		||||
  VERIFY_IS_APPROX(x, m1(r,c));
 | 
			
		||||
  v1.coeffRef(r) = x;
 | 
			
		||||
  VERIFY_IS_APPROX(x, v1.coeff(r));
 | 
			
		||||
  v1(r) = x;
 | 
			
		||||
  VERIFY_IS_APPROX(x, v1(r));
 | 
			
		||||
  v1[r] = x;
 | 
			
		||||
  VERIFY_IS_APPROX(x, v1[r]);
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(               v1,    v1);
 | 
			
		||||
  VERIFY_IS_NOT_APPROX(           v1,    2*v1);
 | 
			
		||||
  VERIFY_IS_MUCH_SMALLER_THAN(    vzero, v1);
 | 
			
		||||
  VERIFY_IS_MUCH_SMALLER_THAN(  vzero, v1.squaredNorm());
 | 
			
		||||
  VERIFY_IS_NOT_MUCH_SMALLER_THAN(v1,    v1);
 | 
			
		||||
  VERIFY_IS_APPROX(               vzero, v1-v1);
 | 
			
		||||
  VERIFY_IS_APPROX(               m1,    m1);
 | 
			
		||||
  VERIFY_IS_NOT_APPROX(           m1,    2*m1);
 | 
			
		||||
  VERIFY_IS_MUCH_SMALLER_THAN(    mzero, m1);
 | 
			
		||||
  VERIFY_IS_NOT_MUCH_SMALLER_THAN(m1,    m1);
 | 
			
		||||
  VERIFY_IS_APPROX(               mzero, m1-m1);
 | 
			
		||||
 | 
			
		||||
  // always test operator() on each read-only expression class,
 | 
			
		||||
  // in order to check const-qualifiers.
 | 
			
		||||
  // indeed, if an expression class (here Zero) is meant to be read-only,
 | 
			
		||||
  // hence has no _write() method, the corresponding MatrixBase method (here zero())
 | 
			
		||||
  // should return a const-qualified object so that it is the const-qualified
 | 
			
		||||
  // operator() that gets called, which in turn calls _read().
 | 
			
		||||
  VERIFY_IS_MUCH_SMALLER_THAN(MatrixType::Zero(rows,cols)(r,c), static_cast<Scalar>(1));
 | 
			
		||||
 | 
			
		||||
  // now test copying a row-vector into a (column-)vector and conversely.
 | 
			
		||||
  square.col(r) = square.row(r).eval();
 | 
			
		||||
  Matrix<Scalar, 1, MatrixType::RowsAtCompileTime> rv(rows);
 | 
			
		||||
  Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> cv(rows);
 | 
			
		||||
  rv = square.row(r);
 | 
			
		||||
  cv = square.col(r);
 | 
			
		||||
  
 | 
			
		||||
  VERIFY_IS_APPROX(rv, cv.transpose());
 | 
			
		||||
 | 
			
		||||
  if(cols!=1 && rows!=1 && MatrixType::SizeAtCompileTime!=Dynamic)
 | 
			
		||||
  {
 | 
			
		||||
    VERIFY_RAISES_ASSERT(m1 = (m2.block(0,0, rows-1, cols-1)));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(cols!=1 && rows!=1)
 | 
			
		||||
  {
 | 
			
		||||
    VERIFY_RAISES_ASSERT(m1[0]);
 | 
			
		||||
    VERIFY_RAISES_ASSERT((m1+m1)[0]);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(m3 = m1,m1);
 | 
			
		||||
  MatrixType m4;
 | 
			
		||||
  VERIFY_IS_APPROX(m4 = m1,m1);
 | 
			
		||||
 | 
			
		||||
  m3.real() = m1.real();
 | 
			
		||||
  VERIFY_IS_APPROX(static_cast<const MatrixType&>(m3).real(), static_cast<const MatrixType&>(m1).real());
 | 
			
		||||
  VERIFY_IS_APPROX(static_cast<const MatrixType&>(m3).real(), m1.real());
 | 
			
		||||
 | 
			
		||||
  // check == / != operators
 | 
			
		||||
  VERIFY(m1==m1);
 | 
			
		||||
  VERIFY(m1!=m2);
 | 
			
		||||
  VERIFY(!(m1==m2));
 | 
			
		||||
  VERIFY(!(m1!=m1));
 | 
			
		||||
  m1 = m2;
 | 
			
		||||
  VERIFY(m1==m2);
 | 
			
		||||
  VERIFY(!(m1!=m2));
 | 
			
		||||
  
 | 
			
		||||
  // check automatic transposition
 | 
			
		||||
  sm2.setZero();
 | 
			
		||||
  for(typename MatrixType::Index i=0;i<rows;++i)
 | 
			
		||||
    sm2.col(i) = sm1.row(i);
 | 
			
		||||
  VERIFY_IS_APPROX(sm2,sm1.transpose());
 | 
			
		||||
  
 | 
			
		||||
  sm2.setZero();
 | 
			
		||||
  for(typename MatrixType::Index i=0;i<rows;++i)
 | 
			
		||||
    sm2.col(i).noalias() = sm1.row(i);
 | 
			
		||||
  VERIFY_IS_APPROX(sm2,sm1.transpose());
 | 
			
		||||
  
 | 
			
		||||
  sm2.setZero();
 | 
			
		||||
  for(typename MatrixType::Index i=0;i<rows;++i)
 | 
			
		||||
    sm2.col(i).noalias() += sm1.row(i);
 | 
			
		||||
  VERIFY_IS_APPROX(sm2,sm1.transpose());
 | 
			
		||||
  
 | 
			
		||||
  sm2.setZero();
 | 
			
		||||
  for(typename MatrixType::Index i=0;i<rows;++i)
 | 
			
		||||
    sm2.col(i).noalias() -= sm1.row(i);
 | 
			
		||||
  VERIFY_IS_APPROX(sm2,-sm1.transpose());
 | 
			
		||||
  
 | 
			
		||||
  // check ternary usage
 | 
			
		||||
  {
 | 
			
		||||
    bool b = internal::random<int>(0,10)>5;
 | 
			
		||||
    m3 = b ? m1 : m2;
 | 
			
		||||
    if(b) VERIFY_IS_APPROX(m3,m1);
 | 
			
		||||
    else  VERIFY_IS_APPROX(m3,m2);
 | 
			
		||||
    m3 = b ? -m1 : m2;
 | 
			
		||||
    if(b) VERIFY_IS_APPROX(m3,-m1);
 | 
			
		||||
    else  VERIFY_IS_APPROX(m3,m2);
 | 
			
		||||
    m3 = b ? m1 : -m2;
 | 
			
		||||
    if(b) VERIFY_IS_APPROX(m3,m1);
 | 
			
		||||
    else  VERIFY_IS_APPROX(m3,-m2);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void basicStuffComplex(const MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
  typedef typename NumTraits<Scalar>::Real RealScalar;
 | 
			
		||||
  typedef Matrix<RealScalar, MatrixType::RowsAtCompileTime, MatrixType::ColsAtCompileTime> RealMatrixType;
 | 
			
		||||
 | 
			
		||||
  Index rows = m.rows();
 | 
			
		||||
  Index cols = m.cols();
 | 
			
		||||
 | 
			
		||||
  Scalar s1 = internal::random<Scalar>(),
 | 
			
		||||
         s2 = internal::random<Scalar>();
 | 
			
		||||
 | 
			
		||||
  VERIFY(numext::real(s1)==numext::real_ref(s1));
 | 
			
		||||
  VERIFY(numext::imag(s1)==numext::imag_ref(s1));
 | 
			
		||||
  numext::real_ref(s1) = numext::real(s2);
 | 
			
		||||
  numext::imag_ref(s1) = numext::imag(s2);
 | 
			
		||||
  VERIFY(internal::isApprox(s1, s2, NumTraits<RealScalar>::epsilon()));
 | 
			
		||||
  // extended precision in Intel FPUs means that s1 == s2 in the line above is not guaranteed.
 | 
			
		||||
 | 
			
		||||
  RealMatrixType rm1 = RealMatrixType::Random(rows,cols),
 | 
			
		||||
                 rm2 = RealMatrixType::Random(rows,cols);
 | 
			
		||||
  MatrixType cm(rows,cols);
 | 
			
		||||
  cm.real() = rm1;
 | 
			
		||||
  cm.imag() = rm2;
 | 
			
		||||
  VERIFY_IS_APPROX(static_cast<const MatrixType&>(cm).real(), rm1);
 | 
			
		||||
  VERIFY_IS_APPROX(static_cast<const MatrixType&>(cm).imag(), rm2);
 | 
			
		||||
  rm1.setZero();
 | 
			
		||||
  rm2.setZero();
 | 
			
		||||
  rm1 = cm.real();
 | 
			
		||||
  rm2 = cm.imag();
 | 
			
		||||
  VERIFY_IS_APPROX(static_cast<const MatrixType&>(cm).real(), rm1);
 | 
			
		||||
  VERIFY_IS_APPROX(static_cast<const MatrixType&>(cm).imag(), rm2);
 | 
			
		||||
  cm.real().setZero();
 | 
			
		||||
  VERIFY(static_cast<const MatrixType&>(cm).real().isZero());
 | 
			
		||||
  VERIFY(!static_cast<const MatrixType&>(cm).imag().isZero());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef EIGEN_TEST_PART_2
 | 
			
		||||
void casting()
 | 
			
		||||
{
 | 
			
		||||
  Matrix4f m = Matrix4f::Random(), m2;
 | 
			
		||||
  Matrix4d n = m.cast<double>();
 | 
			
		||||
  VERIFY(m.isApprox(n.cast<float>()));
 | 
			
		||||
  m2 = m.cast<float>(); // check the specialization when NewType == Type
 | 
			
		||||
  VERIFY(m.isApprox(m2));
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
template <typename Scalar>
 | 
			
		||||
void fixedSizeMatrixConstruction()
 | 
			
		||||
{
 | 
			
		||||
  Scalar raw[4];
 | 
			
		||||
  for(int k=0; k<4; ++k)
 | 
			
		||||
    raw[k] = internal::random<Scalar>();
 | 
			
		||||
  
 | 
			
		||||
  {
 | 
			
		||||
    Matrix<Scalar,4,1> m(raw);
 | 
			
		||||
    Array<Scalar,4,1> a(raw);
 | 
			
		||||
    for(int k=0; k<4; ++k) VERIFY(m(k) == raw[k]);
 | 
			
		||||
    for(int k=0; k<4; ++k) VERIFY(a(k) == raw[k]);    
 | 
			
		||||
    VERIFY_IS_EQUAL(m,(Matrix<Scalar,4,1>(raw[0],raw[1],raw[2],raw[3])));
 | 
			
		||||
    VERIFY((a==(Array<Scalar,4,1>(raw[0],raw[1],raw[2],raw[3]))).all());
 | 
			
		||||
  }
 | 
			
		||||
  {
 | 
			
		||||
    Matrix<Scalar,3,1> m(raw);
 | 
			
		||||
    Array<Scalar,3,1> a(raw);
 | 
			
		||||
    for(int k=0; k<3; ++k) VERIFY(m(k) == raw[k]);
 | 
			
		||||
    for(int k=0; k<3; ++k) VERIFY(a(k) == raw[k]);
 | 
			
		||||
    VERIFY_IS_EQUAL(m,(Matrix<Scalar,3,1>(raw[0],raw[1],raw[2])));
 | 
			
		||||
    VERIFY((a==Array<Scalar,3,1>(raw[0],raw[1],raw[2])).all());
 | 
			
		||||
  }
 | 
			
		||||
  {
 | 
			
		||||
    Matrix<Scalar,2,1> m(raw), m2( (DenseIndex(raw[0])), (DenseIndex(raw[1])) );
 | 
			
		||||
    Array<Scalar,2,1> a(raw),  a2( (DenseIndex(raw[0])), (DenseIndex(raw[1])) );
 | 
			
		||||
    for(int k=0; k<2; ++k) VERIFY(m(k) == raw[k]);
 | 
			
		||||
    for(int k=0; k<2; ++k) VERIFY(a(k) == raw[k]);
 | 
			
		||||
    VERIFY_IS_EQUAL(m,(Matrix<Scalar,2,1>(raw[0],raw[1])));
 | 
			
		||||
    VERIFY((a==Array<Scalar,2,1>(raw[0],raw[1])).all());
 | 
			
		||||
    for(int k=0; k<2; ++k) VERIFY(m2(k) == DenseIndex(raw[k]));
 | 
			
		||||
    for(int k=0; k<2; ++k) VERIFY(a2(k) == DenseIndex(raw[k]));
 | 
			
		||||
  }
 | 
			
		||||
  {
 | 
			
		||||
    Matrix<Scalar,1,2> m(raw),
 | 
			
		||||
                       m2( (DenseIndex(raw[0])), (DenseIndex(raw[1])) ),
 | 
			
		||||
                       m3( (int(raw[0])), (int(raw[1])) ),
 | 
			
		||||
                       m4( (float(raw[0])), (float(raw[1])) );
 | 
			
		||||
    Array<Scalar,1,2> a(raw),  a2( (DenseIndex(raw[0])), (DenseIndex(raw[1])) );
 | 
			
		||||
    for(int k=0; k<2; ++k) VERIFY(m(k) == raw[k]);
 | 
			
		||||
    for(int k=0; k<2; ++k) VERIFY(a(k) == raw[k]);
 | 
			
		||||
    VERIFY_IS_EQUAL(m,(Matrix<Scalar,1,2>(raw[0],raw[1])));
 | 
			
		||||
    VERIFY((a==Array<Scalar,1,2>(raw[0],raw[1])).all());
 | 
			
		||||
    for(int k=0; k<2; ++k) VERIFY(m2(k) == DenseIndex(raw[k]));
 | 
			
		||||
    for(int k=0; k<2; ++k) VERIFY(a2(k) == DenseIndex(raw[k]));
 | 
			
		||||
    for(int k=0; k<2; ++k) VERIFY(m3(k) == int(raw[k]));
 | 
			
		||||
    for(int k=0; k<2; ++k) VERIFY((m4(k)) == Scalar(float(raw[k])));
 | 
			
		||||
  }
 | 
			
		||||
  {
 | 
			
		||||
    Matrix<Scalar,1,1> m(raw), m1(raw[0]), m2( (DenseIndex(raw[0])) ), m3( (int(raw[0])) );
 | 
			
		||||
    Array<Scalar,1,1> a(raw), a1(raw[0]), a2( (DenseIndex(raw[0])) );
 | 
			
		||||
    VERIFY(m(0) == raw[0]);
 | 
			
		||||
    VERIFY(a(0) == raw[0]);
 | 
			
		||||
    VERIFY(m1(0) == raw[0]);
 | 
			
		||||
    VERIFY(a1(0) == raw[0]);
 | 
			
		||||
    VERIFY(m2(0) == DenseIndex(raw[0]));
 | 
			
		||||
    VERIFY(a2(0) == DenseIndex(raw[0]));
 | 
			
		||||
    VERIFY(m3(0) == int(raw[0]));
 | 
			
		||||
    VERIFY_IS_EQUAL(m,(Matrix<Scalar,1,1>(raw[0])));
 | 
			
		||||
    VERIFY((a==Array<Scalar,1,1>(raw[0])).all());
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_basicstuff()
 | 
			
		||||
{
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_1( basicStuff(Matrix<float, 1, 1>()) );
 | 
			
		||||
    CALL_SUBTEST_2( basicStuff(Matrix4d()) );
 | 
			
		||||
    CALL_SUBTEST_3( basicStuff(MatrixXcf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
    CALL_SUBTEST_4( basicStuff(MatrixXi(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
    CALL_SUBTEST_5( basicStuff(MatrixXcd(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
    CALL_SUBTEST_6( basicStuff(Matrix<float, 100, 100>()) );
 | 
			
		||||
    CALL_SUBTEST_7( basicStuff(Matrix<long double,Dynamic,Dynamic>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE),internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_3( basicStuffComplex(MatrixXcf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
    CALL_SUBTEST_5( basicStuffComplex(MatrixXcd(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  CALL_SUBTEST_1(fixedSizeMatrixConstruction<unsigned char>());
 | 
			
		||||
  CALL_SUBTEST_1(fixedSizeMatrixConstruction<float>());
 | 
			
		||||
  CALL_SUBTEST_1(fixedSizeMatrixConstruction<double>());
 | 
			
		||||
  CALL_SUBTEST_1(fixedSizeMatrixConstruction<int>());
 | 
			
		||||
  CALL_SUBTEST_1(fixedSizeMatrixConstruction<long int>());
 | 
			
		||||
  CALL_SUBTEST_1(fixedSizeMatrixConstruction<std::ptrdiff_t>());
 | 
			
		||||
 | 
			
		||||
  CALL_SUBTEST_2(casting());
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										116
									
								
								cs440-acg/ext/eigen/test/bdcsvd.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								cs440-acg/ext/eigen/test/bdcsvd.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,116 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2013 Gauthier Brun <brun.gauthier@gmail.com>
 | 
			
		||||
// Copyright (C) 2013 Nicolas Carre <nicolas.carre@ensimag.fr>
 | 
			
		||||
// Copyright (C) 2013 Jean Ceccato <jean.ceccato@ensimag.fr>
 | 
			
		||||
// Copyright (C) 2013 Pierre Zoppitelli <pierre.zoppitelli@ensimag.fr>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/
 | 
			
		||||
 | 
			
		||||
// discard stack allocation as that too bypasses malloc
 | 
			
		||||
#define EIGEN_STACK_ALLOCATION_LIMIT 0
 | 
			
		||||
#define EIGEN_RUNTIME_NO_MALLOC
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
#include <Eigen/SVD>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <Eigen/LU>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define SVD_DEFAULT(M) BDCSVD<M>
 | 
			
		||||
#define SVD_FOR_MIN_NORM(M) BDCSVD<M>
 | 
			
		||||
#include "svd_common.h"
 | 
			
		||||
 | 
			
		||||
// Check all variants of JacobiSVD
 | 
			
		||||
template<typename MatrixType>
 | 
			
		||||
void bdcsvd(const MatrixType& a = MatrixType(), bool pickrandom = true)
 | 
			
		||||
{
 | 
			
		||||
  MatrixType m;
 | 
			
		||||
  if(pickrandom) {
 | 
			
		||||
    m.resizeLike(a);
 | 
			
		||||
    svd_fill_random(m);
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
    m = a;
 | 
			
		||||
 | 
			
		||||
  CALL_SUBTEST(( svd_test_all_computation_options<BDCSVD<MatrixType> >(m, false)  ));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType>
 | 
			
		||||
void bdcsvd_method()
 | 
			
		||||
{
 | 
			
		||||
  enum { Size = MatrixType::RowsAtCompileTime };
 | 
			
		||||
  typedef typename MatrixType::RealScalar RealScalar;
 | 
			
		||||
  typedef Matrix<RealScalar, Size, 1> RealVecType;
 | 
			
		||||
  MatrixType m = MatrixType::Identity();
 | 
			
		||||
  VERIFY_IS_APPROX(m.bdcSvd().singularValues(), RealVecType::Ones());
 | 
			
		||||
  VERIFY_RAISES_ASSERT(m.bdcSvd().matrixU());
 | 
			
		||||
  VERIFY_RAISES_ASSERT(m.bdcSvd().matrixV());
 | 
			
		||||
  VERIFY_IS_APPROX(m.bdcSvd(ComputeFullU|ComputeFullV).solve(m), m);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// compare the Singular values returned with Jacobi and Bdc
 | 
			
		||||
template<typename MatrixType> 
 | 
			
		||||
void compare_bdc_jacobi(const MatrixType& a = MatrixType(), unsigned int computationOptions = 0)
 | 
			
		||||
{
 | 
			
		||||
  MatrixType m = MatrixType::Random(a.rows(), a.cols());
 | 
			
		||||
  BDCSVD<MatrixType> bdc_svd(m);
 | 
			
		||||
  JacobiSVD<MatrixType> jacobi_svd(m);
 | 
			
		||||
  VERIFY_IS_APPROX(bdc_svd.singularValues(), jacobi_svd.singularValues());
 | 
			
		||||
  if(computationOptions & ComputeFullU) VERIFY_IS_APPROX(bdc_svd.matrixU(), jacobi_svd.matrixU());
 | 
			
		||||
  if(computationOptions & ComputeThinU) VERIFY_IS_APPROX(bdc_svd.matrixU(), jacobi_svd.matrixU());
 | 
			
		||||
  if(computationOptions & ComputeFullV) VERIFY_IS_APPROX(bdc_svd.matrixV(), jacobi_svd.matrixV());
 | 
			
		||||
  if(computationOptions & ComputeThinV) VERIFY_IS_APPROX(bdc_svd.matrixV(), jacobi_svd.matrixV());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_bdcsvd()
 | 
			
		||||
{
 | 
			
		||||
  CALL_SUBTEST_3(( svd_verify_assert<BDCSVD<Matrix3f>  >(Matrix3f()) ));
 | 
			
		||||
  CALL_SUBTEST_4(( svd_verify_assert<BDCSVD<Matrix4d>  >(Matrix4d()) ));
 | 
			
		||||
  CALL_SUBTEST_7(( svd_verify_assert<BDCSVD<MatrixXf>  >(MatrixXf(10,12)) ));
 | 
			
		||||
  CALL_SUBTEST_8(( svd_verify_assert<BDCSVD<MatrixXcd> >(MatrixXcd(7,5)) ));
 | 
			
		||||
  
 | 
			
		||||
  CALL_SUBTEST_101(( svd_all_trivial_2x2(bdcsvd<Matrix2cd>) ));
 | 
			
		||||
  CALL_SUBTEST_102(( svd_all_trivial_2x2(bdcsvd<Matrix2d>) ));
 | 
			
		||||
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_3(( bdcsvd<Matrix3f>() ));
 | 
			
		||||
    CALL_SUBTEST_4(( bdcsvd<Matrix4d>() ));
 | 
			
		||||
    CALL_SUBTEST_5(( bdcsvd<Matrix<float,3,5> >() ));
 | 
			
		||||
 | 
			
		||||
    int r = internal::random<int>(1, EIGEN_TEST_MAX_SIZE/2),
 | 
			
		||||
        c = internal::random<int>(1, EIGEN_TEST_MAX_SIZE/2);
 | 
			
		||||
    
 | 
			
		||||
    TEST_SET_BUT_UNUSED_VARIABLE(r)
 | 
			
		||||
    TEST_SET_BUT_UNUSED_VARIABLE(c)
 | 
			
		||||
    
 | 
			
		||||
    CALL_SUBTEST_6((  bdcsvd(Matrix<double,Dynamic,2>(r,2)) ));
 | 
			
		||||
    CALL_SUBTEST_7((  bdcsvd(MatrixXf(r,c)) ));
 | 
			
		||||
    CALL_SUBTEST_7((  compare_bdc_jacobi(MatrixXf(r,c)) ));
 | 
			
		||||
    CALL_SUBTEST_10(( bdcsvd(MatrixXd(r,c)) ));
 | 
			
		||||
    CALL_SUBTEST_10(( compare_bdc_jacobi(MatrixXd(r,c)) ));
 | 
			
		||||
    CALL_SUBTEST_8((  bdcsvd(MatrixXcd(r,c)) ));
 | 
			
		||||
    CALL_SUBTEST_8((  compare_bdc_jacobi(MatrixXcd(r,c)) ));
 | 
			
		||||
 | 
			
		||||
    // Test on inf/nan matrix
 | 
			
		||||
    CALL_SUBTEST_7(  (svd_inf_nan<BDCSVD<MatrixXf>, MatrixXf>()) );
 | 
			
		||||
    CALL_SUBTEST_10( (svd_inf_nan<BDCSVD<MatrixXd>, MatrixXd>()) );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // test matrixbase method
 | 
			
		||||
  CALL_SUBTEST_1(( bdcsvd_method<Matrix2cd>() ));
 | 
			
		||||
  CALL_SUBTEST_3(( bdcsvd_method<Matrix3f>() ));
 | 
			
		||||
 | 
			
		||||
  // Test problem size constructors
 | 
			
		||||
  CALL_SUBTEST_7( BDCSVD<MatrixXf>(10,10) );
 | 
			
		||||
 | 
			
		||||
  // Check that preallocation avoids subsequent mallocs
 | 
			
		||||
  // Disbaled because not supported by BDCSVD
 | 
			
		||||
  // CALL_SUBTEST_9( svd_preallocate<void>() );
 | 
			
		||||
 | 
			
		||||
  CALL_SUBTEST_2( svd_underoverflow<void>() );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										34
									
								
								cs440-acg/ext/eigen/test/bicgstab.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								cs440-acg/ext/eigen/test/bicgstab.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,34 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2011 Gael Guennebaud <g.gael@free.fr>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "sparse_solver.h"
 | 
			
		||||
#include <Eigen/IterativeLinearSolvers>
 | 
			
		||||
 | 
			
		||||
template<typename T, typename I> void test_bicgstab_T()
 | 
			
		||||
{
 | 
			
		||||
  BiCGSTAB<SparseMatrix<T,0,I>, DiagonalPreconditioner<T> >     bicgstab_colmajor_diag;
 | 
			
		||||
  BiCGSTAB<SparseMatrix<T,0,I>, IdentityPreconditioner    >     bicgstab_colmajor_I;
 | 
			
		||||
  BiCGSTAB<SparseMatrix<T,0,I>, IncompleteLUT<T,I> >              bicgstab_colmajor_ilut;
 | 
			
		||||
  //BiCGSTAB<SparseMatrix<T>, SSORPreconditioner<T> >     bicgstab_colmajor_ssor;
 | 
			
		||||
 | 
			
		||||
  bicgstab_colmajor_diag.setTolerance(NumTraits<T>::epsilon()*4);
 | 
			
		||||
  bicgstab_colmajor_ilut.setTolerance(NumTraits<T>::epsilon()*4);
 | 
			
		||||
  
 | 
			
		||||
  CALL_SUBTEST( check_sparse_square_solving(bicgstab_colmajor_diag)  );
 | 
			
		||||
//   CALL_SUBTEST( check_sparse_square_solving(bicgstab_colmajor_I)     );
 | 
			
		||||
  CALL_SUBTEST( check_sparse_square_solving(bicgstab_colmajor_ilut)     );
 | 
			
		||||
  //CALL_SUBTEST( check_sparse_square_solving(bicgstab_colmajor_ssor)     );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_bicgstab()
 | 
			
		||||
{
 | 
			
		||||
  CALL_SUBTEST_1((test_bicgstab_T<double,int>()) );
 | 
			
		||||
  CALL_SUBTEST_2((test_bicgstab_T<std::complex<double>, int>()));
 | 
			
		||||
  CALL_SUBTEST_3((test_bicgstab_T<double,long int>()));
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										276
									
								
								cs440-acg/ext/eigen/test/block.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										276
									
								
								cs440-acg/ext/eigen/test/block.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,276 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#define EIGEN_NO_STATIC_ASSERT // otherwise we fail at compile time on unused paths
 | 
			
		||||
#include "main.h"
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType, typename Index, typename Scalar>
 | 
			
		||||
typename Eigen::internal::enable_if<!NumTraits<typename MatrixType::Scalar>::IsComplex,typename MatrixType::Scalar>::type
 | 
			
		||||
block_real_only(const MatrixType &m1, Index r1, Index r2, Index c1, Index c2, const Scalar& s1) {
 | 
			
		||||
  // check cwise-Functions:
 | 
			
		||||
  VERIFY_IS_APPROX(m1.row(r1).cwiseMax(s1), m1.cwiseMax(s1).row(r1));
 | 
			
		||||
  VERIFY_IS_APPROX(m1.col(c1).cwiseMin(s1), m1.cwiseMin(s1).col(c1));
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(m1.block(r1,c1,r2-r1+1,c2-c1+1).cwiseMin(s1), m1.cwiseMin(s1).block(r1,c1,r2-r1+1,c2-c1+1));
 | 
			
		||||
  VERIFY_IS_APPROX(m1.block(r1,c1,r2-r1+1,c2-c1+1).cwiseMax(s1), m1.cwiseMax(s1).block(r1,c1,r2-r1+1,c2-c1+1));
 | 
			
		||||
  
 | 
			
		||||
  return Scalar(0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType, typename Index, typename Scalar>
 | 
			
		||||
typename Eigen::internal::enable_if<NumTraits<typename MatrixType::Scalar>::IsComplex,typename MatrixType::Scalar>::type
 | 
			
		||||
block_real_only(const MatrixType &, Index, Index, Index, Index, const Scalar&) {
 | 
			
		||||
  return Scalar(0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void block(const MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
  typedef typename MatrixType::RealScalar RealScalar;
 | 
			
		||||
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;
 | 
			
		||||
  typedef Matrix<Scalar, 1, MatrixType::ColsAtCompileTime> RowVectorType;
 | 
			
		||||
  typedef Matrix<Scalar, Dynamic, Dynamic, MatrixType::IsRowMajor?RowMajor:ColMajor> DynamicMatrixType;
 | 
			
		||||
  typedef Matrix<Scalar, Dynamic, 1> DynamicVectorType;
 | 
			
		||||
  
 | 
			
		||||
  Index rows = m.rows();
 | 
			
		||||
  Index cols = m.cols();
 | 
			
		||||
 | 
			
		||||
  MatrixType m1 = MatrixType::Random(rows, cols),
 | 
			
		||||
             m1_copy = m1,
 | 
			
		||||
             m2 = MatrixType::Random(rows, cols),
 | 
			
		||||
             m3(rows, cols),
 | 
			
		||||
             ones = MatrixType::Ones(rows, cols);
 | 
			
		||||
  VectorType v1 = VectorType::Random(rows);
 | 
			
		||||
 | 
			
		||||
  Scalar s1 = internal::random<Scalar>();
 | 
			
		||||
 | 
			
		||||
  Index r1 = internal::random<Index>(0,rows-1);
 | 
			
		||||
  Index r2 = internal::random<Index>(r1,rows-1);
 | 
			
		||||
  Index c1 = internal::random<Index>(0,cols-1);
 | 
			
		||||
  Index c2 = internal::random<Index>(c1,cols-1);
 | 
			
		||||
 | 
			
		||||
  block_real_only(m1, r1, r2, c1, c1, s1);
 | 
			
		||||
 | 
			
		||||
  //check row() and col()
 | 
			
		||||
  VERIFY_IS_EQUAL(m1.col(c1).transpose(), m1.transpose().row(c1));
 | 
			
		||||
  //check operator(), both constant and non-constant, on row() and col()
 | 
			
		||||
  m1 = m1_copy;
 | 
			
		||||
  m1.row(r1) += s1 * m1_copy.row(r2);
 | 
			
		||||
  VERIFY_IS_APPROX(m1.row(r1), m1_copy.row(r1) + s1 * m1_copy.row(r2));
 | 
			
		||||
  // check nested block xpr on lhs
 | 
			
		||||
  m1.row(r1).row(0) += s1 * m1_copy.row(r2);
 | 
			
		||||
  VERIFY_IS_APPROX(m1.row(r1), m1_copy.row(r1) + Scalar(2) * s1 * m1_copy.row(r2));
 | 
			
		||||
  m1 = m1_copy;
 | 
			
		||||
  m1.col(c1) += s1 * m1_copy.col(c2);
 | 
			
		||||
  VERIFY_IS_APPROX(m1.col(c1), m1_copy.col(c1) + s1 * m1_copy.col(c2));
 | 
			
		||||
  m1.col(c1).col(0) += s1 * m1_copy.col(c2);
 | 
			
		||||
  VERIFY_IS_APPROX(m1.col(c1), m1_copy.col(c1) + Scalar(2) * s1 * m1_copy.col(c2));
 | 
			
		||||
  
 | 
			
		||||
  
 | 
			
		||||
  //check block()
 | 
			
		||||
  Matrix<Scalar,Dynamic,Dynamic> b1(1,1); b1(0,0) = m1(r1,c1);
 | 
			
		||||
 | 
			
		||||
  RowVectorType br1(m1.block(r1,0,1,cols));
 | 
			
		||||
  VectorType bc1(m1.block(0,c1,rows,1));
 | 
			
		||||
  VERIFY_IS_EQUAL(b1, m1.block(r1,c1,1,1));
 | 
			
		||||
  VERIFY_IS_EQUAL(m1.row(r1), br1);
 | 
			
		||||
  VERIFY_IS_EQUAL(m1.col(c1), bc1);
 | 
			
		||||
  //check operator(), both constant and non-constant, on block()
 | 
			
		||||
  m1.block(r1,c1,r2-r1+1,c2-c1+1) = s1 * m2.block(0, 0, r2-r1+1,c2-c1+1);
 | 
			
		||||
  m1.block(r1,c1,r2-r1+1,c2-c1+1)(r2-r1,c2-c1) = m2.block(0, 0, r2-r1+1,c2-c1+1)(0,0);
 | 
			
		||||
 | 
			
		||||
  enum {
 | 
			
		||||
    BlockRows = 2,
 | 
			
		||||
    BlockCols = 5
 | 
			
		||||
  };
 | 
			
		||||
  if (rows>=5 && cols>=8)
 | 
			
		||||
  {
 | 
			
		||||
    // test fixed block() as lvalue
 | 
			
		||||
    m1.template block<BlockRows,BlockCols>(1,1) *= s1;
 | 
			
		||||
    // test operator() on fixed block() both as constant and non-constant
 | 
			
		||||
    m1.template block<BlockRows,BlockCols>(1,1)(0, 3) = m1.template block<2,5>(1,1)(1,2);
 | 
			
		||||
    // check that fixed block() and block() agree
 | 
			
		||||
    Matrix<Scalar,Dynamic,Dynamic> b = m1.template block<BlockRows,BlockCols>(3,3);
 | 
			
		||||
    VERIFY_IS_EQUAL(b, m1.block(3,3,BlockRows,BlockCols));
 | 
			
		||||
 | 
			
		||||
    // same tests with mixed fixed/dynamic size
 | 
			
		||||
    m1.template block<BlockRows,Dynamic>(1,1,BlockRows,BlockCols) *= s1;
 | 
			
		||||
    m1.template block<BlockRows,Dynamic>(1,1,BlockRows,BlockCols)(0,3) = m1.template block<2,5>(1,1)(1,2);
 | 
			
		||||
    Matrix<Scalar,Dynamic,Dynamic> b2 = m1.template block<Dynamic,BlockCols>(3,3,2,5);
 | 
			
		||||
    VERIFY_IS_EQUAL(b2, m1.block(3,3,BlockRows,BlockCols));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (rows>2)
 | 
			
		||||
  {
 | 
			
		||||
    // test sub vectors
 | 
			
		||||
    VERIFY_IS_EQUAL(v1.template head<2>(), v1.block(0,0,2,1));
 | 
			
		||||
    VERIFY_IS_EQUAL(v1.template head<2>(), v1.head(2));
 | 
			
		||||
    VERIFY_IS_EQUAL(v1.template head<2>(), v1.segment(0,2));
 | 
			
		||||
    VERIFY_IS_EQUAL(v1.template head<2>(), v1.template segment<2>(0));
 | 
			
		||||
    Index i = rows-2;
 | 
			
		||||
    VERIFY_IS_EQUAL(v1.template tail<2>(), v1.block(i,0,2,1));
 | 
			
		||||
    VERIFY_IS_EQUAL(v1.template tail<2>(), v1.tail(2));
 | 
			
		||||
    VERIFY_IS_EQUAL(v1.template tail<2>(), v1.segment(i,2));
 | 
			
		||||
    VERIFY_IS_EQUAL(v1.template tail<2>(), v1.template segment<2>(i));
 | 
			
		||||
    i = internal::random<Index>(0,rows-2);
 | 
			
		||||
    VERIFY_IS_EQUAL(v1.segment(i,2), v1.template segment<2>(i));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // stress some basic stuffs with block matrices
 | 
			
		||||
  VERIFY(numext::real(ones.col(c1).sum()) == RealScalar(rows));
 | 
			
		||||
  VERIFY(numext::real(ones.row(r1).sum()) == RealScalar(cols));
 | 
			
		||||
 | 
			
		||||
  VERIFY(numext::real(ones.col(c1).dot(ones.col(c2))) == RealScalar(rows));
 | 
			
		||||
  VERIFY(numext::real(ones.row(r1).dot(ones.row(r2))) == RealScalar(cols));
 | 
			
		||||
  
 | 
			
		||||
  // check that linear acccessors works on blocks
 | 
			
		||||
  m1 = m1_copy;
 | 
			
		||||
  if((MatrixType::Flags&RowMajorBit)==0)
 | 
			
		||||
    VERIFY_IS_EQUAL(m1.leftCols(c1).coeff(r1+c1*rows), m1(r1,c1));
 | 
			
		||||
  else
 | 
			
		||||
    VERIFY_IS_EQUAL(m1.topRows(r1).coeff(c1+r1*cols), m1(r1,c1));
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  // now test some block-inside-of-block.
 | 
			
		||||
  
 | 
			
		||||
  // expressions with direct access
 | 
			
		||||
  VERIFY_IS_EQUAL( (m1.block(r1,c1,rows-r1,cols-c1).block(r2-r1,c2-c1,rows-r2,cols-c2)) , (m1.block(r2,c2,rows-r2,cols-c2)) );
 | 
			
		||||
  VERIFY_IS_EQUAL( (m1.block(r1,c1,r2-r1+1,c2-c1+1).row(0)) , (m1.row(r1).segment(c1,c2-c1+1)) );
 | 
			
		||||
  VERIFY_IS_EQUAL( (m1.block(r1,c1,r2-r1+1,c2-c1+1).col(0)) , (m1.col(c1).segment(r1,r2-r1+1)) );
 | 
			
		||||
  VERIFY_IS_EQUAL( (m1.block(r1,c1,r2-r1+1,c2-c1+1).transpose().col(0)) , (m1.row(r1).segment(c1,c2-c1+1)).transpose() );
 | 
			
		||||
  VERIFY_IS_EQUAL( (m1.transpose().block(c1,r1,c2-c1+1,r2-r1+1).col(0)) , (m1.row(r1).segment(c1,c2-c1+1)).transpose() );
 | 
			
		||||
 | 
			
		||||
  // expressions without direct access
 | 
			
		||||
  VERIFY_IS_APPROX( ((m1+m2).block(r1,c1,rows-r1,cols-c1).block(r2-r1,c2-c1,rows-r2,cols-c2)) , ((m1+m2).block(r2,c2,rows-r2,cols-c2)) );
 | 
			
		||||
  VERIFY_IS_APPROX( ((m1+m2).block(r1,c1,r2-r1+1,c2-c1+1).row(0)) , ((m1+m2).row(r1).segment(c1,c2-c1+1)) );
 | 
			
		||||
  VERIFY_IS_APPROX( ((m1+m2).block(r1,c1,r2-r1+1,c2-c1+1).col(0)) , ((m1+m2).col(c1).segment(r1,r2-r1+1)) );
 | 
			
		||||
  VERIFY_IS_APPROX( ((m1+m2).block(r1,c1,r2-r1+1,c2-c1+1).transpose().col(0)) , ((m1+m2).row(r1).segment(c1,c2-c1+1)).transpose() );
 | 
			
		||||
  VERIFY_IS_APPROX( ((m1+m2).transpose().block(c1,r1,c2-c1+1,r2-r1+1).col(0)) , ((m1+m2).row(r1).segment(c1,c2-c1+1)).transpose() );
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX( (m1*1).topRows(r1),  m1.topRows(r1) );
 | 
			
		||||
  VERIFY_IS_APPROX( (m1*1).leftCols(c1), m1.leftCols(c1) );
 | 
			
		||||
  VERIFY_IS_APPROX( (m1*1).transpose().topRows(c1), m1.transpose().topRows(c1) );
 | 
			
		||||
  VERIFY_IS_APPROX( (m1*1).transpose().leftCols(r1), m1.transpose().leftCols(r1) );
 | 
			
		||||
  VERIFY_IS_APPROX( (m1*1).transpose().middleRows(c1,c2-c1+1), m1.transpose().middleRows(c1,c2-c1+1) );
 | 
			
		||||
  VERIFY_IS_APPROX( (m1*1).transpose().middleCols(r1,r2-r1+1), m1.transpose().middleCols(r1,r2-r1+1) );
 | 
			
		||||
 | 
			
		||||
  // evaluation into plain matrices from expressions with direct access (stress MapBase)
 | 
			
		||||
  DynamicMatrixType dm;
 | 
			
		||||
  DynamicVectorType dv;
 | 
			
		||||
  dm.setZero();
 | 
			
		||||
  dm = m1.block(r1,c1,rows-r1,cols-c1).block(r2-r1,c2-c1,rows-r2,cols-c2);
 | 
			
		||||
  VERIFY_IS_EQUAL(dm, (m1.block(r2,c2,rows-r2,cols-c2)));
 | 
			
		||||
  dm.setZero();
 | 
			
		||||
  dv.setZero();
 | 
			
		||||
  dm = m1.block(r1,c1,r2-r1+1,c2-c1+1).row(0).transpose();
 | 
			
		||||
  dv = m1.row(r1).segment(c1,c2-c1+1);
 | 
			
		||||
  VERIFY_IS_EQUAL(dv, dm);
 | 
			
		||||
  dm.setZero();
 | 
			
		||||
  dv.setZero();
 | 
			
		||||
  dm = m1.col(c1).segment(r1,r2-r1+1);
 | 
			
		||||
  dv = m1.block(r1,c1,r2-r1+1,c2-c1+1).col(0);
 | 
			
		||||
  VERIFY_IS_EQUAL(dv, dm);
 | 
			
		||||
  dm.setZero();
 | 
			
		||||
  dv.setZero();
 | 
			
		||||
  dm = m1.block(r1,c1,r2-r1+1,c2-c1+1).transpose().col(0);
 | 
			
		||||
  dv = m1.row(r1).segment(c1,c2-c1+1);
 | 
			
		||||
  VERIFY_IS_EQUAL(dv, dm);
 | 
			
		||||
  dm.setZero();
 | 
			
		||||
  dv.setZero();
 | 
			
		||||
  dm = m1.row(r1).segment(c1,c2-c1+1).transpose();
 | 
			
		||||
  dv = m1.transpose().block(c1,r1,c2-c1+1,r2-r1+1).col(0);
 | 
			
		||||
  VERIFY_IS_EQUAL(dv, dm);
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_EQUAL( (m1.template block<Dynamic,1>(1,0,0,1)), m1.block(1,0,0,1));
 | 
			
		||||
  VERIFY_IS_EQUAL( (m1.template block<1,Dynamic>(0,1,1,0)), m1.block(0,1,1,0));
 | 
			
		||||
  VERIFY_IS_EQUAL( ((m1*1).template block<Dynamic,1>(1,0,0,1)), m1.block(1,0,0,1));
 | 
			
		||||
  VERIFY_IS_EQUAL( ((m1*1).template block<1,Dynamic>(0,1,1,0)), m1.block(0,1,1,0));
 | 
			
		||||
 | 
			
		||||
  if (rows>=2 && cols>=2)
 | 
			
		||||
  {
 | 
			
		||||
    VERIFY_RAISES_ASSERT( m1 += m1.col(0) );
 | 
			
		||||
    VERIFY_RAISES_ASSERT( m1 -= m1.col(0) );
 | 
			
		||||
    VERIFY_RAISES_ASSERT( m1.array() *= m1.col(0).array() );
 | 
			
		||||
    VERIFY_RAISES_ASSERT( m1.array() /= m1.col(0).array() );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType>
 | 
			
		||||
void compare_using_data_and_stride(const MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  Index rows = m.rows();
 | 
			
		||||
  Index cols = m.cols();
 | 
			
		||||
  Index size = m.size();
 | 
			
		||||
  Index innerStride = m.innerStride();
 | 
			
		||||
  Index outerStride = m.outerStride();
 | 
			
		||||
  Index rowStride = m.rowStride();
 | 
			
		||||
  Index colStride = m.colStride();
 | 
			
		||||
  const typename MatrixType::Scalar* data = m.data();
 | 
			
		||||
 | 
			
		||||
  for(int j=0;j<cols;++j)
 | 
			
		||||
    for(int i=0;i<rows;++i)
 | 
			
		||||
      VERIFY(m.coeff(i,j) == data[i*rowStride + j*colStride]);
 | 
			
		||||
 | 
			
		||||
  if(!MatrixType::IsVectorAtCompileTime)
 | 
			
		||||
  {
 | 
			
		||||
    for(int j=0;j<cols;++j)
 | 
			
		||||
      for(int i=0;i<rows;++i)
 | 
			
		||||
        VERIFY(m.coeff(i,j) == data[(MatrixType::Flags&RowMajorBit)
 | 
			
		||||
                                     ? i*outerStride + j*innerStride
 | 
			
		||||
                                     : j*outerStride + i*innerStride]);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(MatrixType::IsVectorAtCompileTime)
 | 
			
		||||
  {
 | 
			
		||||
    VERIFY(innerStride == int((&m.coeff(1))-(&m.coeff(0))));
 | 
			
		||||
    for (int i=0;i<size;++i)
 | 
			
		||||
      VERIFY(m.coeff(i) == data[i*innerStride]);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType>
 | 
			
		||||
void data_and_stride(const MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  Index rows = m.rows();
 | 
			
		||||
  Index cols = m.cols();
 | 
			
		||||
 | 
			
		||||
  Index r1 = internal::random<Index>(0,rows-1);
 | 
			
		||||
  Index r2 = internal::random<Index>(r1,rows-1);
 | 
			
		||||
  Index c1 = internal::random<Index>(0,cols-1);
 | 
			
		||||
  Index c2 = internal::random<Index>(c1,cols-1);
 | 
			
		||||
 | 
			
		||||
  MatrixType m1 = MatrixType::Random(rows, cols);
 | 
			
		||||
  compare_using_data_and_stride(m1.block(r1, c1, r2-r1+1, c2-c1+1));
 | 
			
		||||
  compare_using_data_and_stride(m1.transpose().block(c1, r1, c2-c1+1, r2-r1+1));
 | 
			
		||||
  compare_using_data_and_stride(m1.row(r1));
 | 
			
		||||
  compare_using_data_and_stride(m1.col(c1));
 | 
			
		||||
  compare_using_data_and_stride(m1.row(r1).transpose());
 | 
			
		||||
  compare_using_data_and_stride(m1.col(c1).transpose());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_block()
 | 
			
		||||
{
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_1( block(Matrix<float, 1, 1>()) );
 | 
			
		||||
    CALL_SUBTEST_2( block(Matrix4d()) );
 | 
			
		||||
    CALL_SUBTEST_3( block(MatrixXcf(3, 3)) );
 | 
			
		||||
    CALL_SUBTEST_4( block(MatrixXi(8, 12)) );
 | 
			
		||||
    CALL_SUBTEST_5( block(MatrixXcd(20, 20)) );
 | 
			
		||||
    CALL_SUBTEST_6( block(MatrixXf(20, 20)) );
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_8( block(Matrix<float,Dynamic,4>(3, 4)) );
 | 
			
		||||
 | 
			
		||||
#ifndef EIGEN_DEFAULT_TO_ROW_MAJOR
 | 
			
		||||
    CALL_SUBTEST_6( data_and_stride(MatrixXf(internal::random(5,50), internal::random(5,50))) );
 | 
			
		||||
    CALL_SUBTEST_7( data_and_stride(Matrix<int,Dynamic,Dynamic,RowMajor>(internal::random(5,50), internal::random(5,50))) );
 | 
			
		||||
#endif
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										201
									
								
								cs440-acg/ext/eigen/test/boostmultiprec.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										201
									
								
								cs440-acg/ext/eigen/test/boostmultiprec.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,201 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2016 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include <sstream>
 | 
			
		||||
 | 
			
		||||
#ifdef EIGEN_TEST_MAX_SIZE
 | 
			
		||||
#undef EIGEN_TEST_MAX_SIZE
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define EIGEN_TEST_MAX_SIZE 50
 | 
			
		||||
 | 
			
		||||
#ifdef EIGEN_TEST_PART_1
 | 
			
		||||
#include "cholesky.cpp"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef EIGEN_TEST_PART_2
 | 
			
		||||
#include "lu.cpp"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef EIGEN_TEST_PART_3
 | 
			
		||||
#include "qr.cpp"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef EIGEN_TEST_PART_4
 | 
			
		||||
#include "qr_colpivoting.cpp"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef EIGEN_TEST_PART_5
 | 
			
		||||
#include "qr_fullpivoting.cpp"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef EIGEN_TEST_PART_6
 | 
			
		||||
#include "eigensolver_selfadjoint.cpp"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef EIGEN_TEST_PART_7
 | 
			
		||||
#include "eigensolver_generic.cpp"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef EIGEN_TEST_PART_8
 | 
			
		||||
#include "eigensolver_generalized_real.cpp"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef EIGEN_TEST_PART_9
 | 
			
		||||
#include "jacobisvd.cpp"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef EIGEN_TEST_PART_10
 | 
			
		||||
#include "bdcsvd.cpp"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <Eigen/Dense>
 | 
			
		||||
 | 
			
		||||
#undef min
 | 
			
		||||
#undef max
 | 
			
		||||
#undef isnan
 | 
			
		||||
#undef isinf
 | 
			
		||||
#undef isfinite
 | 
			
		||||
 | 
			
		||||
#include <boost/multiprecision/cpp_dec_float.hpp>
 | 
			
		||||
#include <boost/multiprecision/number.hpp>
 | 
			
		||||
#include <boost/math/special_functions.hpp>
 | 
			
		||||
#include <boost/math/complex.hpp>
 | 
			
		||||
 | 
			
		||||
namespace mp = boost::multiprecision;
 | 
			
		||||
typedef mp::number<mp::cpp_dec_float<100>, mp::et_on> Real;
 | 
			
		||||
 | 
			
		||||
namespace Eigen {
 | 
			
		||||
  template<> struct NumTraits<Real> : GenericNumTraits<Real> {
 | 
			
		||||
    static inline Real dummy_precision() { return 1e-50; }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  template<typename T1,typename T2,typename T3,typename T4,typename T5>
 | 
			
		||||
  struct NumTraits<boost::multiprecision::detail::expression<T1,T2,T3,T4,T5> > : NumTraits<Real> {};
 | 
			
		||||
 | 
			
		||||
  template<>
 | 
			
		||||
  Real test_precision<Real>() { return 1e-50; }
 | 
			
		||||
 | 
			
		||||
  // needed in C++93 mode where number does not support explicit cast.
 | 
			
		||||
  namespace internal {
 | 
			
		||||
    template<typename NewType>
 | 
			
		||||
    struct cast_impl<Real,NewType> {
 | 
			
		||||
      static inline NewType run(const Real& x) {
 | 
			
		||||
        return x.template convert_to<NewType>();
 | 
			
		||||
      }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    template<>
 | 
			
		||||
    struct cast_impl<Real,std::complex<Real> > {
 | 
			
		||||
      static inline std::complex<Real>  run(const Real& x) {
 | 
			
		||||
        return std::complex<Real>(x);
 | 
			
		||||
      }
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace boost {
 | 
			
		||||
namespace multiprecision {
 | 
			
		||||
  // to make ADL works as expected:
 | 
			
		||||
  using boost::math::isfinite;
 | 
			
		||||
  using boost::math::isnan;
 | 
			
		||||
  using boost::math::isinf;
 | 
			
		||||
  using boost::math::copysign;
 | 
			
		||||
  using boost::math::hypot;
 | 
			
		||||
 | 
			
		||||
  // The following is needed for std::complex<Real>:
 | 
			
		||||
  Real fabs(const Real& a) { return abs EIGEN_NOT_A_MACRO (a); }
 | 
			
		||||
  Real fmax(const Real& a, const Real& b) { using std::max; return max(a,b); }
 | 
			
		||||
 | 
			
		||||
  // some specialization for the unit tests:
 | 
			
		||||
  inline bool test_isMuchSmallerThan(const Real& a, const Real& b) {
 | 
			
		||||
    return internal::isMuchSmallerThan(a, b, test_precision<Real>());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  inline bool test_isApprox(const Real& a, const Real& b) {
 | 
			
		||||
    return internal::isApprox(a, b, test_precision<Real>());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  inline bool test_isApproxOrLessThan(const Real& a, const Real& b) {
 | 
			
		||||
    return internal::isApproxOrLessThan(a, b, test_precision<Real>());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Real get_test_precision(const Real&) {
 | 
			
		||||
    return test_precision<Real>();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Real test_relative_error(const Real &a, const Real &b) {
 | 
			
		||||
    using Eigen::numext::abs2;
 | 
			
		||||
    return sqrt(abs2<Real>(a-b)/Eigen::numext::mini<Real>(abs2(a),abs2(b)));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace Eigen {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_boostmultiprec()
 | 
			
		||||
{
 | 
			
		||||
  typedef Matrix<Real,Dynamic,Dynamic> Mat;
 | 
			
		||||
  typedef Matrix<std::complex<Real>,Dynamic,Dynamic> MatC;
 | 
			
		||||
 | 
			
		||||
  std::cout << "NumTraits<Real>::epsilon()         = " << NumTraits<Real>::epsilon() << std::endl;
 | 
			
		||||
  std::cout << "NumTraits<Real>::dummy_precision() = " << NumTraits<Real>::dummy_precision() << std::endl;
 | 
			
		||||
  std::cout << "NumTraits<Real>::lowest()          = " << NumTraits<Real>::lowest() << std::endl;
 | 
			
		||||
  std::cout << "NumTraits<Real>::highest()         = " << NumTraits<Real>::highest() << std::endl;
 | 
			
		||||
  std::cout << "NumTraits<Real>::digits10()        = " << NumTraits<Real>::digits10() << std::endl;
 | 
			
		||||
 | 
			
		||||
  // chekc stream output
 | 
			
		||||
  {
 | 
			
		||||
    Mat A(10,10);
 | 
			
		||||
    A.setRandom();
 | 
			
		||||
    std::stringstream ss;
 | 
			
		||||
    ss << A;
 | 
			
		||||
  }
 | 
			
		||||
  {
 | 
			
		||||
    MatC A(10,10);
 | 
			
		||||
    A.setRandom();
 | 
			
		||||
    std::stringstream ss;
 | 
			
		||||
    ss << A;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    int s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE);
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_1( cholesky(Mat(s,s)) );
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_2( lu_non_invertible<Mat>() );
 | 
			
		||||
    CALL_SUBTEST_2( lu_invertible<Mat>() );
 | 
			
		||||
    CALL_SUBTEST_2( lu_non_invertible<MatC>() );
 | 
			
		||||
    CALL_SUBTEST_2( lu_invertible<MatC>() );
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_3( qr(Mat(internal::random<int>(1,EIGEN_TEST_MAX_SIZE),internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
    CALL_SUBTEST_3( qr_invertible<Mat>() );
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_4( qr<Mat>() );
 | 
			
		||||
    CALL_SUBTEST_4( cod<Mat>() );
 | 
			
		||||
    CALL_SUBTEST_4( qr_invertible<Mat>() );
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_5( qr<Mat>() );
 | 
			
		||||
    CALL_SUBTEST_5( qr_invertible<Mat>() );
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_6( selfadjointeigensolver(Mat(s,s)) );
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_7( eigensolver(Mat(s,s)) );
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_8( generalized_eigensolver_real(Mat(s,s)) );
 | 
			
		||||
 | 
			
		||||
    TEST_SET_BUT_UNUSED_VARIABLE(s)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  CALL_SUBTEST_9(( jacobisvd(Mat(internal::random<int>(EIGEN_TEST_MAX_SIZE/4, EIGEN_TEST_MAX_SIZE), internal::random<int>(EIGEN_TEST_MAX_SIZE/4, EIGEN_TEST_MAX_SIZE/2))) ));
 | 
			
		||||
  CALL_SUBTEST_10(( bdcsvd(Mat(internal::random<int>(EIGEN_TEST_MAX_SIZE/4, EIGEN_TEST_MAX_SIZE), internal::random<int>(EIGEN_TEST_MAX_SIZE/4, EIGEN_TEST_MAX_SIZE/2))) ));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										13
									
								
								cs440-acg/ext/eigen/test/bug1213.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								cs440-acg/ext/eigen/test/bug1213.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
 | 
			
		||||
// This anonymous enum is essential to trigger the linking issue
 | 
			
		||||
enum {
 | 
			
		||||
  Foo
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#include "bug1213.h"
 | 
			
		||||
 | 
			
		||||
bool bug1213_1(const Eigen::Vector3f& x)
 | 
			
		||||
{
 | 
			
		||||
  return bug1213_2(x);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										8
									
								
								cs440-acg/ext/eigen/test/bug1213.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								cs440-acg/ext/eigen/test/bug1213.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
 | 
			
		||||
#include <Eigen/Core>
 | 
			
		||||
 | 
			
		||||
template<typename T, int dim>
 | 
			
		||||
bool bug1213_2(const Eigen::Matrix<T,dim,1>& x);
 | 
			
		||||
 | 
			
		||||
bool bug1213_1(const Eigen::Vector3f& x);
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										18
									
								
								cs440-acg/ext/eigen/test/bug1213_main.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								cs440-acg/ext/eigen/test/bug1213_main.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
			
		||||
 | 
			
		||||
// This is a regression unit regarding a weird linking issue with gcc.
 | 
			
		||||
 | 
			
		||||
#include "bug1213.h"
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template<typename T, int dim>
 | 
			
		||||
bool bug1213_2(const Eigen::Matrix<T,dim,1>& )
 | 
			
		||||
{
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template bool bug1213_2<float,3>(const Eigen::Vector3f&);
 | 
			
		||||
							
								
								
									
										529
									
								
								cs440-acg/ext/eigen/test/cholesky.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										529
									
								
								cs440-acg/ext/eigen/test/cholesky.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,529 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. 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_NO_ASSERTION_CHECKING
 | 
			
		||||
#define EIGEN_NO_ASSERTION_CHECKING
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define TEST_ENABLE_TEMPORARY_TRACKING
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
#include <Eigen/Cholesky>
 | 
			
		||||
#include <Eigen/QR>
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType, int UpLo>
 | 
			
		||||
typename MatrixType::RealScalar matrix_l1_norm(const MatrixType& m) {
 | 
			
		||||
  if(m.cols()==0) return typename MatrixType::RealScalar(0);
 | 
			
		||||
  MatrixType symm = m.template selfadjointView<UpLo>();
 | 
			
		||||
  return symm.cwiseAbs().colwise().sum().maxCoeff();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType,template <typename,int> class CholType> void test_chol_update(const MatrixType& symm)
 | 
			
		||||
{
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
  typedef typename MatrixType::RealScalar RealScalar;
 | 
			
		||||
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;
 | 
			
		||||
 | 
			
		||||
  MatrixType symmLo = symm.template triangularView<Lower>();
 | 
			
		||||
  MatrixType symmUp = symm.template triangularView<Upper>();
 | 
			
		||||
  MatrixType symmCpy = symm;
 | 
			
		||||
 | 
			
		||||
  CholType<MatrixType,Lower> chollo(symmLo);
 | 
			
		||||
  CholType<MatrixType,Upper> cholup(symmUp);
 | 
			
		||||
 | 
			
		||||
  for (int k=0; k<10; ++k)
 | 
			
		||||
  {
 | 
			
		||||
    VectorType vec = VectorType::Random(symm.rows());
 | 
			
		||||
    RealScalar sigma = internal::random<RealScalar>();
 | 
			
		||||
    symmCpy += sigma * vec * vec.adjoint();
 | 
			
		||||
 | 
			
		||||
    // we are doing some downdates, so it might be the case that the matrix is not SPD anymore
 | 
			
		||||
    CholType<MatrixType,Lower> chol(symmCpy);
 | 
			
		||||
    if(chol.info()!=Success)
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    chollo.rankUpdate(vec, sigma);
 | 
			
		||||
    VERIFY_IS_APPROX(symmCpy, chollo.reconstructedMatrix());
 | 
			
		||||
 | 
			
		||||
    cholup.rankUpdate(vec, sigma);
 | 
			
		||||
    VERIFY_IS_APPROX(symmCpy, cholup.reconstructedMatrix());
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void cholesky(const MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  /* this test covers the following files:
 | 
			
		||||
     LLT.h LDLT.h
 | 
			
		||||
  */
 | 
			
		||||
  Index rows = m.rows();
 | 
			
		||||
  Index cols = m.cols();
 | 
			
		||||
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
  typedef typename NumTraits<Scalar>::Real RealScalar;
 | 
			
		||||
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> SquareMatrixType;
 | 
			
		||||
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;
 | 
			
		||||
 | 
			
		||||
  MatrixType a0 = MatrixType::Random(rows,cols);
 | 
			
		||||
  VectorType vecB = VectorType::Random(rows), vecX(rows);
 | 
			
		||||
  MatrixType matB = MatrixType::Random(rows,cols), matX(rows,cols);
 | 
			
		||||
  SquareMatrixType symm =  a0 * a0.adjoint();
 | 
			
		||||
  // let's make sure the matrix is not singular or near singular
 | 
			
		||||
  for (int k=0; k<3; ++k)
 | 
			
		||||
  {
 | 
			
		||||
    MatrixType a1 = MatrixType::Random(rows,cols);
 | 
			
		||||
    symm += a1 * a1.adjoint();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    SquareMatrixType symmUp = symm.template triangularView<Upper>();
 | 
			
		||||
    SquareMatrixType symmLo = symm.template triangularView<Lower>();
 | 
			
		||||
 | 
			
		||||
    LLT<SquareMatrixType,Lower> chollo(symmLo);
 | 
			
		||||
    VERIFY_IS_APPROX(symm, chollo.reconstructedMatrix());
 | 
			
		||||
    vecX = chollo.solve(vecB);
 | 
			
		||||
    VERIFY_IS_APPROX(symm * vecX, vecB);
 | 
			
		||||
    matX = chollo.solve(matB);
 | 
			
		||||
    VERIFY_IS_APPROX(symm * matX, matB);
 | 
			
		||||
 | 
			
		||||
    const MatrixType symmLo_inverse = chollo.solve(MatrixType::Identity(rows,cols));
 | 
			
		||||
    RealScalar rcond = (RealScalar(1) / matrix_l1_norm<MatrixType, Lower>(symmLo)) /
 | 
			
		||||
                             matrix_l1_norm<MatrixType, Lower>(symmLo_inverse);
 | 
			
		||||
    RealScalar rcond_est = chollo.rcond();
 | 
			
		||||
    // Verify that the estimated condition number is within a factor of 10 of the
 | 
			
		||||
    // truth.
 | 
			
		||||
    VERIFY(rcond_est >= rcond / 10 && rcond_est <= rcond * 10);
 | 
			
		||||
 | 
			
		||||
    // test the upper mode
 | 
			
		||||
    LLT<SquareMatrixType,Upper> cholup(symmUp);
 | 
			
		||||
    VERIFY_IS_APPROX(symm, cholup.reconstructedMatrix());
 | 
			
		||||
    vecX = cholup.solve(vecB);
 | 
			
		||||
    VERIFY_IS_APPROX(symm * vecX, vecB);
 | 
			
		||||
    matX = cholup.solve(matB);
 | 
			
		||||
    VERIFY_IS_APPROX(symm * matX, matB);
 | 
			
		||||
 | 
			
		||||
    // Verify that the estimated condition number is within a factor of 10 of the
 | 
			
		||||
    // truth.
 | 
			
		||||
    const MatrixType symmUp_inverse = cholup.solve(MatrixType::Identity(rows,cols));
 | 
			
		||||
    rcond = (RealScalar(1) / matrix_l1_norm<MatrixType, Upper>(symmUp)) /
 | 
			
		||||
                             matrix_l1_norm<MatrixType, Upper>(symmUp_inverse);
 | 
			
		||||
    rcond_est = cholup.rcond();
 | 
			
		||||
    VERIFY(rcond_est >= rcond / 10 && rcond_est <= rcond * 10);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    MatrixType neg = -symmLo;
 | 
			
		||||
    chollo.compute(neg);
 | 
			
		||||
    VERIFY(neg.size()==0 || chollo.info()==NumericalIssue);
 | 
			
		||||
 | 
			
		||||
    VERIFY_IS_APPROX(MatrixType(chollo.matrixL().transpose().conjugate()), MatrixType(chollo.matrixU()));
 | 
			
		||||
    VERIFY_IS_APPROX(MatrixType(chollo.matrixU().transpose().conjugate()), MatrixType(chollo.matrixL()));
 | 
			
		||||
    VERIFY_IS_APPROX(MatrixType(cholup.matrixL().transpose().conjugate()), MatrixType(cholup.matrixU()));
 | 
			
		||||
    VERIFY_IS_APPROX(MatrixType(cholup.matrixU().transpose().conjugate()), MatrixType(cholup.matrixL()));
 | 
			
		||||
 | 
			
		||||
    // test some special use cases of SelfCwiseBinaryOp:
 | 
			
		||||
    MatrixType m1 = MatrixType::Random(rows,cols), m2(rows,cols);
 | 
			
		||||
    m2 = m1;
 | 
			
		||||
    m2 += symmLo.template selfadjointView<Lower>().llt().solve(matB);
 | 
			
		||||
    VERIFY_IS_APPROX(m2, m1 + symmLo.template selfadjointView<Lower>().llt().solve(matB));
 | 
			
		||||
    m2 = m1;
 | 
			
		||||
    m2 -= symmLo.template selfadjointView<Lower>().llt().solve(matB);
 | 
			
		||||
    VERIFY_IS_APPROX(m2, m1 - symmLo.template selfadjointView<Lower>().llt().solve(matB));
 | 
			
		||||
    m2 = m1;
 | 
			
		||||
    m2.noalias() += symmLo.template selfadjointView<Lower>().llt().solve(matB);
 | 
			
		||||
    VERIFY_IS_APPROX(m2, m1 + symmLo.template selfadjointView<Lower>().llt().solve(matB));
 | 
			
		||||
    m2 = m1;
 | 
			
		||||
    m2.noalias() -= symmLo.template selfadjointView<Lower>().llt().solve(matB);
 | 
			
		||||
    VERIFY_IS_APPROX(m2, m1 - symmLo.template selfadjointView<Lower>().llt().solve(matB));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // LDLT
 | 
			
		||||
  {
 | 
			
		||||
    int sign = internal::random<int>()%2 ? 1 : -1;
 | 
			
		||||
 | 
			
		||||
    if(sign == -1)
 | 
			
		||||
    {
 | 
			
		||||
      symm = -symm; // test a negative matrix
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    SquareMatrixType symmUp = symm.template triangularView<Upper>();
 | 
			
		||||
    SquareMatrixType symmLo = symm.template triangularView<Lower>();
 | 
			
		||||
 | 
			
		||||
    LDLT<SquareMatrixType,Lower> ldltlo(symmLo);
 | 
			
		||||
    VERIFY(ldltlo.info()==Success);
 | 
			
		||||
    VERIFY_IS_APPROX(symm, ldltlo.reconstructedMatrix());
 | 
			
		||||
    vecX = ldltlo.solve(vecB);
 | 
			
		||||
    VERIFY_IS_APPROX(symm * vecX, vecB);
 | 
			
		||||
    matX = ldltlo.solve(matB);
 | 
			
		||||
    VERIFY_IS_APPROX(symm * matX, matB);
 | 
			
		||||
 | 
			
		||||
    const MatrixType symmLo_inverse = ldltlo.solve(MatrixType::Identity(rows,cols));
 | 
			
		||||
    RealScalar rcond = (RealScalar(1) / matrix_l1_norm<MatrixType, Lower>(symmLo)) /
 | 
			
		||||
                             matrix_l1_norm<MatrixType, Lower>(symmLo_inverse);
 | 
			
		||||
    RealScalar rcond_est = ldltlo.rcond();
 | 
			
		||||
    // Verify that the estimated condition number is within a factor of 10 of the
 | 
			
		||||
    // truth.
 | 
			
		||||
    VERIFY(rcond_est >= rcond / 10 && rcond_est <= rcond * 10);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    LDLT<SquareMatrixType,Upper> ldltup(symmUp);
 | 
			
		||||
    VERIFY(ldltup.info()==Success);
 | 
			
		||||
    VERIFY_IS_APPROX(symm, ldltup.reconstructedMatrix());
 | 
			
		||||
    vecX = ldltup.solve(vecB);
 | 
			
		||||
    VERIFY_IS_APPROX(symm * vecX, vecB);
 | 
			
		||||
    matX = ldltup.solve(matB);
 | 
			
		||||
    VERIFY_IS_APPROX(symm * matX, matB);
 | 
			
		||||
 | 
			
		||||
    // Verify that the estimated condition number is within a factor of 10 of the
 | 
			
		||||
    // truth.
 | 
			
		||||
    const MatrixType symmUp_inverse = ldltup.solve(MatrixType::Identity(rows,cols));
 | 
			
		||||
    rcond = (RealScalar(1) / matrix_l1_norm<MatrixType, Upper>(symmUp)) /
 | 
			
		||||
                             matrix_l1_norm<MatrixType, Upper>(symmUp_inverse);
 | 
			
		||||
    rcond_est = ldltup.rcond();
 | 
			
		||||
    VERIFY(rcond_est >= rcond / 10 && rcond_est <= rcond * 10);
 | 
			
		||||
 | 
			
		||||
    VERIFY_IS_APPROX(MatrixType(ldltlo.matrixL().transpose().conjugate()), MatrixType(ldltlo.matrixU()));
 | 
			
		||||
    VERIFY_IS_APPROX(MatrixType(ldltlo.matrixU().transpose().conjugate()), MatrixType(ldltlo.matrixL()));
 | 
			
		||||
    VERIFY_IS_APPROX(MatrixType(ldltup.matrixL().transpose().conjugate()), MatrixType(ldltup.matrixU()));
 | 
			
		||||
    VERIFY_IS_APPROX(MatrixType(ldltup.matrixU().transpose().conjugate()), MatrixType(ldltup.matrixL()));
 | 
			
		||||
 | 
			
		||||
    if(MatrixType::RowsAtCompileTime==Dynamic)
 | 
			
		||||
    {
 | 
			
		||||
      // note : each inplace permutation requires a small temporary vector (mask)
 | 
			
		||||
 | 
			
		||||
      // check inplace solve
 | 
			
		||||
      matX = matB;
 | 
			
		||||
      VERIFY_EVALUATION_COUNT(matX = ldltlo.solve(matX), 0);
 | 
			
		||||
      VERIFY_IS_APPROX(matX, ldltlo.solve(matB).eval());
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      matX = matB;
 | 
			
		||||
      VERIFY_EVALUATION_COUNT(matX = ldltup.solve(matX), 0);
 | 
			
		||||
      VERIFY_IS_APPROX(matX, ldltup.solve(matB).eval());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // restore
 | 
			
		||||
    if(sign == -1)
 | 
			
		||||
      symm = -symm;
 | 
			
		||||
 | 
			
		||||
    // check matrices coming from linear constraints with Lagrange multipliers
 | 
			
		||||
    if(rows>=3)
 | 
			
		||||
    {
 | 
			
		||||
      SquareMatrixType A = symm;
 | 
			
		||||
      Index c = internal::random<Index>(0,rows-2);
 | 
			
		||||
      A.bottomRightCorner(c,c).setZero();
 | 
			
		||||
      // Make sure a solution exists:
 | 
			
		||||
      vecX.setRandom();
 | 
			
		||||
      vecB = A * vecX;
 | 
			
		||||
      vecX.setZero();
 | 
			
		||||
      ldltlo.compute(A);
 | 
			
		||||
      VERIFY_IS_APPROX(A, ldltlo.reconstructedMatrix());
 | 
			
		||||
      vecX = ldltlo.solve(vecB);
 | 
			
		||||
      VERIFY_IS_APPROX(A * vecX, vecB);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // check non-full rank matrices
 | 
			
		||||
    if(rows>=3)
 | 
			
		||||
    {
 | 
			
		||||
      Index r = internal::random<Index>(1,rows-1);
 | 
			
		||||
      Matrix<Scalar,Dynamic,Dynamic> a = Matrix<Scalar,Dynamic,Dynamic>::Random(rows,r);
 | 
			
		||||
      SquareMatrixType A = a * a.adjoint();
 | 
			
		||||
      // Make sure a solution exists:
 | 
			
		||||
      vecX.setRandom();
 | 
			
		||||
      vecB = A * vecX;
 | 
			
		||||
      vecX.setZero();
 | 
			
		||||
      ldltlo.compute(A);
 | 
			
		||||
      VERIFY_IS_APPROX(A, ldltlo.reconstructedMatrix());
 | 
			
		||||
      vecX = ldltlo.solve(vecB);
 | 
			
		||||
      VERIFY_IS_APPROX(A * vecX, vecB);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // check matrices with a wide spectrum
 | 
			
		||||
    if(rows>=3)
 | 
			
		||||
    {
 | 
			
		||||
      using std::pow;
 | 
			
		||||
      using std::sqrt;
 | 
			
		||||
      RealScalar s = (std::min)(16,std::numeric_limits<RealScalar>::max_exponent10/8);
 | 
			
		||||
      Matrix<Scalar,Dynamic,Dynamic> a = Matrix<Scalar,Dynamic,Dynamic>::Random(rows,rows);
 | 
			
		||||
      Matrix<RealScalar,Dynamic,1> d =  Matrix<RealScalar,Dynamic,1>::Random(rows);
 | 
			
		||||
      for(Index k=0; k<rows; ++k)
 | 
			
		||||
        d(k) = d(k)*pow(RealScalar(10),internal::random<RealScalar>(-s,s));
 | 
			
		||||
      SquareMatrixType A = a * d.asDiagonal() * a.adjoint();
 | 
			
		||||
      // Make sure a solution exists:
 | 
			
		||||
      vecX.setRandom();
 | 
			
		||||
      vecB = A * vecX;
 | 
			
		||||
      vecX.setZero();
 | 
			
		||||
      ldltlo.compute(A);
 | 
			
		||||
      VERIFY_IS_APPROX(A, ldltlo.reconstructedMatrix());
 | 
			
		||||
      vecX = ldltlo.solve(vecB);
 | 
			
		||||
 | 
			
		||||
      if(ldltlo.vectorD().real().cwiseAbs().minCoeff()>RealScalar(0))
 | 
			
		||||
      {
 | 
			
		||||
        VERIFY_IS_APPROX(A * vecX,vecB);
 | 
			
		||||
      }
 | 
			
		||||
      else
 | 
			
		||||
      {
 | 
			
		||||
        RealScalar large_tol =  sqrt(test_precision<RealScalar>());
 | 
			
		||||
        VERIFY((A * vecX).isApprox(vecB, large_tol));
 | 
			
		||||
 | 
			
		||||
        ++g_test_level;
 | 
			
		||||
        VERIFY_IS_APPROX(A * vecX,vecB);
 | 
			
		||||
        --g_test_level;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // update/downdate
 | 
			
		||||
  CALL_SUBTEST(( test_chol_update<SquareMatrixType,LLT>(symm)  ));
 | 
			
		||||
  CALL_SUBTEST(( test_chol_update<SquareMatrixType,LDLT>(symm) ));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void cholesky_cplx(const MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  // classic test
 | 
			
		||||
  cholesky(m);
 | 
			
		||||
 | 
			
		||||
  // test mixing real/scalar types
 | 
			
		||||
 | 
			
		||||
  Index rows = m.rows();
 | 
			
		||||
  Index cols = m.cols();
 | 
			
		||||
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
  typedef typename NumTraits<Scalar>::Real RealScalar;
 | 
			
		||||
  typedef Matrix<RealScalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> RealMatrixType;
 | 
			
		||||
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;
 | 
			
		||||
 | 
			
		||||
  RealMatrixType a0 = RealMatrixType::Random(rows,cols);
 | 
			
		||||
  VectorType vecB = VectorType::Random(rows), vecX(rows);
 | 
			
		||||
  MatrixType matB = MatrixType::Random(rows,cols), matX(rows,cols);
 | 
			
		||||
  RealMatrixType symm =  a0 * a0.adjoint();
 | 
			
		||||
  // let's make sure the matrix is not singular or near singular
 | 
			
		||||
  for (int k=0; k<3; ++k)
 | 
			
		||||
  {
 | 
			
		||||
    RealMatrixType a1 = RealMatrixType::Random(rows,cols);
 | 
			
		||||
    symm += a1 * a1.adjoint();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    RealMatrixType symmLo = symm.template triangularView<Lower>();
 | 
			
		||||
 | 
			
		||||
    LLT<RealMatrixType,Lower> chollo(symmLo);
 | 
			
		||||
    VERIFY_IS_APPROX(symm, chollo.reconstructedMatrix());
 | 
			
		||||
    vecX = chollo.solve(vecB);
 | 
			
		||||
    VERIFY_IS_APPROX(symm * vecX, vecB);
 | 
			
		||||
//     matX = chollo.solve(matB);
 | 
			
		||||
//     VERIFY_IS_APPROX(symm * matX, matB);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // LDLT
 | 
			
		||||
  {
 | 
			
		||||
    int sign = internal::random<int>()%2 ? 1 : -1;
 | 
			
		||||
 | 
			
		||||
    if(sign == -1)
 | 
			
		||||
    {
 | 
			
		||||
      symm = -symm; // test a negative matrix
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    RealMatrixType symmLo = symm.template triangularView<Lower>();
 | 
			
		||||
 | 
			
		||||
    LDLT<RealMatrixType,Lower> ldltlo(symmLo);
 | 
			
		||||
    VERIFY(ldltlo.info()==Success);
 | 
			
		||||
    VERIFY_IS_APPROX(symm, ldltlo.reconstructedMatrix());
 | 
			
		||||
    vecX = ldltlo.solve(vecB);
 | 
			
		||||
    VERIFY_IS_APPROX(symm * vecX, vecB);
 | 
			
		||||
//     matX = ldltlo.solve(matB);
 | 
			
		||||
//     VERIFY_IS_APPROX(symm * matX, matB);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// regression test for bug 241
 | 
			
		||||
template<typename MatrixType> void cholesky_bug241(const MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  eigen_assert(m.rows() == 2 && m.cols() == 2);
 | 
			
		||||
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;
 | 
			
		||||
 | 
			
		||||
  MatrixType matA;
 | 
			
		||||
  matA << 1, 1, 1, 1;
 | 
			
		||||
  VectorType vecB;
 | 
			
		||||
  vecB << 1, 1;
 | 
			
		||||
  VectorType vecX = matA.ldlt().solve(vecB);
 | 
			
		||||
  VERIFY_IS_APPROX(matA * vecX, vecB);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// LDLT is not guaranteed to work for indefinite matrices, but happens to work fine if matrix is diagonal.
 | 
			
		||||
// This test checks that LDLT reports correctly that matrix is indefinite.
 | 
			
		||||
// See http://forum.kde.org/viewtopic.php?f=74&t=106942 and bug 736
 | 
			
		||||
template<typename MatrixType> void cholesky_definiteness(const MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  eigen_assert(m.rows() == 2 && m.cols() == 2);
 | 
			
		||||
  MatrixType mat;
 | 
			
		||||
  LDLT<MatrixType> ldlt(2);
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    mat << 1, 0, 0, -1;
 | 
			
		||||
    ldlt.compute(mat);
 | 
			
		||||
    VERIFY(ldlt.info()==Success);
 | 
			
		||||
    VERIFY(!ldlt.isNegative());
 | 
			
		||||
    VERIFY(!ldlt.isPositive());
 | 
			
		||||
    VERIFY_IS_APPROX(mat,ldlt.reconstructedMatrix());
 | 
			
		||||
  }
 | 
			
		||||
  {
 | 
			
		||||
    mat << 1, 2, 2, 1;
 | 
			
		||||
    ldlt.compute(mat);
 | 
			
		||||
    VERIFY(ldlt.info()==Success);
 | 
			
		||||
    VERIFY(!ldlt.isNegative());
 | 
			
		||||
    VERIFY(!ldlt.isPositive());
 | 
			
		||||
    VERIFY_IS_APPROX(mat,ldlt.reconstructedMatrix());
 | 
			
		||||
  }
 | 
			
		||||
  {
 | 
			
		||||
    mat << 0, 0, 0, 0;
 | 
			
		||||
    ldlt.compute(mat);
 | 
			
		||||
    VERIFY(ldlt.info()==Success);
 | 
			
		||||
    VERIFY(ldlt.isNegative());
 | 
			
		||||
    VERIFY(ldlt.isPositive());
 | 
			
		||||
    VERIFY_IS_APPROX(mat,ldlt.reconstructedMatrix());
 | 
			
		||||
  }
 | 
			
		||||
  {
 | 
			
		||||
    mat << 0, 0, 0, 1;
 | 
			
		||||
    ldlt.compute(mat);
 | 
			
		||||
    VERIFY(ldlt.info()==Success);
 | 
			
		||||
    VERIFY(!ldlt.isNegative());
 | 
			
		||||
    VERIFY(ldlt.isPositive());
 | 
			
		||||
    VERIFY_IS_APPROX(mat,ldlt.reconstructedMatrix());
 | 
			
		||||
  }
 | 
			
		||||
  {
 | 
			
		||||
    mat << -1, 0, 0, 0;
 | 
			
		||||
    ldlt.compute(mat);
 | 
			
		||||
    VERIFY(ldlt.info()==Success);
 | 
			
		||||
    VERIFY(ldlt.isNegative());
 | 
			
		||||
    VERIFY(!ldlt.isPositive());
 | 
			
		||||
    VERIFY_IS_APPROX(mat,ldlt.reconstructedMatrix());
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename>
 | 
			
		||||
void cholesky_faillure_cases()
 | 
			
		||||
{
 | 
			
		||||
  MatrixXd mat;
 | 
			
		||||
  LDLT<MatrixXd> ldlt;
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    mat.resize(2,2);
 | 
			
		||||
    mat << 0, 1, 1, 0;
 | 
			
		||||
    ldlt.compute(mat);
 | 
			
		||||
    VERIFY_IS_NOT_APPROX(mat,ldlt.reconstructedMatrix());
 | 
			
		||||
    VERIFY(ldlt.info()==NumericalIssue);
 | 
			
		||||
  }
 | 
			
		||||
#if (!EIGEN_ARCH_i386) || defined(EIGEN_VECTORIZE_SSE2)
 | 
			
		||||
  {
 | 
			
		||||
    mat.resize(3,3);
 | 
			
		||||
    mat << -1, -3, 3,
 | 
			
		||||
           -3, -8.9999999999999999999, 1,
 | 
			
		||||
            3, 1, 0;
 | 
			
		||||
    ldlt.compute(mat);
 | 
			
		||||
    VERIFY(ldlt.info()==NumericalIssue);
 | 
			
		||||
    VERIFY_IS_NOT_APPROX(mat,ldlt.reconstructedMatrix());
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
  {
 | 
			
		||||
    mat.resize(3,3);
 | 
			
		||||
    mat <<  1, 2, 3,
 | 
			
		||||
            2, 4, 1,
 | 
			
		||||
            3, 1, 0;
 | 
			
		||||
    ldlt.compute(mat);
 | 
			
		||||
    VERIFY(ldlt.info()==NumericalIssue);
 | 
			
		||||
    VERIFY_IS_NOT_APPROX(mat,ldlt.reconstructedMatrix());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    mat.resize(8,8);
 | 
			
		||||
    mat <<  0.1, 0, -0.1, 0, 0, 0, 1, 0,
 | 
			
		||||
            0, 4.24667, 0, 2.00333, 0, 0, 0, 0,
 | 
			
		||||
            -0.1, 0, 0.2, 0, -0.1, 0, 0, 0,
 | 
			
		||||
            0, 2.00333, 0, 8.49333, 0, 2.00333, 0, 0,
 | 
			
		||||
            0, 0, -0.1, 0, 0.1, 0, 0, 1,
 | 
			
		||||
            0, 0, 0, 2.00333, 0, 4.24667, 0, 0,
 | 
			
		||||
            1, 0, 0, 0, 0, 0, 0, 0,
 | 
			
		||||
            0, 0, 0, 0, 1, 0, 0, 0;
 | 
			
		||||
    ldlt.compute(mat);
 | 
			
		||||
    VERIFY(ldlt.info()==NumericalIssue);
 | 
			
		||||
    VERIFY_IS_NOT_APPROX(mat,ldlt.reconstructedMatrix());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // bug 1479
 | 
			
		||||
  {
 | 
			
		||||
    mat.resize(4,4);
 | 
			
		||||
    mat <<  1, 2, 0, 1,
 | 
			
		||||
            2, 4, 0, 2,
 | 
			
		||||
            0, 0, 0, 1,
 | 
			
		||||
            1, 2, 1, 1;
 | 
			
		||||
    ldlt.compute(mat);
 | 
			
		||||
    VERIFY(ldlt.info()==NumericalIssue);
 | 
			
		||||
    VERIFY_IS_NOT_APPROX(mat,ldlt.reconstructedMatrix());
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void cholesky_verify_assert()
 | 
			
		||||
{
 | 
			
		||||
  MatrixType tmp;
 | 
			
		||||
 | 
			
		||||
  LLT<MatrixType> llt;
 | 
			
		||||
  VERIFY_RAISES_ASSERT(llt.matrixL())
 | 
			
		||||
  VERIFY_RAISES_ASSERT(llt.matrixU())
 | 
			
		||||
  VERIFY_RAISES_ASSERT(llt.solve(tmp))
 | 
			
		||||
  VERIFY_RAISES_ASSERT(llt.solveInPlace(&tmp))
 | 
			
		||||
 | 
			
		||||
  LDLT<MatrixType> ldlt;
 | 
			
		||||
  VERIFY_RAISES_ASSERT(ldlt.matrixL())
 | 
			
		||||
  VERIFY_RAISES_ASSERT(ldlt.permutationP())
 | 
			
		||||
  VERIFY_RAISES_ASSERT(ldlt.vectorD())
 | 
			
		||||
  VERIFY_RAISES_ASSERT(ldlt.isPositive())
 | 
			
		||||
  VERIFY_RAISES_ASSERT(ldlt.isNegative())
 | 
			
		||||
  VERIFY_RAISES_ASSERT(ldlt.solve(tmp))
 | 
			
		||||
  VERIFY_RAISES_ASSERT(ldlt.solveInPlace(&tmp))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_cholesky()
 | 
			
		||||
{
 | 
			
		||||
  int s = 0;
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_1( cholesky(Matrix<double,1,1>()) );
 | 
			
		||||
    CALL_SUBTEST_3( cholesky(Matrix2d()) );
 | 
			
		||||
    CALL_SUBTEST_3( cholesky_bug241(Matrix2d()) );
 | 
			
		||||
    CALL_SUBTEST_3( cholesky_definiteness(Matrix2d()) );
 | 
			
		||||
    CALL_SUBTEST_4( cholesky(Matrix3f()) );
 | 
			
		||||
    CALL_SUBTEST_5( cholesky(Matrix4d()) );
 | 
			
		||||
 | 
			
		||||
    s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE);
 | 
			
		||||
    CALL_SUBTEST_2( cholesky(MatrixXd(s,s)) );
 | 
			
		||||
    TEST_SET_BUT_UNUSED_VARIABLE(s)
 | 
			
		||||
 | 
			
		||||
    s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2);
 | 
			
		||||
    CALL_SUBTEST_6( cholesky_cplx(MatrixXcd(s,s)) );
 | 
			
		||||
    TEST_SET_BUT_UNUSED_VARIABLE(s)
 | 
			
		||||
  }
 | 
			
		||||
  // empty matrix, regression test for Bug 785:
 | 
			
		||||
  CALL_SUBTEST_2( cholesky(MatrixXd(0,0)) );
 | 
			
		||||
 | 
			
		||||
  // This does not work yet:
 | 
			
		||||
  // CALL_SUBTEST_2( cholesky(Matrix<double,0,0>()) );
 | 
			
		||||
 | 
			
		||||
  CALL_SUBTEST_4( cholesky_verify_assert<Matrix3f>() );
 | 
			
		||||
  CALL_SUBTEST_7( cholesky_verify_assert<Matrix3d>() );
 | 
			
		||||
  CALL_SUBTEST_8( cholesky_verify_assert<MatrixXf>() );
 | 
			
		||||
  CALL_SUBTEST_2( cholesky_verify_assert<MatrixXd>() );
 | 
			
		||||
 | 
			
		||||
  // Test problem size constructors
 | 
			
		||||
  CALL_SUBTEST_9( LLT<MatrixXf>(10) );
 | 
			
		||||
  CALL_SUBTEST_9( LDLT<MatrixXf>(10) );
 | 
			
		||||
 | 
			
		||||
  CALL_SUBTEST_2( cholesky_faillure_cases<void>() );
 | 
			
		||||
 | 
			
		||||
  TEST_SET_BUT_UNUSED_VARIABLE(nb_temporaries)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										57
									
								
								cs440-acg/ext/eigen/test/cholmod_support.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								cs440-acg/ext/eigen/test/cholmod_support.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,57 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2011 Gael Guennebaud <g.gael@free.fr>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#define EIGEN_NO_DEBUG_SMALL_PRODUCT_BLOCKS
 | 
			
		||||
#include "sparse_solver.h"
 | 
			
		||||
 | 
			
		||||
#include <Eigen/CholmodSupport>
 | 
			
		||||
 | 
			
		||||
template<typename T> void test_cholmod_T()
 | 
			
		||||
{
 | 
			
		||||
  CholmodDecomposition<SparseMatrix<T>, Lower> g_chol_colmajor_lower; g_chol_colmajor_lower.setMode(CholmodSupernodalLLt);
 | 
			
		||||
  CholmodDecomposition<SparseMatrix<T>, Upper> g_chol_colmajor_upper; g_chol_colmajor_upper.setMode(CholmodSupernodalLLt);
 | 
			
		||||
  CholmodDecomposition<SparseMatrix<T>, Lower> g_llt_colmajor_lower;  g_llt_colmajor_lower.setMode(CholmodSimplicialLLt);
 | 
			
		||||
  CholmodDecomposition<SparseMatrix<T>, Upper> g_llt_colmajor_upper;  g_llt_colmajor_upper.setMode(CholmodSimplicialLLt);
 | 
			
		||||
  CholmodDecomposition<SparseMatrix<T>, Lower> g_ldlt_colmajor_lower; g_ldlt_colmajor_lower.setMode(CholmodLDLt);
 | 
			
		||||
  CholmodDecomposition<SparseMatrix<T>, Upper> g_ldlt_colmajor_upper; g_ldlt_colmajor_upper.setMode(CholmodLDLt);
 | 
			
		||||
  
 | 
			
		||||
  CholmodSupernodalLLT<SparseMatrix<T>, Lower> chol_colmajor_lower;
 | 
			
		||||
  CholmodSupernodalLLT<SparseMatrix<T>, Upper> chol_colmajor_upper;
 | 
			
		||||
  CholmodSimplicialLLT<SparseMatrix<T>, Lower> llt_colmajor_lower;
 | 
			
		||||
  CholmodSimplicialLLT<SparseMatrix<T>, Upper> llt_colmajor_upper;
 | 
			
		||||
  CholmodSimplicialLDLT<SparseMatrix<T>, Lower> ldlt_colmajor_lower;
 | 
			
		||||
  CholmodSimplicialLDLT<SparseMatrix<T>, Upper> ldlt_colmajor_upper;
 | 
			
		||||
 | 
			
		||||
  check_sparse_spd_solving(g_chol_colmajor_lower);
 | 
			
		||||
  check_sparse_spd_solving(g_chol_colmajor_upper);
 | 
			
		||||
  check_sparse_spd_solving(g_llt_colmajor_lower);
 | 
			
		||||
  check_sparse_spd_solving(g_llt_colmajor_upper);
 | 
			
		||||
  check_sparse_spd_solving(g_ldlt_colmajor_lower);
 | 
			
		||||
  check_sparse_spd_solving(g_ldlt_colmajor_upper);
 | 
			
		||||
  
 | 
			
		||||
  check_sparse_spd_solving(chol_colmajor_lower);
 | 
			
		||||
  check_sparse_spd_solving(chol_colmajor_upper);
 | 
			
		||||
  check_sparse_spd_solving(llt_colmajor_lower);
 | 
			
		||||
  check_sparse_spd_solving(llt_colmajor_upper);
 | 
			
		||||
  check_sparse_spd_solving(ldlt_colmajor_lower);
 | 
			
		||||
  check_sparse_spd_solving(ldlt_colmajor_upper);
 | 
			
		||||
 | 
			
		||||
  check_sparse_spd_determinant(chol_colmajor_lower);
 | 
			
		||||
  check_sparse_spd_determinant(chol_colmajor_upper);
 | 
			
		||||
  check_sparse_spd_determinant(llt_colmajor_lower);
 | 
			
		||||
  check_sparse_spd_determinant(llt_colmajor_upper);
 | 
			
		||||
  check_sparse_spd_determinant(ldlt_colmajor_lower);
 | 
			
		||||
  check_sparse_spd_determinant(ldlt_colmajor_upper);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_cholmod_support()
 | 
			
		||||
{
 | 
			
		||||
  CALL_SUBTEST_1(test_cholmod_T<double>());
 | 
			
		||||
  CALL_SUBTEST_2(test_cholmod_T<std::complex<double> >());
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										106
									
								
								cs440-acg/ext/eigen/test/commainitializer.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								cs440-acg/ext/eigen/test/commainitializer.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,106 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template<int M1, int M2, int N1, int N2>
 | 
			
		||||
void test_blocks()
 | 
			
		||||
{
 | 
			
		||||
  Matrix<int, M1+M2, N1+N2> m_fixed;
 | 
			
		||||
  MatrixXi m_dynamic(M1+M2, N1+N2);
 | 
			
		||||
 | 
			
		||||
  Matrix<int, M1, N1> mat11; mat11.setRandom();
 | 
			
		||||
  Matrix<int, M1, N2> mat12; mat12.setRandom();
 | 
			
		||||
  Matrix<int, M2, N1> mat21; mat21.setRandom();
 | 
			
		||||
  Matrix<int, M2, N2> mat22; mat22.setRandom();
 | 
			
		||||
 | 
			
		||||
  MatrixXi matx11 = mat11, matx12 = mat12, matx21 = mat21, matx22 = mat22;
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    VERIFY_IS_EQUAL((m_fixed << mat11, mat12, mat21, matx22).finished(), (m_dynamic << mat11, matx12, mat21, matx22).finished());
 | 
			
		||||
    VERIFY_IS_EQUAL((m_fixed.template topLeftCorner<M1,N1>()), mat11);
 | 
			
		||||
    VERIFY_IS_EQUAL((m_fixed.template topRightCorner<M1,N2>()), mat12);
 | 
			
		||||
    VERIFY_IS_EQUAL((m_fixed.template bottomLeftCorner<M2,N1>()), mat21);
 | 
			
		||||
    VERIFY_IS_EQUAL((m_fixed.template bottomRightCorner<M2,N2>()), mat22);
 | 
			
		||||
    VERIFY_IS_EQUAL((m_fixed << mat12, mat11, matx21, mat22).finished(), (m_dynamic << mat12, matx11, matx21, mat22).finished());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(N1 > 0)
 | 
			
		||||
  {
 | 
			
		||||
    VERIFY_RAISES_ASSERT((m_fixed << mat11, mat12, mat11, mat21, mat22));
 | 
			
		||||
    VERIFY_RAISES_ASSERT((m_fixed << mat11, mat12, mat21, mat21, mat22));
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    // allow insertion of zero-column blocks:
 | 
			
		||||
    VERIFY_IS_EQUAL((m_fixed << mat11, mat12, mat11, mat11, mat21, mat21, mat22).finished(), (m_dynamic << mat12, mat22).finished());
 | 
			
		||||
  }
 | 
			
		||||
  if(M1 != M2)
 | 
			
		||||
  {
 | 
			
		||||
    VERIFY_RAISES_ASSERT((m_fixed << mat11, mat21, mat12, mat22));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template<int N>
 | 
			
		||||
struct test_block_recursion
 | 
			
		||||
{
 | 
			
		||||
  static void run()
 | 
			
		||||
  {
 | 
			
		||||
    test_blocks<(N>>6)&3, (N>>4)&3, (N>>2)&3, N & 3>();
 | 
			
		||||
    test_block_recursion<N-1>::run();
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<>
 | 
			
		||||
struct test_block_recursion<-1>
 | 
			
		||||
{
 | 
			
		||||
  static void run() { }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void test_commainitializer()
 | 
			
		||||
{
 | 
			
		||||
  Matrix3d m3;
 | 
			
		||||
  Matrix4d m4;
 | 
			
		||||
 | 
			
		||||
  VERIFY_RAISES_ASSERT( (m3 << 1, 2, 3, 4, 5, 6, 7, 8) );
 | 
			
		||||
  
 | 
			
		||||
  #ifndef _MSC_VER
 | 
			
		||||
  VERIFY_RAISES_ASSERT( (m3 << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10) );
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  double data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
 | 
			
		||||
  Matrix3d ref = Map<Matrix<double,3,3,RowMajor> >(data);
 | 
			
		||||
 | 
			
		||||
  m3 = Matrix3d::Random();
 | 
			
		||||
  m3 << 1, 2, 3, 4, 5, 6, 7, 8, 9;
 | 
			
		||||
  VERIFY_IS_APPROX(m3, ref );
 | 
			
		||||
 | 
			
		||||
  Vector3d vec[3];
 | 
			
		||||
  vec[0] << 1, 4, 7;
 | 
			
		||||
  vec[1] << 2, 5, 8;
 | 
			
		||||
  vec[2] << 3, 6, 9;
 | 
			
		||||
  m3 = Matrix3d::Random();
 | 
			
		||||
  m3 << vec[0], vec[1], vec[2];
 | 
			
		||||
  VERIFY_IS_APPROX(m3, ref);
 | 
			
		||||
 | 
			
		||||
  vec[0] << 1, 2, 3;
 | 
			
		||||
  vec[1] << 4, 5, 6;
 | 
			
		||||
  vec[2] << 7, 8, 9;
 | 
			
		||||
  m3 = Matrix3d::Random();
 | 
			
		||||
  m3 << vec[0].transpose(),
 | 
			
		||||
        4, 5, 6,
 | 
			
		||||
        vec[2].transpose();
 | 
			
		||||
  VERIFY_IS_APPROX(m3, ref);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  // recursively test all block-sizes from 0 to 3:
 | 
			
		||||
  test_block_recursion<(1<<8) - 1>();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										34
									
								
								cs440-acg/ext/eigen/test/conjugate_gradient.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								cs440-acg/ext/eigen/test/conjugate_gradient.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,34 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2011 Gael Guennebaud <g.gael@free.fr>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "sparse_solver.h"
 | 
			
		||||
#include <Eigen/IterativeLinearSolvers>
 | 
			
		||||
 | 
			
		||||
template<typename T, typename I> void test_conjugate_gradient_T()
 | 
			
		||||
{
 | 
			
		||||
  typedef SparseMatrix<T,0,I> SparseMatrixType;
 | 
			
		||||
  ConjugateGradient<SparseMatrixType, Lower      > cg_colmajor_lower_diag;
 | 
			
		||||
  ConjugateGradient<SparseMatrixType, Upper      > cg_colmajor_upper_diag;
 | 
			
		||||
  ConjugateGradient<SparseMatrixType, Lower|Upper> cg_colmajor_loup_diag;
 | 
			
		||||
  ConjugateGradient<SparseMatrixType, Lower, IdentityPreconditioner> cg_colmajor_lower_I;
 | 
			
		||||
  ConjugateGradient<SparseMatrixType, Upper, IdentityPreconditioner> cg_colmajor_upper_I;
 | 
			
		||||
 | 
			
		||||
  CALL_SUBTEST( check_sparse_spd_solving(cg_colmajor_lower_diag)  );
 | 
			
		||||
  CALL_SUBTEST( check_sparse_spd_solving(cg_colmajor_upper_diag)  );
 | 
			
		||||
  CALL_SUBTEST( check_sparse_spd_solving(cg_colmajor_loup_diag)   );
 | 
			
		||||
  CALL_SUBTEST( check_sparse_spd_solving(cg_colmajor_lower_I)     );
 | 
			
		||||
  CALL_SUBTEST( check_sparse_spd_solving(cg_colmajor_upper_I)     );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_conjugate_gradient()
 | 
			
		||||
{
 | 
			
		||||
  CALL_SUBTEST_1(( test_conjugate_gradient_T<double,int>() ));
 | 
			
		||||
  CALL_SUBTEST_2(( test_conjugate_gradient_T<std::complex<double>, int>() ));
 | 
			
		||||
  CALL_SUBTEST_3(( test_conjugate_gradient_T<double,long int>() ));
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										133
									
								
								cs440-acg/ext/eigen/test/conservative_resize.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								cs440-acg/ext/eigen/test/conservative_resize.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,133 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2009 Hauke Heibel <hauke.heibel@gmail.com>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
 | 
			
		||||
#include <Eigen/Core>
 | 
			
		||||
 | 
			
		||||
using namespace Eigen;
 | 
			
		||||
 | 
			
		||||
template <typename Scalar, int Storage>
 | 
			
		||||
void run_matrix_tests()
 | 
			
		||||
{
 | 
			
		||||
  typedef Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic, Storage> MatrixType;
 | 
			
		||||
 | 
			
		||||
  MatrixType m, n;
 | 
			
		||||
 | 
			
		||||
  // boundary cases ...
 | 
			
		||||
  m = n = MatrixType::Random(50,50);
 | 
			
		||||
  m.conservativeResize(1,50);
 | 
			
		||||
  VERIFY_IS_APPROX(m, n.block(0,0,1,50));
 | 
			
		||||
 | 
			
		||||
  m = n = MatrixType::Random(50,50);
 | 
			
		||||
  m.conservativeResize(50,1);
 | 
			
		||||
  VERIFY_IS_APPROX(m, n.block(0,0,50,1));
 | 
			
		||||
 | 
			
		||||
  m = n = MatrixType::Random(50,50);
 | 
			
		||||
  m.conservativeResize(50,50);
 | 
			
		||||
  VERIFY_IS_APPROX(m, n.block(0,0,50,50));
 | 
			
		||||
 | 
			
		||||
  // random shrinking ...
 | 
			
		||||
  for (int i=0; i<25; ++i)
 | 
			
		||||
  {
 | 
			
		||||
    const Index rows = internal::random<Index>(1,50);
 | 
			
		||||
    const Index cols = internal::random<Index>(1,50);
 | 
			
		||||
    m = n = MatrixType::Random(50,50);
 | 
			
		||||
    m.conservativeResize(rows,cols);
 | 
			
		||||
    VERIFY_IS_APPROX(m, n.block(0,0,rows,cols));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // random growing with zeroing ...
 | 
			
		||||
  for (int i=0; i<25; ++i)
 | 
			
		||||
  {
 | 
			
		||||
    const Index rows = internal::random<Index>(50,75);
 | 
			
		||||
    const Index cols = internal::random<Index>(50,75);
 | 
			
		||||
    m = n = MatrixType::Random(50,50);
 | 
			
		||||
    m.conservativeResizeLike(MatrixType::Zero(rows,cols));
 | 
			
		||||
    VERIFY_IS_APPROX(m.block(0,0,n.rows(),n.cols()), n);
 | 
			
		||||
    VERIFY( rows<=50 || m.block(50,0,rows-50,cols).sum() == Scalar(0) );
 | 
			
		||||
    VERIFY( cols<=50 || m.block(0,50,rows,cols-50).sum() == Scalar(0) );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename Scalar>
 | 
			
		||||
void run_vector_tests()
 | 
			
		||||
{
 | 
			
		||||
  typedef Matrix<Scalar, 1, Eigen::Dynamic> VectorType;
 | 
			
		||||
 | 
			
		||||
  VectorType m, n;
 | 
			
		||||
 | 
			
		||||
  // boundary cases ...
 | 
			
		||||
  m = n = VectorType::Random(50);
 | 
			
		||||
  m.conservativeResize(1);
 | 
			
		||||
  VERIFY_IS_APPROX(m, n.segment(0,1));
 | 
			
		||||
 | 
			
		||||
  m = n = VectorType::Random(50);
 | 
			
		||||
  m.conservativeResize(50);
 | 
			
		||||
  VERIFY_IS_APPROX(m, n.segment(0,50));
 | 
			
		||||
  
 | 
			
		||||
  m = n = VectorType::Random(50);
 | 
			
		||||
  m.conservativeResize(m.rows(),1);
 | 
			
		||||
  VERIFY_IS_APPROX(m, n.segment(0,1));
 | 
			
		||||
 | 
			
		||||
  m = n = VectorType::Random(50);
 | 
			
		||||
  m.conservativeResize(m.rows(),50);
 | 
			
		||||
  VERIFY_IS_APPROX(m, n.segment(0,50));
 | 
			
		||||
 | 
			
		||||
  // random shrinking ...
 | 
			
		||||
  for (int i=0; i<50; ++i)
 | 
			
		||||
  {
 | 
			
		||||
    const int size = internal::random<int>(1,50);
 | 
			
		||||
    m = n = VectorType::Random(50);
 | 
			
		||||
    m.conservativeResize(size);
 | 
			
		||||
    VERIFY_IS_APPROX(m, n.segment(0,size));
 | 
			
		||||
    
 | 
			
		||||
    m = n = VectorType::Random(50);
 | 
			
		||||
    m.conservativeResize(m.rows(), size);
 | 
			
		||||
    VERIFY_IS_APPROX(m, n.segment(0,size));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // random growing with zeroing ...
 | 
			
		||||
  for (int i=0; i<50; ++i)
 | 
			
		||||
  {
 | 
			
		||||
    const int size = internal::random<int>(50,100);
 | 
			
		||||
    m = n = VectorType::Random(50);
 | 
			
		||||
    m.conservativeResizeLike(VectorType::Zero(size));
 | 
			
		||||
    VERIFY_IS_APPROX(m.segment(0,50), n);
 | 
			
		||||
    VERIFY( size<=50 || m.segment(50,size-50).sum() == Scalar(0) );
 | 
			
		||||
    
 | 
			
		||||
    m = n = VectorType::Random(50);
 | 
			
		||||
    m.conservativeResizeLike(Matrix<Scalar,Dynamic,Dynamic>::Zero(1,size));
 | 
			
		||||
    VERIFY_IS_APPROX(m.segment(0,50), n);
 | 
			
		||||
    VERIFY( size<=50 || m.segment(50,size-50).sum() == Scalar(0) );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_conservative_resize()
 | 
			
		||||
{
 | 
			
		||||
  for(int i=0; i<g_repeat; ++i)
 | 
			
		||||
  {
 | 
			
		||||
    CALL_SUBTEST_1((run_matrix_tests<int, Eigen::RowMajor>()));
 | 
			
		||||
    CALL_SUBTEST_1((run_matrix_tests<int, Eigen::ColMajor>()));
 | 
			
		||||
    CALL_SUBTEST_2((run_matrix_tests<float, Eigen::RowMajor>()));
 | 
			
		||||
    CALL_SUBTEST_2((run_matrix_tests<float, Eigen::ColMajor>()));
 | 
			
		||||
    CALL_SUBTEST_3((run_matrix_tests<double, Eigen::RowMajor>()));
 | 
			
		||||
    CALL_SUBTEST_3((run_matrix_tests<double, Eigen::ColMajor>()));
 | 
			
		||||
    CALL_SUBTEST_4((run_matrix_tests<std::complex<float>, Eigen::RowMajor>()));
 | 
			
		||||
    CALL_SUBTEST_4((run_matrix_tests<std::complex<float>, Eigen::ColMajor>()));
 | 
			
		||||
    CALL_SUBTEST_5((run_matrix_tests<std::complex<double>, Eigen::RowMajor>()));
 | 
			
		||||
    CALL_SUBTEST_6((run_matrix_tests<std::complex<double>, Eigen::ColMajor>()));
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_1((run_vector_tests<int>()));
 | 
			
		||||
    CALL_SUBTEST_2((run_vector_tests<float>()));
 | 
			
		||||
    CALL_SUBTEST_3((run_vector_tests<double>()));
 | 
			
		||||
    CALL_SUBTEST_4((run_vector_tests<std::complex<float> >()));
 | 
			
		||||
    CALL_SUBTEST_5((run_vector_tests<std::complex<double> >()));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										98
									
								
								cs440-acg/ext/eigen/test/constructor.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								cs440-acg/ext/eigen/test/constructor.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,98 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2017 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define TEST_ENABLE_TEMPORARY_TRACKING
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> struct Wrapper
 | 
			
		||||
{
 | 
			
		||||
  MatrixType m_mat;
 | 
			
		||||
  inline Wrapper(const MatrixType &x) : m_mat(x) {}
 | 
			
		||||
  inline operator const MatrixType& () const { return m_mat; }
 | 
			
		||||
  inline operator MatrixType& () { return m_mat; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum my_sizes { M = 12, N = 7};
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void ctor_init1(const MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  // Check logic in PlainObjectBase::_init1
 | 
			
		||||
  Index rows = m.rows();
 | 
			
		||||
  Index cols = m.cols();
 | 
			
		||||
 | 
			
		||||
  MatrixType m0 = MatrixType::Random(rows,cols);
 | 
			
		||||
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( MatrixType m1(m0), 1);
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( MatrixType m2(m0+m0), 1);
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( MatrixType m2(m0.block(0,0,rows,cols)) , 1);
 | 
			
		||||
 | 
			
		||||
  Wrapper<MatrixType> wrapper(m0);
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( MatrixType m3(wrapper) , 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void test_constructor()
 | 
			
		||||
{
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_1( ctor_init1(Matrix<float, 1, 1>()) );
 | 
			
		||||
    CALL_SUBTEST_1( ctor_init1(Matrix4d()) );
 | 
			
		||||
    CALL_SUBTEST_1( ctor_init1(MatrixXcf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
    CALL_SUBTEST_1( ctor_init1(MatrixXi(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
  }
 | 
			
		||||
  {
 | 
			
		||||
    Matrix<Index,1,1> a(123);
 | 
			
		||||
    VERIFY_IS_EQUAL(a[0], 123);
 | 
			
		||||
  }
 | 
			
		||||
  {
 | 
			
		||||
    Matrix<Index,1,1> a(123.0);
 | 
			
		||||
    VERIFY_IS_EQUAL(a[0], 123);
 | 
			
		||||
  }
 | 
			
		||||
  {
 | 
			
		||||
    Matrix<float,1,1> a(123);
 | 
			
		||||
    VERIFY_IS_EQUAL(a[0], 123.f);
 | 
			
		||||
  }
 | 
			
		||||
  {
 | 
			
		||||
    Array<Index,1,1> a(123);
 | 
			
		||||
    VERIFY_IS_EQUAL(a[0], 123);
 | 
			
		||||
  }
 | 
			
		||||
  {
 | 
			
		||||
    Array<Index,1,1> a(123.0);
 | 
			
		||||
    VERIFY_IS_EQUAL(a[0], 123);
 | 
			
		||||
  }
 | 
			
		||||
  {
 | 
			
		||||
    Array<float,1,1> a(123);
 | 
			
		||||
    VERIFY_IS_EQUAL(a[0], 123.f);
 | 
			
		||||
  }
 | 
			
		||||
  {
 | 
			
		||||
    Array<Index,3,3> a(123);
 | 
			
		||||
    VERIFY_IS_EQUAL(a(4), 123);
 | 
			
		||||
  }
 | 
			
		||||
  {
 | 
			
		||||
    Array<Index,3,3> a(123.0);
 | 
			
		||||
    VERIFY_IS_EQUAL(a(4), 123);
 | 
			
		||||
  }
 | 
			
		||||
  {
 | 
			
		||||
    Array<float,3,3> a(123);
 | 
			
		||||
    VERIFY_IS_EQUAL(a(4), 123.f);
 | 
			
		||||
  }
 | 
			
		||||
  {
 | 
			
		||||
    MatrixXi m1(M,N);
 | 
			
		||||
    VERIFY_IS_EQUAL(m1.rows(),M);
 | 
			
		||||
    VERIFY_IS_EQUAL(m1.cols(),N);
 | 
			
		||||
    ArrayXXi a1(M,N);
 | 
			
		||||
    VERIFY_IS_EQUAL(a1.rows(),M);
 | 
			
		||||
    VERIFY_IS_EQUAL(a1.cols(),N);
 | 
			
		||||
    VectorXi v1(M);
 | 
			
		||||
    VERIFY_IS_EQUAL(v1.size(),M);
 | 
			
		||||
    ArrayXi a2(M);
 | 
			
		||||
    VERIFY_IS_EQUAL(a2.size(),M);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										117
									
								
								cs440-acg/ext/eigen/test/corners.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										117
									
								
								cs440-acg/ext/eigen/test/corners.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,117 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
 | 
			
		||||
#define COMPARE_CORNER(A,B) \
 | 
			
		||||
  VERIFY_IS_EQUAL(matrix.A, matrix.B); \
 | 
			
		||||
  VERIFY_IS_EQUAL(const_matrix.A, const_matrix.B);
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void corners(const MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  Index rows = m.rows();
 | 
			
		||||
  Index cols = m.cols();
 | 
			
		||||
 | 
			
		||||
  Index r = internal::random<Index>(1,rows);
 | 
			
		||||
  Index c = internal::random<Index>(1,cols);
 | 
			
		||||
 | 
			
		||||
  MatrixType matrix = MatrixType::Random(rows,cols);
 | 
			
		||||
  const MatrixType const_matrix = MatrixType::Random(rows,cols);
 | 
			
		||||
 | 
			
		||||
  COMPARE_CORNER(topLeftCorner(r,c), block(0,0,r,c));
 | 
			
		||||
  COMPARE_CORNER(topRightCorner(r,c), block(0,cols-c,r,c));
 | 
			
		||||
  COMPARE_CORNER(bottomLeftCorner(r,c), block(rows-r,0,r,c));
 | 
			
		||||
  COMPARE_CORNER(bottomRightCorner(r,c), block(rows-r,cols-c,r,c));
 | 
			
		||||
 | 
			
		||||
  Index sr = internal::random<Index>(1,rows) - 1;
 | 
			
		||||
  Index nr = internal::random<Index>(1,rows-sr);
 | 
			
		||||
  Index sc = internal::random<Index>(1,cols) - 1;
 | 
			
		||||
  Index nc = internal::random<Index>(1,cols-sc);
 | 
			
		||||
 | 
			
		||||
  COMPARE_CORNER(topRows(r), block(0,0,r,cols));
 | 
			
		||||
  COMPARE_CORNER(middleRows(sr,nr), block(sr,0,nr,cols));
 | 
			
		||||
  COMPARE_CORNER(bottomRows(r), block(rows-r,0,r,cols));
 | 
			
		||||
  COMPARE_CORNER(leftCols(c), block(0,0,rows,c));
 | 
			
		||||
  COMPARE_CORNER(middleCols(sc,nc), block(0,sc,rows,nc));
 | 
			
		||||
  COMPARE_CORNER(rightCols(c), block(0,cols-c,rows,c));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType, int CRows, int CCols, int SRows, int SCols> void corners_fixedsize()
 | 
			
		||||
{
 | 
			
		||||
  MatrixType matrix = MatrixType::Random();
 | 
			
		||||
  const MatrixType const_matrix = MatrixType::Random();
 | 
			
		||||
 | 
			
		||||
  enum {
 | 
			
		||||
    rows = MatrixType::RowsAtCompileTime,
 | 
			
		||||
    cols = MatrixType::ColsAtCompileTime,
 | 
			
		||||
    r = CRows,
 | 
			
		||||
    c = CCols,
 | 
			
		||||
	sr = SRows,
 | 
			
		||||
	sc = SCols
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_EQUAL((matrix.template topLeftCorner<r,c>()), (matrix.template block<r,c>(0,0)));
 | 
			
		||||
  VERIFY_IS_EQUAL((matrix.template topRightCorner<r,c>()), (matrix.template block<r,c>(0,cols-c)));
 | 
			
		||||
  VERIFY_IS_EQUAL((matrix.template bottomLeftCorner<r,c>()), (matrix.template block<r,c>(rows-r,0)));
 | 
			
		||||
  VERIFY_IS_EQUAL((matrix.template bottomRightCorner<r,c>()), (matrix.template block<r,c>(rows-r,cols-c)));
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_EQUAL((matrix.template topLeftCorner<r,c>()), (matrix.template topLeftCorner<r,Dynamic>(r,c)));
 | 
			
		||||
  VERIFY_IS_EQUAL((matrix.template topRightCorner<r,c>()), (matrix.template topRightCorner<r,Dynamic>(r,c)));
 | 
			
		||||
  VERIFY_IS_EQUAL((matrix.template bottomLeftCorner<r,c>()), (matrix.template bottomLeftCorner<r,Dynamic>(r,c)));
 | 
			
		||||
  VERIFY_IS_EQUAL((matrix.template bottomRightCorner<r,c>()), (matrix.template bottomRightCorner<r,Dynamic>(r,c)));
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_EQUAL((matrix.template topLeftCorner<r,c>()), (matrix.template topLeftCorner<Dynamic,c>(r,c)));
 | 
			
		||||
  VERIFY_IS_EQUAL((matrix.template topRightCorner<r,c>()), (matrix.template topRightCorner<Dynamic,c>(r,c)));
 | 
			
		||||
  VERIFY_IS_EQUAL((matrix.template bottomLeftCorner<r,c>()), (matrix.template bottomLeftCorner<Dynamic,c>(r,c)));
 | 
			
		||||
  VERIFY_IS_EQUAL((matrix.template bottomRightCorner<r,c>()), (matrix.template bottomRightCorner<Dynamic,c>(r,c)));
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_EQUAL((matrix.template topRows<r>()), (matrix.template block<r,cols>(0,0)));
 | 
			
		||||
  VERIFY_IS_EQUAL((matrix.template middleRows<r>(sr)), (matrix.template block<r,cols>(sr,0)));
 | 
			
		||||
  VERIFY_IS_EQUAL((matrix.template bottomRows<r>()), (matrix.template block<r,cols>(rows-r,0)));
 | 
			
		||||
  VERIFY_IS_EQUAL((matrix.template leftCols<c>()), (matrix.template block<rows,c>(0,0)));
 | 
			
		||||
  VERIFY_IS_EQUAL((matrix.template middleCols<c>(sc)), (matrix.template block<rows,c>(0,sc)));
 | 
			
		||||
  VERIFY_IS_EQUAL((matrix.template rightCols<c>()), (matrix.template block<rows,c>(0,cols-c)));
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_EQUAL((const_matrix.template topLeftCorner<r,c>()), (const_matrix.template block<r,c>(0,0)));
 | 
			
		||||
  VERIFY_IS_EQUAL((const_matrix.template topRightCorner<r,c>()), (const_matrix.template block<r,c>(0,cols-c)));
 | 
			
		||||
  VERIFY_IS_EQUAL((const_matrix.template bottomLeftCorner<r,c>()), (const_matrix.template block<r,c>(rows-r,0)));
 | 
			
		||||
  VERIFY_IS_EQUAL((const_matrix.template bottomRightCorner<r,c>()), (const_matrix.template block<r,c>(rows-r,cols-c)));
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_EQUAL((const_matrix.template topLeftCorner<r,c>()), (const_matrix.template topLeftCorner<r,Dynamic>(r,c)));
 | 
			
		||||
  VERIFY_IS_EQUAL((const_matrix.template topRightCorner<r,c>()), (const_matrix.template topRightCorner<r,Dynamic>(r,c)));
 | 
			
		||||
  VERIFY_IS_EQUAL((const_matrix.template bottomLeftCorner<r,c>()), (const_matrix.template bottomLeftCorner<r,Dynamic>(r,c)));
 | 
			
		||||
  VERIFY_IS_EQUAL((const_matrix.template bottomRightCorner<r,c>()), (const_matrix.template bottomRightCorner<r,Dynamic>(r,c)));
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_EQUAL((const_matrix.template topLeftCorner<r,c>()), (const_matrix.template topLeftCorner<Dynamic,c>(r,c)));
 | 
			
		||||
  VERIFY_IS_EQUAL((const_matrix.template topRightCorner<r,c>()), (const_matrix.template topRightCorner<Dynamic,c>(r,c)));
 | 
			
		||||
  VERIFY_IS_EQUAL((const_matrix.template bottomLeftCorner<r,c>()), (const_matrix.template bottomLeftCorner<Dynamic,c>(r,c)));
 | 
			
		||||
  VERIFY_IS_EQUAL((const_matrix.template bottomRightCorner<r,c>()), (const_matrix.template bottomRightCorner<Dynamic,c>(r,c)));
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_EQUAL((const_matrix.template topRows<r>()), (const_matrix.template block<r,cols>(0,0)));
 | 
			
		||||
  VERIFY_IS_EQUAL((const_matrix.template middleRows<r>(sr)), (const_matrix.template block<r,cols>(sr,0)));
 | 
			
		||||
  VERIFY_IS_EQUAL((const_matrix.template bottomRows<r>()), (const_matrix.template block<r,cols>(rows-r,0)));
 | 
			
		||||
  VERIFY_IS_EQUAL((const_matrix.template leftCols<c>()), (const_matrix.template block<rows,c>(0,0)));
 | 
			
		||||
  VERIFY_IS_EQUAL((const_matrix.template middleCols<c>(sc)), (const_matrix.template block<rows,c>(0,sc)));
 | 
			
		||||
  VERIFY_IS_EQUAL((const_matrix.template rightCols<c>()), (const_matrix.template block<rows,c>(0,cols-c)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_corners()
 | 
			
		||||
{
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_1( corners(Matrix<float, 1, 1>()) );
 | 
			
		||||
    CALL_SUBTEST_2( corners(Matrix4d()) );
 | 
			
		||||
    CALL_SUBTEST_3( corners(Matrix<int,10,12>()) );
 | 
			
		||||
    CALL_SUBTEST_4( corners(MatrixXcf(5, 7)) );
 | 
			
		||||
    CALL_SUBTEST_5( corners(MatrixXf(21, 20)) );
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_1(( corners_fixedsize<Matrix<float, 1, 1>, 1, 1, 0, 0>() ));
 | 
			
		||||
    CALL_SUBTEST_2(( corners_fixedsize<Matrix4d,2,2,1,1>() ));
 | 
			
		||||
    CALL_SUBTEST_3(( corners_fixedsize<Matrix<int,10,12>,4,7,5,2>() ));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										81
									
								
								cs440-acg/ext/eigen/test/ctorleak.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								cs440-acg/ext/eigen/test/ctorleak.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,81 @@
 | 
			
		||||
#include "main.h"
 | 
			
		||||
 | 
			
		||||
#include <exception>  // std::exception
 | 
			
		||||
 | 
			
		||||
struct Foo
 | 
			
		||||
{
 | 
			
		||||
  static Index object_count;
 | 
			
		||||
  static Index object_limit;
 | 
			
		||||
  int dummy;
 | 
			
		||||
 | 
			
		||||
  Foo() : dummy(0)
 | 
			
		||||
  {
 | 
			
		||||
#ifdef EIGEN_EXCEPTIONS
 | 
			
		||||
    // TODO: Is this the correct way to handle this?
 | 
			
		||||
    if (Foo::object_count > Foo::object_limit) { std::cout << "\nThrow!\n"; throw Foo::Fail(); }
 | 
			
		||||
#endif
 | 
			
		||||
	  std::cout << '+';
 | 
			
		||||
    ++Foo::object_count;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ~Foo()
 | 
			
		||||
  {
 | 
			
		||||
	  std::cout << '-';
 | 
			
		||||
    --Foo::object_count;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  class Fail : public std::exception {};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Index Foo::object_count = 0;
 | 
			
		||||
Index Foo::object_limit = 0;
 | 
			
		||||
 | 
			
		||||
#undef EIGEN_TEST_MAX_SIZE
 | 
			
		||||
#define EIGEN_TEST_MAX_SIZE 3
 | 
			
		||||
 | 
			
		||||
void test_ctorleak()
 | 
			
		||||
{
 | 
			
		||||
  typedef Matrix<Foo, Dynamic, Dynamic> MatrixX;
 | 
			
		||||
  typedef Matrix<Foo, Dynamic, 1> VectorX;
 | 
			
		||||
  
 | 
			
		||||
  Foo::object_count = 0;
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    Index rows = internal::random<Index>(2,EIGEN_TEST_MAX_SIZE), cols = internal::random<Index>(2,EIGEN_TEST_MAX_SIZE);
 | 
			
		||||
    Foo::object_limit = rows*cols;
 | 
			
		||||
    {
 | 
			
		||||
    MatrixX r(rows, cols);
 | 
			
		||||
    Foo::object_limit = r.size()+internal::random<Index>(0, rows*cols - 2);
 | 
			
		||||
    std::cout << "object_limit =" << Foo::object_limit << std::endl;
 | 
			
		||||
#ifdef EIGEN_EXCEPTIONS
 | 
			
		||||
    try
 | 
			
		||||
    {
 | 
			
		||||
#endif
 | 
			
		||||
      if(internal::random<bool>()) {
 | 
			
		||||
        std::cout <<       "\nMatrixX m(" << rows << ", " << cols << ");\n";
 | 
			
		||||
        MatrixX m(rows, cols);
 | 
			
		||||
      }
 | 
			
		||||
      else {
 | 
			
		||||
        std::cout <<       "\nMatrixX m(r);\n";
 | 
			
		||||
        MatrixX m(r);
 | 
			
		||||
      }
 | 
			
		||||
#ifdef EIGEN_EXCEPTIONS
 | 
			
		||||
      VERIFY(false);  // not reached if exceptions are enabled
 | 
			
		||||
    }
 | 
			
		||||
    catch (const Foo::Fail&) { /* ignore */ }
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
    VERIFY_IS_EQUAL(Index(0), Foo::object_count);
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
      Foo::object_limit = (rows+1)*(cols+1);
 | 
			
		||||
      MatrixX A(rows, cols);
 | 
			
		||||
      VERIFY_IS_EQUAL(Foo::object_count, rows*cols);
 | 
			
		||||
      VectorX v=A.row(0);
 | 
			
		||||
      VERIFY_IS_EQUAL(Foo::object_count, (rows+1)*cols);
 | 
			
		||||
      v = A.col(0);
 | 
			
		||||
      VERIFY_IS_EQUAL(Foo::object_count, rows*(cols+1));
 | 
			
		||||
    }
 | 
			
		||||
    VERIFY_IS_EQUAL(Index(0), Foo::object_count);
 | 
			
		||||
  }
 | 
			
		||||
  std::cout << "\n";
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										170
									
								
								cs440-acg/ext/eigen/test/cuda_basic.cu
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										170
									
								
								cs440-acg/ext/eigen/test/cuda_basic.cu
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,170 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2015-2016 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
// workaround issue between gcc >= 4.7 and cuda 5.5
 | 
			
		||||
#if (defined __GNUC__) && (__GNUC__>4 || __GNUC_MINOR__>=7)
 | 
			
		||||
  #undef _GLIBCXX_ATOMIC_BUILTINS
 | 
			
		||||
  #undef _GLIBCXX_USE_INT128
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define EIGEN_TEST_NO_LONGDOUBLE
 | 
			
		||||
#define EIGEN_TEST_NO_COMPLEX
 | 
			
		||||
#define EIGEN_TEST_FUNC cuda_basic
 | 
			
		||||
#define EIGEN_DEFAULT_DENSE_INDEX_TYPE int
 | 
			
		||||
 | 
			
		||||
#include <math_constants.h>
 | 
			
		||||
#include <cuda.h>
 | 
			
		||||
#include "main.h"
 | 
			
		||||
#include "cuda_common.h"
 | 
			
		||||
 | 
			
		||||
// Check that dense modules can be properly parsed by nvcc
 | 
			
		||||
#include <Eigen/Dense>
 | 
			
		||||
 | 
			
		||||
// struct Foo{
 | 
			
		||||
//   EIGEN_DEVICE_FUNC
 | 
			
		||||
//   void operator()(int i, const float* mats, float* vecs) const {
 | 
			
		||||
//     using namespace Eigen;
 | 
			
		||||
//   //   Matrix3f M(data);
 | 
			
		||||
//   //   Vector3f x(data+9);
 | 
			
		||||
//   //   Map<Vector3f>(data+9) = M.inverse() * x;
 | 
			
		||||
//     Matrix3f M(mats+i/16);
 | 
			
		||||
//     Vector3f x(vecs+i*3);
 | 
			
		||||
//   //   using std::min;
 | 
			
		||||
//   //   using std::sqrt;
 | 
			
		||||
//     Map<Vector3f>(vecs+i*3) << x.minCoeff(), 1, 2;// / x.dot(x);//(M.inverse() *  x) / x.x();
 | 
			
		||||
//     //x = x*2 + x.y() * x + x * x.maxCoeff() - x / x.sum();
 | 
			
		||||
//   }
 | 
			
		||||
// };
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
struct coeff_wise {
 | 
			
		||||
  EIGEN_DEVICE_FUNC
 | 
			
		||||
  void operator()(int i, const typename T::Scalar* in, typename T::Scalar* out) const
 | 
			
		||||
  {
 | 
			
		||||
    using namespace Eigen;
 | 
			
		||||
    T x1(in+i);
 | 
			
		||||
    T x2(in+i+1);
 | 
			
		||||
    T x3(in+i+2);
 | 
			
		||||
    Map<T> res(out+i*T::MaxSizeAtCompileTime);
 | 
			
		||||
    
 | 
			
		||||
    res.array() += (in[0] * x1 + x2).array() * x3.array();
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
struct replicate {
 | 
			
		||||
  EIGEN_DEVICE_FUNC
 | 
			
		||||
  void operator()(int i, const typename T::Scalar* in, typename T::Scalar* out) const
 | 
			
		||||
  {
 | 
			
		||||
    using namespace Eigen;
 | 
			
		||||
    T x1(in+i);
 | 
			
		||||
    int step   = x1.size() * 4;
 | 
			
		||||
    int stride = 3 * step;
 | 
			
		||||
    
 | 
			
		||||
    typedef Map<Array<typename T::Scalar,Dynamic,Dynamic> > MapType;
 | 
			
		||||
    MapType(out+i*stride+0*step, x1.rows()*2, x1.cols()*2) = x1.replicate(2,2);
 | 
			
		||||
    MapType(out+i*stride+1*step, x1.rows()*3, x1.cols()) = in[i] * x1.colwise().replicate(3);
 | 
			
		||||
    MapType(out+i*stride+2*step, x1.rows(), x1.cols()*3) = in[i] * x1.rowwise().replicate(3);
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
struct redux {
 | 
			
		||||
  EIGEN_DEVICE_FUNC
 | 
			
		||||
  void operator()(int i, const typename T::Scalar* in, typename T::Scalar* out) const
 | 
			
		||||
  {
 | 
			
		||||
    using namespace Eigen;
 | 
			
		||||
    int N = 10;
 | 
			
		||||
    T x1(in+i);
 | 
			
		||||
    out[i*N+0] = x1.minCoeff();
 | 
			
		||||
    out[i*N+1] = x1.maxCoeff();
 | 
			
		||||
    out[i*N+2] = x1.sum();
 | 
			
		||||
    out[i*N+3] = x1.prod();
 | 
			
		||||
    out[i*N+4] = x1.matrix().squaredNorm();
 | 
			
		||||
    out[i*N+5] = x1.matrix().norm();
 | 
			
		||||
    out[i*N+6] = x1.colwise().sum().maxCoeff();
 | 
			
		||||
    out[i*N+7] = x1.rowwise().maxCoeff().sum();
 | 
			
		||||
    out[i*N+8] = x1.matrix().colwise().squaredNorm().sum();
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename T1, typename T2>
 | 
			
		||||
struct prod_test {
 | 
			
		||||
  EIGEN_DEVICE_FUNC
 | 
			
		||||
  void operator()(int i, const typename T1::Scalar* in, typename T1::Scalar* out) const
 | 
			
		||||
  {
 | 
			
		||||
    using namespace Eigen;
 | 
			
		||||
    typedef Matrix<typename T1::Scalar, T1::RowsAtCompileTime, T2::ColsAtCompileTime> T3;
 | 
			
		||||
    T1 x1(in+i);
 | 
			
		||||
    T2 x2(in+i+1);
 | 
			
		||||
    Map<T3> res(out+i*T3::MaxSizeAtCompileTime);
 | 
			
		||||
    res += in[i] * x1 * x2;
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename T1, typename T2>
 | 
			
		||||
struct diagonal {
 | 
			
		||||
  EIGEN_DEVICE_FUNC
 | 
			
		||||
  void operator()(int i, const typename T1::Scalar* in, typename T1::Scalar* out) const
 | 
			
		||||
  {
 | 
			
		||||
    using namespace Eigen;
 | 
			
		||||
    T1 x1(in+i);
 | 
			
		||||
    Map<T2> res(out+i*T2::MaxSizeAtCompileTime);
 | 
			
		||||
    res += x1.diagonal();
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
struct eigenvalues {
 | 
			
		||||
  EIGEN_DEVICE_FUNC
 | 
			
		||||
  void operator()(int i, const typename T::Scalar* in, typename T::Scalar* out) const
 | 
			
		||||
  {
 | 
			
		||||
    using namespace Eigen;
 | 
			
		||||
    typedef Matrix<typename T::Scalar, T::RowsAtCompileTime, 1> Vec;
 | 
			
		||||
    T M(in+i);
 | 
			
		||||
    Map<Vec> res(out+i*Vec::MaxSizeAtCompileTime);
 | 
			
		||||
    T A = M*M.adjoint();
 | 
			
		||||
    SelfAdjointEigenSolver<T> eig;
 | 
			
		||||
    eig.computeDirect(M);
 | 
			
		||||
    res = eig.eigenvalues();
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void test_cuda_basic()
 | 
			
		||||
{
 | 
			
		||||
  ei_test_init_cuda();
 | 
			
		||||
  
 | 
			
		||||
  int nthreads = 100;
 | 
			
		||||
  Eigen::VectorXf in, out;
 | 
			
		||||
  
 | 
			
		||||
  #ifndef __CUDA_ARCH__
 | 
			
		||||
  int data_size = nthreads * 512;
 | 
			
		||||
  in.setRandom(data_size);
 | 
			
		||||
  out.setRandom(data_size);
 | 
			
		||||
  #endif
 | 
			
		||||
  
 | 
			
		||||
  CALL_SUBTEST( run_and_compare_to_cuda(coeff_wise<Vector3f>(), nthreads, in, out) );
 | 
			
		||||
  CALL_SUBTEST( run_and_compare_to_cuda(coeff_wise<Array44f>(), nthreads, in, out) );
 | 
			
		||||
  
 | 
			
		||||
  CALL_SUBTEST( run_and_compare_to_cuda(replicate<Array4f>(), nthreads, in, out) );
 | 
			
		||||
  CALL_SUBTEST( run_and_compare_to_cuda(replicate<Array33f>(), nthreads, in, out) );
 | 
			
		||||
  
 | 
			
		||||
  CALL_SUBTEST( run_and_compare_to_cuda(redux<Array4f>(), nthreads, in, out) );
 | 
			
		||||
  CALL_SUBTEST( run_and_compare_to_cuda(redux<Matrix3f>(), nthreads, in, out) );
 | 
			
		||||
  
 | 
			
		||||
  CALL_SUBTEST( run_and_compare_to_cuda(prod_test<Matrix3f,Matrix3f>(), nthreads, in, out) );
 | 
			
		||||
  CALL_SUBTEST( run_and_compare_to_cuda(prod_test<Matrix4f,Vector4f>(), nthreads, in, out) );
 | 
			
		||||
  
 | 
			
		||||
  CALL_SUBTEST( run_and_compare_to_cuda(diagonal<Matrix3f,Vector3f>(), nthreads, in, out) );
 | 
			
		||||
  CALL_SUBTEST( run_and_compare_to_cuda(diagonal<Matrix4f,Vector4f>(), nthreads, in, out) );
 | 
			
		||||
  
 | 
			
		||||
  CALL_SUBTEST( run_and_compare_to_cuda(eigenvalues<Matrix3f>(), nthreads, in, out) );
 | 
			
		||||
  CALL_SUBTEST( run_and_compare_to_cuda(eigenvalues<Matrix2f>(), nthreads, in, out) );
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										101
									
								
								cs440-acg/ext/eigen/test/cuda_common.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								cs440-acg/ext/eigen/test/cuda_common.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,101 @@
 | 
			
		||||
 | 
			
		||||
#ifndef EIGEN_TEST_CUDA_COMMON_H
 | 
			
		||||
#define EIGEN_TEST_CUDA_COMMON_H
 | 
			
		||||
 | 
			
		||||
#include <cuda.h>
 | 
			
		||||
#include <cuda_runtime.h>
 | 
			
		||||
#include <cuda_runtime_api.h>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
 | 
			
		||||
#ifndef __CUDACC__
 | 
			
		||||
dim3 threadIdx, blockDim, blockIdx;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
template<typename Kernel, typename Input, typename Output>
 | 
			
		||||
void run_on_cpu(const Kernel& ker, int n, const Input& in, Output& out)
 | 
			
		||||
{
 | 
			
		||||
  for(int i=0; i<n; i++)
 | 
			
		||||
    ker(i, in.data(), out.data());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template<typename Kernel, typename Input, typename Output>
 | 
			
		||||
__global__
 | 
			
		||||
void run_on_cuda_meta_kernel(const Kernel ker, int n, const Input* in, Output* out)
 | 
			
		||||
{
 | 
			
		||||
  int i = threadIdx.x + blockIdx.x*blockDim.x;
 | 
			
		||||
  if(i<n) {
 | 
			
		||||
    ker(i, in, out);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template<typename Kernel, typename Input, typename Output>
 | 
			
		||||
void run_on_cuda(const Kernel& ker, int n, const Input& in, Output& out)
 | 
			
		||||
{
 | 
			
		||||
  typename Input::Scalar*  d_in;
 | 
			
		||||
  typename Output::Scalar* d_out;
 | 
			
		||||
  std::ptrdiff_t in_bytes  = in.size()  * sizeof(typename Input::Scalar);
 | 
			
		||||
  std::ptrdiff_t out_bytes = out.size() * sizeof(typename Output::Scalar);
 | 
			
		||||
  
 | 
			
		||||
  cudaMalloc((void**)(&d_in),  in_bytes);
 | 
			
		||||
  cudaMalloc((void**)(&d_out), out_bytes);
 | 
			
		||||
  
 | 
			
		||||
  cudaMemcpy(d_in,  in.data(),  in_bytes,  cudaMemcpyHostToDevice);
 | 
			
		||||
  cudaMemcpy(d_out, out.data(), out_bytes, cudaMemcpyHostToDevice);
 | 
			
		||||
  
 | 
			
		||||
  // Simple and non-optimal 1D mapping assuming n is not too large
 | 
			
		||||
  // That's only for unit testing!
 | 
			
		||||
  dim3 Blocks(128);
 | 
			
		||||
  dim3 Grids( (n+int(Blocks.x)-1)/int(Blocks.x) );
 | 
			
		||||
 | 
			
		||||
  cudaThreadSynchronize();
 | 
			
		||||
  run_on_cuda_meta_kernel<<<Grids,Blocks>>>(ker, n, d_in, d_out);
 | 
			
		||||
  cudaThreadSynchronize();
 | 
			
		||||
  
 | 
			
		||||
  // check inputs have not been modified
 | 
			
		||||
  cudaMemcpy(const_cast<typename Input::Scalar*>(in.data()),  d_in,  in_bytes,  cudaMemcpyDeviceToHost);
 | 
			
		||||
  cudaMemcpy(out.data(), d_out, out_bytes, cudaMemcpyDeviceToHost);
 | 
			
		||||
  
 | 
			
		||||
  cudaFree(d_in);
 | 
			
		||||
  cudaFree(d_out);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template<typename Kernel, typename Input, typename Output>
 | 
			
		||||
void run_and_compare_to_cuda(const Kernel& ker, int n, const Input& in, Output& out)
 | 
			
		||||
{
 | 
			
		||||
  Input  in_ref,  in_cuda;
 | 
			
		||||
  Output out_ref, out_cuda;
 | 
			
		||||
  #ifndef __CUDA_ARCH__
 | 
			
		||||
  in_ref = in_cuda = in;
 | 
			
		||||
  out_ref = out_cuda = out;
 | 
			
		||||
  #endif
 | 
			
		||||
  run_on_cpu (ker, n, in_ref,  out_ref);
 | 
			
		||||
  run_on_cuda(ker, n, in_cuda, out_cuda);
 | 
			
		||||
  #ifndef __CUDA_ARCH__
 | 
			
		||||
  VERIFY_IS_APPROX(in_ref, in_cuda);
 | 
			
		||||
  VERIFY_IS_APPROX(out_ref, out_cuda);
 | 
			
		||||
  #endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void ei_test_init_cuda()
 | 
			
		||||
{
 | 
			
		||||
  int device = 0;
 | 
			
		||||
  cudaDeviceProp deviceProp;
 | 
			
		||||
  cudaGetDeviceProperties(&deviceProp, device);
 | 
			
		||||
  std::cout << "CUDA device info:\n";
 | 
			
		||||
  std::cout << "  name:                        " << deviceProp.name << "\n";
 | 
			
		||||
  std::cout << "  capability:                  " << deviceProp.major << "." << deviceProp.minor << "\n";
 | 
			
		||||
  std::cout << "  multiProcessorCount:         " << deviceProp.multiProcessorCount << "\n";
 | 
			
		||||
  std::cout << "  maxThreadsPerMultiProcessor: " << deviceProp.maxThreadsPerMultiProcessor << "\n";
 | 
			
		||||
  std::cout << "  warpSize:                    " << deviceProp.warpSize << "\n";
 | 
			
		||||
  std::cout << "  regsPerBlock:                " << deviceProp.regsPerBlock << "\n";
 | 
			
		||||
  std::cout << "  concurrentKernels:           " << deviceProp.concurrentKernels << "\n";
 | 
			
		||||
  std::cout << "  clockRate:                   " << deviceProp.clockRate << "\n";
 | 
			
		||||
  std::cout << "  canMapHostMemory:            " << deviceProp.canMapHostMemory << "\n";
 | 
			
		||||
  std::cout << "  computeMode:                 " << deviceProp.computeMode << "\n";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // EIGEN_TEST_CUDA_COMMON_H
 | 
			
		||||
							
								
								
									
										190
									
								
								cs440-acg/ext/eigen/test/denseLM.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										190
									
								
								cs440-acg/ext/eigen/test/denseLM.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,190 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2012 Desire Nuentsa <desire.nuentsa_wakam@inria.fr>
 | 
			
		||||
// Copyright (C) 2012 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <fstream>
 | 
			
		||||
#include <iomanip>
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
#include <Eigen/LevenbergMarquardt>
 | 
			
		||||
using namespace std;
 | 
			
		||||
using namespace Eigen;
 | 
			
		||||
 | 
			
		||||
template<typename Scalar>
 | 
			
		||||
struct DenseLM : DenseFunctor<Scalar>
 | 
			
		||||
{
 | 
			
		||||
  typedef DenseFunctor<Scalar> Base;
 | 
			
		||||
  typedef typename Base::JacobianType JacobianType;
 | 
			
		||||
  typedef Matrix<Scalar,Dynamic,1> VectorType;
 | 
			
		||||
  
 | 
			
		||||
  DenseLM(int n, int m) : DenseFunctor<Scalar>(n,m) 
 | 
			
		||||
  { }
 | 
			
		||||
 
 | 
			
		||||
  VectorType model(const VectorType& uv, VectorType& x)
 | 
			
		||||
  {
 | 
			
		||||
    VectorType y; // Should change to use expression template
 | 
			
		||||
    int m = Base::values(); 
 | 
			
		||||
    int n = Base::inputs();
 | 
			
		||||
    eigen_assert(uv.size()%2 == 0);
 | 
			
		||||
    eigen_assert(uv.size() == n);
 | 
			
		||||
    eigen_assert(x.size() == m);
 | 
			
		||||
    y.setZero(m);
 | 
			
		||||
    int half = n/2;
 | 
			
		||||
    VectorBlock<const VectorType> u(uv, 0, half);
 | 
			
		||||
    VectorBlock<const VectorType> v(uv, half, half);
 | 
			
		||||
    for (int j = 0; j < m; j++)
 | 
			
		||||
    {
 | 
			
		||||
      for (int i = 0; i < half; i++)
 | 
			
		||||
        y(j) += u(i)*std::exp(-(x(j)-i)*(x(j)-i)/(v(i)*v(i)));
 | 
			
		||||
    }
 | 
			
		||||
    return y;
 | 
			
		||||
    
 | 
			
		||||
  }
 | 
			
		||||
  void initPoints(VectorType& uv_ref, VectorType& x)
 | 
			
		||||
  {
 | 
			
		||||
    m_x = x;
 | 
			
		||||
    m_y = this->model(uv_ref, x);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  int operator()(const VectorType& uv, VectorType& fvec)
 | 
			
		||||
  {
 | 
			
		||||
    
 | 
			
		||||
    int m = Base::values(); 
 | 
			
		||||
    int n = Base::inputs();
 | 
			
		||||
    eigen_assert(uv.size()%2 == 0);
 | 
			
		||||
    eigen_assert(uv.size() == n);
 | 
			
		||||
    eigen_assert(fvec.size() == m);
 | 
			
		||||
    int half = n/2;
 | 
			
		||||
    VectorBlock<const VectorType> u(uv, 0, half);
 | 
			
		||||
    VectorBlock<const VectorType> v(uv, half, half);
 | 
			
		||||
    for (int j = 0; j < m; j++)
 | 
			
		||||
    {
 | 
			
		||||
      fvec(j) = m_y(j);
 | 
			
		||||
      for (int i = 0; i < half; i++)
 | 
			
		||||
      {
 | 
			
		||||
        fvec(j) -= u(i) *std::exp(-(m_x(j)-i)*(m_x(j)-i)/(v(i)*v(i)));
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    return 0;
 | 
			
		||||
  }
 | 
			
		||||
  int df(const VectorType& uv, JacobianType& fjac)
 | 
			
		||||
  {
 | 
			
		||||
    int m = Base::values(); 
 | 
			
		||||
    int n = Base::inputs();
 | 
			
		||||
    eigen_assert(n == uv.size());
 | 
			
		||||
    eigen_assert(fjac.rows() == m);
 | 
			
		||||
    eigen_assert(fjac.cols() == n);
 | 
			
		||||
    int half = n/2;
 | 
			
		||||
    VectorBlock<const VectorType> u(uv, 0, half);
 | 
			
		||||
    VectorBlock<const VectorType> v(uv, half, half);
 | 
			
		||||
    for (int j = 0; j < m; j++)
 | 
			
		||||
    {
 | 
			
		||||
      for (int i = 0; i < half; i++)
 | 
			
		||||
      {
 | 
			
		||||
        fjac.coeffRef(j,i) = -std::exp(-(m_x(j)-i)*(m_x(j)-i)/(v(i)*v(i)));
 | 
			
		||||
        fjac.coeffRef(j,i+half) = -2.*u(i)*(m_x(j)-i)*(m_x(j)-i)/(std::pow(v(i),3)) * std::exp(-(m_x(j)-i)*(m_x(j)-i)/(v(i)*v(i)));
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
  }
 | 
			
		||||
  VectorType m_x, m_y; //Data Points
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename FunctorType, typename VectorType>
 | 
			
		||||
int test_minimizeLM(FunctorType& functor, VectorType& uv)
 | 
			
		||||
{
 | 
			
		||||
  LevenbergMarquardt<FunctorType> lm(functor);
 | 
			
		||||
  LevenbergMarquardtSpace::Status info; 
 | 
			
		||||
  
 | 
			
		||||
  info = lm.minimize(uv);
 | 
			
		||||
  
 | 
			
		||||
  VERIFY_IS_EQUAL(info, 1);
 | 
			
		||||
  //FIXME Check other parameters
 | 
			
		||||
  return info;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename FunctorType, typename VectorType>
 | 
			
		||||
int test_lmder(FunctorType& functor, VectorType& uv)
 | 
			
		||||
{
 | 
			
		||||
  typedef typename VectorType::Scalar Scalar;
 | 
			
		||||
  LevenbergMarquardtSpace::Status info; 
 | 
			
		||||
  LevenbergMarquardt<FunctorType> lm(functor);
 | 
			
		||||
  info = lm.lmder1(uv);
 | 
			
		||||
  
 | 
			
		||||
  VERIFY_IS_EQUAL(info, 1);
 | 
			
		||||
  //FIXME Check other parameters
 | 
			
		||||
  return info;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename FunctorType, typename VectorType>
 | 
			
		||||
int test_minimizeSteps(FunctorType& functor, VectorType& uv)
 | 
			
		||||
{
 | 
			
		||||
  LevenbergMarquardtSpace::Status info;   
 | 
			
		||||
  LevenbergMarquardt<FunctorType> lm(functor);
 | 
			
		||||
  info = lm.minimizeInit(uv);
 | 
			
		||||
  if (info==LevenbergMarquardtSpace::ImproperInputParameters)
 | 
			
		||||
      return info;
 | 
			
		||||
  do 
 | 
			
		||||
  {
 | 
			
		||||
    info = lm.minimizeOneStep(uv);
 | 
			
		||||
  } while (info==LevenbergMarquardtSpace::Running);
 | 
			
		||||
  
 | 
			
		||||
  VERIFY_IS_EQUAL(info, 1);
 | 
			
		||||
  //FIXME Check other parameters
 | 
			
		||||
  return info;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
void test_denseLM_T()
 | 
			
		||||
{
 | 
			
		||||
  typedef Matrix<T,Dynamic,1> VectorType;
 | 
			
		||||
  
 | 
			
		||||
  int inputs = 10; 
 | 
			
		||||
  int values = 1000; 
 | 
			
		||||
  DenseLM<T> dense_gaussian(inputs, values);
 | 
			
		||||
  VectorType uv(inputs),uv_ref(inputs);
 | 
			
		||||
  VectorType x(values);
 | 
			
		||||
  
 | 
			
		||||
  // Generate the reference solution 
 | 
			
		||||
  uv_ref << -2, 1, 4 ,8, 6, 1.8, 1.2, 1.1, 1.9 , 3;
 | 
			
		||||
  
 | 
			
		||||
  //Generate the reference data points
 | 
			
		||||
  x.setRandom();
 | 
			
		||||
  x = 10*x;
 | 
			
		||||
  x.array() += 10;
 | 
			
		||||
  dense_gaussian.initPoints(uv_ref, x);
 | 
			
		||||
  
 | 
			
		||||
  // Generate the initial parameters 
 | 
			
		||||
  VectorBlock<VectorType> u(uv, 0, inputs/2); 
 | 
			
		||||
  VectorBlock<VectorType> v(uv, inputs/2, inputs/2);
 | 
			
		||||
  
 | 
			
		||||
  // Solve the optimization problem
 | 
			
		||||
  
 | 
			
		||||
  //Solve in one go
 | 
			
		||||
  u.setOnes(); v.setOnes();
 | 
			
		||||
  test_minimizeLM(dense_gaussian, uv);
 | 
			
		||||
  
 | 
			
		||||
  //Solve until the machine precision
 | 
			
		||||
  u.setOnes(); v.setOnes();
 | 
			
		||||
  test_lmder(dense_gaussian, uv); 
 | 
			
		||||
  
 | 
			
		||||
  // Solve step by step
 | 
			
		||||
  v.setOnes(); u.setOnes();
 | 
			
		||||
  test_minimizeSteps(dense_gaussian, uv);
 | 
			
		||||
  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_denseLM()
 | 
			
		||||
{
 | 
			
		||||
  CALL_SUBTEST_2(test_denseLM_T<double>());
 | 
			
		||||
  
 | 
			
		||||
  // CALL_SUBTEST_2(test_sparseLM_T<std::complex<double>());
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										76
									
								
								cs440-acg/ext/eigen/test/dense_storage.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								cs440-acg/ext/eigen/test/dense_storage.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,76 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2013 Hauke Heibel <hauke.heibel@gmail.com>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
 | 
			
		||||
#include <Eigen/Core>
 | 
			
		||||
 | 
			
		||||
template <typename T, int Rows, int Cols>
 | 
			
		||||
void dense_storage_copy()
 | 
			
		||||
{
 | 
			
		||||
  static const int Size = ((Rows==Dynamic || Cols==Dynamic) ? Dynamic : Rows*Cols);
 | 
			
		||||
  typedef DenseStorage<T,Size, Rows,Cols, 0> DenseStorageType;
 | 
			
		||||
  
 | 
			
		||||
  const int rows = (Rows==Dynamic) ? 4 : Rows;
 | 
			
		||||
  const int cols = (Cols==Dynamic) ? 3 : Cols;
 | 
			
		||||
  const int size = rows*cols;
 | 
			
		||||
  DenseStorageType reference(size, rows, cols);
 | 
			
		||||
  T* raw_reference = reference.data();
 | 
			
		||||
  for (int i=0; i<size; ++i)
 | 
			
		||||
    raw_reference[i] = static_cast<T>(i);
 | 
			
		||||
    
 | 
			
		||||
  DenseStorageType copied_reference(reference);
 | 
			
		||||
  const T* raw_copied_reference = copied_reference.data();
 | 
			
		||||
  for (int i=0; i<size; ++i)
 | 
			
		||||
    VERIFY_IS_EQUAL(raw_reference[i], raw_copied_reference[i]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T, int Rows, int Cols>
 | 
			
		||||
void dense_storage_assignment()
 | 
			
		||||
{
 | 
			
		||||
  static const int Size = ((Rows==Dynamic || Cols==Dynamic) ? Dynamic : Rows*Cols);
 | 
			
		||||
  typedef DenseStorage<T,Size, Rows,Cols, 0> DenseStorageType;
 | 
			
		||||
  
 | 
			
		||||
  const int rows = (Rows==Dynamic) ? 4 : Rows;
 | 
			
		||||
  const int cols = (Cols==Dynamic) ? 3 : Cols;
 | 
			
		||||
  const int size = rows*cols;
 | 
			
		||||
  DenseStorageType reference(size, rows, cols);
 | 
			
		||||
  T* raw_reference = reference.data();
 | 
			
		||||
  for (int i=0; i<size; ++i)
 | 
			
		||||
    raw_reference[i] = static_cast<T>(i);
 | 
			
		||||
    
 | 
			
		||||
  DenseStorageType copied_reference;
 | 
			
		||||
  copied_reference = reference;
 | 
			
		||||
  const T* raw_copied_reference = copied_reference.data();
 | 
			
		||||
  for (int i=0; i<size; ++i)
 | 
			
		||||
    VERIFY_IS_EQUAL(raw_reference[i], raw_copied_reference[i]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_dense_storage()
 | 
			
		||||
{
 | 
			
		||||
  dense_storage_copy<int,Dynamic,Dynamic>();  
 | 
			
		||||
  dense_storage_copy<int,Dynamic,3>();
 | 
			
		||||
  dense_storage_copy<int,4,Dynamic>();
 | 
			
		||||
  dense_storage_copy<int,4,3>();
 | 
			
		||||
 | 
			
		||||
  dense_storage_copy<float,Dynamic,Dynamic>();
 | 
			
		||||
  dense_storage_copy<float,Dynamic,3>();
 | 
			
		||||
  dense_storage_copy<float,4,Dynamic>();  
 | 
			
		||||
  dense_storage_copy<float,4,3>();
 | 
			
		||||
  
 | 
			
		||||
  dense_storage_assignment<int,Dynamic,Dynamic>();  
 | 
			
		||||
  dense_storage_assignment<int,Dynamic,3>();
 | 
			
		||||
  dense_storage_assignment<int,4,Dynamic>();
 | 
			
		||||
  dense_storage_assignment<int,4,3>();
 | 
			
		||||
 | 
			
		||||
  dense_storage_assignment<float,Dynamic,Dynamic>();
 | 
			
		||||
  dense_storage_assignment<float,Dynamic,3>();
 | 
			
		||||
  dense_storage_assignment<float,4,Dynamic>();  
 | 
			
		||||
  dense_storage_assignment<float,4,3>();  
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										66
									
								
								cs440-acg/ext/eigen/test/determinant.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								cs440-acg/ext/eigen/test/determinant.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,66 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
 | 
			
		||||
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
#include <Eigen/LU>
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void determinant(const MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  /* this test covers the following files:
 | 
			
		||||
     Determinant.h
 | 
			
		||||
  */
 | 
			
		||||
  Index size = m.rows();
 | 
			
		||||
 | 
			
		||||
  MatrixType m1(size, size), m2(size, size);
 | 
			
		||||
  m1.setRandom();
 | 
			
		||||
  m2.setRandom();
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
  Scalar x = internal::random<Scalar>();
 | 
			
		||||
  VERIFY_IS_APPROX(MatrixType::Identity(size, size).determinant(), Scalar(1));
 | 
			
		||||
  VERIFY_IS_APPROX((m1*m2).eval().determinant(), m1.determinant() * m2.determinant());
 | 
			
		||||
  if(size==1) return;
 | 
			
		||||
  Index i = internal::random<Index>(0, size-1);
 | 
			
		||||
  Index j;
 | 
			
		||||
  do {
 | 
			
		||||
    j = internal::random<Index>(0, size-1);
 | 
			
		||||
  } while(j==i);
 | 
			
		||||
  m2 = m1;
 | 
			
		||||
  m2.row(i).swap(m2.row(j));
 | 
			
		||||
  VERIFY_IS_APPROX(m2.determinant(), -m1.determinant());
 | 
			
		||||
  m2 = m1;
 | 
			
		||||
  m2.col(i).swap(m2.col(j));
 | 
			
		||||
  VERIFY_IS_APPROX(m2.determinant(), -m1.determinant());
 | 
			
		||||
  VERIFY_IS_APPROX(m2.determinant(), m2.transpose().determinant());
 | 
			
		||||
  VERIFY_IS_APPROX(numext::conj(m2.determinant()), m2.adjoint().determinant());
 | 
			
		||||
  m2 = m1;
 | 
			
		||||
  m2.row(i) += x*m2.row(j);
 | 
			
		||||
  VERIFY_IS_APPROX(m2.determinant(), m1.determinant());
 | 
			
		||||
  m2 = m1;
 | 
			
		||||
  m2.row(i) *= x;
 | 
			
		||||
  VERIFY_IS_APPROX(m2.determinant(), m1.determinant() * x);
 | 
			
		||||
  
 | 
			
		||||
  // check empty matrix
 | 
			
		||||
  VERIFY_IS_APPROX(m2.block(0,0,0,0).determinant(), Scalar(1));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_determinant()
 | 
			
		||||
{
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    int s = 0;
 | 
			
		||||
    CALL_SUBTEST_1( determinant(Matrix<float, 1, 1>()) );
 | 
			
		||||
    CALL_SUBTEST_2( determinant(Matrix<double, 2, 2>()) );
 | 
			
		||||
    CALL_SUBTEST_3( determinant(Matrix<double, 3, 3>()) );
 | 
			
		||||
    CALL_SUBTEST_4( determinant(Matrix<double, 4, 4>()) );
 | 
			
		||||
    CALL_SUBTEST_5( determinant(Matrix<std::complex<double>, 10, 10>()) );
 | 
			
		||||
    s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/4);
 | 
			
		||||
    CALL_SUBTEST_6( determinant(MatrixXd(s, s)) );
 | 
			
		||||
    TEST_SET_BUT_UNUSED_VARIABLE(s)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										105
									
								
								cs440-acg/ext/eigen/test/diagonal.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								cs440-acg/ext/eigen/test/diagonal.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,105 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void diagonal(const MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
 | 
			
		||||
  Index rows = m.rows();
 | 
			
		||||
  Index cols = m.cols();
 | 
			
		||||
 | 
			
		||||
  MatrixType m1 = MatrixType::Random(rows, cols),
 | 
			
		||||
             m2 = MatrixType::Random(rows, cols);
 | 
			
		||||
 | 
			
		||||
  Scalar s1 = internal::random<Scalar>();
 | 
			
		||||
 | 
			
		||||
  //check diagonal()
 | 
			
		||||
  VERIFY_IS_APPROX(m1.diagonal(), m1.transpose().diagonal());
 | 
			
		||||
  m2.diagonal() = 2 * m1.diagonal();
 | 
			
		||||
  m2.diagonal()[0] *= 3;
 | 
			
		||||
 | 
			
		||||
  if (rows>2)
 | 
			
		||||
  {
 | 
			
		||||
    enum {
 | 
			
		||||
      N1 = MatrixType::RowsAtCompileTime>2 ?  2 : 0,
 | 
			
		||||
      N2 = MatrixType::RowsAtCompileTime>1 ? -1 : 0
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // check sub/super diagonal
 | 
			
		||||
    if(MatrixType::SizeAtCompileTime!=Dynamic)
 | 
			
		||||
    {
 | 
			
		||||
      VERIFY(m1.template diagonal<N1>().RowsAtCompileTime == m1.diagonal(N1).size());
 | 
			
		||||
      VERIFY(m1.template diagonal<N2>().RowsAtCompileTime == m1.diagonal(N2).size());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    m2.template diagonal<N1>() = 2 * m1.template diagonal<N1>();
 | 
			
		||||
    VERIFY_IS_APPROX(m2.template diagonal<N1>(), static_cast<Scalar>(2) * m1.diagonal(N1));
 | 
			
		||||
    m2.template diagonal<N1>()[0] *= 3;
 | 
			
		||||
    VERIFY_IS_APPROX(m2.template diagonal<N1>()[0], static_cast<Scalar>(6) * m1.template diagonal<N1>()[0]);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    m2.template diagonal<N2>() = 2 * m1.template diagonal<N2>();
 | 
			
		||||
    m2.template diagonal<N2>()[0] *= 3;
 | 
			
		||||
    VERIFY_IS_APPROX(m2.template diagonal<N2>()[0], static_cast<Scalar>(6) * m1.template diagonal<N2>()[0]);
 | 
			
		||||
 | 
			
		||||
    m2.diagonal(N1) = 2 * m1.diagonal(N1);
 | 
			
		||||
    VERIFY_IS_APPROX(m2.template diagonal<N1>(), static_cast<Scalar>(2) * m1.diagonal(N1));
 | 
			
		||||
    m2.diagonal(N1)[0] *= 3;
 | 
			
		||||
    VERIFY_IS_APPROX(m2.diagonal(N1)[0], static_cast<Scalar>(6) * m1.diagonal(N1)[0]);
 | 
			
		||||
 | 
			
		||||
    m2.diagonal(N2) = 2 * m1.diagonal(N2);
 | 
			
		||||
    VERIFY_IS_APPROX(m2.template diagonal<N2>(), static_cast<Scalar>(2) * m1.diagonal(N2));
 | 
			
		||||
    m2.diagonal(N2)[0] *= 3;
 | 
			
		||||
    VERIFY_IS_APPROX(m2.diagonal(N2)[0], static_cast<Scalar>(6) * m1.diagonal(N2)[0]);
 | 
			
		||||
 | 
			
		||||
    m2.diagonal(N2).x() = s1;
 | 
			
		||||
    VERIFY_IS_APPROX(m2.diagonal(N2).x(), s1);
 | 
			
		||||
    m2.diagonal(N2).coeffRef(0) = Scalar(2)*s1;
 | 
			
		||||
    VERIFY_IS_APPROX(m2.diagonal(N2).coeff(0), Scalar(2)*s1);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  VERIFY( m1.diagonal( cols).size()==0 );
 | 
			
		||||
  VERIFY( m1.diagonal(-rows).size()==0 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void diagonal_assert(const MatrixType& m) {
 | 
			
		||||
  Index rows = m.rows();
 | 
			
		||||
  Index cols = m.cols();
 | 
			
		||||
 | 
			
		||||
  MatrixType m1 = MatrixType::Random(rows, cols);
 | 
			
		||||
 | 
			
		||||
  if (rows>=2 && cols>=2)
 | 
			
		||||
  {
 | 
			
		||||
    VERIFY_RAISES_ASSERT( m1 += m1.diagonal() );
 | 
			
		||||
    VERIFY_RAISES_ASSERT( m1 -= m1.diagonal() );
 | 
			
		||||
    VERIFY_RAISES_ASSERT( m1.array() *= m1.diagonal().array() );
 | 
			
		||||
    VERIFY_RAISES_ASSERT( m1.array() /= m1.diagonal().array() );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  VERIFY_RAISES_ASSERT( m1.diagonal(cols+1) );
 | 
			
		||||
  VERIFY_RAISES_ASSERT( m1.diagonal(-(rows+1)) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_diagonal()
 | 
			
		||||
{
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_1( diagonal(Matrix<float, 1, 1>()) );
 | 
			
		||||
    CALL_SUBTEST_1( diagonal(Matrix<float, 4, 9>()) );
 | 
			
		||||
    CALL_SUBTEST_1( diagonal(Matrix<float, 7, 3>()) );
 | 
			
		||||
    CALL_SUBTEST_2( diagonal(Matrix4d()) );
 | 
			
		||||
    CALL_SUBTEST_2( diagonal(MatrixXcf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
    CALL_SUBTEST_2( diagonal(MatrixXi(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
    CALL_SUBTEST_2( diagonal(MatrixXcd(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
    CALL_SUBTEST_1( diagonal(MatrixXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
    CALL_SUBTEST_1( diagonal(Matrix<float,Dynamic,4>(3, 4)) );
 | 
			
		||||
    CALL_SUBTEST_1( diagonal_assert(MatrixXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										166
									
								
								cs440-acg/ext/eigen/test/diagonalmatrices.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										166
									
								
								cs440-acg/ext/eigen/test/diagonalmatrices.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,166 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
using namespace std;
 | 
			
		||||
template<typename MatrixType> void diagonalmatrices(const MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
  enum { Rows = MatrixType::RowsAtCompileTime, Cols = MatrixType::ColsAtCompileTime };
 | 
			
		||||
  typedef Matrix<Scalar, Rows, 1> VectorType;
 | 
			
		||||
  typedef Matrix<Scalar, 1, Cols> RowVectorType;
 | 
			
		||||
  typedef Matrix<Scalar, Rows, Rows> SquareMatrixType;
 | 
			
		||||
  typedef Matrix<Scalar, Dynamic, Dynamic> DynMatrixType;
 | 
			
		||||
  typedef DiagonalMatrix<Scalar, Rows> LeftDiagonalMatrix;
 | 
			
		||||
  typedef DiagonalMatrix<Scalar, Cols> RightDiagonalMatrix;
 | 
			
		||||
  typedef Matrix<Scalar, Rows==Dynamic?Dynamic:2*Rows, Cols==Dynamic?Dynamic:2*Cols> BigMatrix;
 | 
			
		||||
  Index rows = m.rows();
 | 
			
		||||
  Index cols = m.cols();
 | 
			
		||||
 | 
			
		||||
  MatrixType m1 = MatrixType::Random(rows, cols),
 | 
			
		||||
             m2 = MatrixType::Random(rows, cols);
 | 
			
		||||
  VectorType v1 = VectorType::Random(rows),
 | 
			
		||||
             v2 = VectorType::Random(rows);
 | 
			
		||||
  RowVectorType rv1 = RowVectorType::Random(cols),
 | 
			
		||||
             rv2 = RowVectorType::Random(cols);
 | 
			
		||||
 | 
			
		||||
  LeftDiagonalMatrix ldm1(v1), ldm2(v2);
 | 
			
		||||
  RightDiagonalMatrix rdm1(rv1), rdm2(rv2);
 | 
			
		||||
  
 | 
			
		||||
  Scalar s1 = internal::random<Scalar>();
 | 
			
		||||
 | 
			
		||||
  SquareMatrixType sq_m1 (v1.asDiagonal());
 | 
			
		||||
  VERIFY_IS_APPROX(sq_m1, v1.asDiagonal().toDenseMatrix());
 | 
			
		||||
  sq_m1 = v1.asDiagonal();
 | 
			
		||||
  VERIFY_IS_APPROX(sq_m1, v1.asDiagonal().toDenseMatrix());
 | 
			
		||||
  SquareMatrixType sq_m2 = v1.asDiagonal();
 | 
			
		||||
  VERIFY_IS_APPROX(sq_m1, sq_m2);
 | 
			
		||||
  
 | 
			
		||||
  ldm1 = v1.asDiagonal();
 | 
			
		||||
  LeftDiagonalMatrix ldm3(v1);
 | 
			
		||||
  VERIFY_IS_APPROX(ldm1.diagonal(), ldm3.diagonal());
 | 
			
		||||
  LeftDiagonalMatrix ldm4 = v1.asDiagonal();
 | 
			
		||||
  VERIFY_IS_APPROX(ldm1.diagonal(), ldm4.diagonal());
 | 
			
		||||
  
 | 
			
		||||
  sq_m1.block(0,0,rows,rows) = ldm1;
 | 
			
		||||
  VERIFY_IS_APPROX(sq_m1, ldm1.toDenseMatrix());
 | 
			
		||||
  sq_m1.transpose() = ldm1;
 | 
			
		||||
  VERIFY_IS_APPROX(sq_m1, ldm1.toDenseMatrix());
 | 
			
		||||
  
 | 
			
		||||
  Index i = internal::random<Index>(0, rows-1);
 | 
			
		||||
  Index j = internal::random<Index>(0, cols-1);
 | 
			
		||||
  
 | 
			
		||||
  VERIFY_IS_APPROX( ((ldm1 * m1)(i,j))  , ldm1.diagonal()(i) * m1(i,j) );
 | 
			
		||||
  VERIFY_IS_APPROX( ((ldm1 * (m1+m2))(i,j))  , ldm1.diagonal()(i) * (m1+m2)(i,j) );
 | 
			
		||||
  VERIFY_IS_APPROX( ((m1 * rdm1)(i,j))  , rdm1.diagonal()(j) * m1(i,j) );
 | 
			
		||||
  VERIFY_IS_APPROX( ((v1.asDiagonal() * m1)(i,j))  , v1(i) * m1(i,j) );
 | 
			
		||||
  VERIFY_IS_APPROX( ((m1 * rv1.asDiagonal())(i,j))  , rv1(j) * m1(i,j) );
 | 
			
		||||
  VERIFY_IS_APPROX( (((v1+v2).asDiagonal() * m1)(i,j))  , (v1+v2)(i) * m1(i,j) );
 | 
			
		||||
  VERIFY_IS_APPROX( (((v1+v2).asDiagonal() * (m1+m2))(i,j))  , (v1+v2)(i) * (m1+m2)(i,j) );
 | 
			
		||||
  VERIFY_IS_APPROX( ((m1 * (rv1+rv2).asDiagonal())(i,j))  , (rv1+rv2)(j) * m1(i,j) );
 | 
			
		||||
  VERIFY_IS_APPROX( (((m1+m2) * (rv1+rv2).asDiagonal())(i,j))  , (rv1+rv2)(j) * (m1+m2)(i,j) );
 | 
			
		||||
  
 | 
			
		||||
  if(rows>1)
 | 
			
		||||
  {
 | 
			
		||||
    DynMatrixType tmp = m1.topRows(rows/2), res;
 | 
			
		||||
    VERIFY_IS_APPROX( (res = m1.topRows(rows/2) * rv1.asDiagonal()), tmp * rv1.asDiagonal() );
 | 
			
		||||
    VERIFY_IS_APPROX( (res = v1.head(rows/2).asDiagonal()*m1.topRows(rows/2)), v1.head(rows/2).asDiagonal()*tmp );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  BigMatrix big;
 | 
			
		||||
  big.setZero(2*rows, 2*cols);
 | 
			
		||||
  
 | 
			
		||||
  big.block(i,j,rows,cols) = m1;
 | 
			
		||||
  big.block(i,j,rows,cols) = v1.asDiagonal() * big.block(i,j,rows,cols);
 | 
			
		||||
  
 | 
			
		||||
  VERIFY_IS_APPROX((big.block(i,j,rows,cols)) , v1.asDiagonal() * m1 );
 | 
			
		||||
  
 | 
			
		||||
  big.block(i,j,rows,cols) = m1;
 | 
			
		||||
  big.block(i,j,rows,cols) = big.block(i,j,rows,cols) * rv1.asDiagonal();
 | 
			
		||||
  VERIFY_IS_APPROX((big.block(i,j,rows,cols)) , m1 * rv1.asDiagonal() );
 | 
			
		||||
  
 | 
			
		||||
  
 | 
			
		||||
  // scalar multiple
 | 
			
		||||
  VERIFY_IS_APPROX(LeftDiagonalMatrix(ldm1*s1).diagonal(), ldm1.diagonal() * s1);
 | 
			
		||||
  VERIFY_IS_APPROX(LeftDiagonalMatrix(s1*ldm1).diagonal(), s1 * ldm1.diagonal());
 | 
			
		||||
  
 | 
			
		||||
  VERIFY_IS_APPROX(m1 * (rdm1 * s1), (m1 * rdm1) * s1);
 | 
			
		||||
  VERIFY_IS_APPROX(m1 * (s1 * rdm1), (m1 * rdm1) * s1);
 | 
			
		||||
  
 | 
			
		||||
  // Diagonal to dense
 | 
			
		||||
  sq_m1.setRandom();
 | 
			
		||||
  sq_m2 = sq_m1;
 | 
			
		||||
  VERIFY_IS_APPROX( (sq_m1 += (s1*v1).asDiagonal()), sq_m2 += (s1*v1).asDiagonal().toDenseMatrix() );
 | 
			
		||||
  VERIFY_IS_APPROX( (sq_m1 -= (s1*v1).asDiagonal()), sq_m2 -= (s1*v1).asDiagonal().toDenseMatrix() );
 | 
			
		||||
  VERIFY_IS_APPROX( (sq_m1 = (s1*v1).asDiagonal()), (s1*v1).asDiagonal().toDenseMatrix() );
 | 
			
		||||
 | 
			
		||||
  sq_m1.setRandom();
 | 
			
		||||
  sq_m2 = v1.asDiagonal();
 | 
			
		||||
  sq_m2 = sq_m1 * sq_m2;
 | 
			
		||||
  VERIFY_IS_APPROX( (sq_m1*v1.asDiagonal()).col(i), sq_m2.col(i) );
 | 
			
		||||
  VERIFY_IS_APPROX( (sq_m1*v1.asDiagonal()).row(i), sq_m2.row(i) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void as_scalar_product(const MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;
 | 
			
		||||
  typedef Matrix<Scalar, Dynamic, Dynamic> DynMatrixType;
 | 
			
		||||
  typedef Matrix<Scalar, Dynamic, 1> DynVectorType;
 | 
			
		||||
  typedef Matrix<Scalar, 1, Dynamic> DynRowVectorType;
 | 
			
		||||
 | 
			
		||||
  Index rows = m.rows();
 | 
			
		||||
  Index depth = internal::random<Index>(1,EIGEN_TEST_MAX_SIZE);
 | 
			
		||||
 | 
			
		||||
  VectorType v1 = VectorType::Random(rows);  
 | 
			
		||||
  DynVectorType     dv1  = DynVectorType::Random(depth);
 | 
			
		||||
  DynRowVectorType  drv1 = DynRowVectorType::Random(depth);
 | 
			
		||||
  DynMatrixType     dm1  = dv1;
 | 
			
		||||
  DynMatrixType     drm1 = drv1;
 | 
			
		||||
  
 | 
			
		||||
  Scalar s = v1(0);
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX( v1.asDiagonal() * drv1, s*drv1 );
 | 
			
		||||
  VERIFY_IS_APPROX( dv1 * v1.asDiagonal(), dv1*s );
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX( v1.asDiagonal() * drm1, s*drm1 );
 | 
			
		||||
  VERIFY_IS_APPROX( dm1 * v1.asDiagonal(), dm1*s );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<int>
 | 
			
		||||
void bug987()
 | 
			
		||||
{
 | 
			
		||||
  Matrix3Xd points = Matrix3Xd::Random(3, 3);
 | 
			
		||||
  Vector2d diag = Vector2d::Random();
 | 
			
		||||
  Matrix2Xd tmp1 = points.topRows<2>(), res1, res2;
 | 
			
		||||
  VERIFY_IS_APPROX( res1 = diag.asDiagonal() * points.topRows<2>(), res2 = diag.asDiagonal() * tmp1 );
 | 
			
		||||
  Matrix2d tmp2 = points.topLeftCorner<2,2>();
 | 
			
		||||
  VERIFY_IS_APPROX(( res1 = points.topLeftCorner<2,2>()*diag.asDiagonal()) , res2 = tmp2*diag.asDiagonal() );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_diagonalmatrices()
 | 
			
		||||
{
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_1( diagonalmatrices(Matrix<float, 1, 1>()) );
 | 
			
		||||
    CALL_SUBTEST_1( as_scalar_product(Matrix<float, 1, 1>()) );
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_2( diagonalmatrices(Matrix3f()) );
 | 
			
		||||
    CALL_SUBTEST_3( diagonalmatrices(Matrix<double,3,3,RowMajor>()) );
 | 
			
		||||
    CALL_SUBTEST_4( diagonalmatrices(Matrix4d()) );
 | 
			
		||||
    CALL_SUBTEST_5( diagonalmatrices(Matrix<float,4,4,RowMajor>()) );
 | 
			
		||||
    CALL_SUBTEST_6( diagonalmatrices(MatrixXcf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
    CALL_SUBTEST_6( as_scalar_product(MatrixXcf(1,1)) );
 | 
			
		||||
    CALL_SUBTEST_7( diagonalmatrices(MatrixXi(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
    CALL_SUBTEST_8( diagonalmatrices(Matrix<double,Dynamic,Dynamic,RowMajor>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
    CALL_SUBTEST_9( diagonalmatrices(MatrixXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
    CALL_SUBTEST_9( diagonalmatrices(MatrixXf(1,1)) );
 | 
			
		||||
    CALL_SUBTEST_9( as_scalar_product(MatrixXf(1,1)) );
 | 
			
		||||
  }
 | 
			
		||||
  CALL_SUBTEST_10( bug987<0>() );
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										62
									
								
								cs440-acg/ext/eigen/test/dontalign.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								cs440-acg/ext/eigen/test/dontalign.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,62 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2011 Benoit Jacob <jacob.benoit.1@gmail.com>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#if defined EIGEN_TEST_PART_1 || defined EIGEN_TEST_PART_2 || defined EIGEN_TEST_PART_3 || defined EIGEN_TEST_PART_4
 | 
			
		||||
#define EIGEN_DONT_ALIGN
 | 
			
		||||
#elif defined EIGEN_TEST_PART_5 || defined EIGEN_TEST_PART_6 || defined EIGEN_TEST_PART_7 || defined EIGEN_TEST_PART_8
 | 
			
		||||
#define EIGEN_DONT_ALIGN_STATICALLY
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
#include <Eigen/Dense>
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType>
 | 
			
		||||
void dontalign(const MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;
 | 
			
		||||
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> SquareMatrixType;
 | 
			
		||||
 | 
			
		||||
  Index rows = m.rows();
 | 
			
		||||
  Index cols = m.cols();
 | 
			
		||||
 | 
			
		||||
  MatrixType a = MatrixType::Random(rows,cols);
 | 
			
		||||
  SquareMatrixType square = SquareMatrixType::Random(rows,rows);
 | 
			
		||||
  VectorType v = VectorType::Random(rows);
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(v, square * square.colPivHouseholderQr().solve(v));
 | 
			
		||||
  square = square.inverse().eval();
 | 
			
		||||
  a = square * a;
 | 
			
		||||
  square = square*square;
 | 
			
		||||
  v = square * v;
 | 
			
		||||
  v = a.adjoint() * v;
 | 
			
		||||
  VERIFY(square.determinant() != Scalar(0));
 | 
			
		||||
 | 
			
		||||
  // bug 219: MapAligned() was giving an assert with EIGEN_DONT_ALIGN, because Map Flags were miscomputed
 | 
			
		||||
  Scalar* array = internal::aligned_new<Scalar>(rows);
 | 
			
		||||
  v = VectorType::MapAligned(array, rows);
 | 
			
		||||
  internal::aligned_delete(array, rows);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_dontalign()
 | 
			
		||||
{
 | 
			
		||||
#if defined EIGEN_TEST_PART_1 || defined EIGEN_TEST_PART_5
 | 
			
		||||
  dontalign(Matrix3d());
 | 
			
		||||
  dontalign(Matrix4f());
 | 
			
		||||
#elif defined EIGEN_TEST_PART_2 || defined EIGEN_TEST_PART_6
 | 
			
		||||
  dontalign(Matrix3cd());
 | 
			
		||||
  dontalign(Matrix4cf());
 | 
			
		||||
#elif defined EIGEN_TEST_PART_3 || defined EIGEN_TEST_PART_7
 | 
			
		||||
  dontalign(Matrix<float, 32, 32>());
 | 
			
		||||
  dontalign(Matrix<std::complex<float>, 32, 32>());
 | 
			
		||||
#elif defined EIGEN_TEST_PART_4 || defined EIGEN_TEST_PART_8
 | 
			
		||||
  dontalign(MatrixXd(32, 32));
 | 
			
		||||
  dontalign(MatrixXcf(32, 32));
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										175
									
								
								cs440-acg/ext/eigen/test/dynalloc.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										175
									
								
								cs440-acg/ext/eigen/test/dynalloc.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,175 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
 | 
			
		||||
#if EIGEN_MAX_ALIGN_BYTES>0
 | 
			
		||||
#define ALIGNMENT EIGEN_MAX_ALIGN_BYTES
 | 
			
		||||
#else
 | 
			
		||||
#define ALIGNMENT 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
typedef Matrix<float,8,1> Vector8f;
 | 
			
		||||
 | 
			
		||||
void check_handmade_aligned_malloc()
 | 
			
		||||
{
 | 
			
		||||
  for(int i = 1; i < 1000; i++)
 | 
			
		||||
  {
 | 
			
		||||
    char *p = (char*)internal::handmade_aligned_malloc(i);
 | 
			
		||||
    VERIFY(internal::UIntPtr(p)%ALIGNMENT==0);
 | 
			
		||||
    // if the buffer is wrongly allocated this will give a bad write --> check with valgrind
 | 
			
		||||
    for(int j = 0; j < i; j++) p[j]=0;
 | 
			
		||||
    internal::handmade_aligned_free(p);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void check_aligned_malloc()
 | 
			
		||||
{
 | 
			
		||||
  for(int i = ALIGNMENT; i < 1000; i++)
 | 
			
		||||
  {
 | 
			
		||||
    char *p = (char*)internal::aligned_malloc(i);
 | 
			
		||||
    VERIFY(internal::UIntPtr(p)%ALIGNMENT==0);
 | 
			
		||||
    // if the buffer is wrongly allocated this will give a bad write --> check with valgrind
 | 
			
		||||
    for(int j = 0; j < i; j++) p[j]=0;
 | 
			
		||||
    internal::aligned_free(p);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void check_aligned_new()
 | 
			
		||||
{
 | 
			
		||||
  for(int i = ALIGNMENT; i < 1000; i++)
 | 
			
		||||
  {
 | 
			
		||||
    float *p = internal::aligned_new<float>(i);
 | 
			
		||||
    VERIFY(internal::UIntPtr(p)%ALIGNMENT==0);
 | 
			
		||||
    // if the buffer is wrongly allocated this will give a bad write --> check with valgrind
 | 
			
		||||
    for(int j = 0; j < i; j++) p[j]=0;
 | 
			
		||||
    internal::aligned_delete(p,i);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void check_aligned_stack_alloc()
 | 
			
		||||
{
 | 
			
		||||
  for(int i = ALIGNMENT; i < 400; i++)
 | 
			
		||||
  {
 | 
			
		||||
    ei_declare_aligned_stack_constructed_variable(float,p,i,0);
 | 
			
		||||
    VERIFY(internal::UIntPtr(p)%ALIGNMENT==0);
 | 
			
		||||
    // if the buffer is wrongly allocated this will give a bad write --> check with valgrind
 | 
			
		||||
    for(int j = 0; j < i; j++) p[j]=0;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// test compilation with both a struct and a class...
 | 
			
		||||
struct MyStruct
 | 
			
		||||
{
 | 
			
		||||
  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
 | 
			
		||||
  char dummychar;
 | 
			
		||||
  Vector8f avec;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class MyClassA
 | 
			
		||||
{
 | 
			
		||||
  public:
 | 
			
		||||
    EIGEN_MAKE_ALIGNED_OPERATOR_NEW
 | 
			
		||||
    char dummychar;
 | 
			
		||||
    Vector8f avec;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename T> void check_dynaligned()
 | 
			
		||||
{
 | 
			
		||||
  // TODO have to be updated once we support multiple alignment values
 | 
			
		||||
  if(T::SizeAtCompileTime % ALIGNMENT == 0)
 | 
			
		||||
  {
 | 
			
		||||
    T* obj = new T;
 | 
			
		||||
    VERIFY(T::NeedsToAlign==1);
 | 
			
		||||
    VERIFY(internal::UIntPtr(obj)%ALIGNMENT==0);
 | 
			
		||||
    delete obj;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T> void check_custom_new_delete()
 | 
			
		||||
{
 | 
			
		||||
  {
 | 
			
		||||
    T* t = new T;
 | 
			
		||||
    delete t;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  {
 | 
			
		||||
    std::size_t N = internal::random<std::size_t>(1,10);
 | 
			
		||||
    T* t = new T[N];
 | 
			
		||||
    delete[] t;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
#if EIGEN_MAX_ALIGN_BYTES>0
 | 
			
		||||
  {
 | 
			
		||||
    T* t = static_cast<T *>((T::operator new)(sizeof(T)));
 | 
			
		||||
    (T::operator delete)(t, sizeof(T));
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  {
 | 
			
		||||
    T* t = static_cast<T *>((T::operator new)(sizeof(T)));
 | 
			
		||||
    (T::operator delete)(t);
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_dynalloc()
 | 
			
		||||
{
 | 
			
		||||
  // low level dynamic memory allocation
 | 
			
		||||
  CALL_SUBTEST(check_handmade_aligned_malloc());
 | 
			
		||||
  CALL_SUBTEST(check_aligned_malloc());
 | 
			
		||||
  CALL_SUBTEST(check_aligned_new());
 | 
			
		||||
  CALL_SUBTEST(check_aligned_stack_alloc());
 | 
			
		||||
 | 
			
		||||
  for (int i=0; i<g_repeat*100; ++i)
 | 
			
		||||
  {
 | 
			
		||||
    CALL_SUBTEST( check_custom_new_delete<Vector4f>() );
 | 
			
		||||
    CALL_SUBTEST( check_custom_new_delete<Vector2f>() );
 | 
			
		||||
    CALL_SUBTEST( check_custom_new_delete<Matrix4f>() );
 | 
			
		||||
    CALL_SUBTEST( check_custom_new_delete<MatrixXi>() );
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  // check static allocation, who knows ?
 | 
			
		||||
  #if EIGEN_MAX_STATIC_ALIGN_BYTES
 | 
			
		||||
  for (int i=0; i<g_repeat*100; ++i)
 | 
			
		||||
  {
 | 
			
		||||
    CALL_SUBTEST(check_dynaligned<Vector4f>() );
 | 
			
		||||
    CALL_SUBTEST(check_dynaligned<Vector2d>() );
 | 
			
		||||
    CALL_SUBTEST(check_dynaligned<Matrix4f>() );
 | 
			
		||||
    CALL_SUBTEST(check_dynaligned<Vector4d>() );
 | 
			
		||||
    CALL_SUBTEST(check_dynaligned<Vector4i>() );
 | 
			
		||||
    CALL_SUBTEST(check_dynaligned<Vector8f>() );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    MyStruct foo0;  VERIFY(internal::UIntPtr(foo0.avec.data())%ALIGNMENT==0);
 | 
			
		||||
    MyClassA fooA;  VERIFY(internal::UIntPtr(fooA.avec.data())%ALIGNMENT==0);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  // dynamic allocation, single object
 | 
			
		||||
  for (int i=0; i<g_repeat*100; ++i)
 | 
			
		||||
  {
 | 
			
		||||
    MyStruct *foo0 = new MyStruct();  VERIFY(internal::UIntPtr(foo0->avec.data())%ALIGNMENT==0);
 | 
			
		||||
    MyClassA *fooA = new MyClassA();  VERIFY(internal::UIntPtr(fooA->avec.data())%ALIGNMENT==0);
 | 
			
		||||
    delete foo0;
 | 
			
		||||
    delete fooA;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // dynamic allocation, array
 | 
			
		||||
  const int N = 10;
 | 
			
		||||
  for (int i=0; i<g_repeat*100; ++i)
 | 
			
		||||
  {
 | 
			
		||||
    MyStruct *foo0 = new MyStruct[N];  VERIFY(internal::UIntPtr(foo0->avec.data())%ALIGNMENT==0);
 | 
			
		||||
    MyClassA *fooA = new MyClassA[N];  VERIFY(internal::UIntPtr(fooA->avec.data())%ALIGNMENT==0);
 | 
			
		||||
    delete[] foo0;
 | 
			
		||||
    delete[] fooA;
 | 
			
		||||
  }
 | 
			
		||||
  #endif
 | 
			
		||||
  
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										65
									
								
								cs440-acg/ext/eigen/test/eigen2support.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								cs440-acg/ext/eigen/test/eigen2support.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,65 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#define EIGEN2_SUPPORT
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void eigen2support(const MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
 | 
			
		||||
  Index rows = m.rows();
 | 
			
		||||
  Index cols = m.cols();
 | 
			
		||||
 | 
			
		||||
  MatrixType m1 = MatrixType::Random(rows, cols),
 | 
			
		||||
             m3(rows, cols);
 | 
			
		||||
 | 
			
		||||
  Scalar  s1 = internal::random<Scalar>(),
 | 
			
		||||
          s2 = internal::random<Scalar>();
 | 
			
		||||
 | 
			
		||||
  // scalar addition
 | 
			
		||||
  VERIFY_IS_APPROX(m1.cwise() + s1, s1 + m1.cwise());
 | 
			
		||||
  VERIFY_IS_APPROX(m1.cwise() + s1, MatrixType::Constant(rows,cols,s1) + m1);
 | 
			
		||||
  VERIFY_IS_APPROX((m1*Scalar(2)).cwise() - s2, (m1+m1) - MatrixType::Constant(rows,cols,s2) );
 | 
			
		||||
  m3 = m1;
 | 
			
		||||
  m3.cwise() += s2;
 | 
			
		||||
  VERIFY_IS_APPROX(m3, m1.cwise() + s2);
 | 
			
		||||
  m3 = m1;
 | 
			
		||||
  m3.cwise() -= s1;
 | 
			
		||||
  VERIFY_IS_APPROX(m3, m1.cwise() - s1);
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_EQUAL((m1.corner(TopLeft,1,1)), (m1.block(0,0,1,1)));
 | 
			
		||||
  VERIFY_IS_EQUAL((m1.template corner<1,1>(TopLeft)), (m1.template block<1,1>(0,0)));
 | 
			
		||||
  VERIFY_IS_EQUAL((m1.col(0).start(1)), (m1.col(0).segment(0,1)));
 | 
			
		||||
  VERIFY_IS_EQUAL((m1.col(0).template start<1>()), (m1.col(0).segment(0,1)));
 | 
			
		||||
  VERIFY_IS_EQUAL((m1.col(0).end(1)), (m1.col(0).segment(rows-1,1)));
 | 
			
		||||
  VERIFY_IS_EQUAL((m1.col(0).template end<1>()), (m1.col(0).segment(rows-1,1)));
 | 
			
		||||
  
 | 
			
		||||
  using std::cos;
 | 
			
		||||
  using numext::real;
 | 
			
		||||
  using numext::abs2;
 | 
			
		||||
  VERIFY_IS_EQUAL(ei_cos(s1), cos(s1));
 | 
			
		||||
  VERIFY_IS_EQUAL(ei_real(s1), real(s1));
 | 
			
		||||
  VERIFY_IS_EQUAL(ei_abs2(s1), abs2(s1));
 | 
			
		||||
 | 
			
		||||
  m1.minor(0,0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_eigen2support()
 | 
			
		||||
{
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_1( eigen2support(Matrix<double,1,1>()) );
 | 
			
		||||
    CALL_SUBTEST_2( eigen2support(MatrixXd(1,1)) );
 | 
			
		||||
    CALL_SUBTEST_4( eigen2support(Matrix3f()) );
 | 
			
		||||
    CALL_SUBTEST_5( eigen2support(Matrix4d()) );
 | 
			
		||||
    CALL_SUBTEST_2( eigen2support(MatrixXf(200,200)) );
 | 
			
		||||
    CALL_SUBTEST_6( eigen2support(MatrixXcd(100,100)) );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										176
									
								
								cs440-acg/ext/eigen/test/eigensolver_complex.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										176
									
								
								cs440-acg/ext/eigen/test/eigensolver_complex.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,176 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
// Copyright (C) 2010 Jitse Niesen <jitse@maths.leeds.ac.uk>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
#include <limits>
 | 
			
		||||
#include <Eigen/Eigenvalues>
 | 
			
		||||
#include <Eigen/LU>
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> bool find_pivot(typename MatrixType::Scalar tol, MatrixType &diffs, Index col=0)
 | 
			
		||||
{
 | 
			
		||||
  bool match = diffs.diagonal().sum() <= tol;
 | 
			
		||||
  if(match || col==diffs.cols())
 | 
			
		||||
  {
 | 
			
		||||
    return match;
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    Index n = diffs.cols();
 | 
			
		||||
    std::vector<std::pair<Index,Index> > transpositions;
 | 
			
		||||
    for(Index i=col; i<n; ++i)
 | 
			
		||||
    {
 | 
			
		||||
      Index best_index(0);
 | 
			
		||||
      if(diffs.col(col).segment(col,n-i).minCoeff(&best_index) > tol)
 | 
			
		||||
        break;
 | 
			
		||||
      
 | 
			
		||||
      best_index += col;
 | 
			
		||||
      
 | 
			
		||||
      diffs.row(col).swap(diffs.row(best_index));
 | 
			
		||||
      if(find_pivot(tol,diffs,col+1)) return true;
 | 
			
		||||
      diffs.row(col).swap(diffs.row(best_index));
 | 
			
		||||
      
 | 
			
		||||
      // move current pivot to the end
 | 
			
		||||
      diffs.row(n-(i-col)-1).swap(diffs.row(best_index));
 | 
			
		||||
      transpositions.push_back(std::pair<Index,Index>(n-(i-col)-1,best_index));
 | 
			
		||||
    }
 | 
			
		||||
    // restore
 | 
			
		||||
    for(Index k=transpositions.size()-1; k>=0; --k)
 | 
			
		||||
      diffs.row(transpositions[k].first).swap(diffs.row(transpositions[k].second));
 | 
			
		||||
  }
 | 
			
		||||
  return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Check that two column vectors are approximately equal upto permutations.
 | 
			
		||||
 * Initially, this method checked that the k-th power sums are equal for all k = 1, ..., vec1.rows(),
 | 
			
		||||
 * however this strategy is numerically inacurate because of numerical cancellation issues.
 | 
			
		||||
 */
 | 
			
		||||
template<typename VectorType>
 | 
			
		||||
void verify_is_approx_upto_permutation(const VectorType& vec1, const VectorType& vec2)
 | 
			
		||||
{
 | 
			
		||||
  typedef typename VectorType::Scalar Scalar;
 | 
			
		||||
  typedef typename NumTraits<Scalar>::Real RealScalar;
 | 
			
		||||
 | 
			
		||||
  VERIFY(vec1.cols() == 1);
 | 
			
		||||
  VERIFY(vec2.cols() == 1);
 | 
			
		||||
  VERIFY(vec1.rows() == vec2.rows());
 | 
			
		||||
  
 | 
			
		||||
  Index n = vec1.rows();
 | 
			
		||||
  RealScalar tol = test_precision<RealScalar>()*test_precision<RealScalar>()*numext::maxi(vec1.squaredNorm(),vec2.squaredNorm());
 | 
			
		||||
  Matrix<RealScalar,Dynamic,Dynamic> diffs = (vec1.rowwise().replicate(n) - vec2.rowwise().replicate(n).transpose()).cwiseAbs2();
 | 
			
		||||
  
 | 
			
		||||
  VERIFY( find_pivot(tol, diffs) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void eigensolver(const MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  /* this test covers the following files:
 | 
			
		||||
     ComplexEigenSolver.h, and indirectly ComplexSchur.h
 | 
			
		||||
  */
 | 
			
		||||
  Index rows = m.rows();
 | 
			
		||||
  Index cols = m.cols();
 | 
			
		||||
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
  typedef typename NumTraits<Scalar>::Real RealScalar;
 | 
			
		||||
 | 
			
		||||
  MatrixType a = MatrixType::Random(rows,cols);
 | 
			
		||||
  MatrixType symmA =  a.adjoint() * a;
 | 
			
		||||
 | 
			
		||||
  ComplexEigenSolver<MatrixType> ei0(symmA);
 | 
			
		||||
  VERIFY_IS_EQUAL(ei0.info(), Success);
 | 
			
		||||
  VERIFY_IS_APPROX(symmA * ei0.eigenvectors(), ei0.eigenvectors() * ei0.eigenvalues().asDiagonal());
 | 
			
		||||
 | 
			
		||||
  ComplexEigenSolver<MatrixType> ei1(a);
 | 
			
		||||
  VERIFY_IS_EQUAL(ei1.info(), Success);
 | 
			
		||||
  VERIFY_IS_APPROX(a * ei1.eigenvectors(), ei1.eigenvectors() * ei1.eigenvalues().asDiagonal());
 | 
			
		||||
  // Note: If MatrixType is real then a.eigenvalues() uses EigenSolver and thus
 | 
			
		||||
  // another algorithm so results may differ slightly
 | 
			
		||||
  verify_is_approx_upto_permutation(a.eigenvalues(), ei1.eigenvalues());
 | 
			
		||||
 | 
			
		||||
  ComplexEigenSolver<MatrixType> ei2;
 | 
			
		||||
  ei2.setMaxIterations(ComplexSchur<MatrixType>::m_maxIterationsPerRow * rows).compute(a);
 | 
			
		||||
  VERIFY_IS_EQUAL(ei2.info(), Success);
 | 
			
		||||
  VERIFY_IS_EQUAL(ei2.eigenvectors(), ei1.eigenvectors());
 | 
			
		||||
  VERIFY_IS_EQUAL(ei2.eigenvalues(), ei1.eigenvalues());
 | 
			
		||||
  if (rows > 2) {
 | 
			
		||||
    ei2.setMaxIterations(1).compute(a);
 | 
			
		||||
    VERIFY_IS_EQUAL(ei2.info(), NoConvergence);
 | 
			
		||||
    VERIFY_IS_EQUAL(ei2.getMaxIterations(), 1);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ComplexEigenSolver<MatrixType> eiNoEivecs(a, false);
 | 
			
		||||
  VERIFY_IS_EQUAL(eiNoEivecs.info(), Success);
 | 
			
		||||
  VERIFY_IS_APPROX(ei1.eigenvalues(), eiNoEivecs.eigenvalues());
 | 
			
		||||
 | 
			
		||||
  // Regression test for issue #66
 | 
			
		||||
  MatrixType z = MatrixType::Zero(rows,cols);
 | 
			
		||||
  ComplexEigenSolver<MatrixType> eiz(z);
 | 
			
		||||
  VERIFY((eiz.eigenvalues().cwiseEqual(0)).all());
 | 
			
		||||
 | 
			
		||||
  MatrixType id = MatrixType::Identity(rows, cols);
 | 
			
		||||
  VERIFY_IS_APPROX(id.operatorNorm(), RealScalar(1));
 | 
			
		||||
 | 
			
		||||
  if (rows > 1 && rows < 20)
 | 
			
		||||
  {
 | 
			
		||||
    // Test matrix with NaN
 | 
			
		||||
    a(0,0) = std::numeric_limits<typename MatrixType::RealScalar>::quiet_NaN();
 | 
			
		||||
    ComplexEigenSolver<MatrixType> eiNaN(a);
 | 
			
		||||
    VERIFY_IS_EQUAL(eiNaN.info(), NoConvergence);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // regression test for bug 1098
 | 
			
		||||
  {
 | 
			
		||||
    ComplexEigenSolver<MatrixType> eig(a.adjoint() * a);
 | 
			
		||||
    eig.compute(a.adjoint() * a);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // regression test for bug 478
 | 
			
		||||
  {
 | 
			
		||||
    a.setZero();
 | 
			
		||||
    ComplexEigenSolver<MatrixType> ei3(a);
 | 
			
		||||
    VERIFY_IS_EQUAL(ei3.info(), Success);
 | 
			
		||||
    VERIFY_IS_MUCH_SMALLER_THAN(ei3.eigenvalues().norm(),RealScalar(1));
 | 
			
		||||
    VERIFY((ei3.eigenvectors().transpose()*ei3.eigenvectors().transpose()).eval().isIdentity());
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void eigensolver_verify_assert(const MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  ComplexEigenSolver<MatrixType> eig;
 | 
			
		||||
  VERIFY_RAISES_ASSERT(eig.eigenvectors());
 | 
			
		||||
  VERIFY_RAISES_ASSERT(eig.eigenvalues());
 | 
			
		||||
 | 
			
		||||
  MatrixType a = MatrixType::Random(m.rows(),m.cols());
 | 
			
		||||
  eig.compute(a, false);
 | 
			
		||||
  VERIFY_RAISES_ASSERT(eig.eigenvectors());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_eigensolver_complex()
 | 
			
		||||
{
 | 
			
		||||
  int s = 0;
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_1( eigensolver(Matrix4cf()) );
 | 
			
		||||
    s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/4);
 | 
			
		||||
    CALL_SUBTEST_2( eigensolver(MatrixXcd(s,s)) );
 | 
			
		||||
    CALL_SUBTEST_3( eigensolver(Matrix<std::complex<float>, 1, 1>()) );
 | 
			
		||||
    CALL_SUBTEST_4( eigensolver(Matrix3f()) );
 | 
			
		||||
    TEST_SET_BUT_UNUSED_VARIABLE(s)
 | 
			
		||||
  }
 | 
			
		||||
  CALL_SUBTEST_1( eigensolver_verify_assert(Matrix4cf()) );
 | 
			
		||||
  s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/4);
 | 
			
		||||
  CALL_SUBTEST_2( eigensolver_verify_assert(MatrixXcd(s,s)) );
 | 
			
		||||
  CALL_SUBTEST_3( eigensolver_verify_assert(Matrix<std::complex<float>, 1, 1>()) );
 | 
			
		||||
  CALL_SUBTEST_4( eigensolver_verify_assert(Matrix3f()) );
 | 
			
		||||
 | 
			
		||||
  // Test problem size constructors
 | 
			
		||||
  CALL_SUBTEST_5(ComplexEigenSolver<MatrixXf> tmp(s));
 | 
			
		||||
  
 | 
			
		||||
  TEST_SET_BUT_UNUSED_VARIABLE(s)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										103
									
								
								cs440-acg/ext/eigen/test/eigensolver_generalized_real.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								cs440-acg/ext/eigen/test/eigensolver_generalized_real.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,103 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2012-2016 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#define EIGEN_RUNTIME_NO_MALLOC
 | 
			
		||||
#include "main.h"
 | 
			
		||||
#include <limits>
 | 
			
		||||
#include <Eigen/Eigenvalues>
 | 
			
		||||
#include <Eigen/LU>
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void generalized_eigensolver_real(const MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  /* this test covers the following files:
 | 
			
		||||
     GeneralizedEigenSolver.h
 | 
			
		||||
  */
 | 
			
		||||
  Index rows = m.rows();
 | 
			
		||||
  Index cols = m.cols();
 | 
			
		||||
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
  typedef std::complex<Scalar> ComplexScalar;
 | 
			
		||||
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;
 | 
			
		||||
 | 
			
		||||
  MatrixType a = MatrixType::Random(rows,cols);
 | 
			
		||||
  MatrixType b = MatrixType::Random(rows,cols);
 | 
			
		||||
  MatrixType a1 = MatrixType::Random(rows,cols);
 | 
			
		||||
  MatrixType b1 = MatrixType::Random(rows,cols);
 | 
			
		||||
  MatrixType spdA =  a.adjoint() * a + a1.adjoint() * a1;
 | 
			
		||||
  MatrixType spdB =  b.adjoint() * b + b1.adjoint() * b1;
 | 
			
		||||
 | 
			
		||||
  // lets compare to GeneralizedSelfAdjointEigenSolver
 | 
			
		||||
  {
 | 
			
		||||
    GeneralizedSelfAdjointEigenSolver<MatrixType> symmEig(spdA, spdB);
 | 
			
		||||
    GeneralizedEigenSolver<MatrixType> eig(spdA, spdB);
 | 
			
		||||
 | 
			
		||||
    VERIFY_IS_EQUAL(eig.eigenvalues().imag().cwiseAbs().maxCoeff(), 0);
 | 
			
		||||
 | 
			
		||||
    VectorType realEigenvalues = eig.eigenvalues().real();
 | 
			
		||||
    std::sort(realEigenvalues.data(), realEigenvalues.data()+realEigenvalues.size());
 | 
			
		||||
    VERIFY_IS_APPROX(realEigenvalues, symmEig.eigenvalues());
 | 
			
		||||
 | 
			
		||||
    // check eigenvectors
 | 
			
		||||
    typename GeneralizedEigenSolver<MatrixType>::EigenvectorsType D = eig.eigenvalues().asDiagonal();
 | 
			
		||||
    typename GeneralizedEigenSolver<MatrixType>::EigenvectorsType V = eig.eigenvectors();
 | 
			
		||||
    VERIFY_IS_APPROX(spdA*V, spdB*V*D);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // non symmetric case:
 | 
			
		||||
  {
 | 
			
		||||
    GeneralizedEigenSolver<MatrixType> eig(rows);
 | 
			
		||||
    // TODO enable full-prealocation of required memory, this probably requires an in-place mode for HessenbergDecomposition
 | 
			
		||||
    //Eigen::internal::set_is_malloc_allowed(false);
 | 
			
		||||
    eig.compute(a,b);
 | 
			
		||||
    //Eigen::internal::set_is_malloc_allowed(true);
 | 
			
		||||
    for(Index k=0; k<cols; ++k)
 | 
			
		||||
    {
 | 
			
		||||
      Matrix<ComplexScalar,Dynamic,Dynamic> tmp = (eig.betas()(k)*a).template cast<ComplexScalar>() - eig.alphas()(k)*b;
 | 
			
		||||
      if(tmp.size()>1 && tmp.norm()>(std::numeric_limits<Scalar>::min)())
 | 
			
		||||
        tmp /= tmp.norm();
 | 
			
		||||
      VERIFY_IS_MUCH_SMALLER_THAN( std::abs(tmp.determinant()), Scalar(1) );
 | 
			
		||||
    }
 | 
			
		||||
    // check eigenvectors
 | 
			
		||||
    typename GeneralizedEigenSolver<MatrixType>::EigenvectorsType D = eig.eigenvalues().asDiagonal();
 | 
			
		||||
    typename GeneralizedEigenSolver<MatrixType>::EigenvectorsType V = eig.eigenvectors();
 | 
			
		||||
    VERIFY_IS_APPROX(a*V, b*V*D);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // regression test for bug 1098
 | 
			
		||||
  {
 | 
			
		||||
    GeneralizedSelfAdjointEigenSolver<MatrixType> eig1(a.adjoint() * a,b.adjoint() * b);
 | 
			
		||||
    eig1.compute(a.adjoint() * a,b.adjoint() * b);
 | 
			
		||||
    GeneralizedEigenSolver<MatrixType> eig2(a.adjoint() * a,b.adjoint() * b);
 | 
			
		||||
    eig2.compute(a.adjoint() * a,b.adjoint() * b);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // check without eigenvectors
 | 
			
		||||
  {
 | 
			
		||||
    GeneralizedEigenSolver<MatrixType> eig1(spdA, spdB, true);
 | 
			
		||||
    GeneralizedEigenSolver<MatrixType> eig2(spdA, spdB, false);
 | 
			
		||||
    VERIFY_IS_APPROX(eig1.eigenvalues(), eig2.eigenvalues());
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_eigensolver_generalized_real()
 | 
			
		||||
{
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    int s = 0;
 | 
			
		||||
    CALL_SUBTEST_1( generalized_eigensolver_real(Matrix4f()) );
 | 
			
		||||
    s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/4);
 | 
			
		||||
    CALL_SUBTEST_2( generalized_eigensolver_real(MatrixXd(s,s)) );
 | 
			
		||||
 | 
			
		||||
    // some trivial but implementation-wise special cases
 | 
			
		||||
    CALL_SUBTEST_2( generalized_eigensolver_real(MatrixXd(1,1)) );
 | 
			
		||||
    CALL_SUBTEST_2( generalized_eigensolver_real(MatrixXd(2,2)) );
 | 
			
		||||
    CALL_SUBTEST_3( generalized_eigensolver_real(Matrix<double,1,1>()) );
 | 
			
		||||
    CALL_SUBTEST_4( generalized_eigensolver_real(Matrix2d()) );
 | 
			
		||||
    TEST_SET_BUT_UNUSED_VARIABLE(s)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										165
									
								
								cs440-acg/ext/eigen/test/eigensolver_generic.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										165
									
								
								cs440-acg/ext/eigen/test/eigensolver_generic.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,165 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
// Copyright (C) 2010,2012 Jitse Niesen <jitse@maths.leeds.ac.uk>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
#include <limits>
 | 
			
		||||
#include <Eigen/Eigenvalues>
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void eigensolver(const MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  /* this test covers the following files:
 | 
			
		||||
     EigenSolver.h
 | 
			
		||||
  */
 | 
			
		||||
  Index rows = m.rows();
 | 
			
		||||
  Index cols = m.cols();
 | 
			
		||||
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
  typedef typename NumTraits<Scalar>::Real RealScalar;
 | 
			
		||||
  typedef Matrix<RealScalar, MatrixType::RowsAtCompileTime, 1> RealVectorType;
 | 
			
		||||
  typedef typename std::complex<typename NumTraits<typename MatrixType::Scalar>::Real> Complex;
 | 
			
		||||
 | 
			
		||||
  MatrixType a = MatrixType::Random(rows,cols);
 | 
			
		||||
  MatrixType a1 = MatrixType::Random(rows,cols);
 | 
			
		||||
  MatrixType symmA =  a.adjoint() * a + a1.adjoint() * a1;
 | 
			
		||||
 | 
			
		||||
  EigenSolver<MatrixType> ei0(symmA);
 | 
			
		||||
  VERIFY_IS_EQUAL(ei0.info(), Success);
 | 
			
		||||
  VERIFY_IS_APPROX(symmA * ei0.pseudoEigenvectors(), ei0.pseudoEigenvectors() * ei0.pseudoEigenvalueMatrix());
 | 
			
		||||
  VERIFY_IS_APPROX((symmA.template cast<Complex>()) * (ei0.pseudoEigenvectors().template cast<Complex>()),
 | 
			
		||||
    (ei0.pseudoEigenvectors().template cast<Complex>()) * (ei0.eigenvalues().asDiagonal()));
 | 
			
		||||
 | 
			
		||||
  EigenSolver<MatrixType> ei1(a);
 | 
			
		||||
  VERIFY_IS_EQUAL(ei1.info(), Success);
 | 
			
		||||
  VERIFY_IS_APPROX(a * ei1.pseudoEigenvectors(), ei1.pseudoEigenvectors() * ei1.pseudoEigenvalueMatrix());
 | 
			
		||||
  VERIFY_IS_APPROX(a.template cast<Complex>() * ei1.eigenvectors(),
 | 
			
		||||
                   ei1.eigenvectors() * ei1.eigenvalues().asDiagonal());
 | 
			
		||||
  VERIFY_IS_APPROX(ei1.eigenvectors().colwise().norm(), RealVectorType::Ones(rows).transpose());
 | 
			
		||||
  VERIFY_IS_APPROX(a.eigenvalues(), ei1.eigenvalues());
 | 
			
		||||
 | 
			
		||||
  EigenSolver<MatrixType> ei2;
 | 
			
		||||
  ei2.setMaxIterations(RealSchur<MatrixType>::m_maxIterationsPerRow * rows).compute(a);
 | 
			
		||||
  VERIFY_IS_EQUAL(ei2.info(), Success);
 | 
			
		||||
  VERIFY_IS_EQUAL(ei2.eigenvectors(), ei1.eigenvectors());
 | 
			
		||||
  VERIFY_IS_EQUAL(ei2.eigenvalues(), ei1.eigenvalues());
 | 
			
		||||
  if (rows > 2) {
 | 
			
		||||
    ei2.setMaxIterations(1).compute(a);
 | 
			
		||||
    VERIFY_IS_EQUAL(ei2.info(), NoConvergence);
 | 
			
		||||
    VERIFY_IS_EQUAL(ei2.getMaxIterations(), 1);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  EigenSolver<MatrixType> eiNoEivecs(a, false);
 | 
			
		||||
  VERIFY_IS_EQUAL(eiNoEivecs.info(), Success);
 | 
			
		||||
  VERIFY_IS_APPROX(ei1.eigenvalues(), eiNoEivecs.eigenvalues());
 | 
			
		||||
  VERIFY_IS_APPROX(ei1.pseudoEigenvalueMatrix(), eiNoEivecs.pseudoEigenvalueMatrix());
 | 
			
		||||
 | 
			
		||||
  MatrixType id = MatrixType::Identity(rows, cols);
 | 
			
		||||
  VERIFY_IS_APPROX(id.operatorNorm(), RealScalar(1));
 | 
			
		||||
 | 
			
		||||
  if (rows > 2 && rows < 20)
 | 
			
		||||
  {
 | 
			
		||||
    // Test matrix with NaN
 | 
			
		||||
    a(0,0) = std::numeric_limits<typename MatrixType::RealScalar>::quiet_NaN();
 | 
			
		||||
    EigenSolver<MatrixType> eiNaN(a);
 | 
			
		||||
    VERIFY_IS_NOT_EQUAL(eiNaN.info(), Success);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // regression test for bug 1098
 | 
			
		||||
  {
 | 
			
		||||
    EigenSolver<MatrixType> eig(a.adjoint() * a);
 | 
			
		||||
    eig.compute(a.adjoint() * a);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // regression test for bug 478
 | 
			
		||||
  {
 | 
			
		||||
    a.setZero();
 | 
			
		||||
    EigenSolver<MatrixType> ei3(a);
 | 
			
		||||
    VERIFY_IS_EQUAL(ei3.info(), Success);
 | 
			
		||||
    VERIFY_IS_MUCH_SMALLER_THAN(ei3.eigenvalues().norm(),RealScalar(1));
 | 
			
		||||
    VERIFY((ei3.eigenvectors().transpose()*ei3.eigenvectors().transpose()).eval().isIdentity());
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void eigensolver_verify_assert(const MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  EigenSolver<MatrixType> eig;
 | 
			
		||||
  VERIFY_RAISES_ASSERT(eig.eigenvectors());
 | 
			
		||||
  VERIFY_RAISES_ASSERT(eig.pseudoEigenvectors());
 | 
			
		||||
  VERIFY_RAISES_ASSERT(eig.pseudoEigenvalueMatrix());
 | 
			
		||||
  VERIFY_RAISES_ASSERT(eig.eigenvalues());
 | 
			
		||||
 | 
			
		||||
  MatrixType a = MatrixType::Random(m.rows(),m.cols());
 | 
			
		||||
  eig.compute(a, false);
 | 
			
		||||
  VERIFY_RAISES_ASSERT(eig.eigenvectors());
 | 
			
		||||
  VERIFY_RAISES_ASSERT(eig.pseudoEigenvectors());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_eigensolver_generic()
 | 
			
		||||
{
 | 
			
		||||
  int s = 0;
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_1( eigensolver(Matrix4f()) );
 | 
			
		||||
    s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/4);
 | 
			
		||||
    CALL_SUBTEST_2( eigensolver(MatrixXd(s,s)) );
 | 
			
		||||
    TEST_SET_BUT_UNUSED_VARIABLE(s)
 | 
			
		||||
 | 
			
		||||
    // some trivial but implementation-wise tricky cases
 | 
			
		||||
    CALL_SUBTEST_2( eigensolver(MatrixXd(1,1)) );
 | 
			
		||||
    CALL_SUBTEST_2( eigensolver(MatrixXd(2,2)) );
 | 
			
		||||
    CALL_SUBTEST_3( eigensolver(Matrix<double,1,1>()) );
 | 
			
		||||
    CALL_SUBTEST_4( eigensolver(Matrix2d()) );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  CALL_SUBTEST_1( eigensolver_verify_assert(Matrix4f()) );
 | 
			
		||||
  s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/4);
 | 
			
		||||
  CALL_SUBTEST_2( eigensolver_verify_assert(MatrixXd(s,s)) );
 | 
			
		||||
  CALL_SUBTEST_3( eigensolver_verify_assert(Matrix<double,1,1>()) );
 | 
			
		||||
  CALL_SUBTEST_4( eigensolver_verify_assert(Matrix2d()) );
 | 
			
		||||
 | 
			
		||||
  // Test problem size constructors
 | 
			
		||||
  CALL_SUBTEST_5(EigenSolver<MatrixXf> tmp(s));
 | 
			
		||||
 | 
			
		||||
  // regression test for bug 410
 | 
			
		||||
  CALL_SUBTEST_2(
 | 
			
		||||
  {
 | 
			
		||||
     MatrixXd A(1,1);
 | 
			
		||||
     A(0,0) = std::sqrt(-1.); // is Not-a-Number
 | 
			
		||||
     Eigen::EigenSolver<MatrixXd> solver(A);
 | 
			
		||||
     VERIFY_IS_EQUAL(solver.info(), NumericalIssue);
 | 
			
		||||
  }
 | 
			
		||||
  );
 | 
			
		||||
  
 | 
			
		||||
#ifdef EIGEN_TEST_PART_2
 | 
			
		||||
  {
 | 
			
		||||
    // regression test for bug 793
 | 
			
		||||
    MatrixXd a(3,3);
 | 
			
		||||
    a << 0,  0,  1,
 | 
			
		||||
        1,  1, 1,
 | 
			
		||||
        1, 1e+200,  1;
 | 
			
		||||
    Eigen::EigenSolver<MatrixXd> eig(a);
 | 
			
		||||
    double scale = 1e-200; // scale to avoid overflow during the comparisons
 | 
			
		||||
    VERIFY_IS_APPROX(a * eig.pseudoEigenvectors()*scale, eig.pseudoEigenvectors() * eig.pseudoEigenvalueMatrix()*scale);
 | 
			
		||||
    VERIFY_IS_APPROX(a * eig.eigenvectors()*scale, eig.eigenvectors() * eig.eigenvalues().asDiagonal()*scale);
 | 
			
		||||
  }
 | 
			
		||||
  {
 | 
			
		||||
    // check a case where all eigenvalues are null.
 | 
			
		||||
    MatrixXd a(2,2);
 | 
			
		||||
    a << 1,  1,
 | 
			
		||||
        -1, -1;
 | 
			
		||||
    Eigen::EigenSolver<MatrixXd> eig(a);
 | 
			
		||||
    VERIFY_IS_APPROX(eig.pseudoEigenvectors().squaredNorm(), 2.);
 | 
			
		||||
    VERIFY_IS_APPROX((a * eig.pseudoEigenvectors()).norm()+1., 1.);
 | 
			
		||||
    VERIFY_IS_APPROX((eig.pseudoEigenvectors() * eig.pseudoEigenvalueMatrix()).norm()+1., 1.);
 | 
			
		||||
    VERIFY_IS_APPROX((a * eig.eigenvectors()).norm()+1., 1.);
 | 
			
		||||
    VERIFY_IS_APPROX((eig.eigenvectors() * eig.eigenvalues().asDiagonal()).norm()+1., 1.);
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
  
 | 
			
		||||
  TEST_SET_BUT_UNUSED_VARIABLE(s)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										273
									
								
								cs440-acg/ext/eigen/test/eigensolver_selfadjoint.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										273
									
								
								cs440-acg/ext/eigen/test/eigensolver_selfadjoint.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,273 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
// Copyright (C) 2010 Jitse Niesen <jitse@maths.leeds.ac.uk>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
#include "svd_fill.h"
 | 
			
		||||
#include <limits>
 | 
			
		||||
#include <Eigen/Eigenvalues>
 | 
			
		||||
#include <Eigen/SparseCore>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void selfadjointeigensolver_essential_check(const MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
  typedef typename NumTraits<Scalar>::Real RealScalar;
 | 
			
		||||
  RealScalar eival_eps = numext::mini<RealScalar>(test_precision<RealScalar>(),  NumTraits<Scalar>::dummy_precision()*20000);
 | 
			
		||||
  
 | 
			
		||||
  SelfAdjointEigenSolver<MatrixType> eiSymm(m);
 | 
			
		||||
  VERIFY_IS_EQUAL(eiSymm.info(), Success);
 | 
			
		||||
 | 
			
		||||
  RealScalar scaling = m.cwiseAbs().maxCoeff();
 | 
			
		||||
 | 
			
		||||
  if(scaling<(std::numeric_limits<RealScalar>::min)())
 | 
			
		||||
  {
 | 
			
		||||
    VERIFY(eiSymm.eigenvalues().cwiseAbs().maxCoeff() <= (std::numeric_limits<RealScalar>::min)());
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    VERIFY_IS_APPROX((m.template selfadjointView<Lower>() * eiSymm.eigenvectors())/scaling,
 | 
			
		||||
                     (eiSymm.eigenvectors() * eiSymm.eigenvalues().asDiagonal())/scaling);
 | 
			
		||||
  }
 | 
			
		||||
  VERIFY_IS_APPROX(m.template selfadjointView<Lower>().eigenvalues(), eiSymm.eigenvalues());
 | 
			
		||||
  VERIFY_IS_UNITARY(eiSymm.eigenvectors());
 | 
			
		||||
 | 
			
		||||
  if(m.cols()<=4)
 | 
			
		||||
  {
 | 
			
		||||
    SelfAdjointEigenSolver<MatrixType> eiDirect;
 | 
			
		||||
    eiDirect.computeDirect(m);  
 | 
			
		||||
    VERIFY_IS_EQUAL(eiDirect.info(), Success);
 | 
			
		||||
    if(! eiSymm.eigenvalues().isApprox(eiDirect.eigenvalues(), eival_eps) )
 | 
			
		||||
    {
 | 
			
		||||
      std::cerr << "reference eigenvalues: " << eiSymm.eigenvalues().transpose() << "\n"
 | 
			
		||||
                << "obtained eigenvalues:  " << eiDirect.eigenvalues().transpose() << "\n"
 | 
			
		||||
                << "diff:                  " << (eiSymm.eigenvalues()-eiDirect.eigenvalues()).transpose() << "\n"
 | 
			
		||||
                << "error (eps):           " << (eiSymm.eigenvalues()-eiDirect.eigenvalues()).norm() / eiSymm.eigenvalues().norm() << "  (" << eival_eps << ")\n";
 | 
			
		||||
    }
 | 
			
		||||
    if(scaling<(std::numeric_limits<RealScalar>::min)())
 | 
			
		||||
    {
 | 
			
		||||
      VERIFY(eiDirect.eigenvalues().cwiseAbs().maxCoeff() <= (std::numeric_limits<RealScalar>::min)());
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
      VERIFY_IS_APPROX(eiSymm.eigenvalues()/scaling, eiDirect.eigenvalues()/scaling);
 | 
			
		||||
      VERIFY_IS_APPROX((m.template selfadjointView<Lower>() * eiDirect.eigenvectors())/scaling,
 | 
			
		||||
                       (eiDirect.eigenvectors() * eiDirect.eigenvalues().asDiagonal())/scaling);
 | 
			
		||||
      VERIFY_IS_APPROX(m.template selfadjointView<Lower>().eigenvalues()/scaling, eiDirect.eigenvalues()/scaling);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    VERIFY_IS_UNITARY(eiDirect.eigenvectors());
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void selfadjointeigensolver(const MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  /* this test covers the following files:
 | 
			
		||||
     EigenSolver.h, SelfAdjointEigenSolver.h (and indirectly: Tridiagonalization.h)
 | 
			
		||||
  */
 | 
			
		||||
  Index rows = m.rows();
 | 
			
		||||
  Index cols = m.cols();
 | 
			
		||||
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
  typedef typename NumTraits<Scalar>::Real RealScalar;
 | 
			
		||||
 | 
			
		||||
  RealScalar largerEps = 10*test_precision<RealScalar>();
 | 
			
		||||
 | 
			
		||||
  MatrixType a = MatrixType::Random(rows,cols);
 | 
			
		||||
  MatrixType a1 = MatrixType::Random(rows,cols);
 | 
			
		||||
  MatrixType symmA =  a.adjoint() * a + a1.adjoint() * a1;
 | 
			
		||||
  MatrixType symmC = symmA;
 | 
			
		||||
  
 | 
			
		||||
  svd_fill_random(symmA,Symmetric);
 | 
			
		||||
 | 
			
		||||
  symmA.template triangularView<StrictlyUpper>().setZero();
 | 
			
		||||
  symmC.template triangularView<StrictlyUpper>().setZero();
 | 
			
		||||
 | 
			
		||||
  MatrixType b = MatrixType::Random(rows,cols);
 | 
			
		||||
  MatrixType b1 = MatrixType::Random(rows,cols);
 | 
			
		||||
  MatrixType symmB = b.adjoint() * b + b1.adjoint() * b1;
 | 
			
		||||
  symmB.template triangularView<StrictlyUpper>().setZero();
 | 
			
		||||
  
 | 
			
		||||
  CALL_SUBTEST( selfadjointeigensolver_essential_check(symmA) );
 | 
			
		||||
 | 
			
		||||
  SelfAdjointEigenSolver<MatrixType> eiSymm(symmA);
 | 
			
		||||
  // generalized eigen pb
 | 
			
		||||
  GeneralizedSelfAdjointEigenSolver<MatrixType> eiSymmGen(symmC, symmB);
 | 
			
		||||
 | 
			
		||||
  SelfAdjointEigenSolver<MatrixType> eiSymmNoEivecs(symmA, false);
 | 
			
		||||
  VERIFY_IS_EQUAL(eiSymmNoEivecs.info(), Success);
 | 
			
		||||
  VERIFY_IS_APPROX(eiSymm.eigenvalues(), eiSymmNoEivecs.eigenvalues());
 | 
			
		||||
  
 | 
			
		||||
  // generalized eigen problem Ax = lBx
 | 
			
		||||
  eiSymmGen.compute(symmC, symmB,Ax_lBx);
 | 
			
		||||
  VERIFY_IS_EQUAL(eiSymmGen.info(), Success);
 | 
			
		||||
  VERIFY((symmC.template selfadjointView<Lower>() * eiSymmGen.eigenvectors()).isApprox(
 | 
			
		||||
          symmB.template selfadjointView<Lower>() * (eiSymmGen.eigenvectors() * eiSymmGen.eigenvalues().asDiagonal()), largerEps));
 | 
			
		||||
 | 
			
		||||
  // generalized eigen problem BAx = lx
 | 
			
		||||
  eiSymmGen.compute(symmC, symmB,BAx_lx);
 | 
			
		||||
  VERIFY_IS_EQUAL(eiSymmGen.info(), Success);
 | 
			
		||||
  VERIFY((symmB.template selfadjointView<Lower>() * (symmC.template selfadjointView<Lower>() * eiSymmGen.eigenvectors())).isApprox(
 | 
			
		||||
         (eiSymmGen.eigenvectors() * eiSymmGen.eigenvalues().asDiagonal()), largerEps));
 | 
			
		||||
 | 
			
		||||
  // generalized eigen problem ABx = lx
 | 
			
		||||
  eiSymmGen.compute(symmC, symmB,ABx_lx);
 | 
			
		||||
  VERIFY_IS_EQUAL(eiSymmGen.info(), Success);
 | 
			
		||||
  VERIFY((symmC.template selfadjointView<Lower>() * (symmB.template selfadjointView<Lower>() * eiSymmGen.eigenvectors())).isApprox(
 | 
			
		||||
         (eiSymmGen.eigenvectors() * eiSymmGen.eigenvalues().asDiagonal()), largerEps));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  eiSymm.compute(symmC);
 | 
			
		||||
  MatrixType sqrtSymmA = eiSymm.operatorSqrt();
 | 
			
		||||
  VERIFY_IS_APPROX(MatrixType(symmC.template selfadjointView<Lower>()), sqrtSymmA*sqrtSymmA);
 | 
			
		||||
  VERIFY_IS_APPROX(sqrtSymmA, symmC.template selfadjointView<Lower>()*eiSymm.operatorInverseSqrt());
 | 
			
		||||
 | 
			
		||||
  MatrixType id = MatrixType::Identity(rows, cols);
 | 
			
		||||
  VERIFY_IS_APPROX(id.template selfadjointView<Lower>().operatorNorm(), RealScalar(1));
 | 
			
		||||
 | 
			
		||||
  SelfAdjointEigenSolver<MatrixType> eiSymmUninitialized;
 | 
			
		||||
  VERIFY_RAISES_ASSERT(eiSymmUninitialized.info());
 | 
			
		||||
  VERIFY_RAISES_ASSERT(eiSymmUninitialized.eigenvalues());
 | 
			
		||||
  VERIFY_RAISES_ASSERT(eiSymmUninitialized.eigenvectors());
 | 
			
		||||
  VERIFY_RAISES_ASSERT(eiSymmUninitialized.operatorSqrt());
 | 
			
		||||
  VERIFY_RAISES_ASSERT(eiSymmUninitialized.operatorInverseSqrt());
 | 
			
		||||
 | 
			
		||||
  eiSymmUninitialized.compute(symmA, false);
 | 
			
		||||
  VERIFY_RAISES_ASSERT(eiSymmUninitialized.eigenvectors());
 | 
			
		||||
  VERIFY_RAISES_ASSERT(eiSymmUninitialized.operatorSqrt());
 | 
			
		||||
  VERIFY_RAISES_ASSERT(eiSymmUninitialized.operatorInverseSqrt());
 | 
			
		||||
 | 
			
		||||
  // test Tridiagonalization's methods
 | 
			
		||||
  Tridiagonalization<MatrixType> tridiag(symmC);
 | 
			
		||||
  VERIFY_IS_APPROX(tridiag.diagonal(), tridiag.matrixT().diagonal());
 | 
			
		||||
  VERIFY_IS_APPROX(tridiag.subDiagonal(), tridiag.matrixT().template diagonal<-1>());
 | 
			
		||||
  Matrix<RealScalar,Dynamic,Dynamic> T = tridiag.matrixT();
 | 
			
		||||
  if(rows>1 && cols>1) {
 | 
			
		||||
    // FIXME check that upper and lower part are 0:
 | 
			
		||||
    //VERIFY(T.topRightCorner(rows-2, cols-2).template triangularView<Upper>().isZero());
 | 
			
		||||
  }
 | 
			
		||||
  VERIFY_IS_APPROX(tridiag.diagonal(), T.diagonal());
 | 
			
		||||
  VERIFY_IS_APPROX(tridiag.subDiagonal(), T.template diagonal<1>());
 | 
			
		||||
  VERIFY_IS_APPROX(MatrixType(symmC.template selfadjointView<Lower>()), tridiag.matrixQ() * tridiag.matrixT().eval() * MatrixType(tridiag.matrixQ()).adjoint());
 | 
			
		||||
  VERIFY_IS_APPROX(MatrixType(symmC.template selfadjointView<Lower>()), tridiag.matrixQ() * tridiag.matrixT() * tridiag.matrixQ().adjoint());
 | 
			
		||||
  
 | 
			
		||||
  // Test computation of eigenvalues from tridiagonal matrix
 | 
			
		||||
  if(rows > 1)
 | 
			
		||||
  {
 | 
			
		||||
    SelfAdjointEigenSolver<MatrixType> eiSymmTridiag;
 | 
			
		||||
    eiSymmTridiag.computeFromTridiagonal(tridiag.matrixT().diagonal(), tridiag.matrixT().diagonal(-1), ComputeEigenvectors);
 | 
			
		||||
    VERIFY_IS_APPROX(eiSymm.eigenvalues(), eiSymmTridiag.eigenvalues());
 | 
			
		||||
    VERIFY_IS_APPROX(tridiag.matrixT(), eiSymmTridiag.eigenvectors().real() * eiSymmTridiag.eigenvalues().asDiagonal() * eiSymmTridiag.eigenvectors().real().transpose());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (rows > 1 && rows < 20)
 | 
			
		||||
  {
 | 
			
		||||
    // Test matrix with NaN
 | 
			
		||||
    symmC(0,0) = std::numeric_limits<typename MatrixType::RealScalar>::quiet_NaN();
 | 
			
		||||
    SelfAdjointEigenSolver<MatrixType> eiSymmNaN(symmC);
 | 
			
		||||
    VERIFY_IS_EQUAL(eiSymmNaN.info(), NoConvergence);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // regression test for bug 1098
 | 
			
		||||
  {
 | 
			
		||||
    SelfAdjointEigenSolver<MatrixType> eig(a.adjoint() * a);
 | 
			
		||||
    eig.compute(a.adjoint() * a);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // regression test for bug 478
 | 
			
		||||
  {
 | 
			
		||||
    a.setZero();
 | 
			
		||||
    SelfAdjointEigenSolver<MatrixType> ei3(a);
 | 
			
		||||
    VERIFY_IS_EQUAL(ei3.info(), Success);
 | 
			
		||||
    VERIFY_IS_MUCH_SMALLER_THAN(ei3.eigenvalues().norm(),RealScalar(1));
 | 
			
		||||
    VERIFY((ei3.eigenvectors().transpose()*ei3.eigenvectors().transpose()).eval().isIdentity());
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<int>
 | 
			
		||||
void bug_854()
 | 
			
		||||
{
 | 
			
		||||
  Matrix3d m;
 | 
			
		||||
  m << 850.961, 51.966, 0,
 | 
			
		||||
       51.966, 254.841, 0,
 | 
			
		||||
            0,       0, 0;
 | 
			
		||||
  selfadjointeigensolver_essential_check(m);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<int>
 | 
			
		||||
void bug_1014()
 | 
			
		||||
{
 | 
			
		||||
  Matrix3d m;
 | 
			
		||||
  m <<        0.11111111111111114658, 0, 0,
 | 
			
		||||
       0,     0.11111111111111109107, 0,
 | 
			
		||||
       0, 0,  0.11111111111111107719;
 | 
			
		||||
  selfadjointeigensolver_essential_check(m);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<int>
 | 
			
		||||
void bug_1225()
 | 
			
		||||
{
 | 
			
		||||
  Matrix3d m1, m2;
 | 
			
		||||
  m1.setRandom();
 | 
			
		||||
  m1 = m1*m1.transpose();
 | 
			
		||||
  m2 = m1.triangularView<Upper>();
 | 
			
		||||
  SelfAdjointEigenSolver<Matrix3d> eig1(m1);
 | 
			
		||||
  SelfAdjointEigenSolver<Matrix3d> eig2(m2.selfadjointView<Upper>());
 | 
			
		||||
  VERIFY_IS_APPROX(eig1.eigenvalues(), eig2.eigenvalues());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<int>
 | 
			
		||||
void bug_1204()
 | 
			
		||||
{
 | 
			
		||||
  SparseMatrix<double> A(2,2);
 | 
			
		||||
  A.setIdentity();
 | 
			
		||||
  SelfAdjointEigenSolver<Eigen::SparseMatrix<double> > eig(A);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_eigensolver_selfadjoint()
 | 
			
		||||
{
 | 
			
		||||
  int s = 0;
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    // trivial test for 1x1 matrices:
 | 
			
		||||
    CALL_SUBTEST_1( selfadjointeigensolver(Matrix<float, 1, 1>()));
 | 
			
		||||
    CALL_SUBTEST_1( selfadjointeigensolver(Matrix<double, 1, 1>()));
 | 
			
		||||
    // very important to test 3x3 and 2x2 matrices since we provide special paths for them
 | 
			
		||||
    CALL_SUBTEST_12( selfadjointeigensolver(Matrix2f()) );
 | 
			
		||||
    CALL_SUBTEST_12( selfadjointeigensolver(Matrix2d()) );
 | 
			
		||||
    CALL_SUBTEST_13( selfadjointeigensolver(Matrix3f()) );
 | 
			
		||||
    CALL_SUBTEST_13( selfadjointeigensolver(Matrix3d()) );
 | 
			
		||||
    CALL_SUBTEST_2( selfadjointeigensolver(Matrix4d()) );
 | 
			
		||||
    
 | 
			
		||||
    s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/4);
 | 
			
		||||
    CALL_SUBTEST_3( selfadjointeigensolver(MatrixXf(s,s)) );
 | 
			
		||||
    CALL_SUBTEST_4( selfadjointeigensolver(MatrixXd(s,s)) );
 | 
			
		||||
    CALL_SUBTEST_5( selfadjointeigensolver(MatrixXcd(s,s)) );
 | 
			
		||||
    CALL_SUBTEST_9( selfadjointeigensolver(Matrix<std::complex<double>,Dynamic,Dynamic,RowMajor>(s,s)) );
 | 
			
		||||
    TEST_SET_BUT_UNUSED_VARIABLE(s)
 | 
			
		||||
 | 
			
		||||
    // some trivial but implementation-wise tricky cases
 | 
			
		||||
    CALL_SUBTEST_4( selfadjointeigensolver(MatrixXd(1,1)) );
 | 
			
		||||
    CALL_SUBTEST_4( selfadjointeigensolver(MatrixXd(2,2)) );
 | 
			
		||||
    CALL_SUBTEST_6( selfadjointeigensolver(Matrix<double,1,1>()) );
 | 
			
		||||
    CALL_SUBTEST_7( selfadjointeigensolver(Matrix<double,2,2>()) );
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  CALL_SUBTEST_13( bug_854<0>() );
 | 
			
		||||
  CALL_SUBTEST_13( bug_1014<0>() );
 | 
			
		||||
  CALL_SUBTEST_13( bug_1204<0>() );
 | 
			
		||||
  CALL_SUBTEST_13( bug_1225<0>() );
 | 
			
		||||
 | 
			
		||||
  // Test problem size constructors
 | 
			
		||||
  s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/4);
 | 
			
		||||
  CALL_SUBTEST_8(SelfAdjointEigenSolver<MatrixXf> tmp1(s));
 | 
			
		||||
  CALL_SUBTEST_8(Tridiagonalization<MatrixXf> tmp2(s));
 | 
			
		||||
  
 | 
			
		||||
  TEST_SET_BUT_UNUSED_VARIABLE(s)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										0
									
								
								cs440-acg/ext/eigen/test/evaluator_common.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								cs440-acg/ext/eigen/test/evaluator_common.h
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										499
									
								
								cs440-acg/ext/eigen/test/evaluators.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										499
									
								
								cs440-acg/ext/eigen/test/evaluators.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,499 @@
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
 | 
			
		||||
namespace Eigen {
 | 
			
		||||
 | 
			
		||||
  template<typename Lhs,typename Rhs>
 | 
			
		||||
  const Product<Lhs,Rhs>
 | 
			
		||||
  prod(const Lhs& lhs, const Rhs& rhs)
 | 
			
		||||
  {
 | 
			
		||||
    return Product<Lhs,Rhs>(lhs,rhs);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template<typename Lhs,typename Rhs>
 | 
			
		||||
  const Product<Lhs,Rhs,LazyProduct>
 | 
			
		||||
  lazyprod(const Lhs& lhs, const Rhs& rhs)
 | 
			
		||||
  {
 | 
			
		||||
    return Product<Lhs,Rhs,LazyProduct>(lhs,rhs);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template<typename DstXprType, typename SrcXprType>
 | 
			
		||||
  EIGEN_STRONG_INLINE
 | 
			
		||||
  DstXprType& copy_using_evaluator(const EigenBase<DstXprType> &dst, const SrcXprType &src)
 | 
			
		||||
  {
 | 
			
		||||
    call_assignment(dst.const_cast_derived(), src.derived(), internal::assign_op<typename DstXprType::Scalar,typename SrcXprType::Scalar>());
 | 
			
		||||
    return dst.const_cast_derived();
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template<typename DstXprType, template <typename> class StorageBase, typename SrcXprType>
 | 
			
		||||
  EIGEN_STRONG_INLINE
 | 
			
		||||
  const DstXprType& copy_using_evaluator(const NoAlias<DstXprType, StorageBase>& dst, const SrcXprType &src)
 | 
			
		||||
  {
 | 
			
		||||
    call_assignment(dst, src.derived(), internal::assign_op<typename DstXprType::Scalar,typename SrcXprType::Scalar>());
 | 
			
		||||
    return dst.expression();
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template<typename DstXprType, typename SrcXprType>
 | 
			
		||||
  EIGEN_STRONG_INLINE
 | 
			
		||||
  DstXprType& copy_using_evaluator(const PlainObjectBase<DstXprType> &dst, const SrcXprType &src)
 | 
			
		||||
  {
 | 
			
		||||
    #ifdef EIGEN_NO_AUTOMATIC_RESIZING
 | 
			
		||||
    eigen_assert((dst.size()==0 || (IsVectorAtCompileTime ? (dst.size() == src.size())
 | 
			
		||||
                                                          : (dst.rows() == src.rows() && dst.cols() == src.cols())))
 | 
			
		||||
                && "Size mismatch. Automatic resizing is disabled because EIGEN_NO_AUTOMATIC_RESIZING is defined");
 | 
			
		||||
  #else
 | 
			
		||||
    dst.const_cast_derived().resizeLike(src.derived());
 | 
			
		||||
  #endif
 | 
			
		||||
    
 | 
			
		||||
    call_assignment(dst.const_cast_derived(), src.derived(), internal::assign_op<typename DstXprType::Scalar,typename SrcXprType::Scalar>());
 | 
			
		||||
    return dst.const_cast_derived();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template<typename DstXprType, typename SrcXprType>
 | 
			
		||||
  void add_assign_using_evaluator(const DstXprType& dst, const SrcXprType& src)
 | 
			
		||||
  {
 | 
			
		||||
    typedef typename DstXprType::Scalar Scalar;
 | 
			
		||||
    call_assignment(const_cast<DstXprType&>(dst), src.derived(), internal::add_assign_op<Scalar,typename SrcXprType::Scalar>());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template<typename DstXprType, typename SrcXprType>
 | 
			
		||||
  void subtract_assign_using_evaluator(const DstXprType& dst, const SrcXprType& src)
 | 
			
		||||
  {
 | 
			
		||||
    typedef typename DstXprType::Scalar Scalar;
 | 
			
		||||
    call_assignment(const_cast<DstXprType&>(dst), src.derived(), internal::sub_assign_op<Scalar,typename SrcXprType::Scalar>());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template<typename DstXprType, typename SrcXprType>
 | 
			
		||||
  void multiply_assign_using_evaluator(const DstXprType& dst, const SrcXprType& src)
 | 
			
		||||
  {
 | 
			
		||||
    typedef typename DstXprType::Scalar Scalar;
 | 
			
		||||
    call_assignment(dst.const_cast_derived(), src.derived(), internal::mul_assign_op<Scalar,typename SrcXprType::Scalar>());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template<typename DstXprType, typename SrcXprType>
 | 
			
		||||
  void divide_assign_using_evaluator(const DstXprType& dst, const SrcXprType& src)
 | 
			
		||||
  {
 | 
			
		||||
    typedef typename DstXprType::Scalar Scalar;
 | 
			
		||||
    call_assignment(dst.const_cast_derived(), src.derived(), internal::div_assign_op<Scalar,typename SrcXprType::Scalar>());
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template<typename DstXprType, typename SrcXprType>
 | 
			
		||||
  void swap_using_evaluator(const DstXprType& dst, const SrcXprType& src)
 | 
			
		||||
  {
 | 
			
		||||
    typedef typename DstXprType::Scalar Scalar;
 | 
			
		||||
    call_assignment(dst.const_cast_derived(), src.const_cast_derived(), internal::swap_assign_op<Scalar>());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  namespace internal {
 | 
			
		||||
    template<typename Dst, template <typename> class StorageBase, typename Src, typename Func>
 | 
			
		||||
    EIGEN_DEVICE_FUNC void call_assignment(const NoAlias<Dst,StorageBase>& dst, const Src& src, const Func& func)
 | 
			
		||||
    {
 | 
			
		||||
      call_assignment_no_alias(dst.expression(), src, func);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename XprType> long get_cost(const XprType& ) { return Eigen::internal::evaluator<XprType>::CoeffReadCost; }
 | 
			
		||||
 | 
			
		||||
using namespace std;
 | 
			
		||||
 | 
			
		||||
#define VERIFY_IS_APPROX_EVALUATOR(DEST,EXPR) VERIFY_IS_APPROX(copy_using_evaluator(DEST,(EXPR)), (EXPR).eval());
 | 
			
		||||
#define VERIFY_IS_APPROX_EVALUATOR2(DEST,EXPR,REF) VERIFY_IS_APPROX(copy_using_evaluator(DEST,(EXPR)), (REF).eval());
 | 
			
		||||
 | 
			
		||||
void test_evaluators()
 | 
			
		||||
{
 | 
			
		||||
  // Testing Matrix evaluator and Transpose
 | 
			
		||||
  Vector2d v = Vector2d::Random();
 | 
			
		||||
  const Vector2d v_const(v);
 | 
			
		||||
  Vector2d v2;
 | 
			
		||||
  RowVector2d w;
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX_EVALUATOR(v2, v);
 | 
			
		||||
  VERIFY_IS_APPROX_EVALUATOR(v2, v_const);
 | 
			
		||||
 | 
			
		||||
  // Testing Transpose
 | 
			
		||||
  VERIFY_IS_APPROX_EVALUATOR(w, v.transpose()); // Transpose as rvalue
 | 
			
		||||
  VERIFY_IS_APPROX_EVALUATOR(w, v_const.transpose());
 | 
			
		||||
 | 
			
		||||
  copy_using_evaluator(w.transpose(), v); // Transpose as lvalue
 | 
			
		||||
  VERIFY_IS_APPROX(w,v.transpose().eval());
 | 
			
		||||
 | 
			
		||||
  copy_using_evaluator(w.transpose(), v_const);
 | 
			
		||||
  VERIFY_IS_APPROX(w,v_const.transpose().eval());
 | 
			
		||||
 | 
			
		||||
  // Testing Array evaluator
 | 
			
		||||
  {
 | 
			
		||||
    ArrayXXf a(2,3);
 | 
			
		||||
    ArrayXXf b(3,2);
 | 
			
		||||
    a << 1,2,3, 4,5,6;
 | 
			
		||||
    const ArrayXXf a_const(a);
 | 
			
		||||
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(b, a.transpose());
 | 
			
		||||
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(b, a_const.transpose());
 | 
			
		||||
 | 
			
		||||
    // Testing CwiseNullaryOp evaluator
 | 
			
		||||
    copy_using_evaluator(w, RowVector2d::Random());
 | 
			
		||||
    VERIFY((w.array() >= -1).all() && (w.array() <= 1).all()); // not easy to test ...
 | 
			
		||||
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(w, RowVector2d::Zero());
 | 
			
		||||
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(w, RowVector2d::Constant(3));
 | 
			
		||||
    
 | 
			
		||||
    // mix CwiseNullaryOp and transpose
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(w, Vector2d::Zero().transpose());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    // test product expressions
 | 
			
		||||
    int s = internal::random<int>(1,100);
 | 
			
		||||
    MatrixXf a(s,s), b(s,s), c(s,s), d(s,s);
 | 
			
		||||
    a.setRandom();
 | 
			
		||||
    b.setRandom();
 | 
			
		||||
    c.setRandom();
 | 
			
		||||
    d.setRandom();
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(d, (a + b));
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(d, (a + b).transpose());
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR2(d, prod(a,b), a*b);
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR2(d.noalias(), prod(a,b), a*b);
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR2(d, prod(a,b) + c, a*b + c);
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR2(d, s * prod(a,b), s * a*b);
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR2(d, prod(a,b).transpose(), (a*b).transpose());
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR2(d, prod(a,b) + prod(b,c), a*b + b*c);
 | 
			
		||||
 | 
			
		||||
    // check that prod works even with aliasing present
 | 
			
		||||
    c = a*a;
 | 
			
		||||
    copy_using_evaluator(a, prod(a,a));
 | 
			
		||||
    VERIFY_IS_APPROX(a,c);
 | 
			
		||||
 | 
			
		||||
    // check compound assignment of products
 | 
			
		||||
    d = c;
 | 
			
		||||
    add_assign_using_evaluator(c.noalias(), prod(a,b));
 | 
			
		||||
    d.noalias() += a*b;
 | 
			
		||||
    VERIFY_IS_APPROX(c, d);
 | 
			
		||||
 | 
			
		||||
    d = c;
 | 
			
		||||
    subtract_assign_using_evaluator(c.noalias(), prod(a,b));
 | 
			
		||||
    d.noalias() -= a*b;
 | 
			
		||||
    VERIFY_IS_APPROX(c, d);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    // test product with all possible sizes
 | 
			
		||||
    int s = internal::random<int>(1,100);
 | 
			
		||||
    Matrix<float,      1,      1> m11, res11;  m11.setRandom(1,1);
 | 
			
		||||
    Matrix<float,      1,      4> m14, res14;  m14.setRandom(1,4);
 | 
			
		||||
    Matrix<float,      1,Dynamic> m1X, res1X;  m1X.setRandom(1,s);
 | 
			
		||||
    Matrix<float,      4,      1> m41, res41;  m41.setRandom(4,1);
 | 
			
		||||
    Matrix<float,      4,      4> m44, res44;  m44.setRandom(4,4);
 | 
			
		||||
    Matrix<float,      4,Dynamic> m4X, res4X;  m4X.setRandom(4,s);
 | 
			
		||||
    Matrix<float,Dynamic,      1> mX1, resX1;  mX1.setRandom(s,1);
 | 
			
		||||
    Matrix<float,Dynamic,      4> mX4, resX4;  mX4.setRandom(s,4);
 | 
			
		||||
    Matrix<float,Dynamic,Dynamic> mXX, resXX;  mXX.setRandom(s,s);
 | 
			
		||||
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR2(res11, prod(m11,m11), m11*m11);
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR2(res11, prod(m14,m41), m14*m41);
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR2(res11, prod(m1X,mX1), m1X*mX1);
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR2(res14, prod(m11,m14), m11*m14);
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR2(res14, prod(m14,m44), m14*m44);
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR2(res14, prod(m1X,mX4), m1X*mX4);
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR2(res1X, prod(m11,m1X), m11*m1X);
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR2(res1X, prod(m14,m4X), m14*m4X);
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR2(res1X, prod(m1X,mXX), m1X*mXX);
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR2(res41, prod(m41,m11), m41*m11);
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR2(res41, prod(m44,m41), m44*m41);
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR2(res41, prod(m4X,mX1), m4X*mX1);
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR2(res44, prod(m41,m14), m41*m14);
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR2(res44, prod(m44,m44), m44*m44);
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR2(res44, prod(m4X,mX4), m4X*mX4);
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR2(res4X, prod(m41,m1X), m41*m1X);
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR2(res4X, prod(m44,m4X), m44*m4X);
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR2(res4X, prod(m4X,mXX), m4X*mXX);
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR2(resX1, prod(mX1,m11), mX1*m11);
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR2(resX1, prod(mX4,m41), mX4*m41);
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR2(resX1, prod(mXX,mX1), mXX*mX1);
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR2(resX4, prod(mX1,m14), mX1*m14);
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR2(resX4, prod(mX4,m44), mX4*m44);
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR2(resX4, prod(mXX,mX4), mXX*mX4);
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR2(resXX, prod(mX1,m1X), mX1*m1X);
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR2(resXX, prod(mX4,m4X), mX4*m4X);
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR2(resXX, prod(mXX,mXX), mXX*mXX);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    ArrayXXf a(2,3);
 | 
			
		||||
    ArrayXXf b(3,2);
 | 
			
		||||
    a << 1,2,3, 4,5,6;
 | 
			
		||||
    const ArrayXXf a_const(a);
 | 
			
		||||
    
 | 
			
		||||
    // this does not work because Random is eval-before-nested: 
 | 
			
		||||
    // copy_using_evaluator(w, Vector2d::Random().transpose());
 | 
			
		||||
 | 
			
		||||
    // test CwiseUnaryOp
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(v2, 3 * v);
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(w, (3 * v).transpose());
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(b, (a + 3).transpose());
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(b, (2 * a_const + 3).transpose());
 | 
			
		||||
 | 
			
		||||
    // test CwiseBinaryOp
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(v2, v + Vector2d::Ones());
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(w, (v + Vector2d::Ones()).transpose().cwiseProduct(RowVector2d::Constant(3)));
 | 
			
		||||
 | 
			
		||||
    // dynamic matrices and arrays
 | 
			
		||||
    MatrixXd mat1(6,6), mat2(6,6);
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(mat1, MatrixXd::Identity(6,6));
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(mat2, mat1);
 | 
			
		||||
    copy_using_evaluator(mat2.transpose(), mat1);
 | 
			
		||||
    VERIFY_IS_APPROX(mat2.transpose(), mat1);
 | 
			
		||||
 | 
			
		||||
    ArrayXXd arr1(6,6), arr2(6,6);
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(arr1, ArrayXXd::Constant(6,6, 3.0));
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(arr2, arr1);
 | 
			
		||||
    
 | 
			
		||||
    // test automatic resizing
 | 
			
		||||
    mat2.resize(3,3);
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(mat2, mat1);
 | 
			
		||||
    arr2.resize(9,9);
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(arr2, arr1);
 | 
			
		||||
 | 
			
		||||
    // test direct traversal
 | 
			
		||||
    Matrix3f m3;
 | 
			
		||||
    Array33f a3;
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(m3, Matrix3f::Identity());  // matrix, nullary
 | 
			
		||||
    // TODO: find a way to test direct traversal with array
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(m3.transpose(), Matrix3f::Identity().transpose());  // transpose
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(m3, 2 * Matrix3f::Identity());  // unary
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(m3, Matrix3f::Identity() + Matrix3f::Zero());  // binary
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(m3.block(0,0,2,2), Matrix3f::Identity().block(1,1,2,2));  // block
 | 
			
		||||
 | 
			
		||||
    // test linear traversal
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(m3, Matrix3f::Zero());  // matrix, nullary
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(a3, Array33f::Zero());  // array
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(m3.transpose(), Matrix3f::Zero().transpose());  // transpose
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(m3, 2 * Matrix3f::Zero());  // unary
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(m3, Matrix3f::Zero() + m3);  // binary  
 | 
			
		||||
 | 
			
		||||
    // test inner vectorization
 | 
			
		||||
    Matrix4f m4, m4src = Matrix4f::Random();
 | 
			
		||||
    Array44f a4, a4src = Matrix4f::Random();
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(m4, m4src);  // matrix
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(a4, a4src);  // array
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(m4.transpose(), m4src.transpose());  // transpose
 | 
			
		||||
    // TODO: find out why Matrix4f::Zero() does not allow inner vectorization
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(m4, 2 * m4src);  // unary
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(m4, m4src + m4src);  // binary
 | 
			
		||||
 | 
			
		||||
    // test linear vectorization
 | 
			
		||||
    MatrixXf mX(6,6), mXsrc = MatrixXf::Random(6,6);
 | 
			
		||||
    ArrayXXf aX(6,6), aXsrc = ArrayXXf::Random(6,6);
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(mX, mXsrc);  // matrix
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(aX, aXsrc);  // array
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(mX.transpose(), mXsrc.transpose());  // transpose
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(mX, MatrixXf::Zero(6,6));  // nullary
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(mX, 2 * mXsrc);  // unary
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(mX, mXsrc + mXsrc);  // binary
 | 
			
		||||
 | 
			
		||||
    // test blocks and slice vectorization
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(m4, (mXsrc.block<4,4>(1,0)));
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(aX, ArrayXXf::Constant(10, 10, 3.0).block(2, 3, 6, 6));
 | 
			
		||||
 | 
			
		||||
    Matrix4f m4ref = m4;
 | 
			
		||||
    copy_using_evaluator(m4.block(1, 1, 2, 3), m3.bottomRows(2));
 | 
			
		||||
    m4ref.block(1, 1, 2, 3) = m3.bottomRows(2);
 | 
			
		||||
    VERIFY_IS_APPROX(m4, m4ref);
 | 
			
		||||
 | 
			
		||||
    mX.setIdentity(20,20);
 | 
			
		||||
    MatrixXf mXref = MatrixXf::Identity(20,20);
 | 
			
		||||
    mXsrc = MatrixXf::Random(9,12);
 | 
			
		||||
    copy_using_evaluator(mX.block(4, 4, 9, 12), mXsrc);
 | 
			
		||||
    mXref.block(4, 4, 9, 12) = mXsrc;
 | 
			
		||||
    VERIFY_IS_APPROX(mX, mXref);
 | 
			
		||||
 | 
			
		||||
    // test Map
 | 
			
		||||
    const float raw[3] = {1,2,3};
 | 
			
		||||
    float buffer[3] = {0,0,0};
 | 
			
		||||
    Vector3f v3;
 | 
			
		||||
    Array3f a3f;
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(v3, Map<const Vector3f>(raw));
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(a3f, Map<const Array3f>(raw));
 | 
			
		||||
    Vector3f::Map(buffer) = 2*v3;
 | 
			
		||||
    VERIFY(buffer[0] == 2);
 | 
			
		||||
    VERIFY(buffer[1] == 4);
 | 
			
		||||
    VERIFY(buffer[2] == 6);
 | 
			
		||||
 | 
			
		||||
    // test CwiseUnaryView
 | 
			
		||||
    mat1.setRandom();
 | 
			
		||||
    mat2.setIdentity();
 | 
			
		||||
    MatrixXcd matXcd(6,6), matXcd_ref(6,6);
 | 
			
		||||
    copy_using_evaluator(matXcd.real(), mat1);
 | 
			
		||||
    copy_using_evaluator(matXcd.imag(), mat2);
 | 
			
		||||
    matXcd_ref.real() = mat1;
 | 
			
		||||
    matXcd_ref.imag() = mat2;
 | 
			
		||||
    VERIFY_IS_APPROX(matXcd, matXcd_ref);
 | 
			
		||||
 | 
			
		||||
    // test Select
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(aX, (aXsrc > 0).select(aXsrc, -aXsrc));
 | 
			
		||||
 | 
			
		||||
    // test Replicate
 | 
			
		||||
    mXsrc = MatrixXf::Random(6, 6);
 | 
			
		||||
    VectorXf vX = VectorXf::Random(6);
 | 
			
		||||
    mX.resize(6, 6);
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(mX, mXsrc.colwise() + vX);
 | 
			
		||||
    matXcd.resize(12, 12);
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(matXcd, matXcd_ref.replicate(2,2));
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(matXcd, (matXcd_ref.replicate<2,2>()));
 | 
			
		||||
 | 
			
		||||
    // test partial reductions
 | 
			
		||||
    VectorXd vec1(6);
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(vec1, mat1.rowwise().sum());
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(vec1, mat1.colwise().sum().transpose());
 | 
			
		||||
 | 
			
		||||
    // test MatrixWrapper and ArrayWrapper
 | 
			
		||||
    mat1.setRandom(6,6);
 | 
			
		||||
    arr1.setRandom(6,6);
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(mat2, arr1.matrix());
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(arr2, mat1.array());
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(mat2, (arr1 + 2).matrix());
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(arr2, mat1.array() + 2);
 | 
			
		||||
    mat2.array() = arr1 * arr1;
 | 
			
		||||
    VERIFY_IS_APPROX(mat2, (arr1 * arr1).matrix());
 | 
			
		||||
    arr2.matrix() = MatrixXd::Identity(6,6);
 | 
			
		||||
    VERIFY_IS_APPROX(arr2, MatrixXd::Identity(6,6).array());
 | 
			
		||||
 | 
			
		||||
    // test Reverse
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(arr2, arr1.reverse());
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(arr2, arr1.colwise().reverse());
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(arr2, arr1.rowwise().reverse());
 | 
			
		||||
    arr2.reverse() = arr1;
 | 
			
		||||
    VERIFY_IS_APPROX(arr2, arr1.reverse());
 | 
			
		||||
    mat2.array() = mat1.array().reverse();
 | 
			
		||||
    VERIFY_IS_APPROX(mat2.array(), mat1.array().reverse());
 | 
			
		||||
 | 
			
		||||
    // test Diagonal
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(vec1, mat1.diagonal());
 | 
			
		||||
    vec1.resize(5);
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(vec1, mat1.diagonal(1));
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR(vec1, mat1.diagonal<-1>());
 | 
			
		||||
    vec1.setRandom();
 | 
			
		||||
 | 
			
		||||
    mat2 = mat1;
 | 
			
		||||
    copy_using_evaluator(mat1.diagonal(1), vec1);
 | 
			
		||||
    mat2.diagonal(1) = vec1;
 | 
			
		||||
    VERIFY_IS_APPROX(mat1, mat2);
 | 
			
		||||
 | 
			
		||||
    copy_using_evaluator(mat1.diagonal<-1>(), mat1.diagonal(1));
 | 
			
		||||
    mat2.diagonal<-1>() = mat2.diagonal(1);
 | 
			
		||||
    VERIFY_IS_APPROX(mat1, mat2);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  {
 | 
			
		||||
    // test swapping
 | 
			
		||||
    MatrixXd mat1, mat2, mat1ref, mat2ref;
 | 
			
		||||
    mat1ref = mat1 = MatrixXd::Random(6, 6);
 | 
			
		||||
    mat2ref = mat2 = 2 * mat1 + MatrixXd::Identity(6, 6);
 | 
			
		||||
    swap_using_evaluator(mat1, mat2);
 | 
			
		||||
    mat1ref.swap(mat2ref);
 | 
			
		||||
    VERIFY_IS_APPROX(mat1, mat1ref);
 | 
			
		||||
    VERIFY_IS_APPROX(mat2, mat2ref);
 | 
			
		||||
 | 
			
		||||
    swap_using_evaluator(mat1.block(0, 0, 3, 3), mat2.block(3, 3, 3, 3));
 | 
			
		||||
    mat1ref.block(0, 0, 3, 3).swap(mat2ref.block(3, 3, 3, 3));
 | 
			
		||||
    VERIFY_IS_APPROX(mat1, mat1ref);
 | 
			
		||||
    VERIFY_IS_APPROX(mat2, mat2ref);
 | 
			
		||||
 | 
			
		||||
    swap_using_evaluator(mat1.row(2), mat2.col(3).transpose());
 | 
			
		||||
    mat1.row(2).swap(mat2.col(3).transpose());
 | 
			
		||||
    VERIFY_IS_APPROX(mat1, mat1ref);
 | 
			
		||||
    VERIFY_IS_APPROX(mat2, mat2ref);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    // test compound assignment
 | 
			
		||||
    const Matrix4d mat_const = Matrix4d::Random(); 
 | 
			
		||||
    Matrix4d mat, mat_ref;
 | 
			
		||||
    mat = mat_ref = Matrix4d::Identity();
 | 
			
		||||
    add_assign_using_evaluator(mat, mat_const);
 | 
			
		||||
    mat_ref += mat_const;
 | 
			
		||||
    VERIFY_IS_APPROX(mat, mat_ref);
 | 
			
		||||
 | 
			
		||||
    subtract_assign_using_evaluator(mat.row(1), 2*mat.row(2));
 | 
			
		||||
    mat_ref.row(1) -= 2*mat_ref.row(2);
 | 
			
		||||
    VERIFY_IS_APPROX(mat, mat_ref);
 | 
			
		||||
 | 
			
		||||
    const ArrayXXf arr_const = ArrayXXf::Random(5,3); 
 | 
			
		||||
    ArrayXXf arr, arr_ref;
 | 
			
		||||
    arr = arr_ref = ArrayXXf::Constant(5, 3, 0.5);
 | 
			
		||||
    multiply_assign_using_evaluator(arr, arr_const);
 | 
			
		||||
    arr_ref *= arr_const;
 | 
			
		||||
    VERIFY_IS_APPROX(arr, arr_ref);
 | 
			
		||||
 | 
			
		||||
    divide_assign_using_evaluator(arr.row(1), arr.row(2) + 1);
 | 
			
		||||
    arr_ref.row(1) /= (arr_ref.row(2) + 1);
 | 
			
		||||
    VERIFY_IS_APPROX(arr, arr_ref);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  {
 | 
			
		||||
    // test triangular shapes
 | 
			
		||||
    MatrixXd A = MatrixXd::Random(6,6), B(6,6), C(6,6), D(6,6);
 | 
			
		||||
    A.setRandom();B.setRandom();
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR2(B, A.triangularView<Upper>(), MatrixXd(A.triangularView<Upper>()));
 | 
			
		||||
    
 | 
			
		||||
    A.setRandom();B.setRandom();
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR2(B, A.triangularView<UnitLower>(), MatrixXd(A.triangularView<UnitLower>()));
 | 
			
		||||
    
 | 
			
		||||
    A.setRandom();B.setRandom();
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR2(B, A.triangularView<UnitUpper>(), MatrixXd(A.triangularView<UnitUpper>()));
 | 
			
		||||
    
 | 
			
		||||
    A.setRandom();B.setRandom();
 | 
			
		||||
    C = B; C.triangularView<Upper>() = A;
 | 
			
		||||
    copy_using_evaluator(B.triangularView<Upper>(), A);
 | 
			
		||||
    VERIFY(B.isApprox(C) && "copy_using_evaluator(B.triangularView<Upper>(), A)");
 | 
			
		||||
    
 | 
			
		||||
    A.setRandom();B.setRandom();
 | 
			
		||||
    C = B; C.triangularView<Lower>() = A.triangularView<Lower>();
 | 
			
		||||
    copy_using_evaluator(B.triangularView<Lower>(), A.triangularView<Lower>());
 | 
			
		||||
    VERIFY(B.isApprox(C) && "copy_using_evaluator(B.triangularView<Lower>(), A.triangularView<Lower>())");
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    A.setRandom();B.setRandom();
 | 
			
		||||
    C = B; C.triangularView<Lower>() = A.triangularView<Upper>().transpose();
 | 
			
		||||
    copy_using_evaluator(B.triangularView<Lower>(), A.triangularView<Upper>().transpose());
 | 
			
		||||
    VERIFY(B.isApprox(C) && "copy_using_evaluator(B.triangularView<Lower>(), A.triangularView<Lower>().transpose())");
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    A.setRandom();B.setRandom(); C = B; D = A;
 | 
			
		||||
    C.triangularView<Upper>().swap(D.triangularView<Upper>());
 | 
			
		||||
    swap_using_evaluator(B.triangularView<Upper>(), A.triangularView<Upper>());
 | 
			
		||||
    VERIFY(B.isApprox(C) && "swap_using_evaluator(B.triangularView<Upper>(), A.triangularView<Upper>())");
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR2(B, prod(A.triangularView<Upper>(),A), MatrixXd(A.triangularView<Upper>()*A));
 | 
			
		||||
    
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR2(B, prod(A.selfadjointView<Upper>(),A), MatrixXd(A.selfadjointView<Upper>()*A));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    // test diagonal shapes
 | 
			
		||||
    VectorXd d = VectorXd::Random(6);
 | 
			
		||||
    MatrixXd A = MatrixXd::Random(6,6), B(6,6);
 | 
			
		||||
    A.setRandom();B.setRandom();
 | 
			
		||||
    
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR2(B, lazyprod(d.asDiagonal(),A), MatrixXd(d.asDiagonal()*A));
 | 
			
		||||
    VERIFY_IS_APPROX_EVALUATOR2(B, lazyprod(A,d.asDiagonal()), MatrixXd(A*d.asDiagonal()));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    // test CoeffReadCost
 | 
			
		||||
    Matrix4d a, b;
 | 
			
		||||
    VERIFY_IS_EQUAL( get_cost(a), 1 );
 | 
			
		||||
    VERIFY_IS_EQUAL( get_cost(a+b), 3);
 | 
			
		||||
    VERIFY_IS_EQUAL( get_cost(2*a+b), 4);
 | 
			
		||||
    VERIFY_IS_EQUAL( get_cost(a*b), 1);
 | 
			
		||||
    VERIFY_IS_EQUAL( get_cost(a.lazyProduct(b)), 15);
 | 
			
		||||
    VERIFY_IS_EQUAL( get_cost(a*(a*b)), 1);
 | 
			
		||||
    VERIFY_IS_EQUAL( get_cost(a.lazyProduct(a*b)), 15);
 | 
			
		||||
    VERIFY_IS_EQUAL( get_cost(a*(a+b)), 1);
 | 
			
		||||
    VERIFY_IS_EQUAL( get_cost(a.lazyProduct(a+b)), 15);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										115
									
								
								cs440-acg/ext/eigen/test/exceptions.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								cs440-acg/ext/eigen/test/exceptions.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,115 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2011 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Various sanity tests with exceptions:
 | 
			
		||||
//  - no memory leak when a custom scalar type trow an exceptions
 | 
			
		||||
//  - todo: complete the list of tests!
 | 
			
		||||
 | 
			
		||||
#define EIGEN_STACK_ALLOCATION_LIMIT 100000000
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
 | 
			
		||||
struct my_exception
 | 
			
		||||
{
 | 
			
		||||
  my_exception() {}
 | 
			
		||||
  ~my_exception() {}
 | 
			
		||||
};
 | 
			
		||||
    
 | 
			
		||||
class ScalarWithExceptions
 | 
			
		||||
{
 | 
			
		||||
  public:
 | 
			
		||||
    ScalarWithExceptions() { init(); }
 | 
			
		||||
    ScalarWithExceptions(const float& _v) { init(); *v = _v; }
 | 
			
		||||
    ScalarWithExceptions(const ScalarWithExceptions& other) { init(); *v = *(other.v); }
 | 
			
		||||
    ~ScalarWithExceptions() {
 | 
			
		||||
      delete v;
 | 
			
		||||
      instances--;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void init() {
 | 
			
		||||
      v = new float;
 | 
			
		||||
      instances++;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ScalarWithExceptions operator+(const ScalarWithExceptions& other) const
 | 
			
		||||
    {
 | 
			
		||||
      countdown--;
 | 
			
		||||
      if(countdown<=0)
 | 
			
		||||
        throw my_exception();
 | 
			
		||||
      return ScalarWithExceptions(*v+*other.v);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    ScalarWithExceptions operator-(const ScalarWithExceptions& other) const
 | 
			
		||||
    { return ScalarWithExceptions(*v-*other.v); }
 | 
			
		||||
    
 | 
			
		||||
    ScalarWithExceptions operator*(const ScalarWithExceptions& other) const
 | 
			
		||||
    { return ScalarWithExceptions((*v)*(*other.v)); }
 | 
			
		||||
    
 | 
			
		||||
    ScalarWithExceptions& operator+=(const ScalarWithExceptions& other)
 | 
			
		||||
    { *v+=*other.v; return *this; }
 | 
			
		||||
    ScalarWithExceptions& operator-=(const ScalarWithExceptions& other)
 | 
			
		||||
    { *v-=*other.v; return *this; }
 | 
			
		||||
    ScalarWithExceptions& operator=(const ScalarWithExceptions& other)
 | 
			
		||||
    { *v = *(other.v); return *this; }
 | 
			
		||||
  
 | 
			
		||||
    bool operator==(const ScalarWithExceptions& other) const
 | 
			
		||||
    { return *v==*other.v; }
 | 
			
		||||
    bool operator!=(const ScalarWithExceptions& other) const
 | 
			
		||||
    { return *v!=*other.v; }
 | 
			
		||||
    
 | 
			
		||||
    float* v;
 | 
			
		||||
    static int instances;
 | 
			
		||||
    static int countdown;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
ScalarWithExceptions real(const ScalarWithExceptions &x) { return x; }
 | 
			
		||||
ScalarWithExceptions imag(const ScalarWithExceptions & ) { return 0; }
 | 
			
		||||
ScalarWithExceptions conj(const ScalarWithExceptions &x) { return x; }
 | 
			
		||||
 | 
			
		||||
int ScalarWithExceptions::instances = 0;
 | 
			
		||||
int ScalarWithExceptions::countdown = 0;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define CHECK_MEMLEAK(OP) {                                 \
 | 
			
		||||
    ScalarWithExceptions::countdown = 100;                  \
 | 
			
		||||
    int before = ScalarWithExceptions::instances;           \
 | 
			
		||||
    bool exception_thrown = false;                         \
 | 
			
		||||
    try { OP; }                              \
 | 
			
		||||
    catch (my_exception) {                                  \
 | 
			
		||||
      exception_thrown = true;                              \
 | 
			
		||||
      VERIFY(ScalarWithExceptions::instances==before && "memory leak detected in " && EIGEN_MAKESTRING(OP)); \
 | 
			
		||||
    } \
 | 
			
		||||
    VERIFY(exception_thrown && " no exception thrown in " && EIGEN_MAKESTRING(OP)); \
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
void memoryleak()
 | 
			
		||||
{
 | 
			
		||||
  typedef Eigen::Matrix<ScalarWithExceptions,Dynamic,1> VectorType;
 | 
			
		||||
  typedef Eigen::Matrix<ScalarWithExceptions,Dynamic,Dynamic> MatrixType;
 | 
			
		||||
  
 | 
			
		||||
  {
 | 
			
		||||
    int n = 50;
 | 
			
		||||
    VectorType v0(n), v1(n);
 | 
			
		||||
    MatrixType m0(n,n), m1(n,n), m2(n,n);
 | 
			
		||||
    v0.setOnes(); v1.setOnes();
 | 
			
		||||
    m0.setOnes(); m1.setOnes(); m2.setOnes();
 | 
			
		||||
    CHECK_MEMLEAK(v0 = m0 * m1 * v1);
 | 
			
		||||
    CHECK_MEMLEAK(m2 = m0 * m1 * m2);
 | 
			
		||||
    CHECK_MEMLEAK((v0+v1).dot(v0+v1));
 | 
			
		||||
  }
 | 
			
		||||
  VERIFY(ScalarWithExceptions::instances==0 && "global memory leak detected in " && EIGEN_MAKESTRING(OP)); \
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_exceptions()
 | 
			
		||||
{
 | 
			
		||||
  EIGEN_TRY {
 | 
			
		||||
    CALL_SUBTEST( memoryleak() );
 | 
			
		||||
  } EIGEN_CATCH(...) {}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										99
									
								
								cs440-acg/ext/eigen/test/fastmath.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								cs440-acg/ext/eigen/test/fastmath.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,99 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2015 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
 | 
			
		||||
void check(bool b, bool ref)
 | 
			
		||||
{
 | 
			
		||||
  std::cout << b;
 | 
			
		||||
  if(b==ref)
 | 
			
		||||
    std::cout << " OK  ";
 | 
			
		||||
  else
 | 
			
		||||
    std::cout << " BAD ";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if EIGEN_COMP_MSVC && EIGEN_COMP_MSVC < 1800
 | 
			
		||||
namespace std {
 | 
			
		||||
  template<typename T> bool (isfinite)(T x) { return _finite(x); }
 | 
			
		||||
  template<typename T> bool (isnan)(T x) { return _isnan(x); }
 | 
			
		||||
  template<typename T> bool (isinf)(T x) { return _fpclass(x)==_FPCLASS_NINF || _fpclass(x)==_FPCLASS_PINF; }
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
void check_inf_nan(bool dryrun) {
 | 
			
		||||
  Matrix<T,Dynamic,1> m(10);
 | 
			
		||||
  m.setRandom();
 | 
			
		||||
  m(3) = std::numeric_limits<T>::quiet_NaN();
 | 
			
		||||
 | 
			
		||||
  if(dryrun)
 | 
			
		||||
  {
 | 
			
		||||
    std::cout << "std::isfinite(" << m(3) << ") = "; check((std::isfinite)(m(3)),false); std::cout << "  ; numext::isfinite = "; check((numext::isfinite)(m(3)), false); std::cout << "\n";
 | 
			
		||||
    std::cout << "std::isinf(" << m(3) << ")    = "; check((std::isinf)(m(3)),false);    std::cout << "  ; numext::isinf    = "; check((numext::isinf)(m(3)), false); std::cout << "\n";
 | 
			
		||||
    std::cout << "std::isnan(" << m(3) << ")    = "; check((std::isnan)(m(3)),true);     std::cout << "  ; numext::isnan    = "; check((numext::isnan)(m(3)), true); std::cout << "\n";
 | 
			
		||||
    std::cout << "allFinite: "; check(m.allFinite(), 0); std::cout << "\n";
 | 
			
		||||
    std::cout << "hasNaN:    "; check(m.hasNaN(), 1);    std::cout << "\n";
 | 
			
		||||
    std::cout << "\n";
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    if( (std::isfinite)(m(3))) g_test_level=1;  VERIFY( !(numext::isfinite)(m(3)) ); g_test_level=0;
 | 
			
		||||
    if( (std::isinf)   (m(3))) g_test_level=1;  VERIFY( !(numext::isinf)(m(3)) );    g_test_level=0;
 | 
			
		||||
    if(!(std::isnan)   (m(3))) g_test_level=1;  VERIFY(  (numext::isnan)(m(3)) );    g_test_level=0;
 | 
			
		||||
    if( (std::isfinite)(m(3))) g_test_level=1;  VERIFY( !m.allFinite() );            g_test_level=0;
 | 
			
		||||
    if(!(std::isnan)   (m(3))) g_test_level=1;  VERIFY(  m.hasNaN() );               g_test_level=0;
 | 
			
		||||
  }
 | 
			
		||||
  T hidden_zero = (std::numeric_limits<T>::min)()*(std::numeric_limits<T>::min)();
 | 
			
		||||
  m(4) /= hidden_zero;
 | 
			
		||||
  if(dryrun)
 | 
			
		||||
  {
 | 
			
		||||
    std::cout << "std::isfinite(" << m(4) << ") = "; check((std::isfinite)(m(4)),false); std::cout << "  ; numext::isfinite = "; check((numext::isfinite)(m(4)), false); std::cout << "\n";
 | 
			
		||||
    std::cout << "std::isinf(" << m(4) << ")    = "; check((std::isinf)(m(4)),true);     std::cout << "  ; numext::isinf    = "; check((numext::isinf)(m(4)), true); std::cout << "\n";
 | 
			
		||||
    std::cout << "std::isnan(" << m(4) << ")    = "; check((std::isnan)(m(4)),false);    std::cout << "  ; numext::isnan    = "; check((numext::isnan)(m(4)), false); std::cout << "\n";
 | 
			
		||||
    std::cout << "allFinite: "; check(m.allFinite(), 0); std::cout << "\n";
 | 
			
		||||
    std::cout << "hasNaN:    "; check(m.hasNaN(), 1);    std::cout << "\n";
 | 
			
		||||
    std::cout << "\n";
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    if( (std::isfinite)(m(3))) g_test_level=1;  VERIFY( !(numext::isfinite)(m(4)) );  g_test_level=0;
 | 
			
		||||
    if(!(std::isinf)   (m(3))) g_test_level=1;  VERIFY(  (numext::isinf)(m(4)) );     g_test_level=0;
 | 
			
		||||
    if( (std::isnan)   (m(3))) g_test_level=1;  VERIFY( !(numext::isnan)(m(4)) );     g_test_level=0;
 | 
			
		||||
    if( (std::isfinite)(m(3))) g_test_level=1;  VERIFY( !m.allFinite() );             g_test_level=0;
 | 
			
		||||
    if(!(std::isnan)   (m(3))) g_test_level=1;  VERIFY(  m.hasNaN() );                g_test_level=0;
 | 
			
		||||
  }
 | 
			
		||||
  m(3) = 0;
 | 
			
		||||
  if(dryrun)
 | 
			
		||||
  {
 | 
			
		||||
    std::cout << "std::isfinite(" << m(3) << ") = "; check((std::isfinite)(m(3)),true); std::cout << "  ; numext::isfinite = "; check((numext::isfinite)(m(3)), true); std::cout << "\n";
 | 
			
		||||
    std::cout << "std::isinf(" << m(3) << ")    = "; check((std::isinf)(m(3)),false);   std::cout << "  ; numext::isinf    = "; check((numext::isinf)(m(3)), false); std::cout << "\n";
 | 
			
		||||
    std::cout << "std::isnan(" << m(3) << ")    = "; check((std::isnan)(m(3)),false);   std::cout << "  ; numext::isnan    = "; check((numext::isnan)(m(3)), false); std::cout << "\n";
 | 
			
		||||
    std::cout << "allFinite: "; check(m.allFinite(), 0); std::cout << "\n";
 | 
			
		||||
    std::cout << "hasNaN:    "; check(m.hasNaN(), 0);    std::cout << "\n";
 | 
			
		||||
    std::cout << "\n\n";
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    if(!(std::isfinite)(m(3))) g_test_level=1;  VERIFY(  (numext::isfinite)(m(3)) );  g_test_level=0;
 | 
			
		||||
    if( (std::isinf)   (m(3))) g_test_level=1;  VERIFY( !(numext::isinf)(m(3)) );     g_test_level=0;
 | 
			
		||||
    if( (std::isnan)   (m(3))) g_test_level=1;  VERIFY( !(numext::isnan)(m(3)) );     g_test_level=0;
 | 
			
		||||
    if( (std::isfinite)(m(3))) g_test_level=1;  VERIFY( !m.allFinite() );             g_test_level=0;
 | 
			
		||||
    if( (std::isnan)   (m(3))) g_test_level=1;  VERIFY( !m.hasNaN() );                g_test_level=0;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_fastmath() {
 | 
			
		||||
  std::cout << "*** float *** \n\n"; check_inf_nan<float>(true);
 | 
			
		||||
  std::cout << "*** double ***\n\n"; check_inf_nan<double>(true);
 | 
			
		||||
  std::cout << "*** long double *** \n\n"; check_inf_nan<long double>(true);
 | 
			
		||||
 | 
			
		||||
  check_inf_nan<float>(false);
 | 
			
		||||
  check_inf_nan<double>(false);
 | 
			
		||||
  check_inf_nan<long double>(false);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										51
									
								
								cs440-acg/ext/eigen/test/first_aligned.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								cs440-acg/ext/eigen/test/first_aligned.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,51 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
 | 
			
		||||
template<typename Scalar>
 | 
			
		||||
void test_first_aligned_helper(Scalar *array, int size)
 | 
			
		||||
{
 | 
			
		||||
  const int packet_size = sizeof(Scalar) * internal::packet_traits<Scalar>::size;
 | 
			
		||||
  VERIFY(((size_t(array) + sizeof(Scalar) * internal::first_default_aligned(array, size)) % packet_size) == 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Scalar>
 | 
			
		||||
void test_none_aligned_helper(Scalar *array, int size)
 | 
			
		||||
{
 | 
			
		||||
  EIGEN_UNUSED_VARIABLE(array);
 | 
			
		||||
  EIGEN_UNUSED_VARIABLE(size);
 | 
			
		||||
  VERIFY(internal::packet_traits<Scalar>::size == 1 || internal::first_default_aligned(array, size) == size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct some_non_vectorizable_type { float x; };
 | 
			
		||||
 | 
			
		||||
void test_first_aligned()
 | 
			
		||||
{
 | 
			
		||||
  EIGEN_ALIGN16 float array_float[100];
 | 
			
		||||
  test_first_aligned_helper(array_float, 50);
 | 
			
		||||
  test_first_aligned_helper(array_float+1, 50);
 | 
			
		||||
  test_first_aligned_helper(array_float+2, 50);
 | 
			
		||||
  test_first_aligned_helper(array_float+3, 50);
 | 
			
		||||
  test_first_aligned_helper(array_float+4, 50);
 | 
			
		||||
  test_first_aligned_helper(array_float+5, 50);
 | 
			
		||||
  
 | 
			
		||||
  EIGEN_ALIGN16 double array_double[100];
 | 
			
		||||
  test_first_aligned_helper(array_double, 50);
 | 
			
		||||
  test_first_aligned_helper(array_double+1, 50);
 | 
			
		||||
  test_first_aligned_helper(array_double+2, 50);
 | 
			
		||||
  
 | 
			
		||||
  double *array_double_plus_4_bytes = (double*)(internal::UIntPtr(array_double)+4);
 | 
			
		||||
  test_none_aligned_helper(array_double_plus_4_bytes, 50);
 | 
			
		||||
  test_none_aligned_helper(array_double_plus_4_bytes+1, 50);
 | 
			
		||||
  
 | 
			
		||||
  some_non_vectorizable_type array_nonvec[100];
 | 
			
		||||
  test_first_aligned_helper(array_nonvec, 100);
 | 
			
		||||
  test_none_aligned_helper(array_nonvec, 100);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										188
									
								
								cs440-acg/ext/eigen/test/geo_alignedbox.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										188
									
								
								cs440-acg/ext/eigen/test/geo_alignedbox.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,188 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
#include <Eigen/Geometry>
 | 
			
		||||
#include <Eigen/LU>
 | 
			
		||||
#include <Eigen/QR>
 | 
			
		||||
 | 
			
		||||
#include<iostream>
 | 
			
		||||
using namespace std;
 | 
			
		||||
 | 
			
		||||
// TODO not sure if this is actually still necessary anywhere ...
 | 
			
		||||
template<typename T> EIGEN_DONT_INLINE
 | 
			
		||||
void kill_extra_precision(T& ) {  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template<typename BoxType> void alignedbox(const BoxType& _box)
 | 
			
		||||
{
 | 
			
		||||
  /* this test covers the following files:
 | 
			
		||||
     AlignedBox.h
 | 
			
		||||
  */
 | 
			
		||||
  typedef typename BoxType::Scalar Scalar;
 | 
			
		||||
  typedef typename NumTraits<Scalar>::Real RealScalar;
 | 
			
		||||
  typedef Matrix<Scalar, BoxType::AmbientDimAtCompileTime, 1> VectorType;
 | 
			
		||||
 | 
			
		||||
  const Index dim = _box.dim();
 | 
			
		||||
 | 
			
		||||
  VectorType p0 = VectorType::Random(dim);
 | 
			
		||||
  VectorType p1 = VectorType::Random(dim);
 | 
			
		||||
  while( p1 == p0 ){
 | 
			
		||||
      p1 =  VectorType::Random(dim); }
 | 
			
		||||
  RealScalar s1 = internal::random<RealScalar>(0,1);
 | 
			
		||||
 | 
			
		||||
  BoxType b0(dim);
 | 
			
		||||
  BoxType b1(VectorType::Random(dim),VectorType::Random(dim));
 | 
			
		||||
  BoxType b2;
 | 
			
		||||
  
 | 
			
		||||
  kill_extra_precision(b1);
 | 
			
		||||
  kill_extra_precision(p0);
 | 
			
		||||
  kill_extra_precision(p1);
 | 
			
		||||
 | 
			
		||||
  b0.extend(p0);
 | 
			
		||||
  b0.extend(p1);
 | 
			
		||||
  VERIFY(b0.contains(p0*s1+(Scalar(1)-s1)*p1));
 | 
			
		||||
  VERIFY(b0.contains(b0.center()));
 | 
			
		||||
  VERIFY_IS_APPROX(b0.center(),(p0+p1)/Scalar(2));
 | 
			
		||||
 | 
			
		||||
  (b2 = b0).extend(b1);
 | 
			
		||||
  VERIFY(b2.contains(b0));
 | 
			
		||||
  VERIFY(b2.contains(b1));
 | 
			
		||||
  VERIFY_IS_APPROX(b2.clamp(b0), b0);
 | 
			
		||||
 | 
			
		||||
  // intersection
 | 
			
		||||
  BoxType box1(VectorType::Random(dim));
 | 
			
		||||
  box1.extend(VectorType::Random(dim));
 | 
			
		||||
  BoxType box2(VectorType::Random(dim));
 | 
			
		||||
  box2.extend(VectorType::Random(dim));
 | 
			
		||||
 | 
			
		||||
  VERIFY(box1.intersects(box2) == !box1.intersection(box2).isEmpty()); 
 | 
			
		||||
 | 
			
		||||
  // alignment -- make sure there is no memory alignment assertion
 | 
			
		||||
  BoxType *bp0 = new BoxType(dim);
 | 
			
		||||
  BoxType *bp1 = new BoxType(dim);
 | 
			
		||||
  bp0->extend(*bp1);
 | 
			
		||||
  delete bp0;
 | 
			
		||||
  delete bp1;
 | 
			
		||||
 | 
			
		||||
  // sampling
 | 
			
		||||
  for( int i=0; i<10; ++i )
 | 
			
		||||
  {
 | 
			
		||||
      VectorType r = b0.sample();
 | 
			
		||||
      VERIFY(b0.contains(r));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template<typename BoxType>
 | 
			
		||||
void alignedboxCastTests(const BoxType& _box)
 | 
			
		||||
{
 | 
			
		||||
  // casting  
 | 
			
		||||
  typedef typename BoxType::Scalar Scalar;
 | 
			
		||||
  typedef Matrix<Scalar, BoxType::AmbientDimAtCompileTime, 1> VectorType;
 | 
			
		||||
 | 
			
		||||
  const Index dim = _box.dim();
 | 
			
		||||
 | 
			
		||||
  VectorType p0 = VectorType::Random(dim);
 | 
			
		||||
  VectorType p1 = VectorType::Random(dim);
 | 
			
		||||
 | 
			
		||||
  BoxType b0(dim);
 | 
			
		||||
 | 
			
		||||
  b0.extend(p0);
 | 
			
		||||
  b0.extend(p1);
 | 
			
		||||
 | 
			
		||||
  const int Dim = BoxType::AmbientDimAtCompileTime;
 | 
			
		||||
  typedef typename GetDifferentType<Scalar>::type OtherScalar;
 | 
			
		||||
  AlignedBox<OtherScalar,Dim> hp1f = b0.template cast<OtherScalar>();
 | 
			
		||||
  VERIFY_IS_APPROX(hp1f.template cast<Scalar>(),b0);
 | 
			
		||||
  AlignedBox<Scalar,Dim> hp1d = b0.template cast<Scalar>();
 | 
			
		||||
  VERIFY_IS_APPROX(hp1d.template cast<Scalar>(),b0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void specificTest1()
 | 
			
		||||
{
 | 
			
		||||
    Vector2f m; m << -1.0f, -2.0f;
 | 
			
		||||
    Vector2f M; M <<  1.0f,  5.0f;
 | 
			
		||||
 | 
			
		||||
    typedef AlignedBox2f  BoxType;
 | 
			
		||||
    BoxType box( m, M );
 | 
			
		||||
 | 
			
		||||
    Vector2f sides = M-m;
 | 
			
		||||
    VERIFY_IS_APPROX(sides, box.sizes() );
 | 
			
		||||
    VERIFY_IS_APPROX(sides[1], box.sizes()[1] );
 | 
			
		||||
    VERIFY_IS_APPROX(sides[1], box.sizes().maxCoeff() );
 | 
			
		||||
    VERIFY_IS_APPROX(sides[0], box.sizes().minCoeff() );
 | 
			
		||||
 | 
			
		||||
    VERIFY_IS_APPROX( 14.0f, box.volume() );
 | 
			
		||||
    VERIFY_IS_APPROX( 53.0f, box.diagonal().squaredNorm() );
 | 
			
		||||
    VERIFY_IS_APPROX( std::sqrt( 53.0f ), box.diagonal().norm() );
 | 
			
		||||
 | 
			
		||||
    VERIFY_IS_APPROX( m, box.corner( BoxType::BottomLeft ) );
 | 
			
		||||
    VERIFY_IS_APPROX( M, box.corner( BoxType::TopRight ) );
 | 
			
		||||
    Vector2f bottomRight; bottomRight << M[0], m[1];
 | 
			
		||||
    Vector2f topLeft; topLeft << m[0], M[1];
 | 
			
		||||
    VERIFY_IS_APPROX( bottomRight, box.corner( BoxType::BottomRight ) );
 | 
			
		||||
    VERIFY_IS_APPROX( topLeft, box.corner( BoxType::TopLeft ) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void specificTest2()
 | 
			
		||||
{
 | 
			
		||||
    Vector3i m; m << -1, -2, 0;
 | 
			
		||||
    Vector3i M; M <<  1,  5, 3;
 | 
			
		||||
 | 
			
		||||
    typedef AlignedBox3i  BoxType;
 | 
			
		||||
    BoxType box( m, M );
 | 
			
		||||
 | 
			
		||||
    Vector3i sides = M-m;
 | 
			
		||||
    VERIFY_IS_APPROX(sides, box.sizes() );
 | 
			
		||||
    VERIFY_IS_APPROX(sides[1], box.sizes()[1] );
 | 
			
		||||
    VERIFY_IS_APPROX(sides[1], box.sizes().maxCoeff() );
 | 
			
		||||
    VERIFY_IS_APPROX(sides[0], box.sizes().minCoeff() );
 | 
			
		||||
 | 
			
		||||
    VERIFY_IS_APPROX( 42, box.volume() );
 | 
			
		||||
    VERIFY_IS_APPROX( 62, box.diagonal().squaredNorm() );
 | 
			
		||||
 | 
			
		||||
    VERIFY_IS_APPROX( m, box.corner( BoxType::BottomLeftFloor ) );
 | 
			
		||||
    VERIFY_IS_APPROX( M, box.corner( BoxType::TopRightCeil ) );
 | 
			
		||||
    Vector3i bottomRightFloor; bottomRightFloor << M[0], m[1], m[2];
 | 
			
		||||
    Vector3i topLeftFloor; topLeftFloor << m[0], M[1], m[2];
 | 
			
		||||
    VERIFY_IS_APPROX( bottomRightFloor, box.corner( BoxType::BottomRightFloor ) );
 | 
			
		||||
    VERIFY_IS_APPROX( topLeftFloor, box.corner( BoxType::TopLeftFloor ) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void test_geo_alignedbox()
 | 
			
		||||
{
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++)
 | 
			
		||||
  {
 | 
			
		||||
    CALL_SUBTEST_1( alignedbox(AlignedBox2f()) );
 | 
			
		||||
    CALL_SUBTEST_2( alignedboxCastTests(AlignedBox2f()) );
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_3( alignedbox(AlignedBox3f()) );
 | 
			
		||||
    CALL_SUBTEST_4( alignedboxCastTests(AlignedBox3f()) );
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_5( alignedbox(AlignedBox4d()) );
 | 
			
		||||
    CALL_SUBTEST_6( alignedboxCastTests(AlignedBox4d()) );
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_7( alignedbox(AlignedBox1d()) );
 | 
			
		||||
    CALL_SUBTEST_8( alignedboxCastTests(AlignedBox1d()) );
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_9( alignedbox(AlignedBox1i()) );
 | 
			
		||||
    CALL_SUBTEST_10( alignedbox(AlignedBox2i()) );
 | 
			
		||||
    CALL_SUBTEST_11( alignedbox(AlignedBox3i()) );
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_14( alignedbox(AlignedBox<double,Dynamic>(4)) );
 | 
			
		||||
  }
 | 
			
		||||
  CALL_SUBTEST_12( specificTest1() );
 | 
			
		||||
  CALL_SUBTEST_13( specificTest2() );
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										112
									
								
								cs440-acg/ext/eigen/test/geo_eulerangles.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								cs440-acg/ext/eigen/test/geo_eulerangles.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,112 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2008-2012 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
#include <Eigen/Geometry>
 | 
			
		||||
#include <Eigen/LU>
 | 
			
		||||
#include <Eigen/SVD>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template<typename Scalar>
 | 
			
		||||
void verify_euler(const Matrix<Scalar,3,1>& ea, int i, int j, int k)
 | 
			
		||||
{
 | 
			
		||||
  typedef Matrix<Scalar,3,3> Matrix3;
 | 
			
		||||
  typedef Matrix<Scalar,3,1> Vector3;
 | 
			
		||||
  typedef AngleAxis<Scalar> AngleAxisx;
 | 
			
		||||
  using std::abs;
 | 
			
		||||
  Matrix3 m(AngleAxisx(ea[0], Vector3::Unit(i)) * AngleAxisx(ea[1], Vector3::Unit(j)) * AngleAxisx(ea[2], Vector3::Unit(k)));
 | 
			
		||||
  Vector3 eabis = m.eulerAngles(i, j, k);
 | 
			
		||||
  Matrix3 mbis(AngleAxisx(eabis[0], Vector3::Unit(i)) * AngleAxisx(eabis[1], Vector3::Unit(j)) * AngleAxisx(eabis[2], Vector3::Unit(k))); 
 | 
			
		||||
  VERIFY_IS_APPROX(m,  mbis); 
 | 
			
		||||
  /* If I==K, and ea[1]==0, then there no unique solution. */ 
 | 
			
		||||
  /* The remark apply in the case where I!=K, and |ea[1]| is close to pi/2. */ 
 | 
			
		||||
  if( (i!=k || ea[1]!=0) && (i==k || !internal::isApprox(abs(ea[1]),Scalar(EIGEN_PI/2),test_precision<Scalar>())) ) 
 | 
			
		||||
    VERIFY((ea-eabis).norm() <= test_precision<Scalar>());
 | 
			
		||||
  
 | 
			
		||||
  // approx_or_less_than does not work for 0
 | 
			
		||||
  VERIFY(0 < eabis[0] || test_isMuchSmallerThan(eabis[0], Scalar(1)));
 | 
			
		||||
  VERIFY_IS_APPROX_OR_LESS_THAN(eabis[0], Scalar(EIGEN_PI));
 | 
			
		||||
  VERIFY_IS_APPROX_OR_LESS_THAN(-Scalar(EIGEN_PI), eabis[1]);
 | 
			
		||||
  VERIFY_IS_APPROX_OR_LESS_THAN(eabis[1], Scalar(EIGEN_PI));
 | 
			
		||||
  VERIFY_IS_APPROX_OR_LESS_THAN(-Scalar(EIGEN_PI), eabis[2]);
 | 
			
		||||
  VERIFY_IS_APPROX_OR_LESS_THAN(eabis[2], Scalar(EIGEN_PI));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Scalar> void check_all_var(const Matrix<Scalar,3,1>& ea)
 | 
			
		||||
{
 | 
			
		||||
  verify_euler(ea, 0,1,2);
 | 
			
		||||
  verify_euler(ea, 0,1,0);
 | 
			
		||||
  verify_euler(ea, 0,2,1);
 | 
			
		||||
  verify_euler(ea, 0,2,0);
 | 
			
		||||
 | 
			
		||||
  verify_euler(ea, 1,2,0);
 | 
			
		||||
  verify_euler(ea, 1,2,1);
 | 
			
		||||
  verify_euler(ea, 1,0,2);
 | 
			
		||||
  verify_euler(ea, 1,0,1);
 | 
			
		||||
 | 
			
		||||
  verify_euler(ea, 2,0,1);
 | 
			
		||||
  verify_euler(ea, 2,0,2);
 | 
			
		||||
  verify_euler(ea, 2,1,0);
 | 
			
		||||
  verify_euler(ea, 2,1,2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Scalar> void eulerangles()
 | 
			
		||||
{
 | 
			
		||||
  typedef Matrix<Scalar,3,3> Matrix3;
 | 
			
		||||
  typedef Matrix<Scalar,3,1> Vector3;
 | 
			
		||||
  typedef Array<Scalar,3,1> Array3;
 | 
			
		||||
  typedef Quaternion<Scalar> Quaternionx;
 | 
			
		||||
  typedef AngleAxis<Scalar> AngleAxisx;
 | 
			
		||||
 | 
			
		||||
  Scalar a = internal::random<Scalar>(-Scalar(EIGEN_PI), Scalar(EIGEN_PI));
 | 
			
		||||
  Quaternionx q1;
 | 
			
		||||
  q1 = AngleAxisx(a, Vector3::Random().normalized());
 | 
			
		||||
  Matrix3 m;
 | 
			
		||||
  m = q1;
 | 
			
		||||
  
 | 
			
		||||
  Vector3 ea = m.eulerAngles(0,1,2);
 | 
			
		||||
  check_all_var(ea);
 | 
			
		||||
  ea = m.eulerAngles(0,1,0);
 | 
			
		||||
  check_all_var(ea);
 | 
			
		||||
  
 | 
			
		||||
  // Check with purely random Quaternion:
 | 
			
		||||
  q1.coeffs() = Quaternionx::Coefficients::Random().normalized();
 | 
			
		||||
  m = q1;
 | 
			
		||||
  ea = m.eulerAngles(0,1,2);
 | 
			
		||||
  check_all_var(ea);
 | 
			
		||||
  ea = m.eulerAngles(0,1,0);
 | 
			
		||||
  check_all_var(ea);
 | 
			
		||||
  
 | 
			
		||||
  // Check with random angles in range [0:pi]x[-pi:pi]x[-pi:pi].
 | 
			
		||||
  ea = (Array3::Random() + Array3(1,0,0))*Scalar(EIGEN_PI)*Array3(0.5,1,1);
 | 
			
		||||
  check_all_var(ea);
 | 
			
		||||
  
 | 
			
		||||
  ea[2] = ea[0] = internal::random<Scalar>(0,Scalar(EIGEN_PI));
 | 
			
		||||
  check_all_var(ea);
 | 
			
		||||
  
 | 
			
		||||
  ea[0] = ea[1] = internal::random<Scalar>(0,Scalar(EIGEN_PI));
 | 
			
		||||
  check_all_var(ea);
 | 
			
		||||
  
 | 
			
		||||
  ea[1] = 0;
 | 
			
		||||
  check_all_var(ea);
 | 
			
		||||
  
 | 
			
		||||
  ea.head(2).setZero();
 | 
			
		||||
  check_all_var(ea);
 | 
			
		||||
  
 | 
			
		||||
  ea.setZero();
 | 
			
		||||
  check_all_var(ea);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_geo_eulerangles()
 | 
			
		||||
{
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_1( eulerangles<float>() );
 | 
			
		||||
    CALL_SUBTEST_2( eulerangles<double>() );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										125
									
								
								cs440-acg/ext/eigen/test/geo_homogeneous.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										125
									
								
								cs440-acg/ext/eigen/test/geo_homogeneous.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,125 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
#include <Eigen/Geometry>
 | 
			
		||||
 | 
			
		||||
template<typename Scalar,int Size> void homogeneous(void)
 | 
			
		||||
{
 | 
			
		||||
  /* this test covers the following files:
 | 
			
		||||
     Homogeneous.h
 | 
			
		||||
  */
 | 
			
		||||
 | 
			
		||||
  typedef Matrix<Scalar,Size,Size> MatrixType;
 | 
			
		||||
  typedef Matrix<Scalar,Size,1, ColMajor> VectorType;
 | 
			
		||||
 | 
			
		||||
  typedef Matrix<Scalar,Size+1,Size> HMatrixType;
 | 
			
		||||
  typedef Matrix<Scalar,Size+1,1> HVectorType;
 | 
			
		||||
 | 
			
		||||
  typedef Matrix<Scalar,Size,Size+1>   T1MatrixType;
 | 
			
		||||
  typedef Matrix<Scalar,Size+1,Size+1> T2MatrixType;
 | 
			
		||||
  typedef Matrix<Scalar,Size+1,Size> T3MatrixType;
 | 
			
		||||
 | 
			
		||||
  VectorType v0 = VectorType::Random(),
 | 
			
		||||
             ones = VectorType::Ones();
 | 
			
		||||
 | 
			
		||||
  HVectorType hv0 = HVectorType::Random();
 | 
			
		||||
 | 
			
		||||
  MatrixType m0 = MatrixType::Random();
 | 
			
		||||
 | 
			
		||||
  HMatrixType hm0 = HMatrixType::Random();
 | 
			
		||||
 | 
			
		||||
  hv0 << v0, 1;
 | 
			
		||||
  VERIFY_IS_APPROX(v0.homogeneous(), hv0);
 | 
			
		||||
  VERIFY_IS_APPROX(v0, hv0.hnormalized());
 | 
			
		||||
  
 | 
			
		||||
  VERIFY_IS_APPROX(v0.homogeneous().sum(), hv0.sum());
 | 
			
		||||
  VERIFY_IS_APPROX(v0.homogeneous().minCoeff(), hv0.minCoeff());
 | 
			
		||||
  VERIFY_IS_APPROX(v0.homogeneous().maxCoeff(), hv0.maxCoeff());
 | 
			
		||||
 | 
			
		||||
  hm0 << m0, ones.transpose();
 | 
			
		||||
  VERIFY_IS_APPROX(m0.colwise().homogeneous(), hm0);
 | 
			
		||||
  VERIFY_IS_APPROX(m0, hm0.colwise().hnormalized());
 | 
			
		||||
  hm0.row(Size-1).setRandom();
 | 
			
		||||
  for(int j=0; j<Size; ++j)
 | 
			
		||||
    m0.col(j) = hm0.col(j).head(Size) / hm0(Size,j);
 | 
			
		||||
  VERIFY_IS_APPROX(m0, hm0.colwise().hnormalized());
 | 
			
		||||
 | 
			
		||||
  T1MatrixType t1 = T1MatrixType::Random();
 | 
			
		||||
  VERIFY_IS_APPROX(t1 * (v0.homogeneous().eval()), t1 * v0.homogeneous());
 | 
			
		||||
  VERIFY_IS_APPROX(t1 * (m0.colwise().homogeneous().eval()), t1 * m0.colwise().homogeneous());
 | 
			
		||||
 | 
			
		||||
  T2MatrixType t2 = T2MatrixType::Random();
 | 
			
		||||
  VERIFY_IS_APPROX(t2 * (v0.homogeneous().eval()), t2 * v0.homogeneous());
 | 
			
		||||
  VERIFY_IS_APPROX(t2 * (m0.colwise().homogeneous().eval()), t2 * m0.colwise().homogeneous());
 | 
			
		||||
  VERIFY_IS_APPROX(t2 * (v0.homogeneous().asDiagonal()), t2 * hv0.asDiagonal());
 | 
			
		||||
  VERIFY_IS_APPROX((v0.homogeneous().asDiagonal()) * t2, hv0.asDiagonal() * t2);
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX((v0.transpose().rowwise().homogeneous().eval()) * t2,
 | 
			
		||||
                    v0.transpose().rowwise().homogeneous() * t2);
 | 
			
		||||
  VERIFY_IS_APPROX((m0.transpose().rowwise().homogeneous().eval()) * t2,
 | 
			
		||||
                    m0.transpose().rowwise().homogeneous() * t2);
 | 
			
		||||
 | 
			
		||||
  T3MatrixType t3 = T3MatrixType::Random();
 | 
			
		||||
  VERIFY_IS_APPROX((v0.transpose().rowwise().homogeneous().eval()) * t3,
 | 
			
		||||
                    v0.transpose().rowwise().homogeneous() * t3);
 | 
			
		||||
  VERIFY_IS_APPROX((m0.transpose().rowwise().homogeneous().eval()) * t3,
 | 
			
		||||
                    m0.transpose().rowwise().homogeneous() * t3);
 | 
			
		||||
 | 
			
		||||
  // test product with a Transform object
 | 
			
		||||
  Transform<Scalar, Size, Affine> aff;
 | 
			
		||||
  Transform<Scalar, Size, AffineCompact> caff;
 | 
			
		||||
  Transform<Scalar, Size, Projective> proj;
 | 
			
		||||
  Matrix<Scalar, Size, Dynamic>   pts;
 | 
			
		||||
  Matrix<Scalar, Size+1, Dynamic> pts1, pts2;
 | 
			
		||||
 | 
			
		||||
  aff.affine().setRandom();
 | 
			
		||||
  proj = caff = aff;
 | 
			
		||||
  pts.setRandom(Size,internal::random<int>(1,20));
 | 
			
		||||
  
 | 
			
		||||
  pts1 = pts.colwise().homogeneous();
 | 
			
		||||
  VERIFY_IS_APPROX(aff  * pts.colwise().homogeneous(), (aff  * pts1).colwise().hnormalized());
 | 
			
		||||
  VERIFY_IS_APPROX(caff * pts.colwise().homogeneous(), (caff * pts1).colwise().hnormalized());
 | 
			
		||||
  VERIFY_IS_APPROX(proj * pts.colwise().homogeneous(), (proj * pts1));
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX((aff  * pts1).colwise().hnormalized(),  aff  * pts);
 | 
			
		||||
  VERIFY_IS_APPROX((caff * pts1).colwise().hnormalized(), caff * pts);
 | 
			
		||||
  
 | 
			
		||||
  pts2 = pts1;
 | 
			
		||||
  pts2.row(Size).setRandom();
 | 
			
		||||
  VERIFY_IS_APPROX((aff  * pts2).colwise().hnormalized(), aff  * pts2.colwise().hnormalized());
 | 
			
		||||
  VERIFY_IS_APPROX((caff * pts2).colwise().hnormalized(), caff * pts2.colwise().hnormalized());
 | 
			
		||||
  VERIFY_IS_APPROX((proj * pts2).colwise().hnormalized(), (proj * pts2.colwise().hnormalized().colwise().homogeneous()).colwise().hnormalized());
 | 
			
		||||
  
 | 
			
		||||
  // Test combination of homogeneous
 | 
			
		||||
  
 | 
			
		||||
  VERIFY_IS_APPROX( (t2 * v0.homogeneous()).hnormalized(),
 | 
			
		||||
                       (t2.template topLeftCorner<Size,Size>() * v0 + t2.template topRightCorner<Size,1>())
 | 
			
		||||
                     / ((t2.template bottomLeftCorner<1,Size>()*v0).value() + t2(Size,Size)) );
 | 
			
		||||
  
 | 
			
		||||
  VERIFY_IS_APPROX( (t2 * pts.colwise().homogeneous()).colwise().hnormalized(),
 | 
			
		||||
                    (Matrix<Scalar, Size+1, Dynamic>(t2 * pts1).colwise().hnormalized()) );
 | 
			
		||||
  
 | 
			
		||||
  VERIFY_IS_APPROX( (t2 .lazyProduct( v0.homogeneous() )).hnormalized(), (t2 * v0.homogeneous()).hnormalized() );
 | 
			
		||||
  VERIFY_IS_APPROX( (t2 .lazyProduct  ( pts.colwise().homogeneous() )).colwise().hnormalized(), (t2 * pts1).colwise().hnormalized() );
 | 
			
		||||
  
 | 
			
		||||
  VERIFY_IS_APPROX( (v0.transpose().homogeneous() .lazyProduct( t2 )).hnormalized(), (v0.transpose().homogeneous()*t2).hnormalized() );
 | 
			
		||||
  VERIFY_IS_APPROX( (pts.transpose().rowwise().homogeneous() .lazyProduct( t2 )).rowwise().hnormalized(), (pts1.transpose()*t2).rowwise().hnormalized() );
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX( (t2.template triangularView<Lower>() * v0.homogeneous()).eval(), (t2.template triangularView<Lower>()*hv0) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_geo_homogeneous()
 | 
			
		||||
{
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_1(( homogeneous<float,1>() ));
 | 
			
		||||
    CALL_SUBTEST_2(( homogeneous<double,3>() ));
 | 
			
		||||
    CALL_SUBTEST_3(( homogeneous<double,8>() ));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										197
									
								
								cs440-acg/ext/eigen/test/geo_hyperplane.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										197
									
								
								cs440-acg/ext/eigen/test/geo_hyperplane.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,197 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
#include <Eigen/Geometry>
 | 
			
		||||
#include <Eigen/LU>
 | 
			
		||||
#include <Eigen/QR>
 | 
			
		||||
 | 
			
		||||
template<typename HyperplaneType> void hyperplane(const HyperplaneType& _plane)
 | 
			
		||||
{
 | 
			
		||||
  /* this test covers the following files:
 | 
			
		||||
     Hyperplane.h
 | 
			
		||||
  */
 | 
			
		||||
  using std::abs;
 | 
			
		||||
  const Index dim = _plane.dim();
 | 
			
		||||
  enum { Options = HyperplaneType::Options };
 | 
			
		||||
  typedef typename HyperplaneType::Scalar Scalar;
 | 
			
		||||
  typedef typename HyperplaneType::RealScalar RealScalar;
 | 
			
		||||
  typedef Matrix<Scalar, HyperplaneType::AmbientDimAtCompileTime, 1> VectorType;
 | 
			
		||||
  typedef Matrix<Scalar, HyperplaneType::AmbientDimAtCompileTime,
 | 
			
		||||
                         HyperplaneType::AmbientDimAtCompileTime> MatrixType;
 | 
			
		||||
 | 
			
		||||
  VectorType p0 = VectorType::Random(dim);
 | 
			
		||||
  VectorType p1 = VectorType::Random(dim);
 | 
			
		||||
 | 
			
		||||
  VectorType n0 = VectorType::Random(dim).normalized();
 | 
			
		||||
  VectorType n1 = VectorType::Random(dim).normalized();
 | 
			
		||||
 | 
			
		||||
  HyperplaneType pl0(n0, p0);
 | 
			
		||||
  HyperplaneType pl1(n1, p1);
 | 
			
		||||
  HyperplaneType pl2 = pl1;
 | 
			
		||||
 | 
			
		||||
  Scalar s0 = internal::random<Scalar>();
 | 
			
		||||
  Scalar s1 = internal::random<Scalar>();
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX( n1.dot(n1), Scalar(1) );
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_MUCH_SMALLER_THAN( pl0.absDistance(p0), Scalar(1) );
 | 
			
		||||
  if(numext::abs2(s0)>RealScalar(1e-6))
 | 
			
		||||
    VERIFY_IS_APPROX( pl1.signedDistance(p1 + n1 * s0), s0);
 | 
			
		||||
  else
 | 
			
		||||
    VERIFY_IS_MUCH_SMALLER_THAN( abs(pl1.signedDistance(p1 + n1 * s0) - s0), Scalar(1) );
 | 
			
		||||
  VERIFY_IS_MUCH_SMALLER_THAN( pl1.signedDistance(pl1.projection(p0)), Scalar(1) );
 | 
			
		||||
  VERIFY_IS_MUCH_SMALLER_THAN( pl1.absDistance(p1 +  pl1.normal().unitOrthogonal() * s1), Scalar(1) );
 | 
			
		||||
 | 
			
		||||
  // transform
 | 
			
		||||
  if (!NumTraits<Scalar>::IsComplex)
 | 
			
		||||
  {
 | 
			
		||||
    MatrixType rot = MatrixType::Random(dim,dim).householderQr().householderQ();
 | 
			
		||||
    DiagonalMatrix<Scalar,HyperplaneType::AmbientDimAtCompileTime> scaling(VectorType::Random());
 | 
			
		||||
    Translation<Scalar,HyperplaneType::AmbientDimAtCompileTime> translation(VectorType::Random());
 | 
			
		||||
    
 | 
			
		||||
    while(scaling.diagonal().cwiseAbs().minCoeff()<RealScalar(1e-4)) scaling.diagonal() = VectorType::Random();
 | 
			
		||||
 | 
			
		||||
    pl2 = pl1;
 | 
			
		||||
    VERIFY_IS_MUCH_SMALLER_THAN( pl2.transform(rot).absDistance(rot * p1), Scalar(1) );
 | 
			
		||||
    pl2 = pl1;
 | 
			
		||||
    VERIFY_IS_MUCH_SMALLER_THAN( pl2.transform(rot,Isometry).absDistance(rot * p1), Scalar(1) );
 | 
			
		||||
    pl2 = pl1;
 | 
			
		||||
    VERIFY_IS_MUCH_SMALLER_THAN( pl2.transform(rot*scaling).absDistance((rot*scaling) * p1), Scalar(1) );
 | 
			
		||||
    VERIFY_IS_APPROX( pl2.normal().norm(), RealScalar(1) );
 | 
			
		||||
    pl2 = pl1;
 | 
			
		||||
    VERIFY_IS_MUCH_SMALLER_THAN( pl2.transform(rot*scaling*translation)
 | 
			
		||||
                                  .absDistance((rot*scaling*translation) * p1), Scalar(1) );
 | 
			
		||||
    VERIFY_IS_APPROX( pl2.normal().norm(), RealScalar(1) );
 | 
			
		||||
    pl2 = pl1;
 | 
			
		||||
    VERIFY_IS_MUCH_SMALLER_THAN( pl2.transform(rot*translation,Isometry)
 | 
			
		||||
                                 .absDistance((rot*translation) * p1), Scalar(1) );
 | 
			
		||||
    VERIFY_IS_APPROX( pl2.normal().norm(), RealScalar(1) );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // casting
 | 
			
		||||
  const int Dim = HyperplaneType::AmbientDimAtCompileTime;
 | 
			
		||||
  typedef typename GetDifferentType<Scalar>::type OtherScalar;
 | 
			
		||||
  Hyperplane<OtherScalar,Dim,Options> hp1f = pl1.template cast<OtherScalar>();
 | 
			
		||||
  VERIFY_IS_APPROX(hp1f.template cast<Scalar>(),pl1);
 | 
			
		||||
  Hyperplane<Scalar,Dim,Options> hp1d = pl1.template cast<Scalar>();
 | 
			
		||||
  VERIFY_IS_APPROX(hp1d.template cast<Scalar>(),pl1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Scalar> void lines()
 | 
			
		||||
{
 | 
			
		||||
  using std::abs;
 | 
			
		||||
  typedef Hyperplane<Scalar, 2> HLine;
 | 
			
		||||
  typedef ParametrizedLine<Scalar, 2> PLine;
 | 
			
		||||
  typedef Matrix<Scalar,2,1> Vector;
 | 
			
		||||
  typedef Matrix<Scalar,3,1> CoeffsType;
 | 
			
		||||
 | 
			
		||||
  for(int i = 0; i < 10; i++)
 | 
			
		||||
  {
 | 
			
		||||
    Vector center = Vector::Random();
 | 
			
		||||
    Vector u = Vector::Random();
 | 
			
		||||
    Vector v = Vector::Random();
 | 
			
		||||
    Scalar a = internal::random<Scalar>();
 | 
			
		||||
    while (abs(a-1) < Scalar(1e-4)) a = internal::random<Scalar>();
 | 
			
		||||
    while (u.norm() < Scalar(1e-4)) u = Vector::Random();
 | 
			
		||||
    while (v.norm() < Scalar(1e-4)) v = Vector::Random();
 | 
			
		||||
 | 
			
		||||
    HLine line_u = HLine::Through(center + u, center + a*u);
 | 
			
		||||
    HLine line_v = HLine::Through(center + v, center + a*v);
 | 
			
		||||
 | 
			
		||||
    // the line equations should be normalized so that a^2+b^2=1
 | 
			
		||||
    VERIFY_IS_APPROX(line_u.normal().norm(), Scalar(1));
 | 
			
		||||
    VERIFY_IS_APPROX(line_v.normal().norm(), Scalar(1));
 | 
			
		||||
 | 
			
		||||
    Vector result = line_u.intersection(line_v);
 | 
			
		||||
 | 
			
		||||
    // the lines should intersect at the point we called "center"
 | 
			
		||||
    if(abs(a-1) > Scalar(1e-2) && abs(v.normalized().dot(u.normalized()))<Scalar(0.9))
 | 
			
		||||
      VERIFY_IS_APPROX(result, center);
 | 
			
		||||
 | 
			
		||||
    // check conversions between two types of lines
 | 
			
		||||
    PLine pl(line_u); // gcc 3.3 will commit suicide if we don't name this variable
 | 
			
		||||
    HLine line_u2(pl);
 | 
			
		||||
    CoeffsType converted_coeffs = line_u2.coeffs();
 | 
			
		||||
    if(line_u2.normal().dot(line_u.normal())<Scalar(0))
 | 
			
		||||
      converted_coeffs = -line_u2.coeffs();
 | 
			
		||||
    VERIFY(line_u.coeffs().isApprox(converted_coeffs));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Scalar> void planes()
 | 
			
		||||
{
 | 
			
		||||
  using std::abs;
 | 
			
		||||
  typedef Hyperplane<Scalar, 3> Plane;
 | 
			
		||||
  typedef Matrix<Scalar,3,1> Vector;
 | 
			
		||||
 | 
			
		||||
  for(int i = 0; i < 10; i++)
 | 
			
		||||
  {
 | 
			
		||||
    Vector v0 = Vector::Random();
 | 
			
		||||
    Vector v1(v0), v2(v0);
 | 
			
		||||
    if(internal::random<double>(0,1)>0.25)
 | 
			
		||||
      v1 += Vector::Random();
 | 
			
		||||
    if(internal::random<double>(0,1)>0.25)
 | 
			
		||||
      v2 += v1 * std::pow(internal::random<Scalar>(0,1),internal::random<int>(1,16));
 | 
			
		||||
    if(internal::random<double>(0,1)>0.25)
 | 
			
		||||
      v2 += Vector::Random() * std::pow(internal::random<Scalar>(0,1),internal::random<int>(1,16));
 | 
			
		||||
 | 
			
		||||
    Plane p0 = Plane::Through(v0, v1, v2);
 | 
			
		||||
 | 
			
		||||
    VERIFY_IS_APPROX(p0.normal().norm(), Scalar(1));
 | 
			
		||||
    VERIFY_IS_MUCH_SMALLER_THAN(p0.absDistance(v0), Scalar(1));
 | 
			
		||||
    VERIFY_IS_MUCH_SMALLER_THAN(p0.absDistance(v1), Scalar(1));
 | 
			
		||||
    VERIFY_IS_MUCH_SMALLER_THAN(p0.absDistance(v2), Scalar(1));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Scalar> void hyperplane_alignment()
 | 
			
		||||
{
 | 
			
		||||
  typedef Hyperplane<Scalar,3,AutoAlign> Plane3a;
 | 
			
		||||
  typedef Hyperplane<Scalar,3,DontAlign> Plane3u;
 | 
			
		||||
 | 
			
		||||
  EIGEN_ALIGN_MAX Scalar array1[4];
 | 
			
		||||
  EIGEN_ALIGN_MAX Scalar array2[4];
 | 
			
		||||
  EIGEN_ALIGN_MAX Scalar array3[4+1];
 | 
			
		||||
  Scalar* array3u = array3+1;
 | 
			
		||||
 | 
			
		||||
  Plane3a *p1 = ::new(reinterpret_cast<void*>(array1)) Plane3a;
 | 
			
		||||
  Plane3u *p2 = ::new(reinterpret_cast<void*>(array2)) Plane3u;
 | 
			
		||||
  Plane3u *p3 = ::new(reinterpret_cast<void*>(array3u)) Plane3u;
 | 
			
		||||
  
 | 
			
		||||
  p1->coeffs().setRandom();
 | 
			
		||||
  *p2 = *p1;
 | 
			
		||||
  *p3 = *p1;
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(p1->coeffs(), p2->coeffs());
 | 
			
		||||
  VERIFY_IS_APPROX(p1->coeffs(), p3->coeffs());
 | 
			
		||||
  
 | 
			
		||||
  #if defined(EIGEN_VECTORIZE) && EIGEN_MAX_STATIC_ALIGN_BYTES > 0
 | 
			
		||||
  if(internal::packet_traits<Scalar>::Vectorizable && internal::packet_traits<Scalar>::size<=4)
 | 
			
		||||
    VERIFY_RAISES_ASSERT((::new(reinterpret_cast<void*>(array3u)) Plane3a));
 | 
			
		||||
  #endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void test_geo_hyperplane()
 | 
			
		||||
{
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_1( hyperplane(Hyperplane<float,2>()) );
 | 
			
		||||
    CALL_SUBTEST_2( hyperplane(Hyperplane<float,3>()) );
 | 
			
		||||
    CALL_SUBTEST_2( hyperplane(Hyperplane<float,3,DontAlign>()) );
 | 
			
		||||
    CALL_SUBTEST_2( hyperplane_alignment<float>() );
 | 
			
		||||
    CALL_SUBTEST_3( hyperplane(Hyperplane<double,4>()) );
 | 
			
		||||
    CALL_SUBTEST_4( hyperplane(Hyperplane<std::complex<double>,5>()) );
 | 
			
		||||
    CALL_SUBTEST_1( lines<float>() );
 | 
			
		||||
    CALL_SUBTEST_3( lines<double>() );
 | 
			
		||||
    CALL_SUBTEST_2( planes<float>() );
 | 
			
		||||
    CALL_SUBTEST_5( planes<double>() );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										133
									
								
								cs440-acg/ext/eigen/test/geo_orthomethods.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								cs440-acg/ext/eigen/test/geo_orthomethods.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,133 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
#include <Eigen/Geometry>
 | 
			
		||||
#include <Eigen/LU>
 | 
			
		||||
#include <Eigen/SVD>
 | 
			
		||||
 | 
			
		||||
/* this test covers the following files:
 | 
			
		||||
   Geometry/OrthoMethods.h
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
template<typename Scalar> void orthomethods_3()
 | 
			
		||||
{
 | 
			
		||||
  typedef typename NumTraits<Scalar>::Real RealScalar;
 | 
			
		||||
  typedef Matrix<Scalar,3,3> Matrix3;
 | 
			
		||||
  typedef Matrix<Scalar,3,1> Vector3;
 | 
			
		||||
 | 
			
		||||
  typedef Matrix<Scalar,4,1> Vector4;
 | 
			
		||||
 | 
			
		||||
  Vector3 v0 = Vector3::Random(),
 | 
			
		||||
          v1 = Vector3::Random(),
 | 
			
		||||
          v2 = Vector3::Random();
 | 
			
		||||
 | 
			
		||||
  // cross product
 | 
			
		||||
  VERIFY_IS_MUCH_SMALLER_THAN(v1.cross(v2).dot(v1), Scalar(1));
 | 
			
		||||
  VERIFY_IS_MUCH_SMALLER_THAN(v1.dot(v1.cross(v2)), Scalar(1));
 | 
			
		||||
  VERIFY_IS_MUCH_SMALLER_THAN(v1.cross(v2).dot(v2), Scalar(1));
 | 
			
		||||
  VERIFY_IS_MUCH_SMALLER_THAN(v2.dot(v1.cross(v2)), Scalar(1));
 | 
			
		||||
  VERIFY_IS_MUCH_SMALLER_THAN(v1.cross(Vector3::Random()).dot(v1), Scalar(1));
 | 
			
		||||
  Matrix3 mat3;
 | 
			
		||||
  mat3 << v0.normalized(),
 | 
			
		||||
         (v0.cross(v1)).normalized(),
 | 
			
		||||
         (v0.cross(v1).cross(v0)).normalized();
 | 
			
		||||
  VERIFY(mat3.isUnitary());
 | 
			
		||||
  
 | 
			
		||||
  mat3.setRandom();
 | 
			
		||||
  VERIFY_IS_APPROX(v0.cross(mat3*v1), -(mat3*v1).cross(v0));
 | 
			
		||||
  VERIFY_IS_APPROX(v0.cross(mat3.lazyProduct(v1)), -(mat3.lazyProduct(v1)).cross(v0));
 | 
			
		||||
 | 
			
		||||
  // colwise/rowwise cross product
 | 
			
		||||
  mat3.setRandom();
 | 
			
		||||
  Vector3 vec3 = Vector3::Random();
 | 
			
		||||
  Matrix3 mcross;
 | 
			
		||||
  int i = internal::random<int>(0,2);
 | 
			
		||||
  mcross = mat3.colwise().cross(vec3);
 | 
			
		||||
  VERIFY_IS_APPROX(mcross.col(i), mat3.col(i).cross(vec3));
 | 
			
		||||
  
 | 
			
		||||
  VERIFY_IS_MUCH_SMALLER_THAN((mat3.adjoint() * mat3.colwise().cross(vec3)).diagonal().cwiseAbs().sum(), Scalar(1));
 | 
			
		||||
  VERIFY_IS_MUCH_SMALLER_THAN((mat3.adjoint() * mat3.colwise().cross(Vector3::Random())).diagonal().cwiseAbs().sum(), Scalar(1));
 | 
			
		||||
  
 | 
			
		||||
  VERIFY_IS_MUCH_SMALLER_THAN((vec3.adjoint() * mat3.colwise().cross(vec3)).cwiseAbs().sum(), Scalar(1));
 | 
			
		||||
  VERIFY_IS_MUCH_SMALLER_THAN((vec3.adjoint() * Matrix3::Random().colwise().cross(vec3)).cwiseAbs().sum(), Scalar(1));
 | 
			
		||||
  
 | 
			
		||||
  mcross = mat3.rowwise().cross(vec3);
 | 
			
		||||
  VERIFY_IS_APPROX(mcross.row(i), mat3.row(i).cross(vec3));
 | 
			
		||||
 | 
			
		||||
  // cross3
 | 
			
		||||
  Vector4 v40 = Vector4::Random(),
 | 
			
		||||
          v41 = Vector4::Random(),
 | 
			
		||||
          v42 = Vector4::Random();
 | 
			
		||||
  v40.w() = v41.w() = v42.w() = 0;
 | 
			
		||||
  v42.template head<3>() = v40.template head<3>().cross(v41.template head<3>());
 | 
			
		||||
  VERIFY_IS_APPROX(v40.cross3(v41), v42);
 | 
			
		||||
  VERIFY_IS_MUCH_SMALLER_THAN(v40.cross3(Vector4::Random()).dot(v40), Scalar(1));
 | 
			
		||||
  
 | 
			
		||||
  // check mixed product
 | 
			
		||||
  typedef Matrix<RealScalar, 3, 1> RealVector3;
 | 
			
		||||
  RealVector3 rv1 = RealVector3::Random();
 | 
			
		||||
  VERIFY_IS_APPROX(v1.cross(rv1.template cast<Scalar>()), v1.cross(rv1));
 | 
			
		||||
  VERIFY_IS_APPROX(rv1.template cast<Scalar>().cross(v1), rv1.cross(v1));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Scalar, int Size> void orthomethods(int size=Size)
 | 
			
		||||
{
 | 
			
		||||
  typedef typename NumTraits<Scalar>::Real RealScalar;
 | 
			
		||||
  typedef Matrix<Scalar,Size,1> VectorType;
 | 
			
		||||
  typedef Matrix<Scalar,3,Size> Matrix3N;
 | 
			
		||||
  typedef Matrix<Scalar,Size,3> MatrixN3;
 | 
			
		||||
  typedef Matrix<Scalar,3,1> Vector3;
 | 
			
		||||
 | 
			
		||||
  VectorType v0 = VectorType::Random(size);
 | 
			
		||||
 | 
			
		||||
  // unitOrthogonal
 | 
			
		||||
  VERIFY_IS_MUCH_SMALLER_THAN(v0.unitOrthogonal().dot(v0), Scalar(1));
 | 
			
		||||
  VERIFY_IS_APPROX(v0.unitOrthogonal().norm(), RealScalar(1));
 | 
			
		||||
 | 
			
		||||
  if (size>=3)
 | 
			
		||||
  {
 | 
			
		||||
    v0.template head<2>().setZero();
 | 
			
		||||
    v0.tail(size-2).setRandom();
 | 
			
		||||
 | 
			
		||||
    VERIFY_IS_MUCH_SMALLER_THAN(v0.unitOrthogonal().dot(v0), Scalar(1));
 | 
			
		||||
    VERIFY_IS_APPROX(v0.unitOrthogonal().norm(), RealScalar(1));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // colwise/rowwise cross product
 | 
			
		||||
  Vector3 vec3 = Vector3::Random();
 | 
			
		||||
  int i = internal::random<int>(0,size-1);
 | 
			
		||||
 | 
			
		||||
  Matrix3N mat3N(3,size), mcross3N(3,size);
 | 
			
		||||
  mat3N.setRandom();
 | 
			
		||||
  mcross3N = mat3N.colwise().cross(vec3);
 | 
			
		||||
  VERIFY_IS_APPROX(mcross3N.col(i), mat3N.col(i).cross(vec3));
 | 
			
		||||
 | 
			
		||||
  MatrixN3 matN3(size,3), mcrossN3(size,3);
 | 
			
		||||
  matN3.setRandom();
 | 
			
		||||
  mcrossN3 = matN3.rowwise().cross(vec3);
 | 
			
		||||
  VERIFY_IS_APPROX(mcrossN3.row(i), matN3.row(i).cross(vec3));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_geo_orthomethods()
 | 
			
		||||
{
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_1( orthomethods_3<float>() );
 | 
			
		||||
    CALL_SUBTEST_2( orthomethods_3<double>() );
 | 
			
		||||
    CALL_SUBTEST_4( orthomethods_3<std::complex<double> >() );
 | 
			
		||||
    CALL_SUBTEST_1( (orthomethods<float,2>()) );
 | 
			
		||||
    CALL_SUBTEST_2( (orthomethods<double,2>()) );
 | 
			
		||||
    CALL_SUBTEST_1( (orthomethods<float,3>()) );
 | 
			
		||||
    CALL_SUBTEST_2( (orthomethods<double,3>()) );
 | 
			
		||||
    CALL_SUBTEST_3( (orthomethods<float,7>()) );
 | 
			
		||||
    CALL_SUBTEST_4( (orthomethods<std::complex<double>,8>()) );
 | 
			
		||||
    CALL_SUBTEST_5( (orthomethods<float,Dynamic>(36)) );
 | 
			
		||||
    CALL_SUBTEST_6( (orthomethods<double,Dynamic>(35)) );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										103
									
								
								cs440-acg/ext/eigen/test/geo_parametrizedline.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								cs440-acg/ext/eigen/test/geo_parametrizedline.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,103 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
#include <Eigen/Geometry>
 | 
			
		||||
#include <Eigen/LU>
 | 
			
		||||
#include <Eigen/QR>
 | 
			
		||||
 | 
			
		||||
template<typename LineType> void parametrizedline(const LineType& _line)
 | 
			
		||||
{
 | 
			
		||||
  /* this test covers the following files:
 | 
			
		||||
     ParametrizedLine.h
 | 
			
		||||
  */
 | 
			
		||||
  using std::abs;
 | 
			
		||||
  const Index dim = _line.dim();
 | 
			
		||||
  typedef typename LineType::Scalar Scalar;
 | 
			
		||||
  typedef typename NumTraits<Scalar>::Real RealScalar;
 | 
			
		||||
  typedef Matrix<Scalar, LineType::AmbientDimAtCompileTime, 1> VectorType;
 | 
			
		||||
  typedef Hyperplane<Scalar,LineType::AmbientDimAtCompileTime> HyperplaneType;
 | 
			
		||||
 | 
			
		||||
  VectorType p0 = VectorType::Random(dim);
 | 
			
		||||
  VectorType p1 = VectorType::Random(dim);
 | 
			
		||||
 | 
			
		||||
  VectorType d0 = VectorType::Random(dim).normalized();
 | 
			
		||||
 | 
			
		||||
  LineType l0(p0, d0);
 | 
			
		||||
 | 
			
		||||
  Scalar s0 = internal::random<Scalar>();
 | 
			
		||||
  Scalar s1 = abs(internal::random<Scalar>());
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_MUCH_SMALLER_THAN( l0.distance(p0), RealScalar(1) );
 | 
			
		||||
  VERIFY_IS_MUCH_SMALLER_THAN( l0.distance(p0+s0*d0), RealScalar(1) );
 | 
			
		||||
  VERIFY_IS_APPROX( (l0.projection(p1)-p1).norm(), l0.distance(p1) );
 | 
			
		||||
  VERIFY_IS_MUCH_SMALLER_THAN( l0.distance(l0.projection(p1)), RealScalar(1) );
 | 
			
		||||
  VERIFY_IS_APPROX( Scalar(l0.distance((p0+s0*d0) + d0.unitOrthogonal() * s1)), s1 );
 | 
			
		||||
 | 
			
		||||
  // casting
 | 
			
		||||
  const int Dim = LineType::AmbientDimAtCompileTime;
 | 
			
		||||
  typedef typename GetDifferentType<Scalar>::type OtherScalar;
 | 
			
		||||
  ParametrizedLine<OtherScalar,Dim> hp1f = l0.template cast<OtherScalar>();
 | 
			
		||||
  VERIFY_IS_APPROX(hp1f.template cast<Scalar>(),l0);
 | 
			
		||||
  ParametrizedLine<Scalar,Dim> hp1d = l0.template cast<Scalar>();
 | 
			
		||||
  VERIFY_IS_APPROX(hp1d.template cast<Scalar>(),l0);
 | 
			
		||||
 | 
			
		||||
  // intersections
 | 
			
		||||
  VectorType p2 = VectorType::Random(dim);
 | 
			
		||||
  VectorType n2 = VectorType::Random(dim).normalized();
 | 
			
		||||
  HyperplaneType hp(p2,n2);
 | 
			
		||||
  Scalar t = l0.intersectionParameter(hp);
 | 
			
		||||
  VectorType pi = l0.pointAt(t);
 | 
			
		||||
  VERIFY_IS_MUCH_SMALLER_THAN(hp.signedDistance(pi), RealScalar(1));
 | 
			
		||||
  VERIFY_IS_MUCH_SMALLER_THAN(l0.distance(pi), RealScalar(1));
 | 
			
		||||
  VERIFY_IS_APPROX(l0.intersectionPoint(hp), pi);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Scalar> void parametrizedline_alignment()
 | 
			
		||||
{
 | 
			
		||||
  typedef ParametrizedLine<Scalar,4,AutoAlign> Line4a;
 | 
			
		||||
  typedef ParametrizedLine<Scalar,4,DontAlign> Line4u;
 | 
			
		||||
 | 
			
		||||
  EIGEN_ALIGN_MAX Scalar array1[16];
 | 
			
		||||
  EIGEN_ALIGN_MAX Scalar array2[16];
 | 
			
		||||
  EIGEN_ALIGN_MAX Scalar array3[16+1];
 | 
			
		||||
  Scalar* array3u = array3+1;
 | 
			
		||||
 | 
			
		||||
  Line4a *p1 = ::new(reinterpret_cast<void*>(array1)) Line4a;
 | 
			
		||||
  Line4u *p2 = ::new(reinterpret_cast<void*>(array2)) Line4u;
 | 
			
		||||
  Line4u *p3 = ::new(reinterpret_cast<void*>(array3u)) Line4u;
 | 
			
		||||
  
 | 
			
		||||
  p1->origin().setRandom();
 | 
			
		||||
  p1->direction().setRandom();
 | 
			
		||||
  *p2 = *p1;
 | 
			
		||||
  *p3 = *p1;
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(p1->origin(), p2->origin());
 | 
			
		||||
  VERIFY_IS_APPROX(p1->origin(), p3->origin());
 | 
			
		||||
  VERIFY_IS_APPROX(p1->direction(), p2->direction());
 | 
			
		||||
  VERIFY_IS_APPROX(p1->direction(), p3->direction());
 | 
			
		||||
  
 | 
			
		||||
  #if defined(EIGEN_VECTORIZE) && EIGEN_MAX_STATIC_ALIGN_BYTES>0
 | 
			
		||||
  if(internal::packet_traits<Scalar>::Vectorizable && internal::packet_traits<Scalar>::size<=4)
 | 
			
		||||
    VERIFY_RAISES_ASSERT((::new(reinterpret_cast<void*>(array3u)) Line4a));
 | 
			
		||||
  #endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_geo_parametrizedline()
 | 
			
		||||
{
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_1( parametrizedline(ParametrizedLine<float,2>()) );
 | 
			
		||||
    CALL_SUBTEST_2( parametrizedline(ParametrizedLine<float,3>()) );
 | 
			
		||||
    CALL_SUBTEST_2( parametrizedline_alignment<float>() );
 | 
			
		||||
    CALL_SUBTEST_3( parametrizedline(ParametrizedLine<double,4>()) );
 | 
			
		||||
    CALL_SUBTEST_3( parametrizedline_alignment<double>() );
 | 
			
		||||
    CALL_SUBTEST_4( parametrizedline(ParametrizedLine<std::complex<double>,5>()) );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										310
									
								
								cs440-acg/ext/eigen/test/geo_quaternion.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										310
									
								
								cs440-acg/ext/eigen/test/geo_quaternion.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,310 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
// Copyright (C) 2009 Mathieu Gautier <mathieu.gautier@cea.fr>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
#include <Eigen/Geometry>
 | 
			
		||||
#include <Eigen/LU>
 | 
			
		||||
#include <Eigen/SVD>
 | 
			
		||||
 | 
			
		||||
template<typename T> T bounded_acos(T v)
 | 
			
		||||
{
 | 
			
		||||
  using std::acos;
 | 
			
		||||
  using std::min;
 | 
			
		||||
  using std::max;
 | 
			
		||||
  return acos((max)(T(-1),(min)(v,T(1))));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename QuatType> void check_slerp(const QuatType& q0, const QuatType& q1)
 | 
			
		||||
{
 | 
			
		||||
  using std::abs;
 | 
			
		||||
  typedef typename QuatType::Scalar Scalar;
 | 
			
		||||
  typedef AngleAxis<Scalar> AA;
 | 
			
		||||
 | 
			
		||||
  Scalar largeEps = test_precision<Scalar>();
 | 
			
		||||
 | 
			
		||||
  Scalar theta_tot = AA(q1*q0.inverse()).angle();
 | 
			
		||||
  if(theta_tot>Scalar(EIGEN_PI))
 | 
			
		||||
    theta_tot = Scalar(2.)*Scalar(EIGEN_PI)-theta_tot;
 | 
			
		||||
  for(Scalar t=0; t<=Scalar(1.001); t+=Scalar(0.1))
 | 
			
		||||
  {
 | 
			
		||||
    QuatType q = q0.slerp(t,q1);
 | 
			
		||||
    Scalar theta = AA(q*q0.inverse()).angle();
 | 
			
		||||
    VERIFY(abs(q.norm() - 1) < largeEps);
 | 
			
		||||
    if(theta_tot==0)  VERIFY(theta_tot==0);
 | 
			
		||||
    else              VERIFY(abs(theta - t * theta_tot) < largeEps);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Scalar, int Options> void quaternion(void)
 | 
			
		||||
{
 | 
			
		||||
  /* this test covers the following files:
 | 
			
		||||
     Quaternion.h
 | 
			
		||||
  */
 | 
			
		||||
  using std::abs;
 | 
			
		||||
  typedef Matrix<Scalar,3,1> Vector3;
 | 
			
		||||
  typedef Matrix<Scalar,3,3> Matrix3;
 | 
			
		||||
  typedef Quaternion<Scalar,Options> Quaternionx;
 | 
			
		||||
  typedef AngleAxis<Scalar> AngleAxisx;
 | 
			
		||||
 | 
			
		||||
  Scalar largeEps = test_precision<Scalar>();
 | 
			
		||||
  if (internal::is_same<Scalar,float>::value)
 | 
			
		||||
    largeEps = Scalar(1e-3);
 | 
			
		||||
 | 
			
		||||
  Scalar eps = internal::random<Scalar>() * Scalar(1e-2);
 | 
			
		||||
 | 
			
		||||
  Vector3 v0 = Vector3::Random(),
 | 
			
		||||
          v1 = Vector3::Random(),
 | 
			
		||||
          v2 = Vector3::Random(),
 | 
			
		||||
          v3 = Vector3::Random();
 | 
			
		||||
 | 
			
		||||
  Scalar  a = internal::random<Scalar>(-Scalar(EIGEN_PI), Scalar(EIGEN_PI)),
 | 
			
		||||
          b = internal::random<Scalar>(-Scalar(EIGEN_PI), Scalar(EIGEN_PI));
 | 
			
		||||
 | 
			
		||||
  // Quaternion: Identity(), setIdentity();
 | 
			
		||||
  Quaternionx q1, q2;
 | 
			
		||||
  q2.setIdentity();
 | 
			
		||||
  VERIFY_IS_APPROX(Quaternionx(Quaternionx::Identity()).coeffs(), q2.coeffs());
 | 
			
		||||
  q1.coeffs().setRandom();
 | 
			
		||||
  VERIFY_IS_APPROX(q1.coeffs(), (q1*q2).coeffs());
 | 
			
		||||
 | 
			
		||||
  // concatenation
 | 
			
		||||
  q1 *= q2;
 | 
			
		||||
 | 
			
		||||
  q1 = AngleAxisx(a, v0.normalized());
 | 
			
		||||
  q2 = AngleAxisx(a, v1.normalized());
 | 
			
		||||
 | 
			
		||||
  // angular distance
 | 
			
		||||
  Scalar refangle = abs(AngleAxisx(q1.inverse()*q2).angle());
 | 
			
		||||
  if (refangle>Scalar(EIGEN_PI))
 | 
			
		||||
    refangle = Scalar(2)*Scalar(EIGEN_PI) - refangle;
 | 
			
		||||
 | 
			
		||||
  if((q1.coeffs()-q2.coeffs()).norm() > 10*largeEps)
 | 
			
		||||
  {
 | 
			
		||||
    VERIFY_IS_MUCH_SMALLER_THAN(abs(q1.angularDistance(q2) - refangle), Scalar(1));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // rotation matrix conversion
 | 
			
		||||
  VERIFY_IS_APPROX(q1 * v2, q1.toRotationMatrix() * v2);
 | 
			
		||||
  VERIFY_IS_APPROX(q1 * q2 * v2,
 | 
			
		||||
    q1.toRotationMatrix() * q2.toRotationMatrix() * v2);
 | 
			
		||||
 | 
			
		||||
  VERIFY(  (q2*q1).isApprox(q1*q2, largeEps)
 | 
			
		||||
        || !(q2 * q1 * v2).isApprox(q1.toRotationMatrix() * q2.toRotationMatrix() * v2));
 | 
			
		||||
 | 
			
		||||
  q2 = q1.toRotationMatrix();
 | 
			
		||||
  VERIFY_IS_APPROX(q1*v1,q2*v1);
 | 
			
		||||
 | 
			
		||||
  Matrix3 rot1(q1);
 | 
			
		||||
  VERIFY_IS_APPROX(q1*v1,rot1*v1);
 | 
			
		||||
  Quaternionx q3(rot1.transpose()*rot1);
 | 
			
		||||
  VERIFY_IS_APPROX(q3*v1,v1);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  // angle-axis conversion
 | 
			
		||||
  AngleAxisx aa = AngleAxisx(q1);
 | 
			
		||||
  VERIFY_IS_APPROX(q1 * v1, Quaternionx(aa) * v1);
 | 
			
		||||
 | 
			
		||||
  // Do not execute the test if the rotation angle is almost zero, or
 | 
			
		||||
  // the rotation axis and v1 are almost parallel.
 | 
			
		||||
  if (abs(aa.angle()) > 5*test_precision<Scalar>()
 | 
			
		||||
      && (aa.axis() - v1.normalized()).norm() < Scalar(1.99)
 | 
			
		||||
      && (aa.axis() + v1.normalized()).norm() < Scalar(1.99))
 | 
			
		||||
  {
 | 
			
		||||
    VERIFY_IS_NOT_APPROX(q1 * v1, Quaternionx(AngleAxisx(aa.angle()*2,aa.axis())) * v1);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // from two vector creation
 | 
			
		||||
  VERIFY_IS_APPROX( v2.normalized(),(q2.setFromTwoVectors(v1, v2)*v1).normalized());
 | 
			
		||||
  VERIFY_IS_APPROX( v1.normalized(),(q2.setFromTwoVectors(v1, v1)*v1).normalized());
 | 
			
		||||
  VERIFY_IS_APPROX(-v1.normalized(),(q2.setFromTwoVectors(v1,-v1)*v1).normalized());
 | 
			
		||||
  if (internal::is_same<Scalar,double>::value)
 | 
			
		||||
  {
 | 
			
		||||
    v3 = (v1.array()+eps).matrix();
 | 
			
		||||
    VERIFY_IS_APPROX( v3.normalized(),(q2.setFromTwoVectors(v1, v3)*v1).normalized());
 | 
			
		||||
    VERIFY_IS_APPROX(-v3.normalized(),(q2.setFromTwoVectors(v1,-v3)*v1).normalized());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // from two vector creation static function
 | 
			
		||||
  VERIFY_IS_APPROX( v2.normalized(),(Quaternionx::FromTwoVectors(v1, v2)*v1).normalized());
 | 
			
		||||
  VERIFY_IS_APPROX( v1.normalized(),(Quaternionx::FromTwoVectors(v1, v1)*v1).normalized());
 | 
			
		||||
  VERIFY_IS_APPROX(-v1.normalized(),(Quaternionx::FromTwoVectors(v1,-v1)*v1).normalized());
 | 
			
		||||
  if (internal::is_same<Scalar,double>::value)
 | 
			
		||||
  {
 | 
			
		||||
    v3 = (v1.array()+eps).matrix();
 | 
			
		||||
    VERIFY_IS_APPROX( v3.normalized(),(Quaternionx::FromTwoVectors(v1, v3)*v1).normalized());
 | 
			
		||||
    VERIFY_IS_APPROX(-v3.normalized(),(Quaternionx::FromTwoVectors(v1,-v3)*v1).normalized());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // inverse and conjugate
 | 
			
		||||
  VERIFY_IS_APPROX(q1 * (q1.inverse() * v1), v1);
 | 
			
		||||
  VERIFY_IS_APPROX(q1 * (q1.conjugate() * v1), v1);
 | 
			
		||||
 | 
			
		||||
  // test casting
 | 
			
		||||
  Quaternion<float> q1f = q1.template cast<float>();
 | 
			
		||||
  VERIFY_IS_APPROX(q1f.template cast<Scalar>(),q1);
 | 
			
		||||
  Quaternion<double> q1d = q1.template cast<double>();
 | 
			
		||||
  VERIFY_IS_APPROX(q1d.template cast<Scalar>(),q1);
 | 
			
		||||
 | 
			
		||||
  // test bug 369 - improper alignment.
 | 
			
		||||
  Quaternionx *q = new Quaternionx;
 | 
			
		||||
  delete q;
 | 
			
		||||
 | 
			
		||||
  q1 = Quaternionx::UnitRandom();
 | 
			
		||||
  q2 = Quaternionx::UnitRandom();
 | 
			
		||||
  check_slerp(q1,q2);
 | 
			
		||||
 | 
			
		||||
  q1 = AngleAxisx(b, v1.normalized());
 | 
			
		||||
  q2 = AngleAxisx(b+Scalar(EIGEN_PI), v1.normalized());
 | 
			
		||||
  check_slerp(q1,q2);
 | 
			
		||||
 | 
			
		||||
  q1 = AngleAxisx(b,  v1.normalized());
 | 
			
		||||
  q2 = AngleAxisx(-b, -v1.normalized());
 | 
			
		||||
  check_slerp(q1,q2);
 | 
			
		||||
 | 
			
		||||
  q1 = Quaternionx::UnitRandom();
 | 
			
		||||
  q2.coeffs() = -q1.coeffs();
 | 
			
		||||
  check_slerp(q1,q2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Scalar> void mapQuaternion(void){
 | 
			
		||||
  typedef Map<Quaternion<Scalar>, Aligned> MQuaternionA;
 | 
			
		||||
  typedef Map<const Quaternion<Scalar>, Aligned> MCQuaternionA;
 | 
			
		||||
  typedef Map<Quaternion<Scalar> > MQuaternionUA;
 | 
			
		||||
  typedef Map<const Quaternion<Scalar> > MCQuaternionUA;
 | 
			
		||||
  typedef Quaternion<Scalar> Quaternionx;
 | 
			
		||||
  typedef Matrix<Scalar,3,1> Vector3;
 | 
			
		||||
  typedef AngleAxis<Scalar> AngleAxisx;
 | 
			
		||||
  
 | 
			
		||||
  Vector3 v0 = Vector3::Random(),
 | 
			
		||||
          v1 = Vector3::Random();
 | 
			
		||||
  Scalar  a = internal::random<Scalar>(-Scalar(EIGEN_PI), Scalar(EIGEN_PI));
 | 
			
		||||
 | 
			
		||||
  EIGEN_ALIGN_MAX Scalar array1[4];
 | 
			
		||||
  EIGEN_ALIGN_MAX Scalar array2[4];
 | 
			
		||||
  EIGEN_ALIGN_MAX Scalar array3[4+1];
 | 
			
		||||
  Scalar* array3unaligned = array3+1;
 | 
			
		||||
  
 | 
			
		||||
  MQuaternionA    mq1(array1);
 | 
			
		||||
  MCQuaternionA   mcq1(array1);
 | 
			
		||||
  MQuaternionA    mq2(array2);
 | 
			
		||||
  MQuaternionUA   mq3(array3unaligned);
 | 
			
		||||
  MCQuaternionUA  mcq3(array3unaligned);
 | 
			
		||||
 | 
			
		||||
//  std::cerr << array1 << " " << array2 << " " << array3 << "\n";
 | 
			
		||||
  mq1 = AngleAxisx(a, v0.normalized());
 | 
			
		||||
  mq2 = mq1;
 | 
			
		||||
  mq3 = mq1;
 | 
			
		||||
 | 
			
		||||
  Quaternionx q1 = mq1;
 | 
			
		||||
  Quaternionx q2 = mq2;
 | 
			
		||||
  Quaternionx q3 = mq3;
 | 
			
		||||
  Quaternionx q4 = MCQuaternionUA(array3unaligned);
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(q1.coeffs(), q2.coeffs());
 | 
			
		||||
  VERIFY_IS_APPROX(q1.coeffs(), q3.coeffs());
 | 
			
		||||
  VERIFY_IS_APPROX(q4.coeffs(), q3.coeffs());
 | 
			
		||||
  #ifdef EIGEN_VECTORIZE
 | 
			
		||||
  if(internal::packet_traits<Scalar>::Vectorizable)
 | 
			
		||||
    VERIFY_RAISES_ASSERT((MQuaternionA(array3unaligned)));
 | 
			
		||||
  #endif
 | 
			
		||||
    
 | 
			
		||||
  VERIFY_IS_APPROX(mq1 * (mq1.inverse() * v1), v1);
 | 
			
		||||
  VERIFY_IS_APPROX(mq1 * (mq1.conjugate() * v1), v1);
 | 
			
		||||
  
 | 
			
		||||
  VERIFY_IS_APPROX(mcq1 * (mcq1.inverse() * v1), v1);
 | 
			
		||||
  VERIFY_IS_APPROX(mcq1 * (mcq1.conjugate() * v1), v1);
 | 
			
		||||
  
 | 
			
		||||
  VERIFY_IS_APPROX(mq3 * (mq3.inverse() * v1), v1);
 | 
			
		||||
  VERIFY_IS_APPROX(mq3 * (mq3.conjugate() * v1), v1);
 | 
			
		||||
  
 | 
			
		||||
  VERIFY_IS_APPROX(mcq3 * (mcq3.inverse() * v1), v1);
 | 
			
		||||
  VERIFY_IS_APPROX(mcq3 * (mcq3.conjugate() * v1), v1);
 | 
			
		||||
  
 | 
			
		||||
  VERIFY_IS_APPROX(mq1*mq2, q1*q2);
 | 
			
		||||
  VERIFY_IS_APPROX(mq3*mq2, q3*q2);
 | 
			
		||||
  VERIFY_IS_APPROX(mcq1*mq2, q1*q2);
 | 
			
		||||
  VERIFY_IS_APPROX(mcq3*mq2, q3*q2);
 | 
			
		||||
 | 
			
		||||
  // Bug 1461, compilation issue with Map<const Quat>::w(), and other reference/constness checks:
 | 
			
		||||
  VERIFY_IS_APPROX(mcq3.coeffs().x() + mcq3.coeffs().y() + mcq3.coeffs().z() + mcq3.coeffs().w(), mcq3.coeffs().sum());
 | 
			
		||||
  VERIFY_IS_APPROX(mcq3.x() + mcq3.y() + mcq3.z() + mcq3.w(), mcq3.coeffs().sum());
 | 
			
		||||
  mq3.w() = 1;
 | 
			
		||||
  const Quaternionx& cq3(q3);
 | 
			
		||||
  VERIFY( &cq3.x() == &q3.x() );
 | 
			
		||||
  const MQuaternionUA& cmq3(mq3);
 | 
			
		||||
  VERIFY( &cmq3.x() == &mq3.x() );
 | 
			
		||||
  // FIXME the following should be ok. The problem is that currently the LValueBit flag
 | 
			
		||||
  // is used to determine wether we can return a coeff by reference or not, which is not enough for Map<const ...>.
 | 
			
		||||
  //const MCQuaternionUA& cmcq3(mcq3);
 | 
			
		||||
  //VERIFY( &cmcq3.x() == &mcq3.x() );
 | 
			
		||||
 | 
			
		||||
  // test cast
 | 
			
		||||
  {
 | 
			
		||||
    Quaternion<float> q1f = mq1.template cast<float>();
 | 
			
		||||
    VERIFY_IS_APPROX(q1f.template cast<Scalar>(),mq1);
 | 
			
		||||
    Quaternion<double> q1d = mq1.template cast<double>();
 | 
			
		||||
    VERIFY_IS_APPROX(q1d.template cast<Scalar>(),mq1);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Scalar> void quaternionAlignment(void){
 | 
			
		||||
  typedef Quaternion<Scalar,AutoAlign> QuaternionA;
 | 
			
		||||
  typedef Quaternion<Scalar,DontAlign> QuaternionUA;
 | 
			
		||||
 | 
			
		||||
  EIGEN_ALIGN_MAX Scalar array1[4];
 | 
			
		||||
  EIGEN_ALIGN_MAX Scalar array2[4];
 | 
			
		||||
  EIGEN_ALIGN_MAX Scalar array3[4+1];
 | 
			
		||||
  Scalar* arrayunaligned = array3+1;
 | 
			
		||||
 | 
			
		||||
  QuaternionA *q1 = ::new(reinterpret_cast<void*>(array1)) QuaternionA;
 | 
			
		||||
  QuaternionUA *q2 = ::new(reinterpret_cast<void*>(array2)) QuaternionUA;
 | 
			
		||||
  QuaternionUA *q3 = ::new(reinterpret_cast<void*>(arrayunaligned)) QuaternionUA;
 | 
			
		||||
 | 
			
		||||
  q1->coeffs().setRandom();
 | 
			
		||||
  *q2 = *q1;
 | 
			
		||||
  *q3 = *q1;
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(q1->coeffs(), q2->coeffs());
 | 
			
		||||
  VERIFY_IS_APPROX(q1->coeffs(), q3->coeffs());
 | 
			
		||||
  #if defined(EIGEN_VECTORIZE) && EIGEN_MAX_STATIC_ALIGN_BYTES>0
 | 
			
		||||
  if(internal::packet_traits<Scalar>::Vectorizable && internal::packet_traits<Scalar>::size<=4)
 | 
			
		||||
    VERIFY_RAISES_ASSERT((::new(reinterpret_cast<void*>(arrayunaligned)) QuaternionA));
 | 
			
		||||
  #endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename PlainObjectType> void check_const_correctness(const PlainObjectType&)
 | 
			
		||||
{
 | 
			
		||||
  // there's a lot that we can't test here while still having this test compile!
 | 
			
		||||
  // the only possible approach would be to run a script trying to compile stuff and checking that it fails.
 | 
			
		||||
  // CMake can help with that.
 | 
			
		||||
 | 
			
		||||
  // verify that map-to-const don't have LvalueBit
 | 
			
		||||
  typedef typename internal::add_const<PlainObjectType>::type ConstPlainObjectType;
 | 
			
		||||
  VERIFY( !(internal::traits<Map<ConstPlainObjectType> >::Flags & LvalueBit) );
 | 
			
		||||
  VERIFY( !(internal::traits<Map<ConstPlainObjectType, Aligned> >::Flags & LvalueBit) );
 | 
			
		||||
  VERIFY( !(Map<ConstPlainObjectType>::Flags & LvalueBit) );
 | 
			
		||||
  VERIFY( !(Map<ConstPlainObjectType, Aligned>::Flags & LvalueBit) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_geo_quaternion()
 | 
			
		||||
{
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_1(( quaternion<float,AutoAlign>() ));
 | 
			
		||||
    CALL_SUBTEST_1( check_const_correctness(Quaternionf()) );
 | 
			
		||||
    CALL_SUBTEST_2(( quaternion<double,AutoAlign>() ));
 | 
			
		||||
    CALL_SUBTEST_2( check_const_correctness(Quaterniond()) );
 | 
			
		||||
    CALL_SUBTEST_3(( quaternion<float,DontAlign>() ));
 | 
			
		||||
    CALL_SUBTEST_4(( quaternion<double,DontAlign>() ));
 | 
			
		||||
    CALL_SUBTEST_5(( quaternionAlignment<float>() ));
 | 
			
		||||
    CALL_SUBTEST_6(( quaternionAlignment<double>() ));
 | 
			
		||||
    CALL_SUBTEST_1( mapQuaternion<float>() );
 | 
			
		||||
    CALL_SUBTEST_2( mapQuaternion<double>() );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										704
									
								
								cs440-acg/ext/eigen/test/geo_transformations.cpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										704
									
								
								cs440-acg/ext/eigen/test/geo_transformations.cpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,704 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
#include <Eigen/Geometry>
 | 
			
		||||
#include <Eigen/LU>
 | 
			
		||||
#include <Eigen/SVD>
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
Matrix<T,2,1> angleToVec(T a)
 | 
			
		||||
{
 | 
			
		||||
  return Matrix<T,2,1>(std::cos(a), std::sin(a));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// This permits to workaround a bug in clang/llvm code generation.
 | 
			
		||||
template<typename T>
 | 
			
		||||
EIGEN_DONT_INLINE
 | 
			
		||||
void dont_over_optimize(T& x) { volatile typename T::Scalar tmp = x(0); x(0) = tmp; }
 | 
			
		||||
 | 
			
		||||
template<typename Scalar, int Mode, int Options> void non_projective_only()
 | 
			
		||||
{
 | 
			
		||||
    /* this test covers the following files:
 | 
			
		||||
     Cross.h Quaternion.h, Transform.cpp
 | 
			
		||||
  */
 | 
			
		||||
  typedef Matrix<Scalar,3,1> Vector3;
 | 
			
		||||
  typedef Quaternion<Scalar> Quaternionx;
 | 
			
		||||
  typedef AngleAxis<Scalar> AngleAxisx;
 | 
			
		||||
  typedef Transform<Scalar,3,Mode,Options> Transform3;
 | 
			
		||||
  typedef DiagonalMatrix<Scalar,3> AlignedScaling3;
 | 
			
		||||
  typedef Translation<Scalar,3> Translation3;
 | 
			
		||||
 | 
			
		||||
  Vector3 v0 = Vector3::Random(),
 | 
			
		||||
          v1 = Vector3::Random();
 | 
			
		||||
 | 
			
		||||
  Transform3 t0, t1, t2;
 | 
			
		||||
 | 
			
		||||
  Scalar a = internal::random<Scalar>(-Scalar(EIGEN_PI), Scalar(EIGEN_PI));
 | 
			
		||||
 | 
			
		||||
  Quaternionx q1, q2;
 | 
			
		||||
 | 
			
		||||
  q1 = AngleAxisx(a, v0.normalized());
 | 
			
		||||
 | 
			
		||||
  t0 = Transform3::Identity();
 | 
			
		||||
  VERIFY_IS_APPROX(t0.matrix(), Transform3::MatrixType::Identity());
 | 
			
		||||
 | 
			
		||||
  t0.linear() = q1.toRotationMatrix();
 | 
			
		||||
 | 
			
		||||
  v0 << 50, 2, 1;
 | 
			
		||||
  t0.scale(v0);
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX( (t0 * Vector3(1,0,0)).template head<3>().norm(), v0.x());
 | 
			
		||||
 | 
			
		||||
  t0.setIdentity();
 | 
			
		||||
  t1.setIdentity();
 | 
			
		||||
  v1 << 1, 2, 3;
 | 
			
		||||
  t0.linear() = q1.toRotationMatrix();
 | 
			
		||||
  t0.pretranslate(v0);
 | 
			
		||||
  t0.scale(v1);
 | 
			
		||||
  t1.linear() = q1.conjugate().toRotationMatrix();
 | 
			
		||||
  t1.prescale(v1.cwiseInverse());
 | 
			
		||||
  t1.translate(-v0);
 | 
			
		||||
 | 
			
		||||
  VERIFY((t0 * t1).matrix().isIdentity(test_precision<Scalar>()));
 | 
			
		||||
 | 
			
		||||
  t1.fromPositionOrientationScale(v0, q1, v1);
 | 
			
		||||
  VERIFY_IS_APPROX(t1.matrix(), t0.matrix());
 | 
			
		||||
  VERIFY_IS_APPROX(t1*v1, t0*v1);
 | 
			
		||||
 | 
			
		||||
  // translation * vector
 | 
			
		||||
  t0.setIdentity();
 | 
			
		||||
  t0.translate(v0);
 | 
			
		||||
  VERIFY_IS_APPROX((t0 * v1).template head<3>(), Translation3(v0) * v1);
 | 
			
		||||
 | 
			
		||||
  // AlignedScaling * vector
 | 
			
		||||
  t0.setIdentity();
 | 
			
		||||
  t0.scale(v0);
 | 
			
		||||
  VERIFY_IS_APPROX((t0 * v1).template head<3>(), AlignedScaling3(v0) * v1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Scalar, int Mode, int Options> void transformations()
 | 
			
		||||
{
 | 
			
		||||
  /* this test covers the following files:
 | 
			
		||||
     Cross.h Quaternion.h, Transform.cpp
 | 
			
		||||
  */
 | 
			
		||||
  using std::cos;
 | 
			
		||||
  using std::abs;
 | 
			
		||||
  typedef Matrix<Scalar,3,3> Matrix3;
 | 
			
		||||
  typedef Matrix<Scalar,4,4> Matrix4;
 | 
			
		||||
  typedef Matrix<Scalar,2,1> Vector2;
 | 
			
		||||
  typedef Matrix<Scalar,3,1> Vector3;
 | 
			
		||||
  typedef Matrix<Scalar,4,1> Vector4;
 | 
			
		||||
  typedef Quaternion<Scalar> Quaternionx;
 | 
			
		||||
  typedef AngleAxis<Scalar> AngleAxisx;
 | 
			
		||||
  typedef Transform<Scalar,2,Mode,Options> Transform2;
 | 
			
		||||
  typedef Transform<Scalar,3,Mode,Options> Transform3;
 | 
			
		||||
  typedef typename Transform3::MatrixType MatrixType;
 | 
			
		||||
  typedef DiagonalMatrix<Scalar,3> AlignedScaling3;
 | 
			
		||||
  typedef Translation<Scalar,2> Translation2;
 | 
			
		||||
  typedef Translation<Scalar,3> Translation3;
 | 
			
		||||
 | 
			
		||||
  Vector3 v0 = Vector3::Random(),
 | 
			
		||||
          v1 = Vector3::Random();
 | 
			
		||||
  Matrix3 matrot1, m;
 | 
			
		||||
 | 
			
		||||
  Scalar a = internal::random<Scalar>(-Scalar(EIGEN_PI), Scalar(EIGEN_PI));
 | 
			
		||||
  Scalar s0 = internal::random<Scalar>(), s1 = internal::random<Scalar>();
 | 
			
		||||
  
 | 
			
		||||
  while(v0.norm() < test_precision<Scalar>()) v0 = Vector3::Random();
 | 
			
		||||
  while(v1.norm() < test_precision<Scalar>()) v1 = Vector3::Random();
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(v0, AngleAxisx(a, v0.normalized()) * v0);
 | 
			
		||||
  VERIFY_IS_APPROX(-v0, AngleAxisx(Scalar(EIGEN_PI), v0.unitOrthogonal()) * v0);
 | 
			
		||||
  if(abs(cos(a)) > test_precision<Scalar>())
 | 
			
		||||
  {
 | 
			
		||||
    VERIFY_IS_APPROX(cos(a)*v0.squaredNorm(), v0.dot(AngleAxisx(a, v0.unitOrthogonal()) * v0));
 | 
			
		||||
  }
 | 
			
		||||
  m = AngleAxisx(a, v0.normalized()).toRotationMatrix().adjoint();
 | 
			
		||||
  VERIFY_IS_APPROX(Matrix3::Identity(), m * AngleAxisx(a, v0.normalized()));
 | 
			
		||||
  VERIFY_IS_APPROX(Matrix3::Identity(), AngleAxisx(a, v0.normalized()) * m);
 | 
			
		||||
 | 
			
		||||
  Quaternionx q1, q2;
 | 
			
		||||
  q1 = AngleAxisx(a, v0.normalized());
 | 
			
		||||
  q2 = AngleAxisx(a, v1.normalized());
 | 
			
		||||
 | 
			
		||||
  // rotation matrix conversion
 | 
			
		||||
  matrot1 = AngleAxisx(Scalar(0.1), Vector3::UnitX())
 | 
			
		||||
          * AngleAxisx(Scalar(0.2), Vector3::UnitY())
 | 
			
		||||
          * AngleAxisx(Scalar(0.3), Vector3::UnitZ());
 | 
			
		||||
  VERIFY_IS_APPROX(matrot1 * v1,
 | 
			
		||||
       AngleAxisx(Scalar(0.1), Vector3(1,0,0)).toRotationMatrix()
 | 
			
		||||
    * (AngleAxisx(Scalar(0.2), Vector3(0,1,0)).toRotationMatrix()
 | 
			
		||||
    * (AngleAxisx(Scalar(0.3), Vector3(0,0,1)).toRotationMatrix() * v1)));
 | 
			
		||||
 | 
			
		||||
  // angle-axis conversion
 | 
			
		||||
  AngleAxisx aa = AngleAxisx(q1);
 | 
			
		||||
  VERIFY_IS_APPROX(q1 * v1, Quaternionx(aa) * v1);
 | 
			
		||||
  
 | 
			
		||||
  // The following test is stable only if 2*angle != angle and v1 is not colinear with axis
 | 
			
		||||
  if( (abs(aa.angle()) > test_precision<Scalar>()) && (abs(aa.axis().dot(v1.normalized()))<(Scalar(1)-Scalar(4)*test_precision<Scalar>())) )
 | 
			
		||||
  {
 | 
			
		||||
    VERIFY( !(q1 * v1).isApprox(Quaternionx(AngleAxisx(aa.angle()*2,aa.axis())) * v1) );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  aa.fromRotationMatrix(aa.toRotationMatrix());
 | 
			
		||||
  VERIFY_IS_APPROX(q1 * v1, Quaternionx(aa) * v1);
 | 
			
		||||
  // The following test is stable only if 2*angle != angle and v1 is not colinear with axis
 | 
			
		||||
  if( (abs(aa.angle()) > test_precision<Scalar>()) && (abs(aa.axis().dot(v1.normalized()))<(Scalar(1)-Scalar(4)*test_precision<Scalar>())) )
 | 
			
		||||
  {
 | 
			
		||||
    VERIFY( !(q1 * v1).isApprox(Quaternionx(AngleAxisx(aa.angle()*2,aa.axis())) * v1) );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // AngleAxis
 | 
			
		||||
  VERIFY_IS_APPROX(AngleAxisx(a,v1.normalized()).toRotationMatrix(),
 | 
			
		||||
    Quaternionx(AngleAxisx(a,v1.normalized())).toRotationMatrix());
 | 
			
		||||
 | 
			
		||||
  AngleAxisx aa1;
 | 
			
		||||
  m = q1.toRotationMatrix();
 | 
			
		||||
  aa1 = m;
 | 
			
		||||
  VERIFY_IS_APPROX(AngleAxisx(m).toRotationMatrix(),
 | 
			
		||||
    Quaternionx(m).toRotationMatrix());
 | 
			
		||||
 | 
			
		||||
  // Transform
 | 
			
		||||
  // TODO complete the tests !
 | 
			
		||||
  a = 0;
 | 
			
		||||
  while (abs(a)<Scalar(0.1))
 | 
			
		||||
    a = internal::random<Scalar>(-Scalar(0.4)*Scalar(EIGEN_PI), Scalar(0.4)*Scalar(EIGEN_PI));
 | 
			
		||||
  q1 = AngleAxisx(a, v0.normalized());
 | 
			
		||||
  Transform3 t0, t1, t2;
 | 
			
		||||
 | 
			
		||||
  // first test setIdentity() and Identity()
 | 
			
		||||
  t0.setIdentity();
 | 
			
		||||
  VERIFY_IS_APPROX(t0.matrix(), Transform3::MatrixType::Identity());
 | 
			
		||||
  t0.matrix().setZero();
 | 
			
		||||
  t0 = Transform3::Identity();
 | 
			
		||||
  VERIFY_IS_APPROX(t0.matrix(), Transform3::MatrixType::Identity());
 | 
			
		||||
 | 
			
		||||
  t0.setIdentity();
 | 
			
		||||
  t1.setIdentity();
 | 
			
		||||
  v1 << 1, 2, 3;
 | 
			
		||||
  t0.linear() = q1.toRotationMatrix();
 | 
			
		||||
  t0.pretranslate(v0);
 | 
			
		||||
  t0.scale(v1);
 | 
			
		||||
  t1.linear() = q1.conjugate().toRotationMatrix();
 | 
			
		||||
  t1.prescale(v1.cwiseInverse());
 | 
			
		||||
  t1.translate(-v0);
 | 
			
		||||
 | 
			
		||||
  VERIFY((t0 * t1).matrix().isIdentity(test_precision<Scalar>()));
 | 
			
		||||
 | 
			
		||||
  t1.fromPositionOrientationScale(v0, q1, v1);
 | 
			
		||||
  VERIFY_IS_APPROX(t1.matrix(), t0.matrix());
 | 
			
		||||
 | 
			
		||||
  t0.setIdentity(); t0.scale(v0).rotate(q1.toRotationMatrix());
 | 
			
		||||
  t1.setIdentity(); t1.scale(v0).rotate(q1);
 | 
			
		||||
  VERIFY_IS_APPROX(t0.matrix(), t1.matrix());
 | 
			
		||||
 | 
			
		||||
  t0.setIdentity(); t0.scale(v0).rotate(AngleAxisx(q1));
 | 
			
		||||
  VERIFY_IS_APPROX(t0.matrix(), t1.matrix());
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(t0.scale(a).matrix(), t1.scale(Vector3::Constant(a)).matrix());
 | 
			
		||||
  VERIFY_IS_APPROX(t0.prescale(a).matrix(), t1.prescale(Vector3::Constant(a)).matrix());
 | 
			
		||||
 | 
			
		||||
  // More transform constructors, operator=, operator*=
 | 
			
		||||
 | 
			
		||||
  Matrix3 mat3 = Matrix3::Random();
 | 
			
		||||
  Matrix4 mat4;
 | 
			
		||||
  mat4 << mat3 , Vector3::Zero() , Vector4::Zero().transpose();
 | 
			
		||||
  Transform3 tmat3(mat3), tmat4(mat4);
 | 
			
		||||
  if(Mode!=int(AffineCompact))
 | 
			
		||||
    tmat4.matrix()(3,3) = Scalar(1);
 | 
			
		||||
  VERIFY_IS_APPROX(tmat3.matrix(), tmat4.matrix());
 | 
			
		||||
 | 
			
		||||
  Scalar a3 = internal::random<Scalar>(-Scalar(EIGEN_PI), Scalar(EIGEN_PI));
 | 
			
		||||
  Vector3 v3 = Vector3::Random().normalized();
 | 
			
		||||
  AngleAxisx aa3(a3, v3);
 | 
			
		||||
  Transform3 t3(aa3);
 | 
			
		||||
  Transform3 t4;
 | 
			
		||||
  t4 = aa3;
 | 
			
		||||
  VERIFY_IS_APPROX(t3.matrix(), t4.matrix());
 | 
			
		||||
  t4.rotate(AngleAxisx(-a3,v3));
 | 
			
		||||
  VERIFY_IS_APPROX(t4.matrix(), MatrixType::Identity());
 | 
			
		||||
  t4 *= aa3;
 | 
			
		||||
  VERIFY_IS_APPROX(t3.matrix(), t4.matrix());
 | 
			
		||||
 | 
			
		||||
  do {
 | 
			
		||||
    v3 = Vector3::Random();
 | 
			
		||||
    dont_over_optimize(v3);
 | 
			
		||||
  } while (v3.cwiseAbs().minCoeff()<NumTraits<Scalar>::epsilon());
 | 
			
		||||
  Translation3 tv3(v3);
 | 
			
		||||
  Transform3 t5(tv3);
 | 
			
		||||
  t4 = tv3;
 | 
			
		||||
  VERIFY_IS_APPROX(t5.matrix(), t4.matrix());
 | 
			
		||||
  t4.translate((-v3).eval());
 | 
			
		||||
  VERIFY_IS_APPROX(t4.matrix(), MatrixType::Identity());
 | 
			
		||||
  t4 *= tv3;
 | 
			
		||||
  VERIFY_IS_APPROX(t5.matrix(), t4.matrix());
 | 
			
		||||
 | 
			
		||||
  AlignedScaling3 sv3(v3);
 | 
			
		||||
  Transform3 t6(sv3);
 | 
			
		||||
  t4 = sv3;
 | 
			
		||||
  VERIFY_IS_APPROX(t6.matrix(), t4.matrix());
 | 
			
		||||
  t4.scale(v3.cwiseInverse());
 | 
			
		||||
  VERIFY_IS_APPROX(t4.matrix(), MatrixType::Identity());
 | 
			
		||||
  t4 *= sv3;
 | 
			
		||||
  VERIFY_IS_APPROX(t6.matrix(), t4.matrix());
 | 
			
		||||
 | 
			
		||||
  // matrix * transform
 | 
			
		||||
  VERIFY_IS_APPROX((t3.matrix()*t4).matrix(), (t3*t4).matrix());
 | 
			
		||||
 | 
			
		||||
  // chained Transform product
 | 
			
		||||
  VERIFY_IS_APPROX(((t3*t4)*t5).matrix(), (t3*(t4*t5)).matrix());
 | 
			
		||||
 | 
			
		||||
  // check that Transform product doesn't have aliasing problems
 | 
			
		||||
  t5 = t4;
 | 
			
		||||
  t5 = t5*t5;
 | 
			
		||||
  VERIFY_IS_APPROX(t5, t4*t4);
 | 
			
		||||
 | 
			
		||||
  // 2D transformation
 | 
			
		||||
  Transform2 t20, t21;
 | 
			
		||||
  Vector2 v20 = Vector2::Random();
 | 
			
		||||
  Vector2 v21 = Vector2::Random();
 | 
			
		||||
  for (int k=0; k<2; ++k)
 | 
			
		||||
    if (abs(v21[k])<Scalar(1e-3)) v21[k] = Scalar(1e-3);
 | 
			
		||||
  t21.setIdentity();
 | 
			
		||||
  t21.linear() = Rotation2D<Scalar>(a).toRotationMatrix();
 | 
			
		||||
  VERIFY_IS_APPROX(t20.fromPositionOrientationScale(v20,a,v21).matrix(),
 | 
			
		||||
    t21.pretranslate(v20).scale(v21).matrix());
 | 
			
		||||
 | 
			
		||||
  t21.setIdentity();
 | 
			
		||||
  t21.linear() = Rotation2D<Scalar>(-a).toRotationMatrix();
 | 
			
		||||
  VERIFY( (t20.fromPositionOrientationScale(v20,a,v21)
 | 
			
		||||
        * (t21.prescale(v21.cwiseInverse()).translate(-v20))).matrix().isIdentity(test_precision<Scalar>()) );
 | 
			
		||||
 | 
			
		||||
  // Transform - new API
 | 
			
		||||
  // 3D
 | 
			
		||||
  t0.setIdentity();
 | 
			
		||||
  t0.rotate(q1).scale(v0).translate(v0);
 | 
			
		||||
  // mat * aligned scaling and mat * translation
 | 
			
		||||
  t1 = (Matrix3(q1) * AlignedScaling3(v0)) * Translation3(v0);
 | 
			
		||||
  VERIFY_IS_APPROX(t0.matrix(), t1.matrix());
 | 
			
		||||
  t1 = (Matrix3(q1) * Eigen::Scaling(v0)) * Translation3(v0);
 | 
			
		||||
  VERIFY_IS_APPROX(t0.matrix(), t1.matrix());
 | 
			
		||||
  t1 = (q1 * Eigen::Scaling(v0)) * Translation3(v0);
 | 
			
		||||
  VERIFY_IS_APPROX(t0.matrix(), t1.matrix());
 | 
			
		||||
  // mat * transformation and aligned scaling * translation
 | 
			
		||||
  t1 = Matrix3(q1) * (AlignedScaling3(v0) * Translation3(v0));
 | 
			
		||||
  VERIFY_IS_APPROX(t0.matrix(), t1.matrix());
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  t0.setIdentity();
 | 
			
		||||
  t0.scale(s0).translate(v0);
 | 
			
		||||
  t1 = Eigen::Scaling(s0) * Translation3(v0);
 | 
			
		||||
  VERIFY_IS_APPROX(t0.matrix(), t1.matrix());
 | 
			
		||||
  t0.prescale(s0);
 | 
			
		||||
  t1 = Eigen::Scaling(s0) * t1;
 | 
			
		||||
  VERIFY_IS_APPROX(t0.matrix(), t1.matrix());
 | 
			
		||||
  
 | 
			
		||||
  t0 = t3;
 | 
			
		||||
  t0.scale(s0);
 | 
			
		||||
  t1 = t3 * Eigen::Scaling(s0,s0,s0);
 | 
			
		||||
  VERIFY_IS_APPROX(t0.matrix(), t1.matrix());
 | 
			
		||||
  t0.prescale(s0);
 | 
			
		||||
  t1 = Eigen::Scaling(s0,s0,s0) * t1;
 | 
			
		||||
  VERIFY_IS_APPROX(t0.matrix(), t1.matrix());
 | 
			
		||||
 | 
			
		||||
  t0 = t3;
 | 
			
		||||
  t0.scale(s0);
 | 
			
		||||
  t1 = t3 * Eigen::Scaling(s0);
 | 
			
		||||
  VERIFY_IS_APPROX(t0.matrix(), t1.matrix());
 | 
			
		||||
  t0.prescale(s0);
 | 
			
		||||
  t1 = Eigen::Scaling(s0) * t1;
 | 
			
		||||
  VERIFY_IS_APPROX(t0.matrix(), t1.matrix());
 | 
			
		||||
 | 
			
		||||
  t0.setIdentity();
 | 
			
		||||
  t0.prerotate(q1).prescale(v0).pretranslate(v0);
 | 
			
		||||
  // translation * aligned scaling and transformation * mat
 | 
			
		||||
  t1 = (Translation3(v0) * AlignedScaling3(v0)) * Transform3(q1);
 | 
			
		||||
  VERIFY_IS_APPROX(t0.matrix(), t1.matrix());
 | 
			
		||||
  // scaling * mat and translation * mat
 | 
			
		||||
  t1 = Translation3(v0) * (AlignedScaling3(v0) * Transform3(q1));
 | 
			
		||||
  VERIFY_IS_APPROX(t0.matrix(), t1.matrix());
 | 
			
		||||
 | 
			
		||||
  t0.setIdentity();
 | 
			
		||||
  t0.scale(v0).translate(v0).rotate(q1);
 | 
			
		||||
  // translation * mat and aligned scaling * transformation
 | 
			
		||||
  t1 = AlignedScaling3(v0) * (Translation3(v0) * Transform3(q1));
 | 
			
		||||
  VERIFY_IS_APPROX(t0.matrix(), t1.matrix());
 | 
			
		||||
  // transformation * aligned scaling
 | 
			
		||||
  t0.scale(v0);
 | 
			
		||||
  t1 *= AlignedScaling3(v0);
 | 
			
		||||
  VERIFY_IS_APPROX(t0.matrix(), t1.matrix());
 | 
			
		||||
  t1 = AlignedScaling3(v0) * (Translation3(v0) * Transform3(q1));
 | 
			
		||||
  t1 = t1 * v0.asDiagonal();
 | 
			
		||||
  VERIFY_IS_APPROX(t0.matrix(), t1.matrix());
 | 
			
		||||
  // transformation * translation
 | 
			
		||||
  t0.translate(v0);
 | 
			
		||||
  t1 = t1 * Translation3(v0);
 | 
			
		||||
  VERIFY_IS_APPROX(t0.matrix(), t1.matrix());
 | 
			
		||||
  // translation * transformation
 | 
			
		||||
  t0.pretranslate(v0);
 | 
			
		||||
  t1 = Translation3(v0) * t1;
 | 
			
		||||
  VERIFY_IS_APPROX(t0.matrix(), t1.matrix());
 | 
			
		||||
 | 
			
		||||
  // transform * quaternion
 | 
			
		||||
  t0.rotate(q1);
 | 
			
		||||
  t1 = t1 * q1;
 | 
			
		||||
  VERIFY_IS_APPROX(t0.matrix(), t1.matrix());
 | 
			
		||||
 | 
			
		||||
  // translation * quaternion
 | 
			
		||||
  t0.translate(v1).rotate(q1);
 | 
			
		||||
  t1 = t1 * (Translation3(v1) * q1);
 | 
			
		||||
  VERIFY_IS_APPROX(t0.matrix(), t1.matrix());
 | 
			
		||||
 | 
			
		||||
  // aligned scaling * quaternion
 | 
			
		||||
  t0.scale(v1).rotate(q1);
 | 
			
		||||
  t1 = t1 * (AlignedScaling3(v1) * q1);
 | 
			
		||||
  VERIFY_IS_APPROX(t0.matrix(), t1.matrix());
 | 
			
		||||
 | 
			
		||||
  // quaternion * transform
 | 
			
		||||
  t0.prerotate(q1);
 | 
			
		||||
  t1 = q1 * t1;
 | 
			
		||||
  VERIFY_IS_APPROX(t0.matrix(), t1.matrix());
 | 
			
		||||
 | 
			
		||||
  // quaternion * translation
 | 
			
		||||
  t0.rotate(q1).translate(v1);
 | 
			
		||||
  t1 = t1 * (q1 * Translation3(v1));
 | 
			
		||||
  VERIFY_IS_APPROX(t0.matrix(), t1.matrix());
 | 
			
		||||
 | 
			
		||||
  // quaternion * aligned scaling
 | 
			
		||||
  t0.rotate(q1).scale(v1);
 | 
			
		||||
  t1 = t1 * (q1 * AlignedScaling3(v1));
 | 
			
		||||
  VERIFY_IS_APPROX(t0.matrix(), t1.matrix());
 | 
			
		||||
 | 
			
		||||
  // test transform inversion
 | 
			
		||||
  t0.setIdentity();
 | 
			
		||||
  t0.translate(v0);
 | 
			
		||||
  do {
 | 
			
		||||
    t0.linear().setRandom();
 | 
			
		||||
  } while(t0.linear().jacobiSvd().singularValues()(2)<test_precision<Scalar>());
 | 
			
		||||
  Matrix4 t044 = Matrix4::Zero();
 | 
			
		||||
  t044(3,3) = 1;
 | 
			
		||||
  t044.block(0,0,t0.matrix().rows(),4) = t0.matrix();
 | 
			
		||||
  VERIFY_IS_APPROX(t0.inverse(Affine).matrix(), t044.inverse().block(0,0,t0.matrix().rows(),4));
 | 
			
		||||
  t0.setIdentity();
 | 
			
		||||
  t0.translate(v0).rotate(q1);
 | 
			
		||||
  t044 = Matrix4::Zero();
 | 
			
		||||
  t044(3,3) = 1;
 | 
			
		||||
  t044.block(0,0,t0.matrix().rows(),4) = t0.matrix();
 | 
			
		||||
  VERIFY_IS_APPROX(t0.inverse(Isometry).matrix(), t044.inverse().block(0,0,t0.matrix().rows(),4));
 | 
			
		||||
 | 
			
		||||
  Matrix3 mat_rotation, mat_scaling;
 | 
			
		||||
  t0.setIdentity();
 | 
			
		||||
  t0.translate(v0).rotate(q1).scale(v1);
 | 
			
		||||
  t0.computeRotationScaling(&mat_rotation, &mat_scaling);
 | 
			
		||||
  VERIFY_IS_APPROX(t0.linear(), mat_rotation * mat_scaling);
 | 
			
		||||
  VERIFY_IS_APPROX(mat_rotation*mat_rotation.adjoint(), Matrix3::Identity());
 | 
			
		||||
  VERIFY_IS_APPROX(mat_rotation.determinant(), Scalar(1));
 | 
			
		||||
  t0.computeScalingRotation(&mat_scaling, &mat_rotation);
 | 
			
		||||
  VERIFY_IS_APPROX(t0.linear(), mat_scaling * mat_rotation);
 | 
			
		||||
  VERIFY_IS_APPROX(mat_rotation*mat_rotation.adjoint(), Matrix3::Identity());
 | 
			
		||||
  VERIFY_IS_APPROX(mat_rotation.determinant(), Scalar(1));
 | 
			
		||||
 | 
			
		||||
  // test casting
 | 
			
		||||
  Transform<float,3,Mode> t1f = t1.template cast<float>();
 | 
			
		||||
  VERIFY_IS_APPROX(t1f.template cast<Scalar>(),t1);
 | 
			
		||||
  Transform<double,3,Mode> t1d = t1.template cast<double>();
 | 
			
		||||
  VERIFY_IS_APPROX(t1d.template cast<Scalar>(),t1);
 | 
			
		||||
 | 
			
		||||
  Translation3 tr1(v0);
 | 
			
		||||
  Translation<float,3> tr1f = tr1.template cast<float>();
 | 
			
		||||
  VERIFY_IS_APPROX(tr1f.template cast<Scalar>(),tr1);
 | 
			
		||||
  Translation<double,3> tr1d = tr1.template cast<double>();
 | 
			
		||||
  VERIFY_IS_APPROX(tr1d.template cast<Scalar>(),tr1);
 | 
			
		||||
 | 
			
		||||
  AngleAxis<float> aa1f = aa1.template cast<float>();
 | 
			
		||||
  VERIFY_IS_APPROX(aa1f.template cast<Scalar>(),aa1);
 | 
			
		||||
  AngleAxis<double> aa1d = aa1.template cast<double>();
 | 
			
		||||
  VERIFY_IS_APPROX(aa1d.template cast<Scalar>(),aa1);
 | 
			
		||||
 | 
			
		||||
  Rotation2D<Scalar> r2d1(internal::random<Scalar>());
 | 
			
		||||
  Rotation2D<float> r2d1f = r2d1.template cast<float>();
 | 
			
		||||
  VERIFY_IS_APPROX(r2d1f.template cast<Scalar>(),r2d1);
 | 
			
		||||
  Rotation2D<double> r2d1d = r2d1.template cast<double>();
 | 
			
		||||
  VERIFY_IS_APPROX(r2d1d.template cast<Scalar>(),r2d1);
 | 
			
		||||
  
 | 
			
		||||
  for(int k=0; k<100; ++k)
 | 
			
		||||
  {
 | 
			
		||||
    Scalar angle = internal::random<Scalar>(-100,100);
 | 
			
		||||
    Rotation2D<Scalar> rot2(angle);
 | 
			
		||||
    VERIFY( rot2.smallestPositiveAngle() >= 0 );
 | 
			
		||||
    VERIFY( rot2.smallestPositiveAngle() <= Scalar(2)*Scalar(EIGEN_PI) );
 | 
			
		||||
    VERIFY_IS_APPROX( angleToVec(rot2.smallestPositiveAngle()), angleToVec(rot2.angle()) );
 | 
			
		||||
    
 | 
			
		||||
    VERIFY( rot2.smallestAngle() >= -Scalar(EIGEN_PI) );
 | 
			
		||||
    VERIFY( rot2.smallestAngle() <=  Scalar(EIGEN_PI) );
 | 
			
		||||
    VERIFY_IS_APPROX( angleToVec(rot2.smallestAngle()), angleToVec(rot2.angle()) );
 | 
			
		||||
 | 
			
		||||
    Matrix<Scalar,2,2> rot2_as_mat(rot2);
 | 
			
		||||
    Rotation2D<Scalar> rot3(rot2_as_mat);
 | 
			
		||||
    VERIFY_IS_APPROX( angleToVec(rot2.smallestAngle()),  angleToVec(rot3.angle()) );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  s0 = internal::random<Scalar>(-100,100);
 | 
			
		||||
  s1 = internal::random<Scalar>(-100,100);
 | 
			
		||||
  Rotation2D<Scalar> R0(s0), R1(s1);
 | 
			
		||||
  
 | 
			
		||||
  t20 = Translation2(v20) * (R0 * Eigen::Scaling(s0));
 | 
			
		||||
  t21 = Translation2(v20) * R0 * Eigen::Scaling(s0);
 | 
			
		||||
  VERIFY_IS_APPROX(t20,t21);
 | 
			
		||||
  
 | 
			
		||||
  t20 = Translation2(v20) * (R0 * R0.inverse() * Eigen::Scaling(s0));
 | 
			
		||||
  t21 = Translation2(v20) * Eigen::Scaling(s0);
 | 
			
		||||
  VERIFY_IS_APPROX(t20,t21);
 | 
			
		||||
  
 | 
			
		||||
  VERIFY_IS_APPROX(s0, (R0.slerp(0, R1)).angle());
 | 
			
		||||
  VERIFY_IS_APPROX( angleToVec(R1.smallestPositiveAngle()), angleToVec((R0.slerp(1, R1)).smallestPositiveAngle()) );
 | 
			
		||||
  VERIFY_IS_APPROX(R0.smallestPositiveAngle(), (R0.slerp(0.5, R0)).smallestPositiveAngle());
 | 
			
		||||
 | 
			
		||||
  if(std::cos(s0)>0)
 | 
			
		||||
    VERIFY_IS_MUCH_SMALLER_THAN((R0.slerp(0.5, R0.inverse())).smallestAngle(), Scalar(1));
 | 
			
		||||
  else
 | 
			
		||||
    VERIFY_IS_APPROX(Scalar(EIGEN_PI), (R0.slerp(0.5, R0.inverse())).smallestPositiveAngle());
 | 
			
		||||
  
 | 
			
		||||
  // Check path length
 | 
			
		||||
  Scalar l = 0;
 | 
			
		||||
  int path_steps = 100;
 | 
			
		||||
  for(int k=0; k<path_steps; ++k)
 | 
			
		||||
  {
 | 
			
		||||
    Scalar a1 = R0.slerp(Scalar(k)/Scalar(path_steps), R1).angle();
 | 
			
		||||
    Scalar a2 = R0.slerp(Scalar(k+1)/Scalar(path_steps), R1).angle();
 | 
			
		||||
    l += std::abs(a2-a1);
 | 
			
		||||
  }
 | 
			
		||||
  VERIFY(l<=Scalar(EIGEN_PI)*(Scalar(1)+NumTraits<Scalar>::epsilon()*Scalar(path_steps/2)));
 | 
			
		||||
  
 | 
			
		||||
  // check basic features
 | 
			
		||||
  {
 | 
			
		||||
    Rotation2D<Scalar> r1;           // default ctor
 | 
			
		||||
    r1 = Rotation2D<Scalar>(s0);     // copy assignment
 | 
			
		||||
    VERIFY_IS_APPROX(r1.angle(),s0);
 | 
			
		||||
    Rotation2D<Scalar> r2(r1);       // copy ctor
 | 
			
		||||
    VERIFY_IS_APPROX(r2.angle(),s0);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    Transform3 t32(Matrix4::Random()), t33, t34;
 | 
			
		||||
    t34 = t33 = t32;
 | 
			
		||||
    t32.scale(v0);
 | 
			
		||||
    t33*=AlignedScaling3(v0);
 | 
			
		||||
    VERIFY_IS_APPROX(t32.matrix(), t33.matrix());
 | 
			
		||||
    t33 = t34 * AlignedScaling3(v0);
 | 
			
		||||
    VERIFY_IS_APPROX(t32.matrix(), t33.matrix());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename A1, typename A2, typename P, typename Q, typename V, typename H>
 | 
			
		||||
void transform_associativity_left(const A1& a1, const A2& a2, const P& p, const Q& q, const V& v, const H& h)
 | 
			
		||||
{
 | 
			
		||||
  VERIFY_IS_APPROX( q*(a1*v), (q*a1)*v );
 | 
			
		||||
  VERIFY_IS_APPROX( q*(a2*v), (q*a2)*v );
 | 
			
		||||
  VERIFY_IS_APPROX( q*(p*h).hnormalized(),  ((q*p)*h).hnormalized() );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename A1, typename A2, typename P, typename Q, typename V, typename H>
 | 
			
		||||
void transform_associativity2(const A1& a1, const A2& a2, const P& p, const Q& q, const V& v, const H& h)
 | 
			
		||||
{
 | 
			
		||||
  VERIFY_IS_APPROX( a1*(q*v), (a1*q)*v );
 | 
			
		||||
  VERIFY_IS_APPROX( a2*(q*v), (a2*q)*v );
 | 
			
		||||
  VERIFY_IS_APPROX( p *(q*v).homogeneous(), (p *q)*v.homogeneous() );
 | 
			
		||||
 | 
			
		||||
  transform_associativity_left(a1, a2,p, q, v, h);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Scalar, int Dim, int Options,typename RotationType>
 | 
			
		||||
void transform_associativity(const RotationType& R)
 | 
			
		||||
{
 | 
			
		||||
  typedef Matrix<Scalar,Dim,1> VectorType;
 | 
			
		||||
  typedef Matrix<Scalar,Dim+1,1> HVectorType;
 | 
			
		||||
  typedef Matrix<Scalar,Dim,Dim> LinearType;
 | 
			
		||||
  typedef Matrix<Scalar,Dim+1,Dim+1> MatrixType;
 | 
			
		||||
  typedef Transform<Scalar,Dim,AffineCompact,Options> AffineCompactType;
 | 
			
		||||
  typedef Transform<Scalar,Dim,Affine,Options> AffineType;
 | 
			
		||||
  typedef Transform<Scalar,Dim,Projective,Options> ProjectiveType;
 | 
			
		||||
  typedef DiagonalMatrix<Scalar,Dim> ScalingType;
 | 
			
		||||
  typedef Translation<Scalar,Dim> TranslationType;
 | 
			
		||||
 | 
			
		||||
  AffineCompactType A1c; A1c.matrix().setRandom();
 | 
			
		||||
  AffineCompactType A2c; A2c.matrix().setRandom();
 | 
			
		||||
  AffineType A1(A1c);
 | 
			
		||||
  AffineType A2(A2c);
 | 
			
		||||
  ProjectiveType P1; P1.matrix().setRandom();
 | 
			
		||||
  VectorType v1 = VectorType::Random();
 | 
			
		||||
  VectorType v2 = VectorType::Random();
 | 
			
		||||
  HVectorType h1 = HVectorType::Random();
 | 
			
		||||
  Scalar s1 = internal::random<Scalar>();
 | 
			
		||||
  LinearType L = LinearType::Random();
 | 
			
		||||
  MatrixType M = MatrixType::Random();
 | 
			
		||||
 | 
			
		||||
  CALL_SUBTEST( transform_associativity2(A1c, A1, P1, A2, v2, h1) );
 | 
			
		||||
  CALL_SUBTEST( transform_associativity2(A1c, A1, P1, A2c, v2, h1) );
 | 
			
		||||
  CALL_SUBTEST( transform_associativity2(A1c, A1, P1, v1.asDiagonal(), v2, h1) );
 | 
			
		||||
  CALL_SUBTEST( transform_associativity2(A1c, A1, P1, ScalingType(v1), v2, h1) );
 | 
			
		||||
  CALL_SUBTEST( transform_associativity2(A1c, A1, P1, Scaling(v1), v2, h1) );
 | 
			
		||||
  CALL_SUBTEST( transform_associativity2(A1c, A1, P1, Scaling(s1), v2, h1) );
 | 
			
		||||
  CALL_SUBTEST( transform_associativity2(A1c, A1, P1, TranslationType(v1), v2, h1) );
 | 
			
		||||
  CALL_SUBTEST( transform_associativity_left(A1c, A1, P1, L, v2, h1) );
 | 
			
		||||
  CALL_SUBTEST( transform_associativity2(A1c, A1, P1, R, v2, h1) );
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX( A1*(M*h1), (A1*M)*h1 );
 | 
			
		||||
  VERIFY_IS_APPROX( A1c*(M*h1), (A1c*M)*h1 );
 | 
			
		||||
  VERIFY_IS_APPROX( P1*(M*h1), (P1*M)*h1 );
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX( M*(A1*h1), (M*A1)*h1 );
 | 
			
		||||
  VERIFY_IS_APPROX( M*(A1c*h1), (M*A1c)*h1 );
 | 
			
		||||
  VERIFY_IS_APPROX( M*(P1*h1),  ((M*P1)*h1) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Scalar> void transform_alignment()
 | 
			
		||||
{
 | 
			
		||||
  typedef Transform<Scalar,3,Projective,AutoAlign> Projective3a;
 | 
			
		||||
  typedef Transform<Scalar,3,Projective,DontAlign> Projective3u;
 | 
			
		||||
 | 
			
		||||
  EIGEN_ALIGN_MAX Scalar array1[16];
 | 
			
		||||
  EIGEN_ALIGN_MAX Scalar array2[16];
 | 
			
		||||
  EIGEN_ALIGN_MAX Scalar array3[16+1];
 | 
			
		||||
  Scalar* array3u = array3+1;
 | 
			
		||||
 | 
			
		||||
  Projective3a *p1 = ::new(reinterpret_cast<void*>(array1)) Projective3a;
 | 
			
		||||
  Projective3u *p2 = ::new(reinterpret_cast<void*>(array2)) Projective3u;
 | 
			
		||||
  Projective3u *p3 = ::new(reinterpret_cast<void*>(array3u)) Projective3u;
 | 
			
		||||
  
 | 
			
		||||
  p1->matrix().setRandom();
 | 
			
		||||
  *p2 = *p1;
 | 
			
		||||
  *p3 = *p1;
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(p1->matrix(), p2->matrix());
 | 
			
		||||
  VERIFY_IS_APPROX(p1->matrix(), p3->matrix());
 | 
			
		||||
  
 | 
			
		||||
  VERIFY_IS_APPROX( (*p1) * (*p1), (*p2)*(*p3));
 | 
			
		||||
  
 | 
			
		||||
  #if defined(EIGEN_VECTORIZE) && EIGEN_MAX_STATIC_ALIGN_BYTES>0
 | 
			
		||||
  if(internal::packet_traits<Scalar>::Vectorizable)
 | 
			
		||||
    VERIFY_RAISES_ASSERT((::new(reinterpret_cast<void*>(array3u)) Projective3a));
 | 
			
		||||
  #endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Scalar, int Dim, int Options> void transform_products()
 | 
			
		||||
{
 | 
			
		||||
  typedef Matrix<Scalar,Dim+1,Dim+1> Mat;
 | 
			
		||||
  typedef Transform<Scalar,Dim,Projective,Options> Proj;
 | 
			
		||||
  typedef Transform<Scalar,Dim,Affine,Options> Aff;
 | 
			
		||||
  typedef Transform<Scalar,Dim,AffineCompact,Options> AffC;
 | 
			
		||||
 | 
			
		||||
  Proj p; p.matrix().setRandom();
 | 
			
		||||
  Aff a; a.linear().setRandom(); a.translation().setRandom();
 | 
			
		||||
  AffC ac = a;
 | 
			
		||||
 | 
			
		||||
  Mat p_m(p.matrix()), a_m(a.matrix());
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX((p*p).matrix(), p_m*p_m);
 | 
			
		||||
  VERIFY_IS_APPROX((a*a).matrix(), a_m*a_m);
 | 
			
		||||
  VERIFY_IS_APPROX((p*a).matrix(), p_m*a_m);
 | 
			
		||||
  VERIFY_IS_APPROX((a*p).matrix(), a_m*p_m);
 | 
			
		||||
  VERIFY_IS_APPROX((ac*a).matrix(), a_m*a_m);
 | 
			
		||||
  VERIFY_IS_APPROX((a*ac).matrix(), a_m*a_m);
 | 
			
		||||
  VERIFY_IS_APPROX((p*ac).matrix(), p_m*a_m);
 | 
			
		||||
  VERIFY_IS_APPROX((ac*p).matrix(), a_m*p_m);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Scalar, int Mode, int Options> void transformations_no_scale()
 | 
			
		||||
{
 | 
			
		||||
     /* this test covers the following files:
 | 
			
		||||
     Cross.h Quaternion.h, Transform.h
 | 
			
		||||
  */
 | 
			
		||||
  typedef Matrix<Scalar,3,1> Vector3;
 | 
			
		||||
  typedef Matrix<Scalar,4,1> Vector4;
 | 
			
		||||
  typedef Quaternion<Scalar> Quaternionx;
 | 
			
		||||
  typedef AngleAxis<Scalar> AngleAxisx;
 | 
			
		||||
  typedef Transform<Scalar,3,Mode,Options> Transform3;
 | 
			
		||||
  typedef Translation<Scalar,3> Translation3;
 | 
			
		||||
  typedef Matrix<Scalar,4,4> Matrix4;
 | 
			
		||||
 | 
			
		||||
  Vector3 v0 = Vector3::Random(),
 | 
			
		||||
          v1 = Vector3::Random();
 | 
			
		||||
 | 
			
		||||
  Transform3 t0, t1, t2;
 | 
			
		||||
 | 
			
		||||
  Scalar a = internal::random<Scalar>(-Scalar(EIGEN_PI), Scalar(EIGEN_PI));
 | 
			
		||||
 | 
			
		||||
  Quaternionx q1, q2;
 | 
			
		||||
 | 
			
		||||
  q1 = AngleAxisx(a, v0.normalized());
 | 
			
		||||
 | 
			
		||||
  t0 = Transform3::Identity();
 | 
			
		||||
  VERIFY_IS_APPROX(t0.matrix(), Transform3::MatrixType::Identity());
 | 
			
		||||
 | 
			
		||||
  t0.setIdentity();
 | 
			
		||||
  t1.setIdentity();
 | 
			
		||||
  v1 = Vector3::Ones();
 | 
			
		||||
  t0.linear() = q1.toRotationMatrix();
 | 
			
		||||
  t0.pretranslate(v0);
 | 
			
		||||
  t1.linear() = q1.conjugate().toRotationMatrix();
 | 
			
		||||
  t1.translate(-v0);
 | 
			
		||||
 | 
			
		||||
  VERIFY((t0 * t1).matrix().isIdentity(test_precision<Scalar>()));
 | 
			
		||||
 | 
			
		||||
  t1.fromPositionOrientationScale(v0, q1, v1);
 | 
			
		||||
  VERIFY_IS_APPROX(t1.matrix(), t0.matrix());
 | 
			
		||||
  VERIFY_IS_APPROX(t1*v1, t0*v1);
 | 
			
		||||
 | 
			
		||||
  // translation * vector
 | 
			
		||||
  t0.setIdentity();
 | 
			
		||||
  t0.translate(v0);
 | 
			
		||||
  VERIFY_IS_APPROX((t0 * v1).template head<3>(), Translation3(v0) * v1);
 | 
			
		||||
 | 
			
		||||
  // Conversion to matrix.
 | 
			
		||||
  Transform3 t3;
 | 
			
		||||
  t3.linear() = q1.toRotationMatrix();
 | 
			
		||||
  t3.translation() = v1;
 | 
			
		||||
  Matrix4 m3 = t3.matrix();
 | 
			
		||||
  VERIFY((m3 * m3.inverse()).isIdentity(test_precision<Scalar>()));
 | 
			
		||||
  // Verify implicit last row is initialized.
 | 
			
		||||
  VERIFY_IS_APPROX(Vector4(m3.row(3)), Vector4(0.0, 0.0, 0.0, 1.0));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_geo_transformations()
 | 
			
		||||
{
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_1(( transformations<double,Affine,AutoAlign>() ));
 | 
			
		||||
    CALL_SUBTEST_1(( non_projective_only<double,Affine,AutoAlign>() ));
 | 
			
		||||
    
 | 
			
		||||
    CALL_SUBTEST_2(( transformations<float,AffineCompact,AutoAlign>() ));
 | 
			
		||||
    CALL_SUBTEST_2(( non_projective_only<float,AffineCompact,AutoAlign>() ));
 | 
			
		||||
    CALL_SUBTEST_2(( transform_alignment<float>() ));
 | 
			
		||||
    
 | 
			
		||||
    CALL_SUBTEST_3(( transformations<double,Projective,AutoAlign>() ));
 | 
			
		||||
    CALL_SUBTEST_3(( transformations<double,Projective,DontAlign>() ));
 | 
			
		||||
    CALL_SUBTEST_3(( transform_alignment<double>() ));
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_4(( transformations<float,Affine,RowMajor|AutoAlign>() ));
 | 
			
		||||
    CALL_SUBTEST_4(( non_projective_only<float,Affine,RowMajor>() ));
 | 
			
		||||
    
 | 
			
		||||
    CALL_SUBTEST_5(( transformations<double,AffineCompact,RowMajor|AutoAlign>() ));
 | 
			
		||||
    CALL_SUBTEST_5(( non_projective_only<double,AffineCompact,RowMajor>() ));
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_6(( transformations<double,Projective,RowMajor|AutoAlign>() ));
 | 
			
		||||
    CALL_SUBTEST_6(( transformations<double,Projective,RowMajor|DontAlign>() ));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_7(( transform_products<double,3,RowMajor|AutoAlign>() ));
 | 
			
		||||
    CALL_SUBTEST_7(( transform_products<float,2,AutoAlign>() ));
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_8(( transform_associativity<double,2,ColMajor>(Rotation2D<double>(internal::random<double>()*double(EIGEN_PI))) ));
 | 
			
		||||
    CALL_SUBTEST_8(( transform_associativity<double,3,ColMajor>(Quaterniond::UnitRandom()) ));
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_9(( transformations_no_scale<double,Affine,AutoAlign>() ));
 | 
			
		||||
    CALL_SUBTEST_9(( transformations_no_scale<double,Isometry,AutoAlign>() ));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										268
									
								
								cs440-acg/ext/eigen/test/half_float.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										268
									
								
								cs440-acg/ext/eigen/test/half_float.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,268 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include <sstream>
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
 | 
			
		||||
#include <Eigen/src/Core/arch/CUDA/Half.h>
 | 
			
		||||
 | 
			
		||||
#ifdef EIGEN_HAS_CUDA_FP16
 | 
			
		||||
#error "EIGEN_HAS_CUDA_FP16 should not be defined in this CPU unit test"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Make sure it's possible to forward declare Eigen::half
 | 
			
		||||
namespace Eigen {
 | 
			
		||||
struct half;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
using Eigen::half;
 | 
			
		||||
 | 
			
		||||
void test_conversion()
 | 
			
		||||
{
 | 
			
		||||
  using Eigen::half_impl::__half_raw;
 | 
			
		||||
 | 
			
		||||
  // Conversion from float.
 | 
			
		||||
  VERIFY_IS_EQUAL(half(1.0f).x, 0x3c00);
 | 
			
		||||
  VERIFY_IS_EQUAL(half(0.5f).x, 0x3800);
 | 
			
		||||
  VERIFY_IS_EQUAL(half(0.33333f).x, 0x3555);
 | 
			
		||||
  VERIFY_IS_EQUAL(half(0.0f).x, 0x0000);
 | 
			
		||||
  VERIFY_IS_EQUAL(half(-0.0f).x, 0x8000);
 | 
			
		||||
  VERIFY_IS_EQUAL(half(65504.0f).x, 0x7bff);
 | 
			
		||||
  VERIFY_IS_EQUAL(half(65536.0f).x, 0x7c00);  // Becomes infinity.
 | 
			
		||||
 | 
			
		||||
  // Denormals.
 | 
			
		||||
  VERIFY_IS_EQUAL(half(-5.96046e-08f).x, 0x8001);
 | 
			
		||||
  VERIFY_IS_EQUAL(half(5.96046e-08f).x, 0x0001);
 | 
			
		||||
  VERIFY_IS_EQUAL(half(1.19209e-07f).x, 0x0002);
 | 
			
		||||
 | 
			
		||||
  // Verify round-to-nearest-even behavior.
 | 
			
		||||
  float val1 = float(half(__half_raw(0x3c00)));
 | 
			
		||||
  float val2 = float(half(__half_raw(0x3c01)));
 | 
			
		||||
  float val3 = float(half(__half_raw(0x3c02)));
 | 
			
		||||
  VERIFY_IS_EQUAL(half(0.5f * (val1 + val2)).x, 0x3c00);
 | 
			
		||||
  VERIFY_IS_EQUAL(half(0.5f * (val2 + val3)).x, 0x3c02);
 | 
			
		||||
 | 
			
		||||
  // Conversion from int.
 | 
			
		||||
  VERIFY_IS_EQUAL(half(-1).x, 0xbc00);
 | 
			
		||||
  VERIFY_IS_EQUAL(half(0).x, 0x0000);
 | 
			
		||||
  VERIFY_IS_EQUAL(half(1).x, 0x3c00);
 | 
			
		||||
  VERIFY_IS_EQUAL(half(2).x, 0x4000);
 | 
			
		||||
  VERIFY_IS_EQUAL(half(3).x, 0x4200);
 | 
			
		||||
 | 
			
		||||
  // Conversion from bool.
 | 
			
		||||
  VERIFY_IS_EQUAL(half(false).x, 0x0000);
 | 
			
		||||
  VERIFY_IS_EQUAL(half(true).x, 0x3c00);
 | 
			
		||||
 | 
			
		||||
  // Conversion to float.
 | 
			
		||||
  VERIFY_IS_EQUAL(float(half(__half_raw(0x0000))), 0.0f);
 | 
			
		||||
  VERIFY_IS_EQUAL(float(half(__half_raw(0x3c00))), 1.0f);
 | 
			
		||||
 | 
			
		||||
  // Denormals.
 | 
			
		||||
  VERIFY_IS_APPROX(float(half(__half_raw(0x8001))), -5.96046e-08f);
 | 
			
		||||
  VERIFY_IS_APPROX(float(half(__half_raw(0x0001))), 5.96046e-08f);
 | 
			
		||||
  VERIFY_IS_APPROX(float(half(__half_raw(0x0002))), 1.19209e-07f);
 | 
			
		||||
 | 
			
		||||
  // NaNs and infinities.
 | 
			
		||||
  VERIFY(!(numext::isinf)(float(half(65504.0f))));  // Largest finite number.
 | 
			
		||||
  VERIFY(!(numext::isnan)(float(half(0.0f))));
 | 
			
		||||
  VERIFY((numext::isinf)(float(half(__half_raw(0xfc00)))));
 | 
			
		||||
  VERIFY((numext::isnan)(float(half(__half_raw(0xfc01)))));
 | 
			
		||||
  VERIFY((numext::isinf)(float(half(__half_raw(0x7c00)))));
 | 
			
		||||
  VERIFY((numext::isnan)(float(half(__half_raw(0x7c01)))));
 | 
			
		||||
 | 
			
		||||
#if !EIGEN_COMP_MSVC
 | 
			
		||||
  // Visual Studio errors out on divisions by 0
 | 
			
		||||
  VERIFY((numext::isnan)(float(half(0.0 / 0.0))));
 | 
			
		||||
  VERIFY((numext::isinf)(float(half(1.0 / 0.0))));
 | 
			
		||||
  VERIFY((numext::isinf)(float(half(-1.0 / 0.0))));
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  // Exactly same checks as above, just directly on the half representation.
 | 
			
		||||
  VERIFY(!(numext::isinf)(half(__half_raw(0x7bff))));
 | 
			
		||||
  VERIFY(!(numext::isnan)(half(__half_raw(0x0000))));
 | 
			
		||||
  VERIFY((numext::isinf)(half(__half_raw(0xfc00))));
 | 
			
		||||
  VERIFY((numext::isnan)(half(__half_raw(0xfc01))));
 | 
			
		||||
  VERIFY((numext::isinf)(half(__half_raw(0x7c00))));
 | 
			
		||||
  VERIFY((numext::isnan)(half(__half_raw(0x7c01))));
 | 
			
		||||
 | 
			
		||||
#if !EIGEN_COMP_MSVC
 | 
			
		||||
  // Visual Studio errors out on divisions by 0
 | 
			
		||||
  VERIFY((numext::isnan)(half(0.0 / 0.0)));
 | 
			
		||||
  VERIFY((numext::isinf)(half(1.0 / 0.0)));
 | 
			
		||||
  VERIFY((numext::isinf)(half(-1.0 / 0.0)));
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_numtraits()
 | 
			
		||||
{
 | 
			
		||||
  std::cout << "epsilon       = " << NumTraits<half>::epsilon() << "  (0x" << std::hex << NumTraits<half>::epsilon().x << ")" << std::endl;
 | 
			
		||||
  std::cout << "highest       = " << NumTraits<half>::highest() << "  (0x" << std::hex << NumTraits<half>::highest().x << ")" << std::endl;
 | 
			
		||||
  std::cout << "lowest        = " << NumTraits<half>::lowest() << "  (0x" << std::hex << NumTraits<half>::lowest().x << ")" << std::endl;
 | 
			
		||||
  std::cout << "min           = " << (std::numeric_limits<half>::min)() << "  (0x" << std::hex << half((std::numeric_limits<half>::min)()).x << ")" << std::endl;
 | 
			
		||||
  std::cout << "denorm min    = " << (std::numeric_limits<half>::denorm_min)() << "  (0x" << std::hex << half((std::numeric_limits<half>::denorm_min)()).x << ")" << std::endl;
 | 
			
		||||
  std::cout << "infinity      = " << NumTraits<half>::infinity() << "  (0x" << std::hex << NumTraits<half>::infinity().x << ")" << std::endl;
 | 
			
		||||
  std::cout << "quiet nan     = " << NumTraits<half>::quiet_NaN() << "  (0x" << std::hex << NumTraits<half>::quiet_NaN().x << ")" << std::endl;
 | 
			
		||||
  std::cout << "signaling nan = " << std::numeric_limits<half>::signaling_NaN() << "  (0x" << std::hex << std::numeric_limits<half>::signaling_NaN().x << ")" << std::endl;
 | 
			
		||||
 | 
			
		||||
  VERIFY(NumTraits<half>::IsSigned);
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_EQUAL( std::numeric_limits<half>::infinity().x, half(std::numeric_limits<float>::infinity()).x );
 | 
			
		||||
  VERIFY_IS_EQUAL( std::numeric_limits<half>::quiet_NaN().x, half(std::numeric_limits<float>::quiet_NaN()).x );
 | 
			
		||||
  VERIFY_IS_EQUAL( std::numeric_limits<half>::signaling_NaN().x, half(std::numeric_limits<float>::signaling_NaN()).x );
 | 
			
		||||
  VERIFY( (std::numeric_limits<half>::min)() > half(0.f) );
 | 
			
		||||
  VERIFY( (std::numeric_limits<half>::denorm_min)() > half(0.f) );
 | 
			
		||||
  VERIFY( (std::numeric_limits<half>::min)()/half(2) > half(0.f) );
 | 
			
		||||
  VERIFY_IS_EQUAL( (std::numeric_limits<half>::denorm_min)()/half(2), half(0.f) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_arithmetic()
 | 
			
		||||
{
 | 
			
		||||
  VERIFY_IS_EQUAL(float(half(2) + half(2)), 4);
 | 
			
		||||
  VERIFY_IS_EQUAL(float(half(2) + half(-2)), 0);
 | 
			
		||||
  VERIFY_IS_APPROX(float(half(0.33333f) + half(0.66667f)), 1.0f);
 | 
			
		||||
  VERIFY_IS_EQUAL(float(half(2.0f) * half(-5.5f)), -11.0f);
 | 
			
		||||
  VERIFY_IS_APPROX(float(half(1.0f) / half(3.0f)), 0.33333f);
 | 
			
		||||
  VERIFY_IS_EQUAL(float(-half(4096.0f)), -4096.0f);
 | 
			
		||||
  VERIFY_IS_EQUAL(float(-half(-4096.0f)), 4096.0f);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_comparison()
 | 
			
		||||
{
 | 
			
		||||
  VERIFY(half(1.0f) > half(0.5f));
 | 
			
		||||
  VERIFY(half(0.5f) < half(1.0f));
 | 
			
		||||
  VERIFY(!(half(1.0f) < half(0.5f)));
 | 
			
		||||
  VERIFY(!(half(0.5f) > half(1.0f)));
 | 
			
		||||
 | 
			
		||||
  VERIFY(!(half(4.0f) > half(4.0f)));
 | 
			
		||||
  VERIFY(!(half(4.0f) < half(4.0f)));
 | 
			
		||||
 | 
			
		||||
  VERIFY(!(half(0.0f) < half(-0.0f)));
 | 
			
		||||
  VERIFY(!(half(-0.0f) < half(0.0f)));
 | 
			
		||||
  VERIFY(!(half(0.0f) > half(-0.0f)));
 | 
			
		||||
  VERIFY(!(half(-0.0f) > half(0.0f)));
 | 
			
		||||
 | 
			
		||||
  VERIFY(half(0.2f) > half(-1.0f));
 | 
			
		||||
  VERIFY(half(-1.0f) < half(0.2f));
 | 
			
		||||
  VERIFY(half(-16.0f) < half(-15.0f));
 | 
			
		||||
 | 
			
		||||
  VERIFY(half(1.0f) == half(1.0f));
 | 
			
		||||
  VERIFY(half(1.0f) != half(2.0f));
 | 
			
		||||
 | 
			
		||||
  // Comparisons with NaNs and infinities.
 | 
			
		||||
#if !EIGEN_COMP_MSVC
 | 
			
		||||
  // Visual Studio errors out on divisions by 0
 | 
			
		||||
  VERIFY(!(half(0.0 / 0.0) == half(0.0 / 0.0)));
 | 
			
		||||
  VERIFY(half(0.0 / 0.0) != half(0.0 / 0.0));
 | 
			
		||||
 | 
			
		||||
  VERIFY(!(half(1.0) == half(0.0 / 0.0)));
 | 
			
		||||
  VERIFY(!(half(1.0) < half(0.0 / 0.0)));
 | 
			
		||||
  VERIFY(!(half(1.0) > half(0.0 / 0.0)));
 | 
			
		||||
  VERIFY(half(1.0) != half(0.0 / 0.0));
 | 
			
		||||
 | 
			
		||||
  VERIFY(half(1.0) < half(1.0 / 0.0));
 | 
			
		||||
  VERIFY(half(1.0) > half(-1.0 / 0.0));
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_basic_functions()
 | 
			
		||||
{
 | 
			
		||||
  VERIFY_IS_EQUAL(float(numext::abs(half(3.5f))), 3.5f);
 | 
			
		||||
  VERIFY_IS_EQUAL(float(abs(half(3.5f))), 3.5f);
 | 
			
		||||
  VERIFY_IS_EQUAL(float(numext::abs(half(-3.5f))), 3.5f);
 | 
			
		||||
  VERIFY_IS_EQUAL(float(abs(half(-3.5f))), 3.5f);
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_EQUAL(float(numext::floor(half(3.5f))), 3.0f);
 | 
			
		||||
  VERIFY_IS_EQUAL(float(floor(half(3.5f))), 3.0f);
 | 
			
		||||
  VERIFY_IS_EQUAL(float(numext::floor(half(-3.5f))), -4.0f);
 | 
			
		||||
  VERIFY_IS_EQUAL(float(floor(half(-3.5f))), -4.0f);
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_EQUAL(float(numext::ceil(half(3.5f))), 4.0f);
 | 
			
		||||
  VERIFY_IS_EQUAL(float(ceil(half(3.5f))), 4.0f);
 | 
			
		||||
  VERIFY_IS_EQUAL(float(numext::ceil(half(-3.5f))), -3.0f);
 | 
			
		||||
  VERIFY_IS_EQUAL(float(ceil(half(-3.5f))), -3.0f);
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(float(numext::sqrt(half(0.0f))), 0.0f);
 | 
			
		||||
  VERIFY_IS_APPROX(float(sqrt(half(0.0f))), 0.0f);
 | 
			
		||||
  VERIFY_IS_APPROX(float(numext::sqrt(half(4.0f))), 2.0f);
 | 
			
		||||
  VERIFY_IS_APPROX(float(sqrt(half(4.0f))), 2.0f);
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(float(numext::pow(half(0.0f), half(1.0f))), 0.0f);
 | 
			
		||||
  VERIFY_IS_APPROX(float(pow(half(0.0f), half(1.0f))), 0.0f);
 | 
			
		||||
  VERIFY_IS_APPROX(float(numext::pow(half(2.0f), half(2.0f))), 4.0f);
 | 
			
		||||
  VERIFY_IS_APPROX(float(pow(half(2.0f), half(2.0f))), 4.0f);
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_EQUAL(float(numext::exp(half(0.0f))), 1.0f);
 | 
			
		||||
  VERIFY_IS_EQUAL(float(exp(half(0.0f))), 1.0f);
 | 
			
		||||
  VERIFY_IS_APPROX(float(numext::exp(half(EIGEN_PI))), 20.f + float(EIGEN_PI));
 | 
			
		||||
  VERIFY_IS_APPROX(float(exp(half(EIGEN_PI))), 20.f + float(EIGEN_PI));
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_EQUAL(float(numext::log(half(1.0f))), 0.0f);
 | 
			
		||||
  VERIFY_IS_EQUAL(float(log(half(1.0f))), 0.0f);
 | 
			
		||||
  VERIFY_IS_APPROX(float(numext::log(half(10.0f))), 2.30273f);
 | 
			
		||||
  VERIFY_IS_APPROX(float(log(half(10.0f))), 2.30273f);
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_EQUAL(float(numext::log1p(half(0.0f))), 0.0f);
 | 
			
		||||
  VERIFY_IS_EQUAL(float(log1p(half(0.0f))), 0.0f);
 | 
			
		||||
  VERIFY_IS_APPROX(float(numext::log1p(half(10.0f))), 2.3978953f);
 | 
			
		||||
  VERIFY_IS_APPROX(float(log1p(half(10.0f))), 2.3978953f);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_trigonometric_functions()
 | 
			
		||||
{
 | 
			
		||||
  VERIFY_IS_APPROX(numext::cos(half(0.0f)), half(cosf(0.0f)));
 | 
			
		||||
  VERIFY_IS_APPROX(cos(half(0.0f)), half(cosf(0.0f)));
 | 
			
		||||
  VERIFY_IS_APPROX(numext::cos(half(EIGEN_PI)), half(cosf(EIGEN_PI)));
 | 
			
		||||
  //VERIFY_IS_APPROX(numext::cos(half(EIGEN_PI/2)), half(cosf(EIGEN_PI/2)));
 | 
			
		||||
  //VERIFY_IS_APPROX(numext::cos(half(3*EIGEN_PI/2)), half(cosf(3*EIGEN_PI/2)));
 | 
			
		||||
  VERIFY_IS_APPROX(numext::cos(half(3.5f)), half(cosf(3.5f)));
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(numext::sin(half(0.0f)), half(sinf(0.0f)));
 | 
			
		||||
  VERIFY_IS_APPROX(sin(half(0.0f)), half(sinf(0.0f)));
 | 
			
		||||
  //  VERIFY_IS_APPROX(numext::sin(half(EIGEN_PI)), half(sinf(EIGEN_PI)));
 | 
			
		||||
  VERIFY_IS_APPROX(numext::sin(half(EIGEN_PI/2)), half(sinf(EIGEN_PI/2)));
 | 
			
		||||
  VERIFY_IS_APPROX(numext::sin(half(3*EIGEN_PI/2)), half(sinf(3*EIGEN_PI/2)));
 | 
			
		||||
  VERIFY_IS_APPROX(numext::sin(half(3.5f)), half(sinf(3.5f)));
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(numext::tan(half(0.0f)), half(tanf(0.0f)));
 | 
			
		||||
  VERIFY_IS_APPROX(tan(half(0.0f)), half(tanf(0.0f)));
 | 
			
		||||
  //  VERIFY_IS_APPROX(numext::tan(half(EIGEN_PI)), half(tanf(EIGEN_PI)));
 | 
			
		||||
  //  VERIFY_IS_APPROX(numext::tan(half(EIGEN_PI/2)), half(tanf(EIGEN_PI/2)));
 | 
			
		||||
  //VERIFY_IS_APPROX(numext::tan(half(3*EIGEN_PI/2)), half(tanf(3*EIGEN_PI/2)));
 | 
			
		||||
  VERIFY_IS_APPROX(numext::tan(half(3.5f)), half(tanf(3.5f)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_array()
 | 
			
		||||
{
 | 
			
		||||
  typedef Array<half,1,Dynamic> ArrayXh;
 | 
			
		||||
  Index size = internal::random<Index>(1,10);
 | 
			
		||||
  Index i = internal::random<Index>(0,size-1);
 | 
			
		||||
  ArrayXh a1 = ArrayXh::Random(size), a2 = ArrayXh::Random(size);
 | 
			
		||||
  VERIFY_IS_APPROX( a1+a1, half(2)*a1 );
 | 
			
		||||
  VERIFY( (a1.abs() >= half(0)).all() );
 | 
			
		||||
  VERIFY_IS_APPROX( (a1*a1).sqrt(), a1.abs() );
 | 
			
		||||
 | 
			
		||||
  VERIFY( ((a1.min)(a2) <= (a1.max)(a2)).all() );
 | 
			
		||||
  a1(i) = half(-10.);
 | 
			
		||||
  VERIFY_IS_EQUAL( a1.minCoeff(), half(-10.) );
 | 
			
		||||
  a1(i) = half(10.);
 | 
			
		||||
  VERIFY_IS_EQUAL( a1.maxCoeff(), half(10.) );
 | 
			
		||||
 | 
			
		||||
  std::stringstream ss;
 | 
			
		||||
  ss << a1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_half_float()
 | 
			
		||||
{
 | 
			
		||||
  CALL_SUBTEST(test_conversion());
 | 
			
		||||
  CALL_SUBTEST(test_numtraits());
 | 
			
		||||
  CALL_SUBTEST(test_arithmetic());
 | 
			
		||||
  CALL_SUBTEST(test_comparison());
 | 
			
		||||
  CALL_SUBTEST(test_basic_functions());
 | 
			
		||||
  CALL_SUBTEST(test_trigonometric_functions());
 | 
			
		||||
  CALL_SUBTEST(test_array());
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										62
									
								
								cs440-acg/ext/eigen/test/hessenberg.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								cs440-acg/ext/eigen/test/hessenberg.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,62 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
// Copyright (C) 2010 Jitse Niesen <jitse@maths.leeds.ac.uk>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
#include <Eigen/Eigenvalues>
 | 
			
		||||
 | 
			
		||||
template<typename Scalar,int Size> void hessenberg(int size = Size)
 | 
			
		||||
{
 | 
			
		||||
  typedef Matrix<Scalar,Size,Size> MatrixType;
 | 
			
		||||
 | 
			
		||||
  // Test basic functionality: A = U H U* and H is Hessenberg
 | 
			
		||||
  for(int counter = 0; counter < g_repeat; ++counter) {
 | 
			
		||||
    MatrixType m = MatrixType::Random(size,size);
 | 
			
		||||
    HessenbergDecomposition<MatrixType> hess(m);
 | 
			
		||||
    MatrixType Q = hess.matrixQ();
 | 
			
		||||
    MatrixType H = hess.matrixH();
 | 
			
		||||
    VERIFY_IS_APPROX(m, Q * H * Q.adjoint());
 | 
			
		||||
    for(int row = 2; row < size; ++row) {
 | 
			
		||||
      for(int col = 0; col < row-1; ++col) {
 | 
			
		||||
	VERIFY(H(row,col) == (typename MatrixType::Scalar)0);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Test whether compute() and constructor returns same result
 | 
			
		||||
  MatrixType A = MatrixType::Random(size, size);
 | 
			
		||||
  HessenbergDecomposition<MatrixType> cs1;
 | 
			
		||||
  cs1.compute(A);
 | 
			
		||||
  HessenbergDecomposition<MatrixType> cs2(A);
 | 
			
		||||
  VERIFY_IS_EQUAL(cs1.matrixH().eval(), cs2.matrixH().eval());
 | 
			
		||||
  MatrixType cs1Q = cs1.matrixQ();
 | 
			
		||||
  MatrixType cs2Q = cs2.matrixQ();  
 | 
			
		||||
  VERIFY_IS_EQUAL(cs1Q, cs2Q);
 | 
			
		||||
 | 
			
		||||
  // Test assertions for when used uninitialized
 | 
			
		||||
  HessenbergDecomposition<MatrixType> hessUninitialized;
 | 
			
		||||
  VERIFY_RAISES_ASSERT( hessUninitialized.matrixH() );
 | 
			
		||||
  VERIFY_RAISES_ASSERT( hessUninitialized.matrixQ() );
 | 
			
		||||
  VERIFY_RAISES_ASSERT( hessUninitialized.householderCoefficients() );
 | 
			
		||||
  VERIFY_RAISES_ASSERT( hessUninitialized.packedMatrix() );
 | 
			
		||||
 | 
			
		||||
  // TODO: Add tests for packedMatrix() and householderCoefficients()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_hessenberg()
 | 
			
		||||
{
 | 
			
		||||
  CALL_SUBTEST_1(( hessenberg<std::complex<double>,1>() ));
 | 
			
		||||
  CALL_SUBTEST_2(( hessenberg<std::complex<double>,2>() ));
 | 
			
		||||
  CALL_SUBTEST_3(( hessenberg<std::complex<float>,4>() ));
 | 
			
		||||
  CALL_SUBTEST_4(( hessenberg<float,Dynamic>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE)) ));
 | 
			
		||||
  CALL_SUBTEST_5(( hessenberg<std::complex<double>,Dynamic>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE)) ));
 | 
			
		||||
 | 
			
		||||
  // Test problem size constructors
 | 
			
		||||
  CALL_SUBTEST_6(HessenbergDecomposition<MatrixXf>(10));
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										137
									
								
								cs440-acg/ext/eigen/test/householder.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										137
									
								
								cs440-acg/ext/eigen/test/householder.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,137 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2009-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
#include <Eigen/QR>
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void householder(const MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  static bool even = true;
 | 
			
		||||
  even = !even;
 | 
			
		||||
  /* this test covers the following files:
 | 
			
		||||
     Householder.h
 | 
			
		||||
  */
 | 
			
		||||
  Index rows = m.rows();
 | 
			
		||||
  Index cols = m.cols();
 | 
			
		||||
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
  typedef typename NumTraits<Scalar>::Real RealScalar;
 | 
			
		||||
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;
 | 
			
		||||
  typedef Matrix<Scalar, internal::decrement_size<MatrixType::RowsAtCompileTime>::ret, 1> EssentialVectorType;
 | 
			
		||||
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> SquareMatrixType;
 | 
			
		||||
  typedef Matrix<Scalar, Dynamic, MatrixType::ColsAtCompileTime> HBlockMatrixType;
 | 
			
		||||
  typedef Matrix<Scalar, Dynamic, 1> HCoeffsVectorType;
 | 
			
		||||
 | 
			
		||||
  typedef Matrix<Scalar, MatrixType::ColsAtCompileTime, MatrixType::RowsAtCompileTime> TMatrixType;
 | 
			
		||||
  
 | 
			
		||||
  Matrix<Scalar, EIGEN_SIZE_MAX(MatrixType::RowsAtCompileTime,MatrixType::ColsAtCompileTime), 1> _tmp((std::max)(rows,cols));
 | 
			
		||||
  Scalar* tmp = &_tmp.coeffRef(0,0);
 | 
			
		||||
 | 
			
		||||
  Scalar beta;
 | 
			
		||||
  RealScalar alpha;
 | 
			
		||||
  EssentialVectorType essential;
 | 
			
		||||
 | 
			
		||||
  VectorType v1 = VectorType::Random(rows), v2;
 | 
			
		||||
  v2 = v1;
 | 
			
		||||
  v1.makeHouseholder(essential, beta, alpha);
 | 
			
		||||
  v1.applyHouseholderOnTheLeft(essential,beta,tmp);
 | 
			
		||||
  VERIFY_IS_APPROX(v1.norm(), v2.norm());
 | 
			
		||||
  if(rows>=2) VERIFY_IS_MUCH_SMALLER_THAN(v1.tail(rows-1).norm(), v1.norm());
 | 
			
		||||
  v1 = VectorType::Random(rows);
 | 
			
		||||
  v2 = v1;
 | 
			
		||||
  v1.applyHouseholderOnTheLeft(essential,beta,tmp);
 | 
			
		||||
  VERIFY_IS_APPROX(v1.norm(), v2.norm());
 | 
			
		||||
 | 
			
		||||
  MatrixType m1(rows, cols),
 | 
			
		||||
             m2(rows, cols);
 | 
			
		||||
 | 
			
		||||
  v1 = VectorType::Random(rows);
 | 
			
		||||
  if(even) v1.tail(rows-1).setZero();
 | 
			
		||||
  m1.colwise() = v1;
 | 
			
		||||
  m2 = m1;
 | 
			
		||||
  m1.col(0).makeHouseholder(essential, beta, alpha);
 | 
			
		||||
  m1.applyHouseholderOnTheLeft(essential,beta,tmp);
 | 
			
		||||
  VERIFY_IS_APPROX(m1.norm(), m2.norm());
 | 
			
		||||
  if(rows>=2) VERIFY_IS_MUCH_SMALLER_THAN(m1.block(1,0,rows-1,cols).norm(), m1.norm());
 | 
			
		||||
  VERIFY_IS_MUCH_SMALLER_THAN(numext::imag(m1(0,0)), numext::real(m1(0,0)));
 | 
			
		||||
  VERIFY_IS_APPROX(numext::real(m1(0,0)), alpha);
 | 
			
		||||
 | 
			
		||||
  v1 = VectorType::Random(rows);
 | 
			
		||||
  if(even) v1.tail(rows-1).setZero();
 | 
			
		||||
  SquareMatrixType m3(rows,rows), m4(rows,rows);
 | 
			
		||||
  m3.rowwise() = v1.transpose();
 | 
			
		||||
  m4 = m3;
 | 
			
		||||
  m3.row(0).makeHouseholder(essential, beta, alpha);
 | 
			
		||||
  m3.applyHouseholderOnTheRight(essential,beta,tmp);
 | 
			
		||||
  VERIFY_IS_APPROX(m3.norm(), m4.norm());
 | 
			
		||||
  if(rows>=2) VERIFY_IS_MUCH_SMALLER_THAN(m3.block(0,1,rows,rows-1).norm(), m3.norm());
 | 
			
		||||
  VERIFY_IS_MUCH_SMALLER_THAN(numext::imag(m3(0,0)), numext::real(m3(0,0)));
 | 
			
		||||
  VERIFY_IS_APPROX(numext::real(m3(0,0)), alpha);
 | 
			
		||||
 | 
			
		||||
  // test householder sequence on the left with a shift
 | 
			
		||||
 | 
			
		||||
  Index shift = internal::random<Index>(0, std::max<Index>(rows-2,0));
 | 
			
		||||
  Index brows = rows - shift;
 | 
			
		||||
  m1.setRandom(rows, cols);
 | 
			
		||||
  HBlockMatrixType hbm = m1.block(shift,0,brows,cols);
 | 
			
		||||
  HouseholderQR<HBlockMatrixType> qr(hbm);
 | 
			
		||||
  m2 = m1;
 | 
			
		||||
  m2.block(shift,0,brows,cols) = qr.matrixQR();
 | 
			
		||||
  HCoeffsVectorType hc = qr.hCoeffs().conjugate();
 | 
			
		||||
  HouseholderSequence<MatrixType, HCoeffsVectorType> hseq(m2, hc);
 | 
			
		||||
  hseq.setLength(hc.size()).setShift(shift);
 | 
			
		||||
  VERIFY(hseq.length() == hc.size());
 | 
			
		||||
  VERIFY(hseq.shift() == shift);
 | 
			
		||||
  
 | 
			
		||||
  MatrixType m5 = m2;
 | 
			
		||||
  m5.block(shift,0,brows,cols).template triangularView<StrictlyLower>().setZero();
 | 
			
		||||
  VERIFY_IS_APPROX(hseq * m5, m1); // test applying hseq directly
 | 
			
		||||
  m3 = hseq;
 | 
			
		||||
  VERIFY_IS_APPROX(m3 * m5, m1); // test evaluating hseq to a dense matrix, then applying
 | 
			
		||||
  
 | 
			
		||||
  SquareMatrixType hseq_mat = hseq;
 | 
			
		||||
  SquareMatrixType hseq_mat_conj = hseq.conjugate();
 | 
			
		||||
  SquareMatrixType hseq_mat_adj = hseq.adjoint();
 | 
			
		||||
  SquareMatrixType hseq_mat_trans = hseq.transpose();
 | 
			
		||||
  SquareMatrixType m6 = SquareMatrixType::Random(rows, rows);
 | 
			
		||||
  VERIFY_IS_APPROX(hseq_mat.adjoint(),    hseq_mat_adj);
 | 
			
		||||
  VERIFY_IS_APPROX(hseq_mat.conjugate(),  hseq_mat_conj);
 | 
			
		||||
  VERIFY_IS_APPROX(hseq_mat.transpose(),  hseq_mat_trans);
 | 
			
		||||
  VERIFY_IS_APPROX(hseq_mat * m6,             hseq_mat * m6);
 | 
			
		||||
  VERIFY_IS_APPROX(hseq_mat.adjoint() * m6,   hseq_mat_adj * m6);
 | 
			
		||||
  VERIFY_IS_APPROX(hseq_mat.conjugate() * m6, hseq_mat_conj * m6);
 | 
			
		||||
  VERIFY_IS_APPROX(hseq_mat.transpose() * m6, hseq_mat_trans * m6);
 | 
			
		||||
  VERIFY_IS_APPROX(m6 * hseq_mat,             m6 * hseq_mat);
 | 
			
		||||
  VERIFY_IS_APPROX(m6 * hseq_mat.adjoint(),   m6 * hseq_mat_adj);
 | 
			
		||||
  VERIFY_IS_APPROX(m6 * hseq_mat.conjugate(), m6 * hseq_mat_conj);
 | 
			
		||||
  VERIFY_IS_APPROX(m6 * hseq_mat.transpose(), m6 * hseq_mat_trans);
 | 
			
		||||
 | 
			
		||||
  // test householder sequence on the right with a shift
 | 
			
		||||
 | 
			
		||||
  TMatrixType tm2 = m2.transpose();
 | 
			
		||||
  HouseholderSequence<TMatrixType, HCoeffsVectorType, OnTheRight> rhseq(tm2, hc);
 | 
			
		||||
  rhseq.setLength(hc.size()).setShift(shift);
 | 
			
		||||
  VERIFY_IS_APPROX(rhseq * m5, m1); // test applying rhseq directly
 | 
			
		||||
  m3 = rhseq;
 | 
			
		||||
  VERIFY_IS_APPROX(m3 * m5, m1); // test evaluating rhseq to a dense matrix, then applying
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_householder()
 | 
			
		||||
{
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_1( householder(Matrix<double,2,2>()) );
 | 
			
		||||
    CALL_SUBTEST_2( householder(Matrix<float,2,3>()) );
 | 
			
		||||
    CALL_SUBTEST_3( householder(Matrix<double,3,5>()) );
 | 
			
		||||
    CALL_SUBTEST_4( householder(Matrix<float,4,4>()) );
 | 
			
		||||
    CALL_SUBTEST_5( householder(MatrixXd(internal::random<int>(1,EIGEN_TEST_MAX_SIZE),internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
    CALL_SUBTEST_6( householder(MatrixXcf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE),internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
    CALL_SUBTEST_7( householder(MatrixXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE),internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
    CALL_SUBTEST_8( householder(Matrix<double,1,1>()) );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										65
									
								
								cs440-acg/ext/eigen/test/incomplete_cholesky.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								cs440-acg/ext/eigen/test/incomplete_cholesky.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,65 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2015-2016 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
// #define EIGEN_DONT_VECTORIZE
 | 
			
		||||
// #define EIGEN_MAX_ALIGN_BYTES 0
 | 
			
		||||
#include "sparse_solver.h"
 | 
			
		||||
#include <Eigen/IterativeLinearSolvers>
 | 
			
		||||
#include <unsupported/Eigen/IterativeSolvers>
 | 
			
		||||
 | 
			
		||||
template<typename T, typename I> void test_incomplete_cholesky_T()
 | 
			
		||||
{
 | 
			
		||||
  typedef SparseMatrix<T,0,I> SparseMatrixType;
 | 
			
		||||
  ConjugateGradient<SparseMatrixType, Lower, IncompleteCholesky<T, Lower, AMDOrdering<I> > >        cg_illt_lower_amd;
 | 
			
		||||
  ConjugateGradient<SparseMatrixType, Lower, IncompleteCholesky<T, Lower, NaturalOrdering<I> > >    cg_illt_lower_nat;
 | 
			
		||||
  ConjugateGradient<SparseMatrixType, Upper, IncompleteCholesky<T, Upper, AMDOrdering<I> > >        cg_illt_upper_amd;
 | 
			
		||||
  ConjugateGradient<SparseMatrixType, Upper, IncompleteCholesky<T, Upper, NaturalOrdering<I> > >    cg_illt_upper_nat;
 | 
			
		||||
  ConjugateGradient<SparseMatrixType, Upper|Lower, IncompleteCholesky<T, Lower, AMDOrdering<I> > >  cg_illt_uplo_amd;
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  CALL_SUBTEST( check_sparse_spd_solving(cg_illt_lower_amd) );
 | 
			
		||||
  CALL_SUBTEST( check_sparse_spd_solving(cg_illt_lower_nat) );
 | 
			
		||||
  CALL_SUBTEST( check_sparse_spd_solving(cg_illt_upper_amd) );
 | 
			
		||||
  CALL_SUBTEST( check_sparse_spd_solving(cg_illt_upper_nat) );
 | 
			
		||||
  CALL_SUBTEST( check_sparse_spd_solving(cg_illt_uplo_amd) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_incomplete_cholesky()
 | 
			
		||||
{
 | 
			
		||||
  CALL_SUBTEST_1(( test_incomplete_cholesky_T<double,int>() ));
 | 
			
		||||
  CALL_SUBTEST_2(( test_incomplete_cholesky_T<std::complex<double>, int>() ));
 | 
			
		||||
  CALL_SUBTEST_3(( test_incomplete_cholesky_T<double,long int>() ));
 | 
			
		||||
 | 
			
		||||
#ifdef EIGEN_TEST_PART_1
 | 
			
		||||
    // regression for bug 1150
 | 
			
		||||
  for(int N = 1; N<20; ++N)
 | 
			
		||||
  {
 | 
			
		||||
    Eigen::MatrixXd b( N, N );
 | 
			
		||||
    b.setOnes();
 | 
			
		||||
 | 
			
		||||
    Eigen::SparseMatrix<double> m( N, N );
 | 
			
		||||
    m.reserve(Eigen::VectorXi::Constant(N,4));
 | 
			
		||||
    for( int i = 0; i < N; ++i )
 | 
			
		||||
    {
 | 
			
		||||
        m.insert( i, i ) = 1;
 | 
			
		||||
        m.coeffRef( i, i / 2 ) = 2;
 | 
			
		||||
        m.coeffRef( i, i / 3 ) = 2;
 | 
			
		||||
        m.coeffRef( i, i / 4 ) = 2;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Eigen::SparseMatrix<double> A;
 | 
			
		||||
    A = m * m.transpose();
 | 
			
		||||
 | 
			
		||||
    Eigen::ConjugateGradient<Eigen::SparseMatrix<double>,
 | 
			
		||||
        Eigen::Lower | Eigen::Upper,
 | 
			
		||||
        Eigen::IncompleteCholesky<double> > solver( A );
 | 
			
		||||
    VERIFY(solver.preconditioner().info() == Eigen::Success);
 | 
			
		||||
    VERIFY(solver.info() == Eigen::Success);
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										110
									
								
								cs440-acg/ext/eigen/test/inplace_decomposition.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								cs440-acg/ext/eigen/test/inplace_decomposition.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,110 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2016 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
#include <Eigen/LU>
 | 
			
		||||
#include <Eigen/Cholesky>
 | 
			
		||||
#include <Eigen/QR>
 | 
			
		||||
 | 
			
		||||
// This file test inplace decomposition through Ref<>, as supported by Cholesky, LU, and QR decompositions.
 | 
			
		||||
 | 
			
		||||
template<typename DecType,typename MatrixType> void inplace(bool square = false, bool SPD = false)
 | 
			
		||||
{
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> RhsType;
 | 
			
		||||
  typedef Matrix<Scalar, MatrixType::ColsAtCompileTime, 1> ResType;
 | 
			
		||||
 | 
			
		||||
  Index rows = MatrixType::RowsAtCompileTime==Dynamic ? internal::random<Index>(2,EIGEN_TEST_MAX_SIZE/2) : Index(MatrixType::RowsAtCompileTime);
 | 
			
		||||
  Index cols = MatrixType::ColsAtCompileTime==Dynamic ? (square?rows:internal::random<Index>(2,rows))    : Index(MatrixType::ColsAtCompileTime);
 | 
			
		||||
 | 
			
		||||
  MatrixType A = MatrixType::Random(rows,cols);
 | 
			
		||||
  RhsType b = RhsType::Random(rows);
 | 
			
		||||
  ResType x(cols);
 | 
			
		||||
 | 
			
		||||
  if(SPD)
 | 
			
		||||
  {
 | 
			
		||||
    assert(square);
 | 
			
		||||
    A.topRows(cols) = A.topRows(cols).adjoint() * A.topRows(cols);
 | 
			
		||||
    A.diagonal().array() += 1e-3;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  MatrixType A0 = A;
 | 
			
		||||
  MatrixType A1 = A;
 | 
			
		||||
 | 
			
		||||
  DecType dec(A);
 | 
			
		||||
 | 
			
		||||
  // Check that the content of A has been modified
 | 
			
		||||
  VERIFY_IS_NOT_APPROX( A, A0 );
 | 
			
		||||
 | 
			
		||||
  // Check that the decomposition is correct:
 | 
			
		||||
  if(rows==cols)
 | 
			
		||||
  {
 | 
			
		||||
    VERIFY_IS_APPROX( A0 * (x = dec.solve(b)), b );
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    VERIFY_IS_APPROX( A0.transpose() * A0 * (x = dec.solve(b)), A0.transpose() * b );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Check that modifying A breaks the current dec:
 | 
			
		||||
  A.setRandom();
 | 
			
		||||
  if(rows==cols)
 | 
			
		||||
  {
 | 
			
		||||
    VERIFY_IS_NOT_APPROX( A0 * (x = dec.solve(b)), b );
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    VERIFY_IS_NOT_APPROX( A0.transpose() * A0 * (x = dec.solve(b)), A0.transpose() * b );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Check that calling compute(A1) does not modify A1:
 | 
			
		||||
  A = A0;
 | 
			
		||||
  dec.compute(A1);
 | 
			
		||||
  VERIFY_IS_EQUAL(A0,A1);
 | 
			
		||||
  VERIFY_IS_NOT_APPROX( A, A0 );
 | 
			
		||||
  if(rows==cols)
 | 
			
		||||
  {
 | 
			
		||||
    VERIFY_IS_APPROX( A0 * (x = dec.solve(b)), b );
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    VERIFY_IS_APPROX( A0.transpose() * A0 * (x = dec.solve(b)), A0.transpose() * b );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void test_inplace_decomposition()
 | 
			
		||||
{
 | 
			
		||||
  EIGEN_UNUSED typedef Matrix<double,4,3> Matrix43d;
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_1(( inplace<LLT<Ref<MatrixXd> >, MatrixXd>(true,true) ));
 | 
			
		||||
    CALL_SUBTEST_1(( inplace<LLT<Ref<Matrix4d> >, Matrix4d>(true,true) ));
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_2(( inplace<LDLT<Ref<MatrixXd> >, MatrixXd>(true,true) ));
 | 
			
		||||
    CALL_SUBTEST_2(( inplace<LDLT<Ref<Matrix4d> >, Matrix4d>(true,true) ));
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_3(( inplace<PartialPivLU<Ref<MatrixXd> >, MatrixXd>(true,false) ));
 | 
			
		||||
    CALL_SUBTEST_3(( inplace<PartialPivLU<Ref<Matrix4d> >, Matrix4d>(true,false) ));
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_4(( inplace<FullPivLU<Ref<MatrixXd> >, MatrixXd>(true,false) ));
 | 
			
		||||
    CALL_SUBTEST_4(( inplace<FullPivLU<Ref<Matrix4d> >, Matrix4d>(true,false) ));
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_5(( inplace<HouseholderQR<Ref<MatrixXd> >, MatrixXd>(false,false) ));
 | 
			
		||||
    CALL_SUBTEST_5(( inplace<HouseholderQR<Ref<Matrix43d> >, Matrix43d>(false,false) ));
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_6(( inplace<ColPivHouseholderQR<Ref<MatrixXd> >, MatrixXd>(false,false) ));
 | 
			
		||||
    CALL_SUBTEST_6(( inplace<ColPivHouseholderQR<Ref<Matrix43d> >, Matrix43d>(false,false) ));
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_7(( inplace<FullPivHouseholderQR<Ref<MatrixXd> >, MatrixXd>(false,false) ));
 | 
			
		||||
    CALL_SUBTEST_7(( inplace<FullPivHouseholderQR<Ref<Matrix43d> >, Matrix43d>(false,false) ));
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_8(( inplace<CompleteOrthogonalDecomposition<Ref<MatrixXd> >, MatrixXd>(false,false) ));
 | 
			
		||||
    CALL_SUBTEST_8(( inplace<CompleteOrthogonalDecomposition<Ref<Matrix43d> >, Matrix43d>(false,false) ));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										167
									
								
								cs440-acg/ext/eigen/test/integer_types.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										167
									
								
								cs440-acg/ext/eigen/test/integer_types.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,167 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2010 Benoit Jacob <jacob.benoit.1@gmail.com>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#define EIGEN_NO_STATIC_ASSERT
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
 | 
			
		||||
#undef VERIFY_IS_APPROX
 | 
			
		||||
#define VERIFY_IS_APPROX(a, b) VERIFY((a)==(b));
 | 
			
		||||
#undef VERIFY_IS_NOT_APPROX
 | 
			
		||||
#define VERIFY_IS_NOT_APPROX(a, b) VERIFY((a)!=(b));
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void signed_integer_type_tests(const MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
 | 
			
		||||
  enum { is_signed = (Scalar(-1) > Scalar(0)) ? 0 : 1 };
 | 
			
		||||
  VERIFY(is_signed == 1);
 | 
			
		||||
 | 
			
		||||
  Index rows = m.rows();
 | 
			
		||||
  Index cols = m.cols();
 | 
			
		||||
 | 
			
		||||
  MatrixType m1(rows, cols),
 | 
			
		||||
             m2 = MatrixType::Random(rows, cols),
 | 
			
		||||
             mzero = MatrixType::Zero(rows, cols);
 | 
			
		||||
 | 
			
		||||
  do {
 | 
			
		||||
    m1 = MatrixType::Random(rows, cols);
 | 
			
		||||
  } while(m1 == mzero || m1 == m2);
 | 
			
		||||
 | 
			
		||||
  // check linear structure
 | 
			
		||||
 | 
			
		||||
  Scalar s1;
 | 
			
		||||
  do {
 | 
			
		||||
    s1 = internal::random<Scalar>();
 | 
			
		||||
  } while(s1 == 0);
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_EQUAL(-(-m1),                  m1);
 | 
			
		||||
  VERIFY_IS_EQUAL(-m2+m1+m2,               m1);
 | 
			
		||||
  VERIFY_IS_EQUAL((-m1+m2)*s1,             -s1*m1+s1*m2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void integer_type_tests(const MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
 | 
			
		||||
  VERIFY(NumTraits<Scalar>::IsInteger);
 | 
			
		||||
  enum { is_signed = (Scalar(-1) > Scalar(0)) ? 0 : 1 };
 | 
			
		||||
  VERIFY(int(NumTraits<Scalar>::IsSigned) == is_signed);
 | 
			
		||||
 | 
			
		||||
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;
 | 
			
		||||
 | 
			
		||||
  Index rows = m.rows();
 | 
			
		||||
  Index cols = m.cols();
 | 
			
		||||
 | 
			
		||||
  // this test relies a lot on Random.h, and there's not much more that we can do
 | 
			
		||||
  // to test it, hence I consider that we will have tested Random.h
 | 
			
		||||
  MatrixType m1(rows, cols),
 | 
			
		||||
             m2 = MatrixType::Random(rows, cols),
 | 
			
		||||
             m3(rows, cols),
 | 
			
		||||
             mzero = MatrixType::Zero(rows, cols);
 | 
			
		||||
 | 
			
		||||
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> SquareMatrixType;
 | 
			
		||||
  SquareMatrixType identity = SquareMatrixType::Identity(rows, rows),
 | 
			
		||||
                   square = SquareMatrixType::Random(rows, rows);
 | 
			
		||||
  VectorType v1(rows),
 | 
			
		||||
             v2 = VectorType::Random(rows),
 | 
			
		||||
             vzero = VectorType::Zero(rows);
 | 
			
		||||
 | 
			
		||||
  do {
 | 
			
		||||
    m1 = MatrixType::Random(rows, cols);
 | 
			
		||||
  } while(m1 == mzero || m1 == m2);
 | 
			
		||||
 | 
			
		||||
  do {
 | 
			
		||||
    v1 = VectorType::Random(rows);
 | 
			
		||||
  } while(v1 == vzero || v1 == v2);
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(               v1,    v1);
 | 
			
		||||
  VERIFY_IS_NOT_APPROX(           v1,    2*v1);
 | 
			
		||||
  VERIFY_IS_APPROX(               vzero, v1-v1);
 | 
			
		||||
  VERIFY_IS_APPROX(               m1,    m1);
 | 
			
		||||
  VERIFY_IS_NOT_APPROX(           m1,    2*m1);
 | 
			
		||||
  VERIFY_IS_APPROX(               mzero, m1-m1);
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(m3 = m1,m1);
 | 
			
		||||
  MatrixType m4;
 | 
			
		||||
  VERIFY_IS_APPROX(m4 = m1,m1);
 | 
			
		||||
 | 
			
		||||
  m3.real() = m1.real();
 | 
			
		||||
  VERIFY_IS_APPROX(static_cast<const MatrixType&>(m3).real(), static_cast<const MatrixType&>(m1).real());
 | 
			
		||||
  VERIFY_IS_APPROX(static_cast<const MatrixType&>(m3).real(), m1.real());
 | 
			
		||||
 | 
			
		||||
  // check == / != operators
 | 
			
		||||
  VERIFY(m1==m1);
 | 
			
		||||
  VERIFY(m1!=m2);
 | 
			
		||||
  VERIFY(!(m1==m2));
 | 
			
		||||
  VERIFY(!(m1!=m1));
 | 
			
		||||
  m1 = m2;
 | 
			
		||||
  VERIFY(m1==m2);
 | 
			
		||||
  VERIFY(!(m1!=m2));
 | 
			
		||||
 | 
			
		||||
  // check linear structure
 | 
			
		||||
 | 
			
		||||
  Scalar s1;
 | 
			
		||||
  do {
 | 
			
		||||
    s1 = internal::random<Scalar>();
 | 
			
		||||
  } while(s1 == 0);
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_EQUAL(m1+m1,                   2*m1);
 | 
			
		||||
  VERIFY_IS_EQUAL(m1+m2-m1,                m2);
 | 
			
		||||
  VERIFY_IS_EQUAL(m1*s1,                   s1*m1);
 | 
			
		||||
  VERIFY_IS_EQUAL((m1+m2)*s1,              s1*m1+s1*m2);
 | 
			
		||||
  m3 = m2; m3 += m1;
 | 
			
		||||
  VERIFY_IS_EQUAL(m3,                      m1+m2);
 | 
			
		||||
  m3 = m2; m3 -= m1;
 | 
			
		||||
  VERIFY_IS_EQUAL(m3,                      m2-m1);
 | 
			
		||||
  m3 = m2; m3 *= s1;
 | 
			
		||||
  VERIFY_IS_EQUAL(m3,                      s1*m2);
 | 
			
		||||
 | 
			
		||||
  // check matrix product.
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(identity * m1, m1);
 | 
			
		||||
  VERIFY_IS_APPROX(square * (m1 + m2), square * m1 + square * m2);
 | 
			
		||||
  VERIFY_IS_APPROX((m1 + m2).transpose() * square, m1.transpose() * square + m2.transpose() * square);
 | 
			
		||||
  VERIFY_IS_APPROX((m1 * m2.transpose()) * m1, m1 * (m2.transpose() * m1));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_integer_types()
 | 
			
		||||
{
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_1( integer_type_tests(Matrix<unsigned int, 1, 1>()) );
 | 
			
		||||
    CALL_SUBTEST_1( integer_type_tests(Matrix<unsigned long, 3, 4>()) );
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_2( integer_type_tests(Matrix<long, 2, 2>()) );
 | 
			
		||||
    CALL_SUBTEST_2( signed_integer_type_tests(Matrix<long, 2, 2>()) );
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_3( integer_type_tests(Matrix<char, 2, Dynamic>(2, 10)) );
 | 
			
		||||
    CALL_SUBTEST_3( signed_integer_type_tests(Matrix<signed char, 2, Dynamic>(2, 10)) );
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_4( integer_type_tests(Matrix<unsigned char, 3, 3>()) );
 | 
			
		||||
    CALL_SUBTEST_4( integer_type_tests(Matrix<unsigned char, Dynamic, Dynamic>(20, 20)) );
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_5( integer_type_tests(Matrix<short, Dynamic, 4>(7, 4)) );
 | 
			
		||||
    CALL_SUBTEST_5( signed_integer_type_tests(Matrix<short, Dynamic, 4>(7, 4)) );
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_6( integer_type_tests(Matrix<unsigned short, 4, 4>()) );
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_7( integer_type_tests(Matrix<long long, 11, 13>()) );
 | 
			
		||||
    CALL_SUBTEST_7( signed_integer_type_tests(Matrix<long long, 11, 13>()) );
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_8( integer_type_tests(Matrix<unsigned long long, Dynamic, 5>(1, 5)) );
 | 
			
		||||
  }
 | 
			
		||||
#ifdef EIGEN_TEST_PART_9
 | 
			
		||||
  VERIFY_IS_EQUAL(internal::scalar_div_cost<int>::value, 8);
 | 
			
		||||
  VERIFY_IS_EQUAL(internal::scalar_div_cost<unsigned int>::value, 8);
 | 
			
		||||
  if(sizeof(long)>sizeof(int)) {
 | 
			
		||||
    VERIFY(int(internal::scalar_div_cost<long>::value) > int(internal::scalar_div_cost<int>::value));
 | 
			
		||||
    VERIFY(int(internal::scalar_div_cost<unsigned long>::value) > int(internal::scalar_div_cost<int>::value));
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										135
									
								
								cs440-acg/ext/eigen/test/inverse.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										135
									
								
								cs440-acg/ext/eigen/test/inverse.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,135 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
#include <Eigen/LU>
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void inverse(const MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  using std::abs;
 | 
			
		||||
  /* this test covers the following files:
 | 
			
		||||
     Inverse.h
 | 
			
		||||
  */
 | 
			
		||||
  Index rows = m.rows();
 | 
			
		||||
  Index cols = m.cols();
 | 
			
		||||
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
 | 
			
		||||
  MatrixType m1(rows, cols),
 | 
			
		||||
             m2(rows, cols),
 | 
			
		||||
             identity = MatrixType::Identity(rows, rows);
 | 
			
		||||
  createRandomPIMatrixOfRank(rows,rows,rows,m1);
 | 
			
		||||
  m2 = m1.inverse();
 | 
			
		||||
  VERIFY_IS_APPROX(m1, m2.inverse() );
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX((Scalar(2)*m2).inverse(), m2.inverse()*Scalar(0.5));
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(identity, m1.inverse() * m1 );
 | 
			
		||||
  VERIFY_IS_APPROX(identity, m1 * m1.inverse() );
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(m1, m1.inverse().inverse() );
 | 
			
		||||
 | 
			
		||||
  // since for the general case we implement separately row-major and col-major, test that
 | 
			
		||||
  VERIFY_IS_APPROX(MatrixType(m1.transpose().inverse()), MatrixType(m1.inverse().transpose()));
 | 
			
		||||
 | 
			
		||||
#if !defined(EIGEN_TEST_PART_5) && !defined(EIGEN_TEST_PART_6)
 | 
			
		||||
  typedef typename NumTraits<Scalar>::Real RealScalar;
 | 
			
		||||
  typedef Matrix<Scalar, MatrixType::ColsAtCompileTime, 1> VectorType;
 | 
			
		||||
  
 | 
			
		||||
  //computeInverseAndDetWithCheck tests
 | 
			
		||||
  //First: an invertible matrix
 | 
			
		||||
  bool invertible;
 | 
			
		||||
  Scalar det;
 | 
			
		||||
 | 
			
		||||
  m2.setZero();
 | 
			
		||||
  m1.computeInverseAndDetWithCheck(m2, det, invertible);
 | 
			
		||||
  VERIFY(invertible);
 | 
			
		||||
  VERIFY_IS_APPROX(identity, m1*m2);
 | 
			
		||||
  VERIFY_IS_APPROX(det, m1.determinant());
 | 
			
		||||
 | 
			
		||||
  m2.setZero();
 | 
			
		||||
  m1.computeInverseWithCheck(m2, invertible);
 | 
			
		||||
  VERIFY(invertible);
 | 
			
		||||
  VERIFY_IS_APPROX(identity, m1*m2);
 | 
			
		||||
 | 
			
		||||
  //Second: a rank one matrix (not invertible, except for 1x1 matrices)
 | 
			
		||||
  VectorType v3 = VectorType::Random(rows);
 | 
			
		||||
  MatrixType m3 = v3*v3.transpose(), m4(rows,cols);
 | 
			
		||||
  m3.computeInverseAndDetWithCheck(m4, det, invertible);
 | 
			
		||||
  VERIFY( rows==1 ? invertible : !invertible );
 | 
			
		||||
  VERIFY_IS_MUCH_SMALLER_THAN(abs(det-m3.determinant()), RealScalar(1));
 | 
			
		||||
  m3.computeInverseWithCheck(m4, invertible);
 | 
			
		||||
  VERIFY( rows==1 ? invertible : !invertible );
 | 
			
		||||
  
 | 
			
		||||
  // check with submatrices
 | 
			
		||||
  {
 | 
			
		||||
    Matrix<Scalar, MatrixType::RowsAtCompileTime+1, MatrixType::RowsAtCompileTime+1, MatrixType::Options> m5;
 | 
			
		||||
    m5.setRandom();
 | 
			
		||||
    m5.topLeftCorner(rows,rows) = m1;
 | 
			
		||||
    m2 = m5.template topLeftCorner<MatrixType::RowsAtCompileTime,MatrixType::ColsAtCompileTime>().inverse();
 | 
			
		||||
    VERIFY_IS_APPROX( (m5.template topLeftCorner<MatrixType::RowsAtCompileTime,MatrixType::ColsAtCompileTime>()), m2.inverse() );
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  // check in-place inversion
 | 
			
		||||
  if(MatrixType::RowsAtCompileTime>=2 && MatrixType::RowsAtCompileTime<=4)
 | 
			
		||||
  {
 | 
			
		||||
    // in-place is forbidden
 | 
			
		||||
    VERIFY_RAISES_ASSERT(m1 = m1.inverse());
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    m2 = m1.inverse();
 | 
			
		||||
    m1 = m1.inverse();
 | 
			
		||||
    VERIFY_IS_APPROX(m1,m2);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Scalar>
 | 
			
		||||
void inverse_zerosized()
 | 
			
		||||
{
 | 
			
		||||
  Matrix<Scalar,Dynamic,Dynamic> A(0,0);
 | 
			
		||||
  {
 | 
			
		||||
    Matrix<Scalar,0,1> b, x;
 | 
			
		||||
    x = A.inverse() * b;
 | 
			
		||||
  }
 | 
			
		||||
  {
 | 
			
		||||
    Matrix<Scalar,Dynamic,Dynamic> b(0,1), x;
 | 
			
		||||
    x = A.inverse() * b;
 | 
			
		||||
    VERIFY_IS_EQUAL(x.rows(), 0);
 | 
			
		||||
    VERIFY_IS_EQUAL(x.cols(), 1);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_inverse()
 | 
			
		||||
{
 | 
			
		||||
  int s = 0;
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_1( inverse(Matrix<double,1,1>()) );
 | 
			
		||||
    CALL_SUBTEST_2( inverse(Matrix2d()) );
 | 
			
		||||
    CALL_SUBTEST_3( inverse(Matrix3f()) );
 | 
			
		||||
    CALL_SUBTEST_4( inverse(Matrix4f()) );
 | 
			
		||||
    CALL_SUBTEST_4( inverse(Matrix<float,4,4,DontAlign>()) );
 | 
			
		||||
    
 | 
			
		||||
    s = internal::random<int>(50,320); 
 | 
			
		||||
    CALL_SUBTEST_5( inverse(MatrixXf(s,s)) );
 | 
			
		||||
    TEST_SET_BUT_UNUSED_VARIABLE(s)
 | 
			
		||||
    CALL_SUBTEST_5( inverse_zerosized<float>() );
 | 
			
		||||
    
 | 
			
		||||
    s = internal::random<int>(25,100);
 | 
			
		||||
    CALL_SUBTEST_6( inverse(MatrixXcd(s,s)) );
 | 
			
		||||
    TEST_SET_BUT_UNUSED_VARIABLE(s)
 | 
			
		||||
    
 | 
			
		||||
    CALL_SUBTEST_7( inverse(Matrix4d()) );
 | 
			
		||||
    CALL_SUBTEST_7( inverse(Matrix<double,4,4,DontAlign>()) );
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_8( inverse(Matrix4cd()) );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										33
									
								
								cs440-acg/ext/eigen/test/is_same_dense.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								cs440-acg/ext/eigen/test/is_same_dense.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2015 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
 | 
			
		||||
using internal::is_same_dense;
 | 
			
		||||
 | 
			
		||||
void test_is_same_dense()
 | 
			
		||||
{
 | 
			
		||||
  typedef Matrix<double,Dynamic,Dynamic,ColMajor> ColMatrixXd;
 | 
			
		||||
  ColMatrixXd m1(10,10);
 | 
			
		||||
  Ref<ColMatrixXd> ref_m1(m1);
 | 
			
		||||
  Ref<const ColMatrixXd> const_ref_m1(m1);
 | 
			
		||||
  VERIFY(is_same_dense(m1,m1));
 | 
			
		||||
  VERIFY(is_same_dense(m1,ref_m1));
 | 
			
		||||
  VERIFY(is_same_dense(const_ref_m1,m1));
 | 
			
		||||
  VERIFY(is_same_dense(const_ref_m1,ref_m1));
 | 
			
		||||
  
 | 
			
		||||
  VERIFY(is_same_dense(m1.block(0,0,m1.rows(),m1.cols()),m1));
 | 
			
		||||
  VERIFY(!is_same_dense(m1.row(0),m1.col(0)));
 | 
			
		||||
  
 | 
			
		||||
  Ref<const ColMatrixXd> const_ref_m1_row(m1.row(1));
 | 
			
		||||
  VERIFY(!is_same_dense(m1.row(1),const_ref_m1_row));
 | 
			
		||||
  
 | 
			
		||||
  Ref<const ColMatrixXd> const_ref_m1_col(m1.col(1));
 | 
			
		||||
  VERIFY(is_same_dense(m1.col(1),const_ref_m1_col));
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										80
									
								
								cs440-acg/ext/eigen/test/jacobi.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								cs440-acg/ext/eigen/test/jacobi.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,80 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
#include <Eigen/SVD>
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType, typename JacobiScalar>
 | 
			
		||||
void jacobi(const MatrixType& m = MatrixType())
 | 
			
		||||
{
 | 
			
		||||
  Index rows = m.rows();
 | 
			
		||||
  Index cols = m.cols();
 | 
			
		||||
 | 
			
		||||
  enum {
 | 
			
		||||
    RowsAtCompileTime = MatrixType::RowsAtCompileTime,
 | 
			
		||||
    ColsAtCompileTime = MatrixType::ColsAtCompileTime
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  typedef Matrix<JacobiScalar, 2, 1> JacobiVector;
 | 
			
		||||
 | 
			
		||||
  const MatrixType a(MatrixType::Random(rows, cols));
 | 
			
		||||
 | 
			
		||||
  JacobiVector v = JacobiVector::Random().normalized();
 | 
			
		||||
  JacobiScalar c = v.x(), s = v.y();
 | 
			
		||||
  JacobiRotation<JacobiScalar> rot(c, s);
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    Index p = internal::random<Index>(0, rows-1);
 | 
			
		||||
    Index q;
 | 
			
		||||
    do {
 | 
			
		||||
      q = internal::random<Index>(0, rows-1);
 | 
			
		||||
    } while (q == p);
 | 
			
		||||
 | 
			
		||||
    MatrixType b = a;
 | 
			
		||||
    b.applyOnTheLeft(p, q, rot);
 | 
			
		||||
    VERIFY_IS_APPROX(b.row(p), c * a.row(p) + numext::conj(s) * a.row(q));
 | 
			
		||||
    VERIFY_IS_APPROX(b.row(q), -s * a.row(p) + numext::conj(c) * a.row(q));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    Index p = internal::random<Index>(0, cols-1);
 | 
			
		||||
    Index q;
 | 
			
		||||
    do {
 | 
			
		||||
      q = internal::random<Index>(0, cols-1);
 | 
			
		||||
    } while (q == p);
 | 
			
		||||
 | 
			
		||||
    MatrixType b = a;
 | 
			
		||||
    b.applyOnTheRight(p, q, rot);
 | 
			
		||||
    VERIFY_IS_APPROX(b.col(p), c * a.col(p) - s * a.col(q));
 | 
			
		||||
    VERIFY_IS_APPROX(b.col(q), numext::conj(s) * a.col(p) + numext::conj(c) * a.col(q));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_jacobi()
 | 
			
		||||
{
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_1(( jacobi<Matrix3f, float>() ));
 | 
			
		||||
    CALL_SUBTEST_2(( jacobi<Matrix4d, double>() ));
 | 
			
		||||
    CALL_SUBTEST_3(( jacobi<Matrix4cf, float>() ));
 | 
			
		||||
    CALL_SUBTEST_3(( jacobi<Matrix4cf, std::complex<float> >() ));
 | 
			
		||||
 | 
			
		||||
    int r = internal::random<int>(2, internal::random<int>(1,EIGEN_TEST_MAX_SIZE)/2),
 | 
			
		||||
        c = internal::random<int>(2, internal::random<int>(1,EIGEN_TEST_MAX_SIZE)/2);
 | 
			
		||||
    CALL_SUBTEST_4(( jacobi<MatrixXf, float>(MatrixXf(r,c)) ));
 | 
			
		||||
    CALL_SUBTEST_5(( jacobi<MatrixXcd, double>(MatrixXcd(r,c)) ));
 | 
			
		||||
    CALL_SUBTEST_5(( jacobi<MatrixXcd, std::complex<double> >(MatrixXcd(r,c)) ));
 | 
			
		||||
    // complex<float> is really important to test as it is the only way to cover conjugation issues in certain unaligned paths
 | 
			
		||||
    CALL_SUBTEST_6(( jacobi<MatrixXcf, float>(MatrixXcf(r,c)) ));
 | 
			
		||||
    CALL_SUBTEST_6(( jacobi<MatrixXcf, std::complex<float> >(MatrixXcf(r,c)) ));
 | 
			
		||||
    
 | 
			
		||||
    TEST_SET_BUT_UNUSED_VARIABLE(r);
 | 
			
		||||
    TEST_SET_BUT_UNUSED_VARIABLE(c);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										142
									
								
								cs440-acg/ext/eigen/test/jacobisvd.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										142
									
								
								cs440-acg/ext/eigen/test/jacobisvd.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,142 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2008-2014 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
// discard stack allocation as that too bypasses malloc
 | 
			
		||||
#define EIGEN_STACK_ALLOCATION_LIMIT 0
 | 
			
		||||
#define EIGEN_RUNTIME_NO_MALLOC
 | 
			
		||||
#include "main.h"
 | 
			
		||||
#include <Eigen/SVD>
 | 
			
		||||
 | 
			
		||||
#define SVD_DEFAULT(M) JacobiSVD<M>
 | 
			
		||||
#define SVD_FOR_MIN_NORM(M) JacobiSVD<M,ColPivHouseholderQRPreconditioner>
 | 
			
		||||
#include "svd_common.h"
 | 
			
		||||
 | 
			
		||||
// Check all variants of JacobiSVD
 | 
			
		||||
template<typename MatrixType>
 | 
			
		||||
void jacobisvd(const MatrixType& a = MatrixType(), bool pickrandom = true)
 | 
			
		||||
{
 | 
			
		||||
  MatrixType m = a;
 | 
			
		||||
  if(pickrandom)
 | 
			
		||||
    svd_fill_random(m);
 | 
			
		||||
 | 
			
		||||
  CALL_SUBTEST(( svd_test_all_computation_options<JacobiSVD<MatrixType, FullPivHouseholderQRPreconditioner> >(m, true)  )); // check full only
 | 
			
		||||
  CALL_SUBTEST(( svd_test_all_computation_options<JacobiSVD<MatrixType, ColPivHouseholderQRPreconditioner>  >(m, false) ));
 | 
			
		||||
  CALL_SUBTEST(( svd_test_all_computation_options<JacobiSVD<MatrixType, HouseholderQRPreconditioner>        >(m, false) ));
 | 
			
		||||
  if(m.rows()==m.cols())
 | 
			
		||||
    CALL_SUBTEST(( svd_test_all_computation_options<JacobiSVD<MatrixType, NoQRPreconditioner>               >(m, false) ));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void jacobisvd_verify_assert(const MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  svd_verify_assert<JacobiSVD<MatrixType> >(m);
 | 
			
		||||
  Index rows = m.rows();
 | 
			
		||||
  Index cols = m.cols();
 | 
			
		||||
 | 
			
		||||
  enum {
 | 
			
		||||
    ColsAtCompileTime = MatrixType::ColsAtCompileTime
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  MatrixType a = MatrixType::Zero(rows, cols);
 | 
			
		||||
  a.setZero();
 | 
			
		||||
 | 
			
		||||
  if (ColsAtCompileTime == Dynamic)
 | 
			
		||||
  {
 | 
			
		||||
    JacobiSVD<MatrixType, FullPivHouseholderQRPreconditioner> svd_fullqr;
 | 
			
		||||
    VERIFY_RAISES_ASSERT(svd_fullqr.compute(a, ComputeFullU|ComputeThinV))
 | 
			
		||||
    VERIFY_RAISES_ASSERT(svd_fullqr.compute(a, ComputeThinU|ComputeThinV))
 | 
			
		||||
    VERIFY_RAISES_ASSERT(svd_fullqr.compute(a, ComputeThinU|ComputeFullV))
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType>
 | 
			
		||||
void jacobisvd_method()
 | 
			
		||||
{
 | 
			
		||||
  enum { Size = MatrixType::RowsAtCompileTime };
 | 
			
		||||
  typedef typename MatrixType::RealScalar RealScalar;
 | 
			
		||||
  typedef Matrix<RealScalar, Size, 1> RealVecType;
 | 
			
		||||
  MatrixType m = MatrixType::Identity();
 | 
			
		||||
  VERIFY_IS_APPROX(m.jacobiSvd().singularValues(), RealVecType::Ones());
 | 
			
		||||
  VERIFY_RAISES_ASSERT(m.jacobiSvd().matrixU());
 | 
			
		||||
  VERIFY_RAISES_ASSERT(m.jacobiSvd().matrixV());
 | 
			
		||||
  VERIFY_IS_APPROX(m.jacobiSvd(ComputeFullU|ComputeFullV).solve(m), m);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace Foo {
 | 
			
		||||
// older compiler require a default constructor for Bar
 | 
			
		||||
// cf: https://stackoverflow.com/questions/7411515/
 | 
			
		||||
class Bar {public: Bar() {}};
 | 
			
		||||
bool operator<(const Bar&, const Bar&) { return true; }
 | 
			
		||||
}
 | 
			
		||||
// regression test for a very strange MSVC issue for which simply
 | 
			
		||||
// including SVDBase.h messes up with std::max and custom scalar type
 | 
			
		||||
void msvc_workaround()
 | 
			
		||||
{
 | 
			
		||||
  const Foo::Bar a;
 | 
			
		||||
  const Foo::Bar b;
 | 
			
		||||
  std::max EIGEN_NOT_A_MACRO (a,b);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_jacobisvd()
 | 
			
		||||
{
 | 
			
		||||
  CALL_SUBTEST_3(( jacobisvd_verify_assert(Matrix3f()) ));
 | 
			
		||||
  CALL_SUBTEST_4(( jacobisvd_verify_assert(Matrix4d()) ));
 | 
			
		||||
  CALL_SUBTEST_7(( jacobisvd_verify_assert(MatrixXf(10,12)) ));
 | 
			
		||||
  CALL_SUBTEST_8(( jacobisvd_verify_assert(MatrixXcd(7,5)) ));
 | 
			
		||||
  
 | 
			
		||||
  CALL_SUBTEST_11(svd_all_trivial_2x2(jacobisvd<Matrix2cd>));
 | 
			
		||||
  CALL_SUBTEST_12(svd_all_trivial_2x2(jacobisvd<Matrix2d>));
 | 
			
		||||
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_3(( jacobisvd<Matrix3f>() ));
 | 
			
		||||
    CALL_SUBTEST_4(( jacobisvd<Matrix4d>() ));
 | 
			
		||||
    CALL_SUBTEST_5(( jacobisvd<Matrix<float,3,5> >() ));
 | 
			
		||||
    CALL_SUBTEST_6(( jacobisvd<Matrix<double,Dynamic,2> >(Matrix<double,Dynamic,2>(10,2)) ));
 | 
			
		||||
 | 
			
		||||
    int r = internal::random<int>(1, 30),
 | 
			
		||||
        c = internal::random<int>(1, 30);
 | 
			
		||||
    
 | 
			
		||||
    TEST_SET_BUT_UNUSED_VARIABLE(r)
 | 
			
		||||
    TEST_SET_BUT_UNUSED_VARIABLE(c)
 | 
			
		||||
    
 | 
			
		||||
    CALL_SUBTEST_10(( jacobisvd<MatrixXd>(MatrixXd(r,c)) ));
 | 
			
		||||
    CALL_SUBTEST_7(( jacobisvd<MatrixXf>(MatrixXf(r,c)) ));
 | 
			
		||||
    CALL_SUBTEST_8(( jacobisvd<MatrixXcd>(MatrixXcd(r,c)) ));
 | 
			
		||||
    (void) r;
 | 
			
		||||
    (void) c;
 | 
			
		||||
 | 
			
		||||
    // Test on inf/nan matrix
 | 
			
		||||
    CALL_SUBTEST_7(  (svd_inf_nan<JacobiSVD<MatrixXf>, MatrixXf>()) );
 | 
			
		||||
    CALL_SUBTEST_10( (svd_inf_nan<JacobiSVD<MatrixXd>, MatrixXd>()) );
 | 
			
		||||
 | 
			
		||||
    // bug1395 test compile-time vectors as input
 | 
			
		||||
    CALL_SUBTEST_13(( jacobisvd_verify_assert(Matrix<double,6,1>()) ));
 | 
			
		||||
    CALL_SUBTEST_13(( jacobisvd_verify_assert(Matrix<double,1,6>()) ));
 | 
			
		||||
    CALL_SUBTEST_13(( jacobisvd_verify_assert(Matrix<double,Dynamic,1>(r)) ));
 | 
			
		||||
    CALL_SUBTEST_13(( jacobisvd_verify_assert(Matrix<double,1,Dynamic>(c)) ));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  CALL_SUBTEST_7(( jacobisvd<MatrixXf>(MatrixXf(internal::random<int>(EIGEN_TEST_MAX_SIZE/4, EIGEN_TEST_MAX_SIZE/2), internal::random<int>(EIGEN_TEST_MAX_SIZE/4, EIGEN_TEST_MAX_SIZE/2))) ));
 | 
			
		||||
  CALL_SUBTEST_8(( jacobisvd<MatrixXcd>(MatrixXcd(internal::random<int>(EIGEN_TEST_MAX_SIZE/4, EIGEN_TEST_MAX_SIZE/3), internal::random<int>(EIGEN_TEST_MAX_SIZE/4, EIGEN_TEST_MAX_SIZE/3))) ));
 | 
			
		||||
 | 
			
		||||
  // test matrixbase method
 | 
			
		||||
  CALL_SUBTEST_1(( jacobisvd_method<Matrix2cd>() ));
 | 
			
		||||
  CALL_SUBTEST_3(( jacobisvd_method<Matrix3f>() ));
 | 
			
		||||
 | 
			
		||||
  // Test problem size constructors
 | 
			
		||||
  CALL_SUBTEST_7( JacobiSVD<MatrixXf>(10,10) );
 | 
			
		||||
 | 
			
		||||
  // Check that preallocation avoids subsequent mallocs
 | 
			
		||||
  CALL_SUBTEST_9( svd_preallocate<void>() );
 | 
			
		||||
 | 
			
		||||
  CALL_SUBTEST_2( svd_underoverflow<void>() );
 | 
			
		||||
 | 
			
		||||
  msvc_workaround();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										148
									
								
								cs440-acg/ext/eigen/test/linearstructure.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										148
									
								
								cs440-acg/ext/eigen/test/linearstructure.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,148 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
 | 
			
		||||
// Copyright (C) 2014 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
static bool g_called;
 | 
			
		||||
#define EIGEN_SCALAR_BINARY_OP_PLUGIN { g_called |= (!internal::is_same<LhsScalar,RhsScalar>::value); }
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void linearStructure(const MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  using std::abs;
 | 
			
		||||
  /* this test covers the following files:
 | 
			
		||||
     CwiseUnaryOp.h, CwiseBinaryOp.h, SelfCwiseBinaryOp.h 
 | 
			
		||||
  */
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
  typedef typename MatrixType::RealScalar RealScalar;
 | 
			
		||||
 | 
			
		||||
  Index rows = m.rows();
 | 
			
		||||
  Index cols = m.cols();
 | 
			
		||||
 | 
			
		||||
  // this test relies a lot on Random.h, and there's not much more that we can do
 | 
			
		||||
  // to test it, hence I consider that we will have tested Random.h
 | 
			
		||||
  MatrixType m1 = MatrixType::Random(rows, cols),
 | 
			
		||||
             m2 = MatrixType::Random(rows, cols),
 | 
			
		||||
             m3(rows, cols);
 | 
			
		||||
 | 
			
		||||
  Scalar s1 = internal::random<Scalar>();
 | 
			
		||||
  while (abs(s1)<RealScalar(1e-3)) s1 = internal::random<Scalar>();
 | 
			
		||||
 | 
			
		||||
  Index r = internal::random<Index>(0, rows-1),
 | 
			
		||||
        c = internal::random<Index>(0, cols-1);
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(-(-m1),                  m1);
 | 
			
		||||
  VERIFY_IS_APPROX(m1+m1,                   2*m1);
 | 
			
		||||
  VERIFY_IS_APPROX(m1+m2-m1,                m2);
 | 
			
		||||
  VERIFY_IS_APPROX(-m2+m1+m2,               m1);
 | 
			
		||||
  VERIFY_IS_APPROX(m1*s1,                   s1*m1);
 | 
			
		||||
  VERIFY_IS_APPROX((m1+m2)*s1,              s1*m1+s1*m2);
 | 
			
		||||
  VERIFY_IS_APPROX((-m1+m2)*s1,             -s1*m1+s1*m2);
 | 
			
		||||
  m3 = m2; m3 += m1;
 | 
			
		||||
  VERIFY_IS_APPROX(m3,                      m1+m2);
 | 
			
		||||
  m3 = m2; m3 -= m1;
 | 
			
		||||
  VERIFY_IS_APPROX(m3,                      m2-m1);
 | 
			
		||||
  m3 = m2; m3 *= s1;
 | 
			
		||||
  VERIFY_IS_APPROX(m3,                      s1*m2);
 | 
			
		||||
  if(!NumTraits<Scalar>::IsInteger)
 | 
			
		||||
  {
 | 
			
		||||
    m3 = m2; m3 /= s1;
 | 
			
		||||
    VERIFY_IS_APPROX(m3,                    m2/s1);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // again, test operator() to check const-qualification
 | 
			
		||||
  VERIFY_IS_APPROX((-m1)(r,c), -(m1(r,c)));
 | 
			
		||||
  VERIFY_IS_APPROX((m1-m2)(r,c), (m1(r,c))-(m2(r,c)));
 | 
			
		||||
  VERIFY_IS_APPROX((m1+m2)(r,c), (m1(r,c))+(m2(r,c)));
 | 
			
		||||
  VERIFY_IS_APPROX((s1*m1)(r,c), s1*(m1(r,c)));
 | 
			
		||||
  VERIFY_IS_APPROX((m1*s1)(r,c), (m1(r,c))*s1);
 | 
			
		||||
  if(!NumTraits<Scalar>::IsInteger)
 | 
			
		||||
    VERIFY_IS_APPROX((m1/s1)(r,c), (m1(r,c))/s1);
 | 
			
		||||
 | 
			
		||||
  // use .block to disable vectorization and compare to the vectorized version
 | 
			
		||||
  VERIFY_IS_APPROX(m1+m1.block(0,0,rows,cols), m1+m1);
 | 
			
		||||
  VERIFY_IS_APPROX(m1.cwiseProduct(m1.block(0,0,rows,cols)), m1.cwiseProduct(m1));
 | 
			
		||||
  VERIFY_IS_APPROX(m1 - m1.block(0,0,rows,cols), m1 - m1);
 | 
			
		||||
  VERIFY_IS_APPROX(m1.block(0,0,rows,cols) * s1, m1 * s1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Make sure that complex * real and real * complex are properly optimized
 | 
			
		||||
template<typename MatrixType> void real_complex(DenseIndex rows = MatrixType::RowsAtCompileTime, DenseIndex cols = MatrixType::ColsAtCompileTime)
 | 
			
		||||
{
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
  typedef typename MatrixType::RealScalar RealScalar;
 | 
			
		||||
  
 | 
			
		||||
  RealScalar s = internal::random<RealScalar>();
 | 
			
		||||
  MatrixType m1 = MatrixType::Random(rows, cols);
 | 
			
		||||
  
 | 
			
		||||
  g_called = false;
 | 
			
		||||
  VERIFY_IS_APPROX(s*m1, Scalar(s)*m1);
 | 
			
		||||
  VERIFY(g_called && "real * matrix<complex> not properly optimized");
 | 
			
		||||
  
 | 
			
		||||
  g_called = false;
 | 
			
		||||
  VERIFY_IS_APPROX(m1*s, m1*Scalar(s));
 | 
			
		||||
  VERIFY(g_called && "matrix<complex> * real not properly optimized");
 | 
			
		||||
  
 | 
			
		||||
  g_called = false;
 | 
			
		||||
  VERIFY_IS_APPROX(m1/s, m1/Scalar(s));
 | 
			
		||||
  VERIFY(g_called && "matrix<complex> / real not properly optimized");
 | 
			
		||||
 | 
			
		||||
  g_called = false;
 | 
			
		||||
  VERIFY_IS_APPROX(s+m1.array(), Scalar(s)+m1.array());
 | 
			
		||||
  VERIFY(g_called && "real + matrix<complex> not properly optimized");
 | 
			
		||||
 | 
			
		||||
  g_called = false;
 | 
			
		||||
  VERIFY_IS_APPROX(m1.array()+s, m1.array()+Scalar(s));
 | 
			
		||||
  VERIFY(g_called && "matrix<complex> + real not properly optimized");
 | 
			
		||||
 | 
			
		||||
  g_called = false;
 | 
			
		||||
  VERIFY_IS_APPROX(s-m1.array(), Scalar(s)-m1.array());
 | 
			
		||||
  VERIFY(g_called && "real - matrix<complex> not properly optimized");
 | 
			
		||||
 | 
			
		||||
  g_called = false;
 | 
			
		||||
  VERIFY_IS_APPROX(m1.array()-s, m1.array()-Scalar(s));
 | 
			
		||||
  VERIFY(g_called && "matrix<complex> - real not properly optimized");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_linearstructure()
 | 
			
		||||
{
 | 
			
		||||
  g_called = true;
 | 
			
		||||
  VERIFY(g_called); // avoid `unneeded-internal-declaration` warning.
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_1( linearStructure(Matrix<float, 1, 1>()) );
 | 
			
		||||
    CALL_SUBTEST_2( linearStructure(Matrix2f()) );
 | 
			
		||||
    CALL_SUBTEST_3( linearStructure(Vector3d()) );
 | 
			
		||||
    CALL_SUBTEST_4( linearStructure(Matrix4d()) );
 | 
			
		||||
    CALL_SUBTEST_5( linearStructure(MatrixXcf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2), internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2))) );
 | 
			
		||||
    CALL_SUBTEST_6( linearStructure(MatrixXf (internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
    CALL_SUBTEST_7( linearStructure(MatrixXi (internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
    CALL_SUBTEST_8( linearStructure(MatrixXcd(internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2), internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2))) );
 | 
			
		||||
    CALL_SUBTEST_9( linearStructure(ArrayXXf (internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
    CALL_SUBTEST_10( linearStructure(ArrayXXcf (internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
    
 | 
			
		||||
    CALL_SUBTEST_11( real_complex<Matrix4cd>() );
 | 
			
		||||
    CALL_SUBTEST_11( real_complex<MatrixXcf>(10,10) );
 | 
			
		||||
    CALL_SUBTEST_11( real_complex<ArrayXXcf>(10,10) );
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
#ifdef EIGEN_TEST_PART_4
 | 
			
		||||
  {
 | 
			
		||||
    // make sure that /=scalar and /scalar do not overflow
 | 
			
		||||
    // rational: 1.0/4.94e-320 overflow, but m/4.94e-320 should not
 | 
			
		||||
    Matrix4d m2, m3;
 | 
			
		||||
    m3 = m2 =  Matrix4d::Random()*1e-20;
 | 
			
		||||
    m2 = m2 / 4.9e-320;
 | 
			
		||||
    VERIFY_IS_APPROX(m2.cwiseQuotient(m2), Matrix4d::Ones());
 | 
			
		||||
    m3 /= 4.9e-320;
 | 
			
		||||
    VERIFY_IS_APPROX(m3.cwiseQuotient(m3), Matrix4d::Ones());
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										37
									
								
								cs440-acg/ext/eigen/test/lscg.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								cs440-acg/ext/eigen/test/lscg.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2011 Gael Guennebaud <g.gael@free.fr>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "sparse_solver.h"
 | 
			
		||||
#include <Eigen/IterativeLinearSolvers>
 | 
			
		||||
 | 
			
		||||
template<typename T> void test_lscg_T()
 | 
			
		||||
{
 | 
			
		||||
  LeastSquaresConjugateGradient<SparseMatrix<T> > lscg_colmajor_diag;
 | 
			
		||||
  LeastSquaresConjugateGradient<SparseMatrix<T>, IdentityPreconditioner> lscg_colmajor_I;
 | 
			
		||||
  LeastSquaresConjugateGradient<SparseMatrix<T,RowMajor> > lscg_rowmajor_diag;
 | 
			
		||||
  LeastSquaresConjugateGradient<SparseMatrix<T,RowMajor>, IdentityPreconditioner> lscg_rowmajor_I;
 | 
			
		||||
 | 
			
		||||
  CALL_SUBTEST( check_sparse_square_solving(lscg_colmajor_diag)  );
 | 
			
		||||
  CALL_SUBTEST( check_sparse_square_solving(lscg_colmajor_I)     );
 | 
			
		||||
  
 | 
			
		||||
  CALL_SUBTEST( check_sparse_leastsquare_solving(lscg_colmajor_diag)  );
 | 
			
		||||
  CALL_SUBTEST( check_sparse_leastsquare_solving(lscg_colmajor_I)     );
 | 
			
		||||
 | 
			
		||||
  CALL_SUBTEST( check_sparse_square_solving(lscg_rowmajor_diag)  );
 | 
			
		||||
  CALL_SUBTEST( check_sparse_square_solving(lscg_rowmajor_I)     );
 | 
			
		||||
 | 
			
		||||
  CALL_SUBTEST( check_sparse_leastsquare_solving(lscg_rowmajor_diag)  );
 | 
			
		||||
  CALL_SUBTEST( check_sparse_leastsquare_solving(lscg_rowmajor_I)     );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_lscg()
 | 
			
		||||
{
 | 
			
		||||
  CALL_SUBTEST_1(test_lscg_T<double>());
 | 
			
		||||
  CALL_SUBTEST_2(test_lscg_T<std::complex<double> >());
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										283
									
								
								cs440-acg/ext/eigen/test/lu.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										283
									
								
								cs440-acg/ext/eigen/test/lu.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,283 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2008-2009 Benoit Jacob <jacob.benoit.1@gmail.com>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
#include <Eigen/LU>
 | 
			
		||||
using namespace std;
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType>
 | 
			
		||||
typename MatrixType::RealScalar matrix_l1_norm(const MatrixType& m) {
 | 
			
		||||
  return m.cwiseAbs().colwise().sum().maxCoeff();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void lu_non_invertible()
 | 
			
		||||
{
 | 
			
		||||
  typedef typename MatrixType::RealScalar RealScalar;
 | 
			
		||||
  /* this test covers the following files:
 | 
			
		||||
     LU.h
 | 
			
		||||
  */
 | 
			
		||||
  Index rows, cols, cols2;
 | 
			
		||||
  if(MatrixType::RowsAtCompileTime==Dynamic)
 | 
			
		||||
  {
 | 
			
		||||
    rows = internal::random<Index>(2,EIGEN_TEST_MAX_SIZE);
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    rows = MatrixType::RowsAtCompileTime;
 | 
			
		||||
  }
 | 
			
		||||
  if(MatrixType::ColsAtCompileTime==Dynamic)
 | 
			
		||||
  {
 | 
			
		||||
    cols = internal::random<Index>(2,EIGEN_TEST_MAX_SIZE);
 | 
			
		||||
    cols2 = internal::random<int>(2,EIGEN_TEST_MAX_SIZE);
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    cols2 = cols = MatrixType::ColsAtCompileTime;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  enum {
 | 
			
		||||
    RowsAtCompileTime = MatrixType::RowsAtCompileTime,
 | 
			
		||||
    ColsAtCompileTime = MatrixType::ColsAtCompileTime
 | 
			
		||||
  };
 | 
			
		||||
  typedef typename internal::kernel_retval_base<FullPivLU<MatrixType> >::ReturnType KernelMatrixType;
 | 
			
		||||
  typedef typename internal::image_retval_base<FullPivLU<MatrixType> >::ReturnType ImageMatrixType;
 | 
			
		||||
  typedef Matrix<typename MatrixType::Scalar, ColsAtCompileTime, ColsAtCompileTime>
 | 
			
		||||
          CMatrixType;
 | 
			
		||||
  typedef Matrix<typename MatrixType::Scalar, RowsAtCompileTime, RowsAtCompileTime>
 | 
			
		||||
          RMatrixType;
 | 
			
		||||
 | 
			
		||||
  Index rank = internal::random<Index>(1, (std::min)(rows, cols)-1);
 | 
			
		||||
 | 
			
		||||
  // The image of the zero matrix should consist of a single (zero) column vector
 | 
			
		||||
  VERIFY((MatrixType::Zero(rows,cols).fullPivLu().image(MatrixType::Zero(rows,cols)).cols() == 1));
 | 
			
		||||
 | 
			
		||||
  // The kernel of the zero matrix is the entire space, and thus is an invertible matrix of dimensions cols.
 | 
			
		||||
  KernelMatrixType kernel = MatrixType::Zero(rows,cols).fullPivLu().kernel();
 | 
			
		||||
  VERIFY((kernel.fullPivLu().isInvertible()));
 | 
			
		||||
 | 
			
		||||
  MatrixType m1(rows, cols), m3(rows, cols2);
 | 
			
		||||
  CMatrixType m2(cols, cols2);
 | 
			
		||||
  createRandomPIMatrixOfRank(rank, rows, cols, m1);
 | 
			
		||||
 | 
			
		||||
  FullPivLU<MatrixType> lu;
 | 
			
		||||
 | 
			
		||||
  // The special value 0.01 below works well in tests. Keep in mind that we're only computing the rank
 | 
			
		||||
  // of singular values are either 0 or 1.
 | 
			
		||||
  // So it's not clear at all that the epsilon should play any role there.
 | 
			
		||||
  lu.setThreshold(RealScalar(0.01));
 | 
			
		||||
  lu.compute(m1);
 | 
			
		||||
 | 
			
		||||
  MatrixType u(rows,cols);
 | 
			
		||||
  u = lu.matrixLU().template triangularView<Upper>();
 | 
			
		||||
  RMatrixType l = RMatrixType::Identity(rows,rows);
 | 
			
		||||
  l.block(0,0,rows,(std::min)(rows,cols)).template triangularView<StrictlyLower>()
 | 
			
		||||
    = lu.matrixLU().block(0,0,rows,(std::min)(rows,cols));
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(lu.permutationP() * m1 * lu.permutationQ(), l*u);
 | 
			
		||||
 | 
			
		||||
  KernelMatrixType m1kernel = lu.kernel();
 | 
			
		||||
  ImageMatrixType m1image = lu.image(m1);
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(m1, lu.reconstructedMatrix());
 | 
			
		||||
  VERIFY(rank == lu.rank());
 | 
			
		||||
  VERIFY(cols - lu.rank() == lu.dimensionOfKernel());
 | 
			
		||||
  VERIFY(!lu.isInjective());
 | 
			
		||||
  VERIFY(!lu.isInvertible());
 | 
			
		||||
  VERIFY(!lu.isSurjective());
 | 
			
		||||
  VERIFY_IS_MUCH_SMALLER_THAN((m1 * m1kernel), m1);
 | 
			
		||||
  VERIFY(m1image.fullPivLu().rank() == rank);
 | 
			
		||||
  VERIFY_IS_APPROX(m1 * m1.adjoint() * m1image, m1image);
 | 
			
		||||
 | 
			
		||||
  m2 = CMatrixType::Random(cols,cols2);
 | 
			
		||||
  m3 = m1*m2;
 | 
			
		||||
  m2 = CMatrixType::Random(cols,cols2);
 | 
			
		||||
  // test that the code, which does resize(), may be applied to an xpr
 | 
			
		||||
  m2.block(0,0,m2.rows(),m2.cols()) = lu.solve(m3);
 | 
			
		||||
  VERIFY_IS_APPROX(m3, m1*m2);
 | 
			
		||||
 | 
			
		||||
  // test solve with transposed
 | 
			
		||||
  m3 = MatrixType::Random(rows,cols2);
 | 
			
		||||
  m2 = m1.transpose()*m3;
 | 
			
		||||
  m3 = MatrixType::Random(rows,cols2);
 | 
			
		||||
  lu.template _solve_impl_transposed<false>(m2, m3);
 | 
			
		||||
  VERIFY_IS_APPROX(m2, m1.transpose()*m3);
 | 
			
		||||
  m3 = MatrixType::Random(rows,cols2);
 | 
			
		||||
  m3 = lu.transpose().solve(m2);
 | 
			
		||||
  VERIFY_IS_APPROX(m2, m1.transpose()*m3);
 | 
			
		||||
 | 
			
		||||
  // test solve with conjugate transposed
 | 
			
		||||
  m3 = MatrixType::Random(rows,cols2);
 | 
			
		||||
  m2 = m1.adjoint()*m3;
 | 
			
		||||
  m3 = MatrixType::Random(rows,cols2);
 | 
			
		||||
  lu.template _solve_impl_transposed<true>(m2, m3);
 | 
			
		||||
  VERIFY_IS_APPROX(m2, m1.adjoint()*m3);
 | 
			
		||||
  m3 = MatrixType::Random(rows,cols2);
 | 
			
		||||
  m3 = lu.adjoint().solve(m2);
 | 
			
		||||
  VERIFY_IS_APPROX(m2, m1.adjoint()*m3);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void lu_invertible()
 | 
			
		||||
{
 | 
			
		||||
  /* this test covers the following files:
 | 
			
		||||
     LU.h
 | 
			
		||||
  */
 | 
			
		||||
  typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
 | 
			
		||||
  Index size = MatrixType::RowsAtCompileTime;
 | 
			
		||||
  if( size==Dynamic)
 | 
			
		||||
    size = internal::random<Index>(1,EIGEN_TEST_MAX_SIZE);
 | 
			
		||||
 | 
			
		||||
  MatrixType m1(size, size), m2(size, size), m3(size, size);
 | 
			
		||||
  FullPivLU<MatrixType> lu;
 | 
			
		||||
  lu.setThreshold(RealScalar(0.01));
 | 
			
		||||
  do {
 | 
			
		||||
    m1 = MatrixType::Random(size,size);
 | 
			
		||||
    lu.compute(m1);
 | 
			
		||||
  } while(!lu.isInvertible());
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(m1, lu.reconstructedMatrix());
 | 
			
		||||
  VERIFY(0 == lu.dimensionOfKernel());
 | 
			
		||||
  VERIFY(lu.kernel().cols() == 1); // the kernel() should consist of a single (zero) column vector
 | 
			
		||||
  VERIFY(size == lu.rank());
 | 
			
		||||
  VERIFY(lu.isInjective());
 | 
			
		||||
  VERIFY(lu.isSurjective());
 | 
			
		||||
  VERIFY(lu.isInvertible());
 | 
			
		||||
  VERIFY(lu.image(m1).fullPivLu().isInvertible());
 | 
			
		||||
  m3 = MatrixType::Random(size,size);
 | 
			
		||||
  m2 = lu.solve(m3);
 | 
			
		||||
  VERIFY_IS_APPROX(m3, m1*m2);
 | 
			
		||||
  MatrixType m1_inverse = lu.inverse();
 | 
			
		||||
  VERIFY_IS_APPROX(m2, m1_inverse*m3);
 | 
			
		||||
 | 
			
		||||
  RealScalar rcond = (RealScalar(1) / matrix_l1_norm(m1)) / matrix_l1_norm(m1_inverse);
 | 
			
		||||
  const RealScalar rcond_est = lu.rcond();
 | 
			
		||||
  // Verify that the estimated condition number is within a factor of 10 of the
 | 
			
		||||
  // truth.
 | 
			
		||||
  VERIFY(rcond_est > rcond / 10 && rcond_est < rcond * 10);
 | 
			
		||||
 | 
			
		||||
  // test solve with transposed
 | 
			
		||||
  lu.template _solve_impl_transposed<false>(m3, m2);
 | 
			
		||||
  VERIFY_IS_APPROX(m3, m1.transpose()*m2);
 | 
			
		||||
  m3 = MatrixType::Random(size,size);
 | 
			
		||||
  m3 = lu.transpose().solve(m2);
 | 
			
		||||
  VERIFY_IS_APPROX(m2, m1.transpose()*m3);
 | 
			
		||||
 | 
			
		||||
  // test solve with conjugate transposed
 | 
			
		||||
  lu.template _solve_impl_transposed<true>(m3, m2);
 | 
			
		||||
  VERIFY_IS_APPROX(m3, m1.adjoint()*m2);
 | 
			
		||||
  m3 = MatrixType::Random(size,size);
 | 
			
		||||
  m3 = lu.adjoint().solve(m2);
 | 
			
		||||
  VERIFY_IS_APPROX(m2, m1.adjoint()*m3);
 | 
			
		||||
 | 
			
		||||
  // Regression test for Bug 302
 | 
			
		||||
  MatrixType m4 = MatrixType::Random(size,size);
 | 
			
		||||
  VERIFY_IS_APPROX(lu.solve(m3*m4), lu.solve(m3)*m4);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void lu_partial_piv()
 | 
			
		||||
{
 | 
			
		||||
  /* this test covers the following files:
 | 
			
		||||
     PartialPivLU.h
 | 
			
		||||
  */
 | 
			
		||||
  typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
 | 
			
		||||
  Index size = internal::random<Index>(1,4);
 | 
			
		||||
 | 
			
		||||
  MatrixType m1(size, size), m2(size, size), m3(size, size);
 | 
			
		||||
  m1.setRandom();
 | 
			
		||||
  PartialPivLU<MatrixType> plu(m1);
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(m1, plu.reconstructedMatrix());
 | 
			
		||||
 | 
			
		||||
  m3 = MatrixType::Random(size,size);
 | 
			
		||||
  m2 = plu.solve(m3);
 | 
			
		||||
  VERIFY_IS_APPROX(m3, m1*m2);
 | 
			
		||||
  MatrixType m1_inverse = plu.inverse();
 | 
			
		||||
  VERIFY_IS_APPROX(m2, m1_inverse*m3);
 | 
			
		||||
 | 
			
		||||
  RealScalar rcond = (RealScalar(1) / matrix_l1_norm(m1)) / matrix_l1_norm(m1_inverse);
 | 
			
		||||
  const RealScalar rcond_est = plu.rcond();
 | 
			
		||||
  // Verify that the estimate is within a factor of 10 of the truth.
 | 
			
		||||
  VERIFY(rcond_est > rcond / 10 && rcond_est < rcond * 10);
 | 
			
		||||
 | 
			
		||||
  // test solve with transposed
 | 
			
		||||
  plu.template _solve_impl_transposed<false>(m3, m2);
 | 
			
		||||
  VERIFY_IS_APPROX(m3, m1.transpose()*m2);
 | 
			
		||||
  m3 = MatrixType::Random(size,size);
 | 
			
		||||
  m3 = plu.transpose().solve(m2);
 | 
			
		||||
  VERIFY_IS_APPROX(m2, m1.transpose()*m3);
 | 
			
		||||
 | 
			
		||||
  // test solve with conjugate transposed
 | 
			
		||||
  plu.template _solve_impl_transposed<true>(m3, m2);
 | 
			
		||||
  VERIFY_IS_APPROX(m3, m1.adjoint()*m2);
 | 
			
		||||
  m3 = MatrixType::Random(size,size);
 | 
			
		||||
  m3 = plu.adjoint().solve(m2);
 | 
			
		||||
  VERIFY_IS_APPROX(m2, m1.adjoint()*m3);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void lu_verify_assert()
 | 
			
		||||
{
 | 
			
		||||
  MatrixType tmp;
 | 
			
		||||
 | 
			
		||||
  FullPivLU<MatrixType> lu;
 | 
			
		||||
  VERIFY_RAISES_ASSERT(lu.matrixLU())
 | 
			
		||||
  VERIFY_RAISES_ASSERT(lu.permutationP())
 | 
			
		||||
  VERIFY_RAISES_ASSERT(lu.permutationQ())
 | 
			
		||||
  VERIFY_RAISES_ASSERT(lu.kernel())
 | 
			
		||||
  VERIFY_RAISES_ASSERT(lu.image(tmp))
 | 
			
		||||
  VERIFY_RAISES_ASSERT(lu.solve(tmp))
 | 
			
		||||
  VERIFY_RAISES_ASSERT(lu.determinant())
 | 
			
		||||
  VERIFY_RAISES_ASSERT(lu.rank())
 | 
			
		||||
  VERIFY_RAISES_ASSERT(lu.dimensionOfKernel())
 | 
			
		||||
  VERIFY_RAISES_ASSERT(lu.isInjective())
 | 
			
		||||
  VERIFY_RAISES_ASSERT(lu.isSurjective())
 | 
			
		||||
  VERIFY_RAISES_ASSERT(lu.isInvertible())
 | 
			
		||||
  VERIFY_RAISES_ASSERT(lu.inverse())
 | 
			
		||||
 | 
			
		||||
  PartialPivLU<MatrixType> plu;
 | 
			
		||||
  VERIFY_RAISES_ASSERT(plu.matrixLU())
 | 
			
		||||
  VERIFY_RAISES_ASSERT(plu.permutationP())
 | 
			
		||||
  VERIFY_RAISES_ASSERT(plu.solve(tmp))
 | 
			
		||||
  VERIFY_RAISES_ASSERT(plu.determinant())
 | 
			
		||||
  VERIFY_RAISES_ASSERT(plu.inverse())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_lu()
 | 
			
		||||
{
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_1( lu_non_invertible<Matrix3f>() );
 | 
			
		||||
    CALL_SUBTEST_1( lu_invertible<Matrix3f>() );
 | 
			
		||||
    CALL_SUBTEST_1( lu_verify_assert<Matrix3f>() );
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_2( (lu_non_invertible<Matrix<double, 4, 6> >()) );
 | 
			
		||||
    CALL_SUBTEST_2( (lu_verify_assert<Matrix<double, 4, 6> >()) );
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_3( lu_non_invertible<MatrixXf>() );
 | 
			
		||||
    CALL_SUBTEST_3( lu_invertible<MatrixXf>() );
 | 
			
		||||
    CALL_SUBTEST_3( lu_verify_assert<MatrixXf>() );
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_4( lu_non_invertible<MatrixXd>() );
 | 
			
		||||
    CALL_SUBTEST_4( lu_invertible<MatrixXd>() );
 | 
			
		||||
    CALL_SUBTEST_4( lu_partial_piv<MatrixXd>() );
 | 
			
		||||
    CALL_SUBTEST_4( lu_verify_assert<MatrixXd>() );
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_5( lu_non_invertible<MatrixXcf>() );
 | 
			
		||||
    CALL_SUBTEST_5( lu_invertible<MatrixXcf>() );
 | 
			
		||||
    CALL_SUBTEST_5( lu_verify_assert<MatrixXcf>() );
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_6( lu_non_invertible<MatrixXcd>() );
 | 
			
		||||
    CALL_SUBTEST_6( lu_invertible<MatrixXcd>() );
 | 
			
		||||
    CALL_SUBTEST_6( lu_partial_piv<MatrixXcd>() );
 | 
			
		||||
    CALL_SUBTEST_6( lu_verify_assert<MatrixXcd>() );
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_7(( lu_non_invertible<Matrix<float,Dynamic,16> >() ));
 | 
			
		||||
 | 
			
		||||
    // Test problem size constructors
 | 
			
		||||
    CALL_SUBTEST_9( PartialPivLU<MatrixXf>(10) );
 | 
			
		||||
    CALL_SUBTEST_9( FullPivLU<MatrixXf>(10, 20); );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										808
									
								
								cs440-acg/ext/eigen/test/main.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										808
									
								
								cs440-acg/ext/eigen/test/main.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,808 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
 | 
			
		||||
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include <cstdlib>
 | 
			
		||||
#include <cerrno>
 | 
			
		||||
#include <ctime>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <fstream>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <sstream>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <typeinfo>
 | 
			
		||||
 | 
			
		||||
// The following includes of STL headers have to be done _before_ the
 | 
			
		||||
// definition of macros min() and max().  The reason is that many STL
 | 
			
		||||
// implementations will not work properly as the min and max symbols collide
 | 
			
		||||
// with the STL functions std:min() and std::max().  The STL headers may check
 | 
			
		||||
// for the macro definition of min/max and issue a warning or undefine the
 | 
			
		||||
// macros.
 | 
			
		||||
//
 | 
			
		||||
// Still, Windows defines min() and max() in windef.h as part of the regular
 | 
			
		||||
// Windows system interfaces and many other Windows APIs depend on these
 | 
			
		||||
// macros being available.  To prevent the macro expansion of min/max and to
 | 
			
		||||
// make Eigen compatible with the Windows environment all function calls of
 | 
			
		||||
// std::min() and std::max() have to be written with parenthesis around the
 | 
			
		||||
// function name.
 | 
			
		||||
//
 | 
			
		||||
// All STL headers used by Eigen should be included here.  Because main.h is
 | 
			
		||||
// included before any Eigen header and because the STL headers are guarded
 | 
			
		||||
// against multiple inclusions, no STL header will see our own min/max macro
 | 
			
		||||
// definitions.
 | 
			
		||||
#include <limits>
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <complex>
 | 
			
		||||
#include <deque>
 | 
			
		||||
#include <queue>
 | 
			
		||||
#include <cassert>
 | 
			
		||||
#include <list>
 | 
			
		||||
#if __cplusplus >= 201103L
 | 
			
		||||
#include <random>
 | 
			
		||||
#ifdef EIGEN_USE_THREADS
 | 
			
		||||
#include <future>
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Same for cuda_fp16.h
 | 
			
		||||
#if defined(__CUDACC_VER_MAJOR__) && (__CUDACC_VER_MAJOR__ >= 9)
 | 
			
		||||
#define EIGEN_TEST_CUDACC_VER  ((__CUDACC_VER_MAJOR__ * 10000) + (__CUDACC_VER_MINOR__ * 100))
 | 
			
		||||
#elif defined(__CUDACC_VER__)
 | 
			
		||||
#define EIGEN_TEST_CUDACC_VER __CUDACC_VER__
 | 
			
		||||
#else
 | 
			
		||||
#define EIGEN_TEST_CUDACC_VER 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if EIGEN_TEST_CUDACC_VER >= 70500
 | 
			
		||||
#include <cuda_fp16.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// To test that all calls from Eigen code to std::min() and std::max() are
 | 
			
		||||
// protected by parenthesis against macro expansion, the min()/max() macros
 | 
			
		||||
// are defined here and any not-parenthesized min/max call will cause a
 | 
			
		||||
// compiler error.
 | 
			
		||||
#define min(A,B) please_protect_your_min_with_parentheses
 | 
			
		||||
#define max(A,B) please_protect_your_max_with_parentheses
 | 
			
		||||
#define isnan(X) please_protect_your_isnan_with_parentheses
 | 
			
		||||
#define isinf(X) please_protect_your_isinf_with_parentheses
 | 
			
		||||
#define isfinite(X) please_protect_your_isfinite_with_parentheses
 | 
			
		||||
 | 
			
		||||
// test possible conflicts
 | 
			
		||||
struct real {};
 | 
			
		||||
struct imag {};
 | 
			
		||||
 | 
			
		||||
#ifdef M_PI
 | 
			
		||||
#undef M_PI
 | 
			
		||||
#endif
 | 
			
		||||
#define M_PI please_use_EIGEN_PI_instead_of_M_PI
 | 
			
		||||
 | 
			
		||||
#define FORBIDDEN_IDENTIFIER (this_identifier_is_forbidden_to_avoid_clashes) this_identifier_is_forbidden_to_avoid_clashes
 | 
			
		||||
// B0 is defined in POSIX header termios.h
 | 
			
		||||
#define B0 FORBIDDEN_IDENTIFIER
 | 
			
		||||
 | 
			
		||||
// Unit tests calling Eigen's blas library must preserve the default blocking size
 | 
			
		||||
// to avoid troubles.
 | 
			
		||||
#ifndef EIGEN_NO_DEBUG_SMALL_PRODUCT_BLOCKS
 | 
			
		||||
#define EIGEN_DEBUG_SMALL_PRODUCT_BLOCKS
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// shuts down ICC's remark #593: variable "XXX" was set but never used
 | 
			
		||||
#define TEST_SET_BUT_UNUSED_VARIABLE(X) EIGEN_UNUSED_VARIABLE(X)
 | 
			
		||||
 | 
			
		||||
#ifdef TEST_ENABLE_TEMPORARY_TRACKING
 | 
			
		||||
 | 
			
		||||
static long int nb_temporaries;
 | 
			
		||||
static long int nb_temporaries_on_assert = -1;
 | 
			
		||||
 | 
			
		||||
inline void on_temporary_creation(long int size) {
 | 
			
		||||
  // here's a great place to set a breakpoint when debugging failures in this test!
 | 
			
		||||
  if(size!=0) nb_temporaries++;
 | 
			
		||||
  if(nb_temporaries_on_assert>0) assert(nb_temporaries<nb_temporaries_on_assert);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define EIGEN_DENSE_STORAGE_CTOR_PLUGIN { on_temporary_creation(size); }
 | 
			
		||||
 | 
			
		||||
#define VERIFY_EVALUATION_COUNT(XPR,N) {\
 | 
			
		||||
    nb_temporaries = 0; \
 | 
			
		||||
    XPR; \
 | 
			
		||||
    if(nb_temporaries!=N) { std::cerr << "nb_temporaries == " << nb_temporaries << "\n"; }\
 | 
			
		||||
    VERIFY( (#XPR) && nb_temporaries==N ); \
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// the following file is automatically generated by cmake
 | 
			
		||||
#include "split_test_helper.h"
 | 
			
		||||
 | 
			
		||||
#ifdef NDEBUG
 | 
			
		||||
#undef NDEBUG
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// On windows CE, NDEBUG is automatically defined <assert.h> if NDEBUG is not defined.
 | 
			
		||||
#ifndef DEBUG
 | 
			
		||||
#define DEBUG
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// bounds integer values for AltiVec
 | 
			
		||||
#if defined(__ALTIVEC__) || defined(__VSX__)
 | 
			
		||||
#define EIGEN_MAKING_DOCS
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef EIGEN_TEST_FUNC
 | 
			
		||||
#error EIGEN_TEST_FUNC must be defined
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define DEFAULT_REPEAT 10
 | 
			
		||||
 | 
			
		||||
namespace Eigen
 | 
			
		||||
{
 | 
			
		||||
  static std::vector<std::string> g_test_stack;
 | 
			
		||||
  // level == 0 <=> abort if test fail
 | 
			
		||||
  // level >= 1 <=> warning message to std::cerr if test fail
 | 
			
		||||
  static int g_test_level = 0;
 | 
			
		||||
  static int g_repeat;
 | 
			
		||||
  static unsigned int g_seed;
 | 
			
		||||
  static bool g_has_set_repeat, g_has_set_seed;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define TRACK std::cerr << __FILE__ << " " << __LINE__ << std::endl
 | 
			
		||||
// #define TRACK while()
 | 
			
		||||
 | 
			
		||||
#define EI_PP_MAKE_STRING2(S) #S
 | 
			
		||||
#define EI_PP_MAKE_STRING(S) EI_PP_MAKE_STRING2(S)
 | 
			
		||||
 | 
			
		||||
#define EIGEN_DEFAULT_IO_FORMAT IOFormat(4, 0, "  ", "\n", "", "", "", "")
 | 
			
		||||
 | 
			
		||||
#if (defined(_CPPUNWIND) || defined(__EXCEPTIONS)) && !defined(__CUDA_ARCH__)
 | 
			
		||||
  #define EIGEN_EXCEPTIONS
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef EIGEN_NO_ASSERTION_CHECKING
 | 
			
		||||
 | 
			
		||||
  namespace Eigen
 | 
			
		||||
  {
 | 
			
		||||
    static const bool should_raise_an_assert = false;
 | 
			
		||||
 | 
			
		||||
    // Used to avoid to raise two exceptions at a time in which
 | 
			
		||||
    // case the exception is not properly caught.
 | 
			
		||||
    // This may happen when a second exceptions is triggered in a destructor.
 | 
			
		||||
    static bool no_more_assert = false;
 | 
			
		||||
    static bool report_on_cerr_on_assert_failure = true;
 | 
			
		||||
 | 
			
		||||
    struct eigen_assert_exception
 | 
			
		||||
    {
 | 
			
		||||
      eigen_assert_exception(void) {}
 | 
			
		||||
      ~eigen_assert_exception() { Eigen::no_more_assert = false; }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    struct eigen_static_assert_exception
 | 
			
		||||
    {
 | 
			
		||||
      eigen_static_assert_exception(void) {}
 | 
			
		||||
      ~eigen_static_assert_exception() { Eigen::no_more_assert = false; }
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
  // If EIGEN_DEBUG_ASSERTS is defined and if no assertion is triggered while
 | 
			
		||||
  // one should have been, then the list of excecuted assertions is printed out.
 | 
			
		||||
  //
 | 
			
		||||
  // EIGEN_DEBUG_ASSERTS is not enabled by default as it
 | 
			
		||||
  // significantly increases the compilation time
 | 
			
		||||
  // and might even introduce side effects that would hide
 | 
			
		||||
  // some memory errors.
 | 
			
		||||
  #ifdef EIGEN_DEBUG_ASSERTS
 | 
			
		||||
 | 
			
		||||
    namespace Eigen
 | 
			
		||||
    {
 | 
			
		||||
      namespace internal
 | 
			
		||||
      {
 | 
			
		||||
        static bool push_assert = false;
 | 
			
		||||
      }
 | 
			
		||||
      static std::vector<std::string> eigen_assert_list;
 | 
			
		||||
    }
 | 
			
		||||
    #define eigen_assert(a)                       \
 | 
			
		||||
      if( (!(a)) && (!no_more_assert) )     \
 | 
			
		||||
      { \
 | 
			
		||||
        if(report_on_cerr_on_assert_failure) \
 | 
			
		||||
          std::cerr <<  #a << " " __FILE__ << "(" << __LINE__ << ")\n"; \
 | 
			
		||||
        Eigen::no_more_assert = true;       \
 | 
			
		||||
        EIGEN_THROW_X(Eigen::eigen_assert_exception()); \
 | 
			
		||||
      }                                     \
 | 
			
		||||
      else if (Eigen::internal::push_assert)       \
 | 
			
		||||
      {                                     \
 | 
			
		||||
        eigen_assert_list.push_back(std::string(EI_PP_MAKE_STRING(__FILE__) " (" EI_PP_MAKE_STRING(__LINE__) ") : " #a) ); \
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    #ifdef EIGEN_EXCEPTIONS
 | 
			
		||||
    #define VERIFY_RAISES_ASSERT(a)                                                   \
 | 
			
		||||
      {                                                                               \
 | 
			
		||||
        Eigen::no_more_assert = false;                                                \
 | 
			
		||||
        Eigen::eigen_assert_list.clear();                                             \
 | 
			
		||||
        Eigen::internal::push_assert = true;                                          \
 | 
			
		||||
        Eigen::report_on_cerr_on_assert_failure = false;                              \
 | 
			
		||||
        try {                                                                         \
 | 
			
		||||
          a;                                                                          \
 | 
			
		||||
          std::cerr << "One of the following asserts should have been triggered:\n";  \
 | 
			
		||||
          for (uint ai=0 ; ai<eigen_assert_list.size() ; ++ai)                        \
 | 
			
		||||
            std::cerr << "  " << eigen_assert_list[ai] << "\n";                       \
 | 
			
		||||
          VERIFY(Eigen::should_raise_an_assert && # a);                               \
 | 
			
		||||
        } catch (Eigen::eigen_assert_exception) {                                     \
 | 
			
		||||
          Eigen::internal::push_assert = false; VERIFY(true);                         \
 | 
			
		||||
        }                                                                             \
 | 
			
		||||
        Eigen::report_on_cerr_on_assert_failure = true;                               \
 | 
			
		||||
        Eigen::internal::push_assert = false;                                         \
 | 
			
		||||
      }
 | 
			
		||||
    #endif //EIGEN_EXCEPTIONS
 | 
			
		||||
 | 
			
		||||
  #elif !defined(__CUDACC__) // EIGEN_DEBUG_ASSERTS
 | 
			
		||||
    // see bug 89. The copy_bool here is working around a bug in gcc <= 4.3
 | 
			
		||||
    #define eigen_assert(a) \
 | 
			
		||||
      if( (!Eigen::internal::copy_bool(a)) && (!no_more_assert) )\
 | 
			
		||||
      {                                       \
 | 
			
		||||
        Eigen::no_more_assert = true;         \
 | 
			
		||||
        if(report_on_cerr_on_assert_failure)  \
 | 
			
		||||
          eigen_plain_assert(a);              \
 | 
			
		||||
        else                                  \
 | 
			
		||||
          EIGEN_THROW_X(Eigen::eigen_assert_exception()); \
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    #ifdef EIGEN_EXCEPTIONS
 | 
			
		||||
      #define VERIFY_RAISES_ASSERT(a) {                           \
 | 
			
		||||
        Eigen::no_more_assert = false;                            \
 | 
			
		||||
        Eigen::report_on_cerr_on_assert_failure = false;          \
 | 
			
		||||
        try {                                                     \
 | 
			
		||||
          a;                                                      \
 | 
			
		||||
          VERIFY(Eigen::should_raise_an_assert && # a);           \
 | 
			
		||||
        }                                                         \
 | 
			
		||||
        catch (Eigen::eigen_assert_exception&) { VERIFY(true); }  \
 | 
			
		||||
        Eigen::report_on_cerr_on_assert_failure = true;           \
 | 
			
		||||
      }
 | 
			
		||||
    #endif // EIGEN_EXCEPTIONS
 | 
			
		||||
  #endif // EIGEN_DEBUG_ASSERTS
 | 
			
		||||
 | 
			
		||||
  #if defined(TEST_CHECK_STATIC_ASSERTIONS) && defined(EIGEN_EXCEPTIONS)
 | 
			
		||||
    #define EIGEN_STATIC_ASSERT(a,MSG) \
 | 
			
		||||
      if( (!Eigen::internal::copy_bool(a)) && (!no_more_assert) )\
 | 
			
		||||
      {                                       \
 | 
			
		||||
        Eigen::no_more_assert = true;         \
 | 
			
		||||
        if(report_on_cerr_on_assert_failure)  \
 | 
			
		||||
          eigen_plain_assert((a) && #MSG);      \
 | 
			
		||||
        else                                  \
 | 
			
		||||
          EIGEN_THROW_X(Eigen::eigen_static_assert_exception()); \
 | 
			
		||||
      }
 | 
			
		||||
    #define VERIFY_RAISES_STATIC_ASSERT(a) {                    \
 | 
			
		||||
      Eigen::no_more_assert = false;                            \
 | 
			
		||||
      Eigen::report_on_cerr_on_assert_failure = false;          \
 | 
			
		||||
      try {                                                     \
 | 
			
		||||
        a;                                                      \
 | 
			
		||||
        VERIFY(Eigen::should_raise_an_assert && # a);           \
 | 
			
		||||
      }                                                         \
 | 
			
		||||
      catch (Eigen::eigen_static_assert_exception&) { VERIFY(true); }  \
 | 
			
		||||
      Eigen::report_on_cerr_on_assert_failure = true;           \
 | 
			
		||||
    }
 | 
			
		||||
  #endif // TEST_CHECK_STATIC_ASSERTIONS
 | 
			
		||||
 | 
			
		||||
#ifndef VERIFY_RAISES_ASSERT
 | 
			
		||||
  #define VERIFY_RAISES_ASSERT(a) \
 | 
			
		||||
    std::cout << "Can't VERIFY_RAISES_ASSERT( " #a " ) with exceptions disabled\n";
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef VERIFY_RAISES_STATIC_ASSERT
 | 
			
		||||
  #define VERIFY_RAISES_STATIC_ASSERT(a) \
 | 
			
		||||
    std::cout << "Can't VERIFY_RAISES_STATIC_ASSERT( " #a " ) with exceptions disabled\n";
 | 
			
		||||
#endif
 | 
			
		||||
    
 | 
			
		||||
  #if !defined(__CUDACC__)
 | 
			
		||||
  #define EIGEN_USE_CUSTOM_ASSERT
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
#else // EIGEN_NO_ASSERTION_CHECKING
 | 
			
		||||
 | 
			
		||||
  #define VERIFY_RAISES_ASSERT(a) {}
 | 
			
		||||
  #define VERIFY_RAISES_STATIC_ASSERT(a) {}
 | 
			
		||||
 | 
			
		||||
#endif // EIGEN_NO_ASSERTION_CHECKING
 | 
			
		||||
 | 
			
		||||
#define EIGEN_INTERNAL_DEBUGGING
 | 
			
		||||
#include <Eigen/QR> // required for createRandomPIMatrixOfRank
 | 
			
		||||
 | 
			
		||||
inline void verify_impl(bool condition, const char *testname, const char *file, int line, const char *condition_as_string)
 | 
			
		||||
{
 | 
			
		||||
  if (!condition)
 | 
			
		||||
  {
 | 
			
		||||
    if(Eigen::g_test_level>0)
 | 
			
		||||
      std::cerr << "WARNING: ";
 | 
			
		||||
    std::cerr << "Test " << testname << " failed in " << file << " (" << line << ")"
 | 
			
		||||
      << std::endl << "    " << condition_as_string << std::endl;
 | 
			
		||||
    std::cerr << "Stack:\n";
 | 
			
		||||
    const int test_stack_size = static_cast<int>(Eigen::g_test_stack.size());
 | 
			
		||||
    for(int i=test_stack_size-1; i>=0; --i)
 | 
			
		||||
      std::cerr << "  - " << Eigen::g_test_stack[i] << "\n";
 | 
			
		||||
    std::cerr << "\n";
 | 
			
		||||
    if(Eigen::g_test_level==0)
 | 
			
		||||
      abort();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define VERIFY(a) ::verify_impl(a, g_test_stack.back().c_str(), __FILE__, __LINE__, EI_PP_MAKE_STRING(a))
 | 
			
		||||
 | 
			
		||||
#define VERIFY_GE(a, b) ::verify_impl(a >= b, g_test_stack.back().c_str(), __FILE__, __LINE__, EI_PP_MAKE_STRING(a >= b))
 | 
			
		||||
#define VERIFY_LE(a, b) ::verify_impl(a <= b, g_test_stack.back().c_str(), __FILE__, __LINE__, EI_PP_MAKE_STRING(a <= b))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define VERIFY_IS_EQUAL(a, b) VERIFY(test_is_equal(a, b, true))
 | 
			
		||||
#define VERIFY_IS_NOT_EQUAL(a, b) VERIFY(test_is_equal(a, b, false))
 | 
			
		||||
#define VERIFY_IS_APPROX(a, b) VERIFY(verifyIsApprox(a, b))
 | 
			
		||||
#define VERIFY_IS_NOT_APPROX(a, b) VERIFY(!test_isApprox(a, b))
 | 
			
		||||
#define VERIFY_IS_MUCH_SMALLER_THAN(a, b) VERIFY(test_isMuchSmallerThan(a, b))
 | 
			
		||||
#define VERIFY_IS_NOT_MUCH_SMALLER_THAN(a, b) VERIFY(!test_isMuchSmallerThan(a, b))
 | 
			
		||||
#define VERIFY_IS_APPROX_OR_LESS_THAN(a, b) VERIFY(test_isApproxOrLessThan(a, b))
 | 
			
		||||
#define VERIFY_IS_NOT_APPROX_OR_LESS_THAN(a, b) VERIFY(!test_isApproxOrLessThan(a, b))
 | 
			
		||||
 | 
			
		||||
#define VERIFY_IS_UNITARY(a) VERIFY(test_isUnitary(a))
 | 
			
		||||
 | 
			
		||||
#define CALL_SUBTEST(FUNC) do { \
 | 
			
		||||
    g_test_stack.push_back(EI_PP_MAKE_STRING(FUNC)); \
 | 
			
		||||
    FUNC; \
 | 
			
		||||
    g_test_stack.pop_back(); \
 | 
			
		||||
  } while (0)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
namespace Eigen {
 | 
			
		||||
 | 
			
		||||
template<typename T> inline typename NumTraits<T>::Real test_precision() { return NumTraits<T>::dummy_precision(); }
 | 
			
		||||
template<> inline float test_precision<float>() { return 1e-3f; }
 | 
			
		||||
template<> inline double test_precision<double>() { return 1e-6; }
 | 
			
		||||
template<> inline long double test_precision<long double>() { return 1e-6l; }
 | 
			
		||||
template<> inline float test_precision<std::complex<float> >() { return test_precision<float>(); }
 | 
			
		||||
template<> inline double test_precision<std::complex<double> >() { return test_precision<double>(); }
 | 
			
		||||
template<> inline long double test_precision<std::complex<long double> >() { return test_precision<long double>(); }
 | 
			
		||||
 | 
			
		||||
inline bool test_isApprox(const short& a, const short& b)
 | 
			
		||||
{ return internal::isApprox(a, b, test_precision<short>()); }
 | 
			
		||||
inline bool test_isApprox(const unsigned short& a, const unsigned short& b)
 | 
			
		||||
{ return internal::isApprox(a, b, test_precision<unsigned short>()); }
 | 
			
		||||
inline bool test_isApprox(const unsigned int& a, const unsigned int& b)
 | 
			
		||||
{ return internal::isApprox(a, b, test_precision<unsigned int>()); }
 | 
			
		||||
inline bool test_isApprox(const long& a, const long& b)
 | 
			
		||||
{ return internal::isApprox(a, b, test_precision<long>()); }
 | 
			
		||||
inline bool test_isApprox(const unsigned long& a, const unsigned long& b)
 | 
			
		||||
{ return internal::isApprox(a, b, test_precision<unsigned long>()); }
 | 
			
		||||
 | 
			
		||||
inline bool test_isApprox(const int& a, const int& b)
 | 
			
		||||
{ return internal::isApprox(a, b, test_precision<int>()); }
 | 
			
		||||
inline bool test_isMuchSmallerThan(const int& a, const int& b)
 | 
			
		||||
{ return internal::isMuchSmallerThan(a, b, test_precision<int>()); }
 | 
			
		||||
inline bool test_isApproxOrLessThan(const int& a, const int& b)
 | 
			
		||||
{ return internal::isApproxOrLessThan(a, b, test_precision<int>()); }
 | 
			
		||||
 | 
			
		||||
inline bool test_isApprox(const float& a, const float& b)
 | 
			
		||||
{ return internal::isApprox(a, b, test_precision<float>()); }
 | 
			
		||||
inline bool test_isMuchSmallerThan(const float& a, const float& b)
 | 
			
		||||
{ return internal::isMuchSmallerThan(a, b, test_precision<float>()); }
 | 
			
		||||
inline bool test_isApproxOrLessThan(const float& a, const float& b)
 | 
			
		||||
{ return internal::isApproxOrLessThan(a, b, test_precision<float>()); }
 | 
			
		||||
 | 
			
		||||
inline bool test_isApprox(const double& a, const double& b)
 | 
			
		||||
{ return internal::isApprox(a, b, test_precision<double>()); }
 | 
			
		||||
inline bool test_isMuchSmallerThan(const double& a, const double& b)
 | 
			
		||||
{ return internal::isMuchSmallerThan(a, b, test_precision<double>()); }
 | 
			
		||||
inline bool test_isApproxOrLessThan(const double& a, const double& b)
 | 
			
		||||
{ return internal::isApproxOrLessThan(a, b, test_precision<double>()); }
 | 
			
		||||
 | 
			
		||||
#ifndef EIGEN_TEST_NO_COMPLEX
 | 
			
		||||
inline bool test_isApprox(const std::complex<float>& a, const std::complex<float>& b)
 | 
			
		||||
{ return internal::isApprox(a, b, test_precision<std::complex<float> >()); }
 | 
			
		||||
inline bool test_isMuchSmallerThan(const std::complex<float>& a, const std::complex<float>& b)
 | 
			
		||||
{ return internal::isMuchSmallerThan(a, b, test_precision<std::complex<float> >()); }
 | 
			
		||||
 | 
			
		||||
inline bool test_isApprox(const std::complex<double>& a, const std::complex<double>& b)
 | 
			
		||||
{ return internal::isApprox(a, b, test_precision<std::complex<double> >()); }
 | 
			
		||||
inline bool test_isMuchSmallerThan(const std::complex<double>& a, const std::complex<double>& b)
 | 
			
		||||
{ return internal::isMuchSmallerThan(a, b, test_precision<std::complex<double> >()); }
 | 
			
		||||
 | 
			
		||||
#ifndef EIGEN_TEST_NO_LONGDOUBLE
 | 
			
		||||
inline bool test_isApprox(const std::complex<long double>& a, const std::complex<long double>& b)
 | 
			
		||||
{ return internal::isApprox(a, b, test_precision<std::complex<long double> >()); }
 | 
			
		||||
inline bool test_isMuchSmallerThan(const std::complex<long double>& a, const std::complex<long double>& b)
 | 
			
		||||
{ return internal::isMuchSmallerThan(a, b, test_precision<std::complex<long double> >()); }
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef EIGEN_TEST_NO_LONGDOUBLE
 | 
			
		||||
inline bool test_isApprox(const long double& a, const long double& b)
 | 
			
		||||
{
 | 
			
		||||
    bool ret = internal::isApprox(a, b, test_precision<long double>());
 | 
			
		||||
    if (!ret) std::cerr
 | 
			
		||||
        << std::endl << "    actual   = " << a
 | 
			
		||||
        << std::endl << "    expected = " << b << std::endl << std::endl;
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool test_isMuchSmallerThan(const long double& a, const long double& b)
 | 
			
		||||
{ return internal::isMuchSmallerThan(a, b, test_precision<long double>()); }
 | 
			
		||||
inline bool test_isApproxOrLessThan(const long double& a, const long double& b)
 | 
			
		||||
{ return internal::isApproxOrLessThan(a, b, test_precision<long double>()); }
 | 
			
		||||
#endif // EIGEN_TEST_NO_LONGDOUBLE
 | 
			
		||||
 | 
			
		||||
inline bool test_isApprox(const half& a, const half& b)
 | 
			
		||||
{ return internal::isApprox(a, b, test_precision<half>()); }
 | 
			
		||||
inline bool test_isMuchSmallerThan(const half& a, const half& b)
 | 
			
		||||
{ return internal::isMuchSmallerThan(a, b, test_precision<half>()); }
 | 
			
		||||
inline bool test_isApproxOrLessThan(const half& a, const half& b)
 | 
			
		||||
{ return internal::isApproxOrLessThan(a, b, test_precision<half>()); }
 | 
			
		||||
 | 
			
		||||
// test_relative_error returns the relative difference between a and b as a real scalar as used in isApprox.
 | 
			
		||||
template<typename T1,typename T2>
 | 
			
		||||
typename NumTraits<typename T1::RealScalar>::NonInteger test_relative_error(const EigenBase<T1> &a, const EigenBase<T2> &b)
 | 
			
		||||
{
 | 
			
		||||
  using std::sqrt;
 | 
			
		||||
  typedef typename NumTraits<typename T1::RealScalar>::NonInteger RealScalar;
 | 
			
		||||
  typename internal::nested_eval<T1,2>::type ea(a.derived());
 | 
			
		||||
  typename internal::nested_eval<T2,2>::type eb(b.derived());
 | 
			
		||||
  return sqrt(RealScalar((ea-eb).cwiseAbs2().sum()) / RealScalar((std::min)(eb.cwiseAbs2().sum(),ea.cwiseAbs2().sum())));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T1,typename T2>
 | 
			
		||||
typename T1::RealScalar test_relative_error(const T1 &a, const T2 &b, const typename T1::Coefficients* = 0)
 | 
			
		||||
{
 | 
			
		||||
  return test_relative_error(a.coeffs(), b.coeffs());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T1,typename T2>
 | 
			
		||||
typename T1::Scalar test_relative_error(const T1 &a, const T2 &b, const typename T1::MatrixType* = 0)
 | 
			
		||||
{
 | 
			
		||||
  return test_relative_error(a.matrix(), b.matrix());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename S, int D>
 | 
			
		||||
S test_relative_error(const Translation<S,D> &a, const Translation<S,D> &b)
 | 
			
		||||
{
 | 
			
		||||
  return test_relative_error(a.vector(), b.vector());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename S, int D, int O>
 | 
			
		||||
S test_relative_error(const ParametrizedLine<S,D,O> &a, const ParametrizedLine<S,D,O> &b)
 | 
			
		||||
{
 | 
			
		||||
  return (std::max)(test_relative_error(a.origin(), b.origin()), test_relative_error(a.origin(), b.origin()));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename S, int D>
 | 
			
		||||
S test_relative_error(const AlignedBox<S,D> &a, const AlignedBox<S,D> &b)
 | 
			
		||||
{
 | 
			
		||||
  return (std::max)(test_relative_error((a.min)(), (b.min)()), test_relative_error((a.max)(), (b.max)()));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Derived> class SparseMatrixBase;
 | 
			
		||||
template<typename T1,typename T2>
 | 
			
		||||
typename T1::RealScalar test_relative_error(const MatrixBase<T1> &a, const SparseMatrixBase<T2> &b)
 | 
			
		||||
{
 | 
			
		||||
  return test_relative_error(a,b.toDense());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Derived> class SparseMatrixBase;
 | 
			
		||||
template<typename T1,typename T2>
 | 
			
		||||
typename T1::RealScalar test_relative_error(const SparseMatrixBase<T1> &a, const MatrixBase<T2> &b)
 | 
			
		||||
{
 | 
			
		||||
  return test_relative_error(a.toDense(),b);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Derived> class SparseMatrixBase;
 | 
			
		||||
template<typename T1,typename T2>
 | 
			
		||||
typename T1::RealScalar test_relative_error(const SparseMatrixBase<T1> &a, const SparseMatrixBase<T2> &b)
 | 
			
		||||
{
 | 
			
		||||
  return test_relative_error(a.toDense(),b.toDense());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T1,typename T2>
 | 
			
		||||
typename NumTraits<typename NumTraits<T1>::Real>::NonInteger test_relative_error(const T1 &a, const T2 &b, typename internal::enable_if<internal::is_arithmetic<typename NumTraits<T1>::Real>::value, T1>::type* = 0)
 | 
			
		||||
{
 | 
			
		||||
  typedef typename NumTraits<typename NumTraits<T1>::Real>::NonInteger RealScalar;
 | 
			
		||||
  return numext::sqrt(RealScalar(numext::abs2(a-b))/RealScalar((numext::mini)(numext::abs2(a),numext::abs2(b))));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
T test_relative_error(const Rotation2D<T> &a, const Rotation2D<T> &b)
 | 
			
		||||
{
 | 
			
		||||
  return test_relative_error(a.angle(), b.angle());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
T test_relative_error(const AngleAxis<T> &a, const AngleAxis<T> &b)
 | 
			
		||||
{
 | 
			
		||||
  return (std::max)(test_relative_error(a.angle(), b.angle()), test_relative_error(a.axis(), b.axis()));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Type1, typename Type2>
 | 
			
		||||
inline bool test_isApprox(const Type1& a, const Type2& b, typename Type1::Scalar* = 0) // Enabled for Eigen's type only
 | 
			
		||||
{
 | 
			
		||||
  return a.isApprox(b, test_precision<typename Type1::Scalar>());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// get_test_precision is a small wrapper to test_precision allowing to return the scalar precision for either scalars or expressions
 | 
			
		||||
template<typename T>
 | 
			
		||||
typename NumTraits<typename T::Scalar>::Real get_test_precision(const T&, const typename T::Scalar* = 0)
 | 
			
		||||
{
 | 
			
		||||
  return test_precision<typename NumTraits<typename T::Scalar>::Real>();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
typename NumTraits<T>::Real get_test_precision(const T&,typename internal::enable_if<internal::is_arithmetic<typename NumTraits<T>::Real>::value, T>::type* = 0)
 | 
			
		||||
{
 | 
			
		||||
  return test_precision<typename NumTraits<T>::Real>();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// verifyIsApprox is a wrapper to test_isApprox that outputs the relative difference magnitude if the test fails.
 | 
			
		||||
template<typename Type1, typename Type2>
 | 
			
		||||
inline bool verifyIsApprox(const Type1& a, const Type2& b)
 | 
			
		||||
{
 | 
			
		||||
  bool ret = test_isApprox(a,b);
 | 
			
		||||
  if(!ret)
 | 
			
		||||
  {
 | 
			
		||||
    std::cerr << "Difference too large wrt tolerance " << get_test_precision(a)  << ", relative error is: " << test_relative_error(a,b) << std::endl;
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// The idea behind this function is to compare the two scalars a and b where
 | 
			
		||||
// the scalar ref is a hint about the expected order of magnitude of a and b.
 | 
			
		||||
// WARNING: the scalar a and b must be positive
 | 
			
		||||
// Therefore, if for some reason a and b are very small compared to ref,
 | 
			
		||||
// we won't issue a false negative.
 | 
			
		||||
// This test could be: abs(a-b) <= eps * ref
 | 
			
		||||
// However, it seems that simply comparing a+ref and b+ref is more sensitive to true error.
 | 
			
		||||
template<typename Scalar,typename ScalarRef>
 | 
			
		||||
inline bool test_isApproxWithRef(const Scalar& a, const Scalar& b, const ScalarRef& ref)
 | 
			
		||||
{
 | 
			
		||||
  return test_isApprox(a+ref, b+ref);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Derived1, typename Derived2>
 | 
			
		||||
inline bool test_isMuchSmallerThan(const MatrixBase<Derived1>& m1,
 | 
			
		||||
                                   const MatrixBase<Derived2>& m2)
 | 
			
		||||
{
 | 
			
		||||
  return m1.isMuchSmallerThan(m2, test_precision<typename internal::traits<Derived1>::Scalar>());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Derived>
 | 
			
		||||
inline bool test_isMuchSmallerThan(const MatrixBase<Derived>& m,
 | 
			
		||||
                                   const typename NumTraits<typename internal::traits<Derived>::Scalar>::Real& s)
 | 
			
		||||
{
 | 
			
		||||
  return m.isMuchSmallerThan(s, test_precision<typename internal::traits<Derived>::Scalar>());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Derived>
 | 
			
		||||
inline bool test_isUnitary(const MatrixBase<Derived>& m)
 | 
			
		||||
{
 | 
			
		||||
  return m.isUnitary(test_precision<typename internal::traits<Derived>::Scalar>());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Forward declaration to avoid ICC warning
 | 
			
		||||
template<typename T, typename U>
 | 
			
		||||
bool test_is_equal(const T& actual, const U& expected, bool expect_equal=true);
 | 
			
		||||
 | 
			
		||||
template<typename T, typename U>
 | 
			
		||||
bool test_is_equal(const T& actual, const U& expected, bool expect_equal)
 | 
			
		||||
{
 | 
			
		||||
    if ((actual==expected) == expect_equal)
 | 
			
		||||
        return true;
 | 
			
		||||
    // false:
 | 
			
		||||
    std::cerr
 | 
			
		||||
        << "\n    actual   = " << actual
 | 
			
		||||
        << "\n    expected " << (expect_equal ? "= " : "!=") << expected << "\n\n";
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Creates a random Partial Isometry matrix of given rank.
 | 
			
		||||
  *
 | 
			
		||||
  * A partial isometry is a matrix all of whose singular values are either 0 or 1.
 | 
			
		||||
  * This is very useful to test rank-revealing algorithms.
 | 
			
		||||
  */
 | 
			
		||||
// Forward declaration to avoid ICC warning
 | 
			
		||||
template<typename MatrixType>
 | 
			
		||||
void createRandomPIMatrixOfRank(Index desired_rank, Index rows, Index cols, MatrixType& m);
 | 
			
		||||
template<typename MatrixType>
 | 
			
		||||
void createRandomPIMatrixOfRank(Index desired_rank, Index rows, Index cols, MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  typedef typename internal::traits<MatrixType>::Scalar Scalar;
 | 
			
		||||
  enum { Rows = MatrixType::RowsAtCompileTime, Cols = MatrixType::ColsAtCompileTime };
 | 
			
		||||
 | 
			
		||||
  typedef Matrix<Scalar, Dynamic, 1> VectorType;
 | 
			
		||||
  typedef Matrix<Scalar, Rows, Rows> MatrixAType;
 | 
			
		||||
  typedef Matrix<Scalar, Cols, Cols> MatrixBType;
 | 
			
		||||
 | 
			
		||||
  if(desired_rank == 0)
 | 
			
		||||
  {
 | 
			
		||||
    m.setZero(rows,cols);
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(desired_rank == 1)
 | 
			
		||||
  {
 | 
			
		||||
    // here we normalize the vectors to get a partial isometry
 | 
			
		||||
    m = VectorType::Random(rows).normalized() * VectorType::Random(cols).normalized().transpose();
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  MatrixAType a = MatrixAType::Random(rows,rows);
 | 
			
		||||
  MatrixType d = MatrixType::Identity(rows,cols);
 | 
			
		||||
  MatrixBType  b = MatrixBType::Random(cols,cols);
 | 
			
		||||
 | 
			
		||||
  // set the diagonal such that only desired_rank non-zero entries reamain
 | 
			
		||||
  const Index diag_size = (std::min)(d.rows(),d.cols());
 | 
			
		||||
  if(diag_size != desired_rank)
 | 
			
		||||
    d.diagonal().segment(desired_rank, diag_size-desired_rank) = VectorType::Zero(diag_size-desired_rank);
 | 
			
		||||
 | 
			
		||||
  HouseholderQR<MatrixAType> qra(a);
 | 
			
		||||
  HouseholderQR<MatrixBType> qrb(b);
 | 
			
		||||
  m = qra.householderQ() * d * qrb.householderQ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Forward declaration to avoid ICC warning
 | 
			
		||||
template<typename PermutationVectorType>
 | 
			
		||||
void randomPermutationVector(PermutationVectorType& v, Index size);
 | 
			
		||||
template<typename PermutationVectorType>
 | 
			
		||||
void randomPermutationVector(PermutationVectorType& v, Index size)
 | 
			
		||||
{
 | 
			
		||||
  typedef typename PermutationVectorType::Scalar Scalar;
 | 
			
		||||
  v.resize(size);
 | 
			
		||||
  for(Index i = 0; i < size; ++i) v(i) = Scalar(i);
 | 
			
		||||
  if(size == 1) return;
 | 
			
		||||
  for(Index n = 0; n < 3 * size; ++n)
 | 
			
		||||
  {
 | 
			
		||||
    Index i = internal::random<Index>(0, size-1);
 | 
			
		||||
    Index j;
 | 
			
		||||
    do j = internal::random<Index>(0, size-1); while(j==i);
 | 
			
		||||
    std::swap(v(i), v(j));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T> bool isNotNaN(const T& x)
 | 
			
		||||
{
 | 
			
		||||
  return x==x;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T> bool isPlusInf(const T& x)
 | 
			
		||||
{
 | 
			
		||||
  return x > NumTraits<T>::highest();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T> bool isMinusInf(const T& x)
 | 
			
		||||
{
 | 
			
		||||
  return x < NumTraits<T>::lowest();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // end namespace Eigen
 | 
			
		||||
 | 
			
		||||
template<typename T> struct GetDifferentType;
 | 
			
		||||
 | 
			
		||||
template<> struct GetDifferentType<float> { typedef double type; };
 | 
			
		||||
template<> struct GetDifferentType<double> { typedef float type; };
 | 
			
		||||
template<typename T> struct GetDifferentType<std::complex<T> >
 | 
			
		||||
{ typedef std::complex<typename GetDifferentType<T>::type> type; };
 | 
			
		||||
 | 
			
		||||
// Forward declaration to avoid ICC warning
 | 
			
		||||
template<typename T> std::string type_name();
 | 
			
		||||
template<typename T> std::string type_name()                    { return "other"; }
 | 
			
		||||
template<> std::string type_name<float>()                       { return "float"; }
 | 
			
		||||
template<> std::string type_name<double>()                      { return "double"; }
 | 
			
		||||
template<> std::string type_name<long double>()                 { return "long double"; }
 | 
			
		||||
template<> std::string type_name<int>()                         { return "int"; }
 | 
			
		||||
template<> std::string type_name<std::complex<float> >()        { return "complex<float>"; }
 | 
			
		||||
template<> std::string type_name<std::complex<double> >()       { return "complex<double>"; }
 | 
			
		||||
template<> std::string type_name<std::complex<long double> >()  { return "complex<long double>"; }
 | 
			
		||||
template<> std::string type_name<std::complex<int> >()          { return "complex<int>"; }
 | 
			
		||||
 | 
			
		||||
// forward declaration of the main test function
 | 
			
		||||
void EIGEN_CAT(test_,EIGEN_TEST_FUNC)();
 | 
			
		||||
 | 
			
		||||
using namespace Eigen;
 | 
			
		||||
 | 
			
		||||
inline void set_repeat_from_string(const char *str)
 | 
			
		||||
{
 | 
			
		||||
  errno = 0;
 | 
			
		||||
  g_repeat = int(strtoul(str, 0, 10));
 | 
			
		||||
  if(errno || g_repeat <= 0)
 | 
			
		||||
  {
 | 
			
		||||
    std::cout << "Invalid repeat value " << str << std::endl;
 | 
			
		||||
    exit(EXIT_FAILURE);
 | 
			
		||||
  }
 | 
			
		||||
  g_has_set_repeat = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void set_seed_from_string(const char *str)
 | 
			
		||||
{
 | 
			
		||||
  errno = 0;
 | 
			
		||||
  g_seed = int(strtoul(str, 0, 10));
 | 
			
		||||
  if(errno || g_seed == 0)
 | 
			
		||||
  {
 | 
			
		||||
    std::cout << "Invalid seed value " << str << std::endl;
 | 
			
		||||
    exit(EXIT_FAILURE);
 | 
			
		||||
  }
 | 
			
		||||
  g_has_set_seed = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int main(int argc, char *argv[])
 | 
			
		||||
{
 | 
			
		||||
    g_has_set_repeat = false;
 | 
			
		||||
    g_has_set_seed = false;
 | 
			
		||||
    bool need_help = false;
 | 
			
		||||
 | 
			
		||||
    for(int i = 1; i < argc; i++)
 | 
			
		||||
    {
 | 
			
		||||
      if(argv[i][0] == 'r')
 | 
			
		||||
      {
 | 
			
		||||
        if(g_has_set_repeat)
 | 
			
		||||
        {
 | 
			
		||||
          std::cout << "Argument " << argv[i] << " conflicting with a former argument" << std::endl;
 | 
			
		||||
          return 1;
 | 
			
		||||
        }
 | 
			
		||||
        set_repeat_from_string(argv[i]+1);
 | 
			
		||||
      }
 | 
			
		||||
      else if(argv[i][0] == 's')
 | 
			
		||||
      {
 | 
			
		||||
        if(g_has_set_seed)
 | 
			
		||||
        {
 | 
			
		||||
          std::cout << "Argument " << argv[i] << " conflicting with a former argument" << std::endl;
 | 
			
		||||
          return 1;
 | 
			
		||||
        }
 | 
			
		||||
         set_seed_from_string(argv[i]+1);
 | 
			
		||||
      }
 | 
			
		||||
      else
 | 
			
		||||
      {
 | 
			
		||||
        need_help = true;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(need_help)
 | 
			
		||||
    {
 | 
			
		||||
      std::cout << "This test application takes the following optional arguments:" << std::endl;
 | 
			
		||||
      std::cout << "  rN     Repeat each test N times (default: " << DEFAULT_REPEAT << ")" << std::endl;
 | 
			
		||||
      std::cout << "  sN     Use N as seed for random numbers (default: based on current time)" << std::endl;
 | 
			
		||||
      std::cout << std::endl;
 | 
			
		||||
      std::cout << "If defined, the environment variables EIGEN_REPEAT and EIGEN_SEED" << std::endl;
 | 
			
		||||
      std::cout << "will be used as default values for these parameters." << std::endl;
 | 
			
		||||
      return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    char *env_EIGEN_REPEAT = getenv("EIGEN_REPEAT");
 | 
			
		||||
    if(!g_has_set_repeat && env_EIGEN_REPEAT)
 | 
			
		||||
      set_repeat_from_string(env_EIGEN_REPEAT);
 | 
			
		||||
    char *env_EIGEN_SEED = getenv("EIGEN_SEED");
 | 
			
		||||
    if(!g_has_set_seed && env_EIGEN_SEED)
 | 
			
		||||
      set_seed_from_string(env_EIGEN_SEED);
 | 
			
		||||
 | 
			
		||||
    if(!g_has_set_seed) g_seed = (unsigned int) time(NULL);
 | 
			
		||||
    if(!g_has_set_repeat) g_repeat = DEFAULT_REPEAT;
 | 
			
		||||
 | 
			
		||||
    std::cout << "Initializing random number generator with seed " << g_seed << std::endl;
 | 
			
		||||
    std::stringstream ss;
 | 
			
		||||
    ss << "Seed: " << g_seed;
 | 
			
		||||
    g_test_stack.push_back(ss.str());
 | 
			
		||||
    srand(g_seed);
 | 
			
		||||
    std::cout << "Repeating each test " << g_repeat << " times" << std::endl;
 | 
			
		||||
 | 
			
		||||
    Eigen::g_test_stack.push_back(std::string(EI_PP_MAKE_STRING(EIGEN_TEST_FUNC)));
 | 
			
		||||
 | 
			
		||||
    EIGEN_CAT(test_,EIGEN_TEST_FUNC)();
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// These warning are disabled here such that they are still ON when parsing Eigen's header files.
 | 
			
		||||
#if defined __INTEL_COMPILER
 | 
			
		||||
  // remark #383: value copied to temporary, reference to temporary used
 | 
			
		||||
  //  -> this warning is raised even for legal usage as: g_test_stack.push_back("foo"); where g_test_stack is a std::vector<std::string>
 | 
			
		||||
  // remark #1418: external function definition with no prior declaration
 | 
			
		||||
  //  -> this warning is raised for all our test functions. Declaring them static would fix the issue.
 | 
			
		||||
  // warning #279: controlling expression is constant
 | 
			
		||||
  // remark #1572: floating-point equality and inequality comparisons are unreliable
 | 
			
		||||
  #pragma warning disable 279 383 1418 1572
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef _MSC_VER
 | 
			
		||||
  // 4503 - decorated name length exceeded, name was truncated
 | 
			
		||||
  #pragma warning( disable : 4503)
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										208
									
								
								cs440-acg/ext/eigen/test/mapped_matrix.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										208
									
								
								cs440-acg/ext/eigen/test/mapped_matrix.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,208 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. 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_NO_STATIC_ASSERT
 | 
			
		||||
#define EIGEN_NO_STATIC_ASSERT // turn static asserts into runtime asserts in order to check them
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
 | 
			
		||||
#define EIGEN_TESTMAP_MAX_SIZE 256
 | 
			
		||||
 | 
			
		||||
template<typename VectorType> void map_class_vector(const VectorType& m)
 | 
			
		||||
{
 | 
			
		||||
  typedef typename VectorType::Scalar Scalar;
 | 
			
		||||
 | 
			
		||||
  Index size = m.size();
 | 
			
		||||
 | 
			
		||||
  Scalar* array1 = internal::aligned_new<Scalar>(size);
 | 
			
		||||
  Scalar* array2 = internal::aligned_new<Scalar>(size);
 | 
			
		||||
  Scalar* array3 = new Scalar[size+1];
 | 
			
		||||
  Scalar* array3unaligned = (internal::UIntPtr(array3)%EIGEN_MAX_ALIGN_BYTES) == 0 ? array3+1 : array3;
 | 
			
		||||
  Scalar  array4[EIGEN_TESTMAP_MAX_SIZE];
 | 
			
		||||
 | 
			
		||||
  Map<VectorType, AlignedMax>(array1, size) = VectorType::Random(size);
 | 
			
		||||
  Map<VectorType, AlignedMax>(array2, size) = Map<VectorType,AlignedMax>(array1, size);
 | 
			
		||||
  Map<VectorType>(array3unaligned, size) = Map<VectorType>(array1, size);
 | 
			
		||||
  Map<VectorType>(array4, size)          = Map<VectorType,AlignedMax>(array1, size);
 | 
			
		||||
  VectorType ma1 = Map<VectorType, AlignedMax>(array1, size);
 | 
			
		||||
  VectorType ma2 = Map<VectorType, AlignedMax>(array2, size);
 | 
			
		||||
  VectorType ma3 = Map<VectorType>(array3unaligned, size);
 | 
			
		||||
  VectorType ma4 = Map<VectorType>(array4, size);
 | 
			
		||||
  VERIFY_IS_EQUAL(ma1, ma2);
 | 
			
		||||
  VERIFY_IS_EQUAL(ma1, ma3);
 | 
			
		||||
  VERIFY_IS_EQUAL(ma1, ma4);
 | 
			
		||||
  #ifdef EIGEN_VECTORIZE
 | 
			
		||||
  if(internal::packet_traits<Scalar>::Vectorizable && size>=AlignedMax)
 | 
			
		||||
    VERIFY_RAISES_ASSERT((Map<VectorType,AlignedMax>(array3unaligned, size)))
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  internal::aligned_delete(array1, size);
 | 
			
		||||
  internal::aligned_delete(array2, size);
 | 
			
		||||
  delete[] array3;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void map_class_matrix(const MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
 | 
			
		||||
  Index rows = m.rows(), cols = m.cols(), size = rows*cols;
 | 
			
		||||
  Scalar s1 = internal::random<Scalar>();
 | 
			
		||||
 | 
			
		||||
  // array1 and array2 -> aligned heap allocation
 | 
			
		||||
  Scalar* array1 = internal::aligned_new<Scalar>(size);
 | 
			
		||||
  for(int i = 0; i < size; i++) array1[i] = Scalar(1);
 | 
			
		||||
  Scalar* array2 = internal::aligned_new<Scalar>(size);
 | 
			
		||||
  for(int i = 0; i < size; i++) array2[i] = Scalar(1);
 | 
			
		||||
  // array3unaligned -> unaligned pointer to heap
 | 
			
		||||
  Scalar* array3 = new Scalar[size+1];
 | 
			
		||||
  Index sizep1 = size + 1; // <- without this temporary MSVC 2103 generates bad code
 | 
			
		||||
  for(Index i = 0; i < sizep1; i++) array3[i] = Scalar(1);
 | 
			
		||||
  Scalar* array3unaligned = (internal::UIntPtr(array3)%EIGEN_MAX_ALIGN_BYTES) == 0 ? array3+1 : array3;
 | 
			
		||||
  Scalar array4[256];
 | 
			
		||||
  if(size<=256)
 | 
			
		||||
    for(int i = 0; i < size; i++) array4[i] = Scalar(1);
 | 
			
		||||
  
 | 
			
		||||
  Map<MatrixType> map1(array1, rows, cols);
 | 
			
		||||
  Map<MatrixType, AlignedMax> map2(array2, rows, cols);
 | 
			
		||||
  Map<MatrixType> map3(array3unaligned, rows, cols);
 | 
			
		||||
  Map<MatrixType> map4(array4, rows, cols);
 | 
			
		||||
  
 | 
			
		||||
  VERIFY_IS_EQUAL(map1, MatrixType::Ones(rows,cols));
 | 
			
		||||
  VERIFY_IS_EQUAL(map2, MatrixType::Ones(rows,cols));
 | 
			
		||||
  VERIFY_IS_EQUAL(map3, MatrixType::Ones(rows,cols));
 | 
			
		||||
  map1 = MatrixType::Random(rows,cols);
 | 
			
		||||
  map2 = map1;
 | 
			
		||||
  map3 = map1;
 | 
			
		||||
  MatrixType ma1 = map1;
 | 
			
		||||
  MatrixType ma2 = map2;
 | 
			
		||||
  MatrixType ma3 = map3;
 | 
			
		||||
  VERIFY_IS_EQUAL(map1, map2);
 | 
			
		||||
  VERIFY_IS_EQUAL(map1, map3);
 | 
			
		||||
  VERIFY_IS_EQUAL(ma1, ma2);
 | 
			
		||||
  VERIFY_IS_EQUAL(ma1, ma3);
 | 
			
		||||
  VERIFY_IS_EQUAL(ma1, map3);
 | 
			
		||||
  
 | 
			
		||||
  VERIFY_IS_APPROX(s1*map1, s1*map2);
 | 
			
		||||
  VERIFY_IS_APPROX(s1*ma1, s1*ma2);
 | 
			
		||||
  VERIFY_IS_EQUAL(s1*ma1, s1*ma3);
 | 
			
		||||
  VERIFY_IS_APPROX(s1*map1, s1*map3);
 | 
			
		||||
  
 | 
			
		||||
  map2 *= s1;
 | 
			
		||||
  map3 *= s1;
 | 
			
		||||
  VERIFY_IS_APPROX(s1*map1, map2);
 | 
			
		||||
  VERIFY_IS_APPROX(s1*map1, map3);
 | 
			
		||||
  
 | 
			
		||||
  if(size<=256)
 | 
			
		||||
  {
 | 
			
		||||
    VERIFY_IS_EQUAL(map4, MatrixType::Ones(rows,cols));
 | 
			
		||||
    map4 = map1;
 | 
			
		||||
    MatrixType ma4 = map4;
 | 
			
		||||
    VERIFY_IS_EQUAL(map1, map4);
 | 
			
		||||
    VERIFY_IS_EQUAL(ma1, map4);
 | 
			
		||||
    VERIFY_IS_EQUAL(ma1, ma4);
 | 
			
		||||
    VERIFY_IS_APPROX(s1*map1, s1*map4);
 | 
			
		||||
    
 | 
			
		||||
    map4 *= s1;
 | 
			
		||||
    VERIFY_IS_APPROX(s1*map1, map4);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  internal::aligned_delete(array1, size);
 | 
			
		||||
  internal::aligned_delete(array2, size);
 | 
			
		||||
  delete[] array3;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename VectorType> void map_static_methods(const VectorType& m)
 | 
			
		||||
{
 | 
			
		||||
  typedef typename VectorType::Scalar Scalar;
 | 
			
		||||
 | 
			
		||||
  Index size = m.size();
 | 
			
		||||
 | 
			
		||||
  Scalar* array1 = internal::aligned_new<Scalar>(size);
 | 
			
		||||
  Scalar* array2 = internal::aligned_new<Scalar>(size);
 | 
			
		||||
  Scalar* array3 = new Scalar[size+1];
 | 
			
		||||
  Scalar* array3unaligned = internal::UIntPtr(array3)%EIGEN_MAX_ALIGN_BYTES == 0 ? array3+1 : array3;
 | 
			
		||||
 | 
			
		||||
  VectorType::MapAligned(array1, size) = VectorType::Random(size);
 | 
			
		||||
  VectorType::Map(array2, size) = VectorType::Map(array1, size);
 | 
			
		||||
  VectorType::Map(array3unaligned, size) = VectorType::Map(array1, size);
 | 
			
		||||
  VectorType ma1 = VectorType::Map(array1, size);
 | 
			
		||||
  VectorType ma2 = VectorType::MapAligned(array2, size);
 | 
			
		||||
  VectorType ma3 = VectorType::Map(array3unaligned, size);
 | 
			
		||||
  VERIFY_IS_EQUAL(ma1, ma2);
 | 
			
		||||
  VERIFY_IS_EQUAL(ma1, ma3);
 | 
			
		||||
 | 
			
		||||
  internal::aligned_delete(array1, size);
 | 
			
		||||
  internal::aligned_delete(array2, size);
 | 
			
		||||
  delete[] array3;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename PlainObjectType> void check_const_correctness(const PlainObjectType&)
 | 
			
		||||
{
 | 
			
		||||
  // there's a lot that we can't test here while still having this test compile!
 | 
			
		||||
  // the only possible approach would be to run a script trying to compile stuff and checking that it fails.
 | 
			
		||||
  // CMake can help with that.
 | 
			
		||||
 | 
			
		||||
  // verify that map-to-const don't have LvalueBit
 | 
			
		||||
  typedef typename internal::add_const<PlainObjectType>::type ConstPlainObjectType;
 | 
			
		||||
  VERIFY( !(internal::traits<Map<ConstPlainObjectType> >::Flags & LvalueBit) );
 | 
			
		||||
  VERIFY( !(internal::traits<Map<ConstPlainObjectType, AlignedMax> >::Flags & LvalueBit) );
 | 
			
		||||
  VERIFY( !(Map<ConstPlainObjectType>::Flags & LvalueBit) );
 | 
			
		||||
  VERIFY( !(Map<ConstPlainObjectType, AlignedMax>::Flags & LvalueBit) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Scalar>
 | 
			
		||||
void map_not_aligned_on_scalar()
 | 
			
		||||
{
 | 
			
		||||
  typedef Matrix<Scalar,Dynamic,Dynamic> MatrixType;
 | 
			
		||||
  Index size = 11;
 | 
			
		||||
  Scalar* array1 = internal::aligned_new<Scalar>((size+1)*(size+1)+1);
 | 
			
		||||
  Scalar* array2 = reinterpret_cast<Scalar*>(sizeof(Scalar)/2+std::size_t(array1));
 | 
			
		||||
  Map<MatrixType,0,OuterStride<> > map2(array2, size, size, OuterStride<>(size+1));
 | 
			
		||||
  MatrixType m2 = MatrixType::Random(size,size);
 | 
			
		||||
  map2 = m2;
 | 
			
		||||
  VERIFY_IS_EQUAL(m2, map2);
 | 
			
		||||
  
 | 
			
		||||
  typedef Matrix<Scalar,Dynamic,1> VectorType;
 | 
			
		||||
  Map<VectorType> map3(array2, size);
 | 
			
		||||
  MatrixType v3 = VectorType::Random(size);
 | 
			
		||||
  map3 = v3;
 | 
			
		||||
  VERIFY_IS_EQUAL(v3, map3);
 | 
			
		||||
  
 | 
			
		||||
  internal::aligned_delete(array1, (size+1)*(size+1)+1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_mapped_matrix()
 | 
			
		||||
{
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_1( map_class_vector(Matrix<float, 1, 1>()) );
 | 
			
		||||
    CALL_SUBTEST_1( check_const_correctness(Matrix<float, 1, 1>()) );
 | 
			
		||||
    CALL_SUBTEST_2( map_class_vector(Vector4d()) );
 | 
			
		||||
    CALL_SUBTEST_2( map_class_vector(VectorXd(13)) );
 | 
			
		||||
    CALL_SUBTEST_2( check_const_correctness(Matrix4d()) );
 | 
			
		||||
    CALL_SUBTEST_3( map_class_vector(RowVector4f()) );
 | 
			
		||||
    CALL_SUBTEST_4( map_class_vector(VectorXcf(8)) );
 | 
			
		||||
    CALL_SUBTEST_5( map_class_vector(VectorXi(12)) );
 | 
			
		||||
    CALL_SUBTEST_5( check_const_correctness(VectorXi(12)) );
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_1( map_class_matrix(Matrix<float, 1, 1>()) );
 | 
			
		||||
    CALL_SUBTEST_2( map_class_matrix(Matrix4d()) );
 | 
			
		||||
    CALL_SUBTEST_11( map_class_matrix(Matrix<float,3,5>()) );
 | 
			
		||||
    CALL_SUBTEST_4( map_class_matrix(MatrixXcf(internal::random<int>(1,10),internal::random<int>(1,10))) );
 | 
			
		||||
    CALL_SUBTEST_5( map_class_matrix(MatrixXi(internal::random<int>(1,10),internal::random<int>(1,10))) );
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_6( map_static_methods(Matrix<double, 1, 1>()) );
 | 
			
		||||
    CALL_SUBTEST_7( map_static_methods(Vector3f()) );
 | 
			
		||||
    CALL_SUBTEST_8( map_static_methods(RowVector3d()) );
 | 
			
		||||
    CALL_SUBTEST_9( map_static_methods(VectorXcd(8)) );
 | 
			
		||||
    CALL_SUBTEST_10( map_static_methods(VectorXf(12)) );
 | 
			
		||||
    
 | 
			
		||||
    CALL_SUBTEST_11( map_not_aligned_on_scalar<double>() );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										173
									
								
								cs440-acg/ext/eigen/test/mapstaticmethods.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										173
									
								
								cs440-acg/ext/eigen/test/mapstaticmethods.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,173 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2011 Benoit Jacob <jacob.benoit.1@gmail.com>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
 | 
			
		||||
float *ptr;
 | 
			
		||||
const float *const_ptr;
 | 
			
		||||
 | 
			
		||||
template<typename PlainObjectType,
 | 
			
		||||
         bool IsDynamicSize = PlainObjectType::SizeAtCompileTime == Dynamic,
 | 
			
		||||
         bool IsVector = PlainObjectType::IsVectorAtCompileTime
 | 
			
		||||
>
 | 
			
		||||
struct mapstaticmethods_impl {};
 | 
			
		||||
 | 
			
		||||
template<typename PlainObjectType, bool IsVector>
 | 
			
		||||
struct mapstaticmethods_impl<PlainObjectType, false, IsVector>
 | 
			
		||||
{
 | 
			
		||||
  static void run(const PlainObjectType& m)
 | 
			
		||||
  {
 | 
			
		||||
    mapstaticmethods_impl<PlainObjectType, true, IsVector>::run(m);
 | 
			
		||||
 | 
			
		||||
    int i = internal::random<int>(2,5), j = internal::random<int>(2,5);
 | 
			
		||||
 | 
			
		||||
    PlainObjectType::Map(ptr).setZero();
 | 
			
		||||
    PlainObjectType::MapAligned(ptr).setZero();
 | 
			
		||||
    PlainObjectType::Map(const_ptr).sum();
 | 
			
		||||
    PlainObjectType::MapAligned(const_ptr).sum();
 | 
			
		||||
 | 
			
		||||
    PlainObjectType::Map(ptr, InnerStride<>(i)).setZero();
 | 
			
		||||
    PlainObjectType::MapAligned(ptr, InnerStride<>(i)).setZero();
 | 
			
		||||
    PlainObjectType::Map(const_ptr, InnerStride<>(i)).sum();
 | 
			
		||||
    PlainObjectType::MapAligned(const_ptr, InnerStride<>(i)).sum();
 | 
			
		||||
 | 
			
		||||
    PlainObjectType::Map(ptr, InnerStride<2>()).setZero();
 | 
			
		||||
    PlainObjectType::MapAligned(ptr, InnerStride<3>()).setZero();
 | 
			
		||||
    PlainObjectType::Map(const_ptr, InnerStride<4>()).sum();
 | 
			
		||||
    PlainObjectType::MapAligned(const_ptr, InnerStride<5>()).sum();
 | 
			
		||||
 | 
			
		||||
    PlainObjectType::Map(ptr, OuterStride<>(i)).setZero();
 | 
			
		||||
    PlainObjectType::MapAligned(ptr, OuterStride<>(i)).setZero();
 | 
			
		||||
    PlainObjectType::Map(const_ptr, OuterStride<>(i)).sum();
 | 
			
		||||
    PlainObjectType::MapAligned(const_ptr, OuterStride<>(i)).sum();
 | 
			
		||||
 | 
			
		||||
    PlainObjectType::Map(ptr, OuterStride<2>()).setZero();
 | 
			
		||||
    PlainObjectType::MapAligned(ptr, OuterStride<3>()).setZero();
 | 
			
		||||
    PlainObjectType::Map(const_ptr, OuterStride<4>()).sum();
 | 
			
		||||
    PlainObjectType::MapAligned(const_ptr, OuterStride<5>()).sum();
 | 
			
		||||
 | 
			
		||||
    PlainObjectType::Map(ptr, Stride<Dynamic, Dynamic>(i,j)).setZero();
 | 
			
		||||
    PlainObjectType::MapAligned(ptr, Stride<2,Dynamic>(2,i)).setZero();
 | 
			
		||||
    PlainObjectType::Map(const_ptr, Stride<Dynamic,3>(i,3)).sum();
 | 
			
		||||
    PlainObjectType::MapAligned(const_ptr, Stride<Dynamic, Dynamic>(i,j)).sum();
 | 
			
		||||
 | 
			
		||||
    PlainObjectType::Map(ptr, Stride<2,3>()).setZero();
 | 
			
		||||
    PlainObjectType::MapAligned(ptr, Stride<3,4>()).setZero();
 | 
			
		||||
    PlainObjectType::Map(const_ptr, Stride<2,4>()).sum();
 | 
			
		||||
    PlainObjectType::MapAligned(const_ptr, Stride<5,3>()).sum();
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename PlainObjectType>
 | 
			
		||||
struct mapstaticmethods_impl<PlainObjectType, true, false>
 | 
			
		||||
{
 | 
			
		||||
  static void run(const PlainObjectType& m)
 | 
			
		||||
  {
 | 
			
		||||
    Index rows = m.rows(), cols = m.cols();
 | 
			
		||||
 | 
			
		||||
    int i = internal::random<int>(2,5), j = internal::random<int>(2,5);
 | 
			
		||||
 | 
			
		||||
    PlainObjectType::Map(ptr, rows, cols).setZero();
 | 
			
		||||
    PlainObjectType::MapAligned(ptr, rows, cols).setZero();
 | 
			
		||||
    PlainObjectType::Map(const_ptr, rows, cols).sum();
 | 
			
		||||
    PlainObjectType::MapAligned(const_ptr, rows, cols).sum();
 | 
			
		||||
 | 
			
		||||
    PlainObjectType::Map(ptr, rows, cols, InnerStride<>(i)).setZero();
 | 
			
		||||
    PlainObjectType::MapAligned(ptr, rows, cols, InnerStride<>(i)).setZero();
 | 
			
		||||
    PlainObjectType::Map(const_ptr, rows, cols, InnerStride<>(i)).sum();
 | 
			
		||||
    PlainObjectType::MapAligned(const_ptr, rows, cols, InnerStride<>(i)).sum();
 | 
			
		||||
 | 
			
		||||
    PlainObjectType::Map(ptr, rows, cols, InnerStride<2>()).setZero();
 | 
			
		||||
    PlainObjectType::MapAligned(ptr, rows, cols, InnerStride<3>()).setZero();
 | 
			
		||||
    PlainObjectType::Map(const_ptr, rows, cols, InnerStride<4>()).sum();
 | 
			
		||||
    PlainObjectType::MapAligned(const_ptr, rows, cols, InnerStride<5>()).sum();
 | 
			
		||||
 | 
			
		||||
    PlainObjectType::Map(ptr, rows, cols, OuterStride<>(i)).setZero();
 | 
			
		||||
    PlainObjectType::MapAligned(ptr, rows, cols, OuterStride<>(i)).setZero();
 | 
			
		||||
    PlainObjectType::Map(const_ptr, rows, cols, OuterStride<>(i)).sum();
 | 
			
		||||
    PlainObjectType::MapAligned(const_ptr, rows, cols, OuterStride<>(i)).sum();
 | 
			
		||||
 | 
			
		||||
    PlainObjectType::Map(ptr, rows, cols, OuterStride<2>()).setZero();
 | 
			
		||||
    PlainObjectType::MapAligned(ptr, rows, cols, OuterStride<3>()).setZero();
 | 
			
		||||
    PlainObjectType::Map(const_ptr, rows, cols, OuterStride<4>()).sum();
 | 
			
		||||
    PlainObjectType::MapAligned(const_ptr, rows, cols, OuterStride<5>()).sum();
 | 
			
		||||
 | 
			
		||||
    PlainObjectType::Map(ptr, rows, cols, Stride<Dynamic, Dynamic>(i,j)).setZero();
 | 
			
		||||
    PlainObjectType::MapAligned(ptr, rows, cols, Stride<2,Dynamic>(2,i)).setZero();
 | 
			
		||||
    PlainObjectType::Map(const_ptr, rows, cols, Stride<Dynamic,3>(i,3)).sum();
 | 
			
		||||
    PlainObjectType::MapAligned(const_ptr, rows, cols, Stride<Dynamic, Dynamic>(i,j)).sum();
 | 
			
		||||
 | 
			
		||||
    PlainObjectType::Map(ptr, rows, cols, Stride<2,3>()).setZero();
 | 
			
		||||
    PlainObjectType::MapAligned(ptr, rows, cols, Stride<3,4>()).setZero();
 | 
			
		||||
    PlainObjectType::Map(const_ptr, rows, cols, Stride<2,4>()).sum();
 | 
			
		||||
    PlainObjectType::MapAligned(const_ptr, rows, cols, Stride<5,3>()).sum();
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename PlainObjectType>
 | 
			
		||||
struct mapstaticmethods_impl<PlainObjectType, true, true>
 | 
			
		||||
{
 | 
			
		||||
  static void run(const PlainObjectType& v)
 | 
			
		||||
  {
 | 
			
		||||
    Index size = v.size();
 | 
			
		||||
 | 
			
		||||
    int i = internal::random<int>(2,5);
 | 
			
		||||
 | 
			
		||||
    PlainObjectType::Map(ptr, size).setZero();
 | 
			
		||||
    PlainObjectType::MapAligned(ptr, size).setZero();
 | 
			
		||||
    PlainObjectType::Map(const_ptr, size).sum();
 | 
			
		||||
    PlainObjectType::MapAligned(const_ptr, size).sum();
 | 
			
		||||
 | 
			
		||||
    PlainObjectType::Map(ptr, size, InnerStride<>(i)).setZero();
 | 
			
		||||
    PlainObjectType::MapAligned(ptr, size, InnerStride<>(i)).setZero();
 | 
			
		||||
    PlainObjectType::Map(const_ptr, size, InnerStride<>(i)).sum();
 | 
			
		||||
    PlainObjectType::MapAligned(const_ptr, size, InnerStride<>(i)).sum();
 | 
			
		||||
 | 
			
		||||
    PlainObjectType::Map(ptr, size, InnerStride<2>()).setZero();
 | 
			
		||||
    PlainObjectType::MapAligned(ptr, size, InnerStride<3>()).setZero();
 | 
			
		||||
    PlainObjectType::Map(const_ptr, size, InnerStride<4>()).sum();
 | 
			
		||||
    PlainObjectType::MapAligned(const_ptr, size, InnerStride<5>()).sum();
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename PlainObjectType>
 | 
			
		||||
void mapstaticmethods(const PlainObjectType& m)
 | 
			
		||||
{
 | 
			
		||||
  mapstaticmethods_impl<PlainObjectType>::run(m);
 | 
			
		||||
  VERIFY(true); // just to avoid 'unused function' warning
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_mapstaticmethods()
 | 
			
		||||
{
 | 
			
		||||
  ptr = internal::aligned_new<float>(1000);
 | 
			
		||||
  for(int i = 0; i < 1000; i++) ptr[i] = float(i);
 | 
			
		||||
 | 
			
		||||
  const_ptr = ptr;
 | 
			
		||||
 | 
			
		||||
  CALL_SUBTEST_1(( mapstaticmethods(Matrix<float, 1, 1>()) ));
 | 
			
		||||
  CALL_SUBTEST_1(( mapstaticmethods(Vector2f()) ));
 | 
			
		||||
  CALL_SUBTEST_2(( mapstaticmethods(Vector3f()) ));
 | 
			
		||||
  CALL_SUBTEST_2(( mapstaticmethods(Matrix2f()) ));
 | 
			
		||||
  CALL_SUBTEST_3(( mapstaticmethods(Matrix4f()) ));
 | 
			
		||||
  CALL_SUBTEST_3(( mapstaticmethods(Array4f()) ));
 | 
			
		||||
  CALL_SUBTEST_4(( mapstaticmethods(Array3f()) ));
 | 
			
		||||
  CALL_SUBTEST_4(( mapstaticmethods(Array33f()) ));
 | 
			
		||||
  CALL_SUBTEST_5(( mapstaticmethods(Array44f()) ));
 | 
			
		||||
  CALL_SUBTEST_5(( mapstaticmethods(VectorXf(1)) ));
 | 
			
		||||
  CALL_SUBTEST_5(( mapstaticmethods(VectorXf(8)) ));
 | 
			
		||||
  CALL_SUBTEST_6(( mapstaticmethods(MatrixXf(1,1)) ));
 | 
			
		||||
  CALL_SUBTEST_6(( mapstaticmethods(MatrixXf(5,7)) ));
 | 
			
		||||
  CALL_SUBTEST_7(( mapstaticmethods(ArrayXf(1)) ));
 | 
			
		||||
  CALL_SUBTEST_7(( mapstaticmethods(ArrayXf(5)) ));
 | 
			
		||||
  CALL_SUBTEST_8(( mapstaticmethods(ArrayXXf(1,1)) ));
 | 
			
		||||
  CALL_SUBTEST_8(( mapstaticmethods(ArrayXXf(8,6)) ));
 | 
			
		||||
 | 
			
		||||
  internal::aligned_delete(ptr, 1000);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										234
									
								
								cs440-acg/ext/eigen/test/mapstride.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										234
									
								
								cs440-acg/ext/eigen/test/mapstride.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,234 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2010 Benoit Jacob <jacob.benoit.1@gmail.com>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
 | 
			
		||||
template<int Alignment,typename VectorType> void map_class_vector(const VectorType& m)
 | 
			
		||||
{
 | 
			
		||||
  typedef typename VectorType::Scalar Scalar;
 | 
			
		||||
 | 
			
		||||
  Index size = m.size();
 | 
			
		||||
 | 
			
		||||
  VectorType v = VectorType::Random(size);
 | 
			
		||||
 | 
			
		||||
  Index arraysize = 3*size;
 | 
			
		||||
  
 | 
			
		||||
  Scalar* a_array = internal::aligned_new<Scalar>(arraysize+1);
 | 
			
		||||
  Scalar* array = a_array;
 | 
			
		||||
  if(Alignment!=Aligned)
 | 
			
		||||
    array = (Scalar*)(internal::IntPtr(a_array) + (internal::packet_traits<Scalar>::AlignedOnScalar?sizeof(Scalar):sizeof(typename NumTraits<Scalar>::Real)));
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    Map<VectorType, Alignment, InnerStride<3> > map(array, size);
 | 
			
		||||
    map = v;
 | 
			
		||||
    for(int i = 0; i < size; ++i)
 | 
			
		||||
    {
 | 
			
		||||
      VERIFY(array[3*i] == v[i]);
 | 
			
		||||
      VERIFY(map[i] == v[i]);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    Map<VectorType, Unaligned, InnerStride<Dynamic> > map(array, size, InnerStride<Dynamic>(2));
 | 
			
		||||
    map = v;
 | 
			
		||||
    for(int i = 0; i < size; ++i)
 | 
			
		||||
    {
 | 
			
		||||
      VERIFY(array[2*i] == v[i]);
 | 
			
		||||
      VERIFY(map[i] == v[i]);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  internal::aligned_delete(a_array, arraysize+1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<int Alignment,typename MatrixType> void map_class_matrix(const MatrixType& _m)
 | 
			
		||||
{
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
 | 
			
		||||
  Index rows = _m.rows(), cols = _m.cols();
 | 
			
		||||
 | 
			
		||||
  MatrixType m = MatrixType::Random(rows,cols);
 | 
			
		||||
  Scalar s1 = internal::random<Scalar>();
 | 
			
		||||
 | 
			
		||||
  Index arraysize = 4*(rows+4)*(cols+4);
 | 
			
		||||
 | 
			
		||||
  Scalar* a_array1 = internal::aligned_new<Scalar>(arraysize+1);
 | 
			
		||||
  Scalar* array1 = a_array1;
 | 
			
		||||
  if(Alignment!=Aligned)
 | 
			
		||||
    array1 = (Scalar*)(internal::IntPtr(a_array1) + (internal::packet_traits<Scalar>::AlignedOnScalar?sizeof(Scalar):sizeof(typename NumTraits<Scalar>::Real)));
 | 
			
		||||
 | 
			
		||||
  Scalar a_array2[256];
 | 
			
		||||
  Scalar* array2 = a_array2;
 | 
			
		||||
  if(Alignment!=Aligned)
 | 
			
		||||
    array2 = (Scalar*)(internal::IntPtr(a_array2) + (internal::packet_traits<Scalar>::AlignedOnScalar?sizeof(Scalar):sizeof(typename NumTraits<Scalar>::Real)));
 | 
			
		||||
  else
 | 
			
		||||
    array2 = (Scalar*)(((internal::UIntPtr(a_array2)+EIGEN_MAX_ALIGN_BYTES-1)/EIGEN_MAX_ALIGN_BYTES)*EIGEN_MAX_ALIGN_BYTES);
 | 
			
		||||
  Index maxsize2 = a_array2 - array2 + 256;
 | 
			
		||||
  
 | 
			
		||||
  // test no inner stride and some dynamic outer stride
 | 
			
		||||
  for(int k=0; k<2; ++k)
 | 
			
		||||
  {
 | 
			
		||||
    if(k==1 && (m.innerSize()+1)*m.outerSize() > maxsize2)
 | 
			
		||||
      break;
 | 
			
		||||
    Scalar* array = (k==0 ? array1 : array2);
 | 
			
		||||
    
 | 
			
		||||
    Map<MatrixType, Alignment, OuterStride<Dynamic> > map(array, rows, cols, OuterStride<Dynamic>(m.innerSize()+1));
 | 
			
		||||
    map = m;
 | 
			
		||||
    VERIFY(map.outerStride() == map.innerSize()+1);
 | 
			
		||||
    for(int i = 0; i < m.outerSize(); ++i)
 | 
			
		||||
      for(int j = 0; j < m.innerSize(); ++j)
 | 
			
		||||
      {
 | 
			
		||||
        VERIFY(array[map.outerStride()*i+j] == m.coeffByOuterInner(i,j));
 | 
			
		||||
        VERIFY(map.coeffByOuterInner(i,j) == m.coeffByOuterInner(i,j));
 | 
			
		||||
      }
 | 
			
		||||
    VERIFY_IS_APPROX(s1*map,s1*m);
 | 
			
		||||
    map *= s1;
 | 
			
		||||
    VERIFY_IS_APPROX(map,s1*m);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // test no inner stride and an outer stride of +4. This is quite important as for fixed-size matrices,
 | 
			
		||||
  // this allows to hit the special case where it's vectorizable.
 | 
			
		||||
  for(int k=0; k<2; ++k)
 | 
			
		||||
  {
 | 
			
		||||
    if(k==1 && (m.innerSize()+4)*m.outerSize() > maxsize2)
 | 
			
		||||
      break;
 | 
			
		||||
    Scalar* array = (k==0 ? array1 : array2);
 | 
			
		||||
    
 | 
			
		||||
    enum {
 | 
			
		||||
      InnerSize = MatrixType::InnerSizeAtCompileTime,
 | 
			
		||||
      OuterStrideAtCompileTime = InnerSize==Dynamic ? Dynamic : InnerSize+4
 | 
			
		||||
    };
 | 
			
		||||
    Map<MatrixType, Alignment, OuterStride<OuterStrideAtCompileTime> >
 | 
			
		||||
      map(array, rows, cols, OuterStride<OuterStrideAtCompileTime>(m.innerSize()+4));
 | 
			
		||||
    map = m;
 | 
			
		||||
    VERIFY(map.outerStride() == map.innerSize()+4);
 | 
			
		||||
    for(int i = 0; i < m.outerSize(); ++i)
 | 
			
		||||
      for(int j = 0; j < m.innerSize(); ++j)
 | 
			
		||||
      {
 | 
			
		||||
        VERIFY(array[map.outerStride()*i+j] == m.coeffByOuterInner(i,j));
 | 
			
		||||
        VERIFY(map.coeffByOuterInner(i,j) == m.coeffByOuterInner(i,j));
 | 
			
		||||
      }
 | 
			
		||||
    VERIFY_IS_APPROX(s1*map,s1*m);
 | 
			
		||||
    map *= s1;
 | 
			
		||||
    VERIFY_IS_APPROX(map,s1*m);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // test both inner stride and outer stride
 | 
			
		||||
  for(int k=0; k<2; ++k)
 | 
			
		||||
  {
 | 
			
		||||
    if(k==1 && (2*m.innerSize()+1)*(m.outerSize()*2) > maxsize2)
 | 
			
		||||
      break;
 | 
			
		||||
    Scalar* array = (k==0 ? array1 : array2);
 | 
			
		||||
    
 | 
			
		||||
    Map<MatrixType, Alignment, Stride<Dynamic,Dynamic> > map(array, rows, cols, Stride<Dynamic,Dynamic>(2*m.innerSize()+1, 2));
 | 
			
		||||
    map = m;
 | 
			
		||||
    VERIFY(map.outerStride() == 2*map.innerSize()+1);
 | 
			
		||||
    VERIFY(map.innerStride() == 2);
 | 
			
		||||
    for(int i = 0; i < m.outerSize(); ++i)
 | 
			
		||||
      for(int j = 0; j < m.innerSize(); ++j)
 | 
			
		||||
      {
 | 
			
		||||
        VERIFY(array[map.outerStride()*i+map.innerStride()*j] == m.coeffByOuterInner(i,j));
 | 
			
		||||
        VERIFY(map.coeffByOuterInner(i,j) == m.coeffByOuterInner(i,j));
 | 
			
		||||
      }
 | 
			
		||||
    VERIFY_IS_APPROX(s1*map,s1*m);
 | 
			
		||||
    map *= s1;
 | 
			
		||||
    VERIFY_IS_APPROX(map,s1*m);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // test inner stride and no outer stride
 | 
			
		||||
  for(int k=0; k<2; ++k)
 | 
			
		||||
  {
 | 
			
		||||
    if(k==1 && (m.innerSize()*2)*m.outerSize() > maxsize2)
 | 
			
		||||
      break;
 | 
			
		||||
    Scalar* array = (k==0 ? array1 : array2);
 | 
			
		||||
 | 
			
		||||
    Map<MatrixType, Alignment, InnerStride<Dynamic> > map(array, rows, cols, InnerStride<Dynamic>(2));
 | 
			
		||||
    map = m;
 | 
			
		||||
    VERIFY(map.outerStride() == map.innerSize()*2);
 | 
			
		||||
    for(int i = 0; i < m.outerSize(); ++i)
 | 
			
		||||
      for(int j = 0; j < m.innerSize(); ++j)
 | 
			
		||||
      {
 | 
			
		||||
        VERIFY(array[map.innerSize()*i*2+j*2] == m.coeffByOuterInner(i,j));
 | 
			
		||||
        VERIFY(map.coeffByOuterInner(i,j) == m.coeffByOuterInner(i,j));
 | 
			
		||||
      }
 | 
			
		||||
    VERIFY_IS_APPROX(s1*map,s1*m);
 | 
			
		||||
    map *= s1;
 | 
			
		||||
    VERIFY_IS_APPROX(map,s1*m);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  internal::aligned_delete(a_array1, arraysize+1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Additional tests for inner-stride but no outer-stride
 | 
			
		||||
template<int>
 | 
			
		||||
void bug1453()
 | 
			
		||||
{
 | 
			
		||||
  const int data[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31};
 | 
			
		||||
  typedef Matrix<int,Dynamic,Dynamic,RowMajor> RowMatrixXi;
 | 
			
		||||
  typedef Matrix<int,2,3,ColMajor> ColMatrix23i;
 | 
			
		||||
  typedef Matrix<int,3,2,ColMajor> ColMatrix32i;
 | 
			
		||||
  typedef Matrix<int,2,3,RowMajor> RowMatrix23i;
 | 
			
		||||
  typedef Matrix<int,3,2,RowMajor> RowMatrix32i;
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(MatrixXi::Map(data, 2, 3, InnerStride<2>()), MatrixXi::Map(data, 2, 3, Stride<4,2>()));
 | 
			
		||||
  VERIFY_IS_APPROX(MatrixXi::Map(data, 2, 3, InnerStride<>(2)), MatrixXi::Map(data, 2, 3, Stride<4,2>()));
 | 
			
		||||
  VERIFY_IS_APPROX(MatrixXi::Map(data, 3, 2, InnerStride<2>()), MatrixXi::Map(data, 3, 2, Stride<6,2>()));
 | 
			
		||||
  VERIFY_IS_APPROX(MatrixXi::Map(data, 3, 2, InnerStride<>(2)), MatrixXi::Map(data, 3, 2, Stride<6,2>()));
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(RowMatrixXi::Map(data, 2, 3, InnerStride<2>()), RowMatrixXi::Map(data, 2, 3, Stride<6,2>()));
 | 
			
		||||
  VERIFY_IS_APPROX(RowMatrixXi::Map(data, 2, 3, InnerStride<>(2)), RowMatrixXi::Map(data, 2, 3, Stride<6,2>()));
 | 
			
		||||
  VERIFY_IS_APPROX(RowMatrixXi::Map(data, 3, 2, InnerStride<2>()), RowMatrixXi::Map(data, 3, 2, Stride<4,2>()));
 | 
			
		||||
  VERIFY_IS_APPROX(RowMatrixXi::Map(data, 3, 2, InnerStride<>(2)), RowMatrixXi::Map(data, 3, 2, Stride<4,2>()));
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(ColMatrix23i::Map(data, InnerStride<2>()), MatrixXi::Map(data, 2, 3, Stride<4,2>()));
 | 
			
		||||
  VERIFY_IS_APPROX(ColMatrix23i::Map(data, InnerStride<>(2)), MatrixXi::Map(data, 2, 3, Stride<4,2>()));
 | 
			
		||||
  VERIFY_IS_APPROX(ColMatrix32i::Map(data, InnerStride<2>()), MatrixXi::Map(data, 3, 2, Stride<6,2>()));
 | 
			
		||||
  VERIFY_IS_APPROX(ColMatrix32i::Map(data, InnerStride<>(2)), MatrixXi::Map(data, 3, 2, Stride<6,2>()));
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(RowMatrix23i::Map(data, InnerStride<2>()), RowMatrixXi::Map(data, 2, 3, Stride<6,2>()));
 | 
			
		||||
  VERIFY_IS_APPROX(RowMatrix23i::Map(data, InnerStride<>(2)), RowMatrixXi::Map(data, 2, 3, Stride<6,2>()));
 | 
			
		||||
  VERIFY_IS_APPROX(RowMatrix32i::Map(data, InnerStride<2>()), RowMatrixXi::Map(data, 3, 2, Stride<4,2>()));
 | 
			
		||||
  VERIFY_IS_APPROX(RowMatrix32i::Map(data, InnerStride<>(2)), RowMatrixXi::Map(data, 3, 2, Stride<4,2>()));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_mapstride()
 | 
			
		||||
{
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    int maxn = 30;
 | 
			
		||||
    CALL_SUBTEST_1( map_class_vector<Aligned>(Matrix<float, 1, 1>()) );
 | 
			
		||||
    CALL_SUBTEST_1( map_class_vector<Unaligned>(Matrix<float, 1, 1>()) );
 | 
			
		||||
    CALL_SUBTEST_2( map_class_vector<Aligned>(Vector4d()) );
 | 
			
		||||
    CALL_SUBTEST_2( map_class_vector<Unaligned>(Vector4d()) );
 | 
			
		||||
    CALL_SUBTEST_3( map_class_vector<Aligned>(RowVector4f()) );
 | 
			
		||||
    CALL_SUBTEST_3( map_class_vector<Unaligned>(RowVector4f()) );
 | 
			
		||||
    CALL_SUBTEST_4( map_class_vector<Aligned>(VectorXcf(internal::random<int>(1,maxn))) );
 | 
			
		||||
    CALL_SUBTEST_4( map_class_vector<Unaligned>(VectorXcf(internal::random<int>(1,maxn))) );
 | 
			
		||||
    CALL_SUBTEST_5( map_class_vector<Aligned>(VectorXi(internal::random<int>(1,maxn))) );
 | 
			
		||||
    CALL_SUBTEST_5( map_class_vector<Unaligned>(VectorXi(internal::random<int>(1,maxn))) );
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_1( map_class_matrix<Aligned>(Matrix<float, 1, 1>()) );
 | 
			
		||||
    CALL_SUBTEST_1( map_class_matrix<Unaligned>(Matrix<float, 1, 1>()) );
 | 
			
		||||
    CALL_SUBTEST_2( map_class_matrix<Aligned>(Matrix4d()) );
 | 
			
		||||
    CALL_SUBTEST_2( map_class_matrix<Unaligned>(Matrix4d()) );
 | 
			
		||||
    CALL_SUBTEST_3( map_class_matrix<Aligned>(Matrix<float,3,5>()) );
 | 
			
		||||
    CALL_SUBTEST_3( map_class_matrix<Unaligned>(Matrix<float,3,5>()) );
 | 
			
		||||
    CALL_SUBTEST_3( map_class_matrix<Aligned>(Matrix<float,4,8>()) );
 | 
			
		||||
    CALL_SUBTEST_3( map_class_matrix<Unaligned>(Matrix<float,4,8>()) );
 | 
			
		||||
    CALL_SUBTEST_4( map_class_matrix<Aligned>(MatrixXcf(internal::random<int>(1,maxn),internal::random<int>(1,maxn))) );
 | 
			
		||||
    CALL_SUBTEST_4( map_class_matrix<Unaligned>(MatrixXcf(internal::random<int>(1,maxn),internal::random<int>(1,maxn))) );
 | 
			
		||||
    CALL_SUBTEST_5( map_class_matrix<Aligned>(MatrixXi(internal::random<int>(1,maxn),internal::random<int>(1,maxn))) );
 | 
			
		||||
    CALL_SUBTEST_5( map_class_matrix<Unaligned>(MatrixXi(internal::random<int>(1,maxn),internal::random<int>(1,maxn))) );
 | 
			
		||||
    CALL_SUBTEST_6( map_class_matrix<Aligned>(MatrixXcd(internal::random<int>(1,maxn),internal::random<int>(1,maxn))) );
 | 
			
		||||
    CALL_SUBTEST_6( map_class_matrix<Unaligned>(MatrixXcd(internal::random<int>(1,maxn),internal::random<int>(1,maxn))) );
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_5( bug1453<0>() );
 | 
			
		||||
    
 | 
			
		||||
    TEST_SET_BUT_UNUSED_VARIABLE(maxn);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										97
									
								
								cs440-acg/ext/eigen/test/meta.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								cs440-acg/ext/eigen/test/meta.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,97 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
 | 
			
		||||
template<typename From, typename To>
 | 
			
		||||
bool check_is_convertible(const From&, const To&)
 | 
			
		||||
{
 | 
			
		||||
  return internal::is_convertible<From,To>::value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_meta()
 | 
			
		||||
{
 | 
			
		||||
  VERIFY((internal::conditional<(3<4),internal::true_type, internal::false_type>::type::value));
 | 
			
		||||
  VERIFY(( internal::is_same<float,float>::value));
 | 
			
		||||
  VERIFY((!internal::is_same<float,double>::value));
 | 
			
		||||
  VERIFY((!internal::is_same<float,float&>::value));
 | 
			
		||||
  VERIFY((!internal::is_same<float,const float&>::value));
 | 
			
		||||
  
 | 
			
		||||
  VERIFY(( internal::is_same<float,internal::remove_all<const float&>::type >::value));
 | 
			
		||||
  VERIFY(( internal::is_same<float,internal::remove_all<const float*>::type >::value));
 | 
			
		||||
  VERIFY(( internal::is_same<float,internal::remove_all<const float*&>::type >::value));
 | 
			
		||||
  VERIFY(( internal::is_same<float,internal::remove_all<float**>::type >::value));
 | 
			
		||||
  VERIFY(( internal::is_same<float,internal::remove_all<float**&>::type >::value));
 | 
			
		||||
  VERIFY(( internal::is_same<float,internal::remove_all<float* const *&>::type >::value));
 | 
			
		||||
  VERIFY(( internal::is_same<float,internal::remove_all<float* const>::type >::value));
 | 
			
		||||
 | 
			
		||||
  // test add_const
 | 
			
		||||
  VERIFY(( internal::is_same< internal::add_const<float>::type, const float >::value));
 | 
			
		||||
  VERIFY(( internal::is_same< internal::add_const<float*>::type, float* const>::value));
 | 
			
		||||
  VERIFY(( internal::is_same< internal::add_const<float const*>::type, float const* const>::value));
 | 
			
		||||
  VERIFY(( internal::is_same< internal::add_const<float&>::type, float& >::value));
 | 
			
		||||
 | 
			
		||||
  // test remove_const
 | 
			
		||||
  VERIFY(( internal::is_same< internal::remove_const<float const* const>::type, float const* >::value));
 | 
			
		||||
  VERIFY(( internal::is_same< internal::remove_const<float const*>::type, float const* >::value));
 | 
			
		||||
  VERIFY(( internal::is_same< internal::remove_const<float* const>::type, float* >::value));
 | 
			
		||||
 | 
			
		||||
  // test add_const_on_value_type
 | 
			
		||||
  VERIFY(( internal::is_same< internal::add_const_on_value_type<float&>::type, float const& >::value));
 | 
			
		||||
  VERIFY(( internal::is_same< internal::add_const_on_value_type<float*>::type, float const* >::value));
 | 
			
		||||
 | 
			
		||||
  VERIFY(( internal::is_same< internal::add_const_on_value_type<float>::type, const float >::value));
 | 
			
		||||
  VERIFY(( internal::is_same< internal::add_const_on_value_type<const float>::type, const float >::value));
 | 
			
		||||
 | 
			
		||||
  VERIFY(( internal::is_same< internal::add_const_on_value_type<const float* const>::type, const float* const>::value));
 | 
			
		||||
  VERIFY(( internal::is_same< internal::add_const_on_value_type<float* const>::type, const float* const>::value));
 | 
			
		||||
  
 | 
			
		||||
  VERIFY(( internal::is_same<float,internal::remove_reference<float&>::type >::value));
 | 
			
		||||
  VERIFY(( internal::is_same<const float,internal::remove_reference<const float&>::type >::value));
 | 
			
		||||
  VERIFY(( internal::is_same<float,internal::remove_pointer<float*>::type >::value));
 | 
			
		||||
  VERIFY(( internal::is_same<const float,internal::remove_pointer<const float*>::type >::value));
 | 
			
		||||
  VERIFY(( internal::is_same<float,internal::remove_pointer<float* const >::type >::value));
 | 
			
		||||
  
 | 
			
		||||
  VERIFY(( internal::is_convertible<float,double>::value ));
 | 
			
		||||
  VERIFY(( internal::is_convertible<int,double>::value ));
 | 
			
		||||
  VERIFY(( internal::is_convertible<double,int>::value ));
 | 
			
		||||
  VERIFY((!internal::is_convertible<std::complex<double>,double>::value ));
 | 
			
		||||
  VERIFY(( internal::is_convertible<Array33f,Matrix3f>::value ));
 | 
			
		||||
//   VERIFY((!internal::is_convertible<Matrix3f,Matrix3d>::value )); //does not work because the conversion is prevented by a static assertion
 | 
			
		||||
  VERIFY((!internal::is_convertible<Array33f,int>::value ));
 | 
			
		||||
  VERIFY((!internal::is_convertible<MatrixXf,float>::value ));
 | 
			
		||||
  {
 | 
			
		||||
    float f;
 | 
			
		||||
    MatrixXf A, B;
 | 
			
		||||
    VectorXf a, b;
 | 
			
		||||
    VERIFY(( check_is_convertible(a.dot(b), f) ));
 | 
			
		||||
    VERIFY(( check_is_convertible(a.transpose()*b, f) ));
 | 
			
		||||
    VERIFY((!check_is_convertible(A*B, f) ));
 | 
			
		||||
    VERIFY(( check_is_convertible(A*B, A) ));
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  VERIFY(internal::meta_sqrt<1>::ret == 1);
 | 
			
		||||
  #define VERIFY_META_SQRT(X) VERIFY(internal::meta_sqrt<X>::ret == int(std::sqrt(double(X))))
 | 
			
		||||
  VERIFY_META_SQRT(2);
 | 
			
		||||
  VERIFY_META_SQRT(3);
 | 
			
		||||
  VERIFY_META_SQRT(4);
 | 
			
		||||
  VERIFY_META_SQRT(5);
 | 
			
		||||
  VERIFY_META_SQRT(6);
 | 
			
		||||
  VERIFY_META_SQRT(8);
 | 
			
		||||
  VERIFY_META_SQRT(9);
 | 
			
		||||
  VERIFY_META_SQRT(15);
 | 
			
		||||
  VERIFY_META_SQRT(16);
 | 
			
		||||
  VERIFY_META_SQRT(17);
 | 
			
		||||
  VERIFY_META_SQRT(255);
 | 
			
		||||
  VERIFY_META_SQRT(256);
 | 
			
		||||
  VERIFY_META_SQRT(257);
 | 
			
		||||
  VERIFY_META_SQRT(1023);
 | 
			
		||||
  VERIFY_META_SQRT(1024);
 | 
			
		||||
  VERIFY_META_SQRT(1025);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										25
									
								
								cs440-acg/ext/eigen/test/metis_support.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								cs440-acg/ext/eigen/test/metis_support.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2012 Désiré Nuentsa-Wakam <desire.nuentsa_wakam@inria.fr>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "sparse_solver.h"
 | 
			
		||||
#include <Eigen/SparseLU>
 | 
			
		||||
#include <Eigen/MetisSupport>
 | 
			
		||||
#include <unsupported/Eigen/SparseExtra>
 | 
			
		||||
 | 
			
		||||
template<typename T> void test_metis_T()
 | 
			
		||||
{
 | 
			
		||||
  SparseLU<SparseMatrix<T, ColMajor>, MetisOrdering<int> > sparselu_metis;
 | 
			
		||||
  
 | 
			
		||||
  check_sparse_square_solving(sparselu_metis); 
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_metis_support()
 | 
			
		||||
{
 | 
			
		||||
  CALL_SUBTEST_1(test_metis_T<double>());
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										46
									
								
								cs440-acg/ext/eigen/test/miscmatrices.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								cs440-acg/ext/eigen/test/miscmatrices.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void miscMatrices(const MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  /* this test covers the following files:
 | 
			
		||||
     DiagonalMatrix.h Ones.h
 | 
			
		||||
  */
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;
 | 
			
		||||
  Index rows = m.rows();
 | 
			
		||||
  Index cols = m.cols();
 | 
			
		||||
 | 
			
		||||
  Index r = internal::random<Index>(0, rows-1), r2 = internal::random<Index>(0, rows-1), c = internal::random<Index>(0, cols-1);
 | 
			
		||||
  VERIFY_IS_APPROX(MatrixType::Ones(rows,cols)(r,c), static_cast<Scalar>(1));
 | 
			
		||||
  MatrixType m1 = MatrixType::Ones(rows,cols);
 | 
			
		||||
  VERIFY_IS_APPROX(m1(r,c), static_cast<Scalar>(1));
 | 
			
		||||
  VectorType v1 = VectorType::Random(rows);
 | 
			
		||||
  v1[0];
 | 
			
		||||
  Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime>
 | 
			
		||||
  square(v1.asDiagonal());
 | 
			
		||||
  if(r==r2) VERIFY_IS_APPROX(square(r,r2), v1[r]);
 | 
			
		||||
  else VERIFY_IS_MUCH_SMALLER_THAN(square(r,r2), static_cast<Scalar>(1));
 | 
			
		||||
  square = MatrixType::Zero(rows, rows);
 | 
			
		||||
  square.diagonal() = VectorType::Ones(rows);
 | 
			
		||||
  VERIFY_IS_APPROX(square, MatrixType::Identity(rows, rows));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_miscmatrices()
 | 
			
		||||
{
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_1( miscMatrices(Matrix<float, 1, 1>()) );
 | 
			
		||||
    CALL_SUBTEST_2( miscMatrices(Matrix4d()) );
 | 
			
		||||
    CALL_SUBTEST_3( miscMatrices(MatrixXcf(3, 3)) );
 | 
			
		||||
    CALL_SUBTEST_4( miscMatrices(MatrixXi(8, 12)) );
 | 
			
		||||
    CALL_SUBTEST_5( miscMatrices(MatrixXcd(20, 20)) );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										328
									
								
								cs440-acg/ext/eigen/test/mixingtypes.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										328
									
								
								cs440-acg/ext/eigen/test/mixingtypes.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,328 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2008-2015 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#if defined(EIGEN_TEST_PART_7)
 | 
			
		||||
 | 
			
		||||
#ifndef EIGEN_NO_STATIC_ASSERT
 | 
			
		||||
#define EIGEN_NO_STATIC_ASSERT // turn static asserts into runtime asserts in order to check them
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// ignore double-promotion diagnostic for clang and gcc, if we check for static assertion anyway:
 | 
			
		||||
// TODO do the same for MSVC?
 | 
			
		||||
#if defined(__clang__)
 | 
			
		||||
#  if (__clang_major__ * 100 + __clang_minor__) >= 308
 | 
			
		||||
#    pragma clang diagnostic ignored "-Wdouble-promotion"
 | 
			
		||||
#  endif
 | 
			
		||||
#elif defined(__GNUC__)
 | 
			
		||||
  // TODO is there a minimal GCC version for this? At least g++-4.7 seems to be fine with this.
 | 
			
		||||
#  pragma GCC diagnostic ignored "-Wdouble-promotion"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if defined(EIGEN_TEST_PART_1) || defined(EIGEN_TEST_PART_2) || defined(EIGEN_TEST_PART_3)
 | 
			
		||||
 | 
			
		||||
#ifndef EIGEN_DONT_VECTORIZE
 | 
			
		||||
#define EIGEN_DONT_VECTORIZE
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static bool g_called;
 | 
			
		||||
#define EIGEN_SCALAR_BINARY_OP_PLUGIN { g_called |= (!internal::is_same<LhsScalar,RhsScalar>::value); }
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
 | 
			
		||||
using namespace std;
 | 
			
		||||
 | 
			
		||||
#define VERIFY_MIX_SCALAR(XPR,REF) \
 | 
			
		||||
  g_called = false; \
 | 
			
		||||
  VERIFY_IS_APPROX(XPR,REF); \
 | 
			
		||||
  VERIFY( g_called && #XPR" not properly optimized");
 | 
			
		||||
 | 
			
		||||
template<int SizeAtCompileType>
 | 
			
		||||
void raise_assertion(Index size = SizeAtCompileType)
 | 
			
		||||
{
 | 
			
		||||
  // VERIFY_RAISES_ASSERT(mf+md); // does not even compile
 | 
			
		||||
  Matrix<float, SizeAtCompileType, 1> vf; vf.setRandom(size);
 | 
			
		||||
  Matrix<double, SizeAtCompileType, 1> vd; vd.setRandom(size);
 | 
			
		||||
  VERIFY_RAISES_ASSERT(vf=vd);
 | 
			
		||||
  VERIFY_RAISES_ASSERT(vf+=vd);
 | 
			
		||||
  VERIFY_RAISES_ASSERT(vf-=vd);
 | 
			
		||||
  VERIFY_RAISES_ASSERT(vd=vf);
 | 
			
		||||
  VERIFY_RAISES_ASSERT(vd+=vf);
 | 
			
		||||
  VERIFY_RAISES_ASSERT(vd-=vf);
 | 
			
		||||
 | 
			
		||||
  //   vd.asDiagonal() * mf;    // does not even compile
 | 
			
		||||
  //   vcd.asDiagonal() * mf;   // does not even compile
 | 
			
		||||
 | 
			
		||||
#if 0 // we get other compilation errors here than just static asserts
 | 
			
		||||
  VERIFY_RAISES_ASSERT(vd.dot(vf));
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template<int SizeAtCompileType> void mixingtypes(int size = SizeAtCompileType)
 | 
			
		||||
{
 | 
			
		||||
  typedef std::complex<float>   CF;
 | 
			
		||||
  typedef std::complex<double>  CD;
 | 
			
		||||
  typedef Matrix<float, SizeAtCompileType, SizeAtCompileType> Mat_f;
 | 
			
		||||
  typedef Matrix<double, SizeAtCompileType, SizeAtCompileType> Mat_d;
 | 
			
		||||
  typedef Matrix<std::complex<float>, SizeAtCompileType, SizeAtCompileType> Mat_cf;
 | 
			
		||||
  typedef Matrix<std::complex<double>, SizeAtCompileType, SizeAtCompileType> Mat_cd;
 | 
			
		||||
  typedef Matrix<float, SizeAtCompileType, 1> Vec_f;
 | 
			
		||||
  typedef Matrix<double, SizeAtCompileType, 1> Vec_d;
 | 
			
		||||
  typedef Matrix<std::complex<float>, SizeAtCompileType, 1> Vec_cf;
 | 
			
		||||
  typedef Matrix<std::complex<double>, SizeAtCompileType, 1> Vec_cd;
 | 
			
		||||
 | 
			
		||||
  Mat_f mf    = Mat_f::Random(size,size);
 | 
			
		||||
  Mat_d md    = mf.template cast<double>();
 | 
			
		||||
  //Mat_d rd    = md;
 | 
			
		||||
  Mat_cf mcf  = Mat_cf::Random(size,size);
 | 
			
		||||
  Mat_cd mcd  = mcf.template cast<complex<double> >();
 | 
			
		||||
  Mat_cd rcd = mcd;
 | 
			
		||||
  Vec_f vf    = Vec_f::Random(size,1);
 | 
			
		||||
  Vec_d vd    = vf.template cast<double>();
 | 
			
		||||
  Vec_cf vcf  = Vec_cf::Random(size,1);
 | 
			
		||||
  Vec_cd vcd  = vcf.template cast<complex<double> >();
 | 
			
		||||
  float           sf  = internal::random<float>();
 | 
			
		||||
  double          sd  = internal::random<double>();
 | 
			
		||||
  complex<float>  scf = internal::random<complex<float> >();
 | 
			
		||||
  complex<double> scd = internal::random<complex<double> >();
 | 
			
		||||
 | 
			
		||||
  mf+mf;
 | 
			
		||||
 | 
			
		||||
  float  epsf = std::sqrt(std::numeric_limits<float> ::min EIGEN_EMPTY ());
 | 
			
		||||
  double epsd = std::sqrt(std::numeric_limits<double>::min EIGEN_EMPTY ());
 | 
			
		||||
 | 
			
		||||
  while(std::abs(sf )<epsf) sf  = internal::random<float>();
 | 
			
		||||
  while(std::abs(sd )<epsd) sd  = internal::random<double>();
 | 
			
		||||
  while(std::abs(scf)<epsf) scf = internal::random<CF>();
 | 
			
		||||
  while(std::abs(scd)<epsd) scd = internal::random<CD>();
 | 
			
		||||
 | 
			
		||||
  // check scalar products
 | 
			
		||||
  VERIFY_MIX_SCALAR(vcf * sf , vcf * complex<float>(sf));
 | 
			
		||||
  VERIFY_MIX_SCALAR(sd * vcd , complex<double>(sd) * vcd);
 | 
			
		||||
  VERIFY_MIX_SCALAR(vf * scf , vf.template cast<complex<float> >() * scf);
 | 
			
		||||
  VERIFY_MIX_SCALAR(scd * vd , scd * vd.template cast<complex<double> >());
 | 
			
		||||
 | 
			
		||||
  VERIFY_MIX_SCALAR(vcf * 2 , vcf * complex<float>(2));
 | 
			
		||||
  VERIFY_MIX_SCALAR(vcf * 2.1 , vcf * complex<float>(2.1));
 | 
			
		||||
  VERIFY_MIX_SCALAR(2 * vcf, vcf * complex<float>(2));
 | 
			
		||||
  VERIFY_MIX_SCALAR(2.1 * vcf , vcf * complex<float>(2.1));
 | 
			
		||||
 | 
			
		||||
  // check scalar quotients
 | 
			
		||||
  VERIFY_MIX_SCALAR(vcf / sf , vcf / complex<float>(sf));
 | 
			
		||||
  VERIFY_MIX_SCALAR(vf / scf , vf.template cast<complex<float> >() / scf);
 | 
			
		||||
  VERIFY_MIX_SCALAR(vf.array()  / scf, vf.template cast<complex<float> >().array() / scf);
 | 
			
		||||
  VERIFY_MIX_SCALAR(scd / vd.array() , scd / vd.template cast<complex<double> >().array());
 | 
			
		||||
 | 
			
		||||
  // check scalar increment
 | 
			
		||||
  VERIFY_MIX_SCALAR(vcf.array() + sf , vcf.array() + complex<float>(sf));
 | 
			
		||||
  VERIFY_MIX_SCALAR(sd  + vcd.array(), complex<double>(sd) + vcd.array());
 | 
			
		||||
  VERIFY_MIX_SCALAR(vf.array()  + scf, vf.template cast<complex<float> >().array() + scf);
 | 
			
		||||
  VERIFY_MIX_SCALAR(scd + vd.array() , scd + vd.template cast<complex<double> >().array());
 | 
			
		||||
 | 
			
		||||
  // check scalar subtractions
 | 
			
		||||
  VERIFY_MIX_SCALAR(vcf.array() - sf , vcf.array() - complex<float>(sf));
 | 
			
		||||
  VERIFY_MIX_SCALAR(sd  - vcd.array(), complex<double>(sd) - vcd.array());
 | 
			
		||||
  VERIFY_MIX_SCALAR(vf.array()  - scf, vf.template cast<complex<float> >().array() - scf);
 | 
			
		||||
  VERIFY_MIX_SCALAR(scd - vd.array() , scd - vd.template cast<complex<double> >().array());
 | 
			
		||||
 | 
			
		||||
  // check scalar powers
 | 
			
		||||
  VERIFY_MIX_SCALAR( pow(vcf.array(), sf),        Eigen::pow(vcf.array(), complex<float>(sf)) );
 | 
			
		||||
  VERIFY_MIX_SCALAR( vcf.array().pow(sf) ,        Eigen::pow(vcf.array(), complex<float>(sf)) );
 | 
			
		||||
  VERIFY_MIX_SCALAR( pow(sd, vcd.array()),        Eigen::pow(complex<double>(sd), vcd.array()) );
 | 
			
		||||
  VERIFY_MIX_SCALAR( Eigen::pow(vf.array(), scf), Eigen::pow(vf.template cast<complex<float> >().array(), scf) );
 | 
			
		||||
  VERIFY_MIX_SCALAR( vf.array().pow(scf) ,        Eigen::pow(vf.template cast<complex<float> >().array(), scf) );
 | 
			
		||||
  VERIFY_MIX_SCALAR( Eigen::pow(scd, vd.array()), Eigen::pow(scd, vd.template cast<complex<double> >().array()) );
 | 
			
		||||
 | 
			
		||||
  // check dot product
 | 
			
		||||
  vf.dot(vf);
 | 
			
		||||
  VERIFY_IS_APPROX(vcf.dot(vf), vcf.dot(vf.template cast<complex<float> >()));
 | 
			
		||||
 | 
			
		||||
  // check diagonal product
 | 
			
		||||
  VERIFY_IS_APPROX(vf.asDiagonal() * mcf, vf.template cast<complex<float> >().asDiagonal() * mcf);
 | 
			
		||||
  VERIFY_IS_APPROX(vcd.asDiagonal() * md, vcd.asDiagonal() * md.template cast<complex<double> >());
 | 
			
		||||
  VERIFY_IS_APPROX(mcf * vf.asDiagonal(), mcf * vf.template cast<complex<float> >().asDiagonal());
 | 
			
		||||
  VERIFY_IS_APPROX(md * vcd.asDiagonal(), md.template cast<complex<double> >() * vcd.asDiagonal());
 | 
			
		||||
 | 
			
		||||
  // check inner product
 | 
			
		||||
  VERIFY_IS_APPROX((vf.transpose() * vcf).value(), (vf.template cast<complex<float> >().transpose() * vcf).value());
 | 
			
		||||
 | 
			
		||||
  // check outer product
 | 
			
		||||
  VERIFY_IS_APPROX((vf * vcf.transpose()).eval(), (vf.template cast<complex<float> >() * vcf.transpose()).eval());
 | 
			
		||||
 | 
			
		||||
  // coeff wise product
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX((vf * vcf.transpose()).eval(), (vf.template cast<complex<float> >() * vcf.transpose()).eval());
 | 
			
		||||
 | 
			
		||||
  Mat_cd mcd2 = mcd;
 | 
			
		||||
  VERIFY_IS_APPROX(mcd.array() *= md.array(), mcd2.array() *= md.array().template cast<std::complex<double> >());
 | 
			
		||||
  
 | 
			
		||||
  // check matrix-matrix products
 | 
			
		||||
  VERIFY_IS_APPROX(sd*md*mcd, (sd*md).template cast<CD>().eval()*mcd);
 | 
			
		||||
  VERIFY_IS_APPROX(sd*mcd*md, sd*mcd*md.template cast<CD>());
 | 
			
		||||
  VERIFY_IS_APPROX(scd*md*mcd, scd*md.template cast<CD>().eval()*mcd);
 | 
			
		||||
  VERIFY_IS_APPROX(scd*mcd*md, scd*mcd*md.template cast<CD>());
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(sf*mf*mcf, sf*mf.template cast<CF>()*mcf);
 | 
			
		||||
  VERIFY_IS_APPROX(sf*mcf*mf, sf*mcf*mf.template cast<CF>());
 | 
			
		||||
  VERIFY_IS_APPROX(scf*mf*mcf, scf*mf.template cast<CF>()*mcf);
 | 
			
		||||
  VERIFY_IS_APPROX(scf*mcf*mf, scf*mcf*mf.template cast<CF>());
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(sd*md.adjoint()*mcd, (sd*md).template cast<CD>().eval().adjoint()*mcd);
 | 
			
		||||
  VERIFY_IS_APPROX(sd*mcd.adjoint()*md, sd*mcd.adjoint()*md.template cast<CD>());
 | 
			
		||||
  VERIFY_IS_APPROX(sd*md.adjoint()*mcd.adjoint(), (sd*md).template cast<CD>().eval().adjoint()*mcd.adjoint());
 | 
			
		||||
  VERIFY_IS_APPROX(sd*mcd.adjoint()*md.adjoint(), sd*mcd.adjoint()*md.template cast<CD>().adjoint());
 | 
			
		||||
  VERIFY_IS_APPROX(sd*md*mcd.adjoint(), (sd*md).template cast<CD>().eval()*mcd.adjoint());
 | 
			
		||||
  VERIFY_IS_APPROX(sd*mcd*md.adjoint(), sd*mcd*md.template cast<CD>().adjoint());
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(sf*mf.adjoint()*mcf, (sf*mf).template cast<CF>().eval().adjoint()*mcf);
 | 
			
		||||
  VERIFY_IS_APPROX(sf*mcf.adjoint()*mf, sf*mcf.adjoint()*mf.template cast<CF>());
 | 
			
		||||
  VERIFY_IS_APPROX(sf*mf.adjoint()*mcf.adjoint(), (sf*mf).template cast<CF>().eval().adjoint()*mcf.adjoint());
 | 
			
		||||
  VERIFY_IS_APPROX(sf*mcf.adjoint()*mf.adjoint(), sf*mcf.adjoint()*mf.template cast<CF>().adjoint());
 | 
			
		||||
  VERIFY_IS_APPROX(sf*mf*mcf.adjoint(), (sf*mf).template cast<CF>().eval()*mcf.adjoint());
 | 
			
		||||
  VERIFY_IS_APPROX(sf*mcf*mf.adjoint(), sf*mcf*mf.template cast<CF>().adjoint());
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(sf*mf*vcf, (sf*mf).template cast<CF>().eval()*vcf);
 | 
			
		||||
  VERIFY_IS_APPROX(scf*mf*vcf,(scf*mf.template cast<CF>()).eval()*vcf);
 | 
			
		||||
  VERIFY_IS_APPROX(sf*mcf*vf, sf*mcf*vf.template cast<CF>());
 | 
			
		||||
  VERIFY_IS_APPROX(scf*mcf*vf,scf*mcf*vf.template cast<CF>());
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(sf*vcf.adjoint()*mf,  sf*vcf.adjoint()*mf.template cast<CF>().eval());
 | 
			
		||||
  VERIFY_IS_APPROX(scf*vcf.adjoint()*mf, scf*vcf.adjoint()*mf.template cast<CF>().eval());
 | 
			
		||||
  VERIFY_IS_APPROX(sf*vf.adjoint()*mcf,  sf*vf.adjoint().template cast<CF>().eval()*mcf);
 | 
			
		||||
  VERIFY_IS_APPROX(scf*vf.adjoint()*mcf, scf*vf.adjoint().template cast<CF>().eval()*mcf);
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(sd*md*vcd, (sd*md).template cast<CD>().eval()*vcd);
 | 
			
		||||
  VERIFY_IS_APPROX(scd*md*vcd,(scd*md.template cast<CD>()).eval()*vcd);
 | 
			
		||||
  VERIFY_IS_APPROX(sd*mcd*vd, sd*mcd*vd.template cast<CD>().eval());
 | 
			
		||||
  VERIFY_IS_APPROX(scd*mcd*vd,scd*mcd*vd.template cast<CD>().eval());
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(sd*vcd.adjoint()*md,  sd*vcd.adjoint()*md.template cast<CD>().eval());
 | 
			
		||||
  VERIFY_IS_APPROX(scd*vcd.adjoint()*md, scd*vcd.adjoint()*md.template cast<CD>().eval());
 | 
			
		||||
  VERIFY_IS_APPROX(sd*vd.adjoint()*mcd,  sd*vd.adjoint().template cast<CD>().eval()*mcd);
 | 
			
		||||
  VERIFY_IS_APPROX(scd*vd.adjoint()*mcd, scd*vd.adjoint().template cast<CD>().eval()*mcd);
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX( sd*vcd.adjoint()*md.template triangularView<Upper>(),  sd*vcd.adjoint()*md.template cast<CD>().eval().template triangularView<Upper>());
 | 
			
		||||
  VERIFY_IS_APPROX(scd*vcd.adjoint()*md.template triangularView<Lower>(), scd*vcd.adjoint()*md.template cast<CD>().eval().template triangularView<Lower>());
 | 
			
		||||
  VERIFY_IS_APPROX( sd*vcd.adjoint()*md.transpose().template triangularView<Upper>(),  sd*vcd.adjoint()*md.transpose().template cast<CD>().eval().template triangularView<Upper>());
 | 
			
		||||
  VERIFY_IS_APPROX(scd*vcd.adjoint()*md.transpose().template triangularView<Lower>(), scd*vcd.adjoint()*md.transpose().template cast<CD>().eval().template triangularView<Lower>());
 | 
			
		||||
  VERIFY_IS_APPROX( sd*vd.adjoint()*mcd.template triangularView<Lower>(),  sd*vd.adjoint().template cast<CD>().eval()*mcd.template triangularView<Lower>());
 | 
			
		||||
  VERIFY_IS_APPROX(scd*vd.adjoint()*mcd.template triangularView<Upper>(), scd*vd.adjoint().template cast<CD>().eval()*mcd.template triangularView<Upper>());
 | 
			
		||||
  VERIFY_IS_APPROX( sd*vd.adjoint()*mcd.transpose().template triangularView<Lower>(),  sd*vd.adjoint().template cast<CD>().eval()*mcd.transpose().template triangularView<Lower>());
 | 
			
		||||
  VERIFY_IS_APPROX(scd*vd.adjoint()*mcd.transpose().template triangularView<Upper>(), scd*vd.adjoint().template cast<CD>().eval()*mcd.transpose().template triangularView<Upper>());
 | 
			
		||||
 | 
			
		||||
  // Not supported yet: trmm
 | 
			
		||||
//   VERIFY_IS_APPROX(sd*mcd*md.template triangularView<Lower>(),  sd*mcd*md.template cast<CD>().eval().template triangularView<Lower>());
 | 
			
		||||
//   VERIFY_IS_APPROX(scd*mcd*md.template triangularView<Upper>(), scd*mcd*md.template cast<CD>().eval().template triangularView<Upper>());
 | 
			
		||||
//   VERIFY_IS_APPROX(sd*md*mcd.template triangularView<Lower>(),  sd*md.template cast<CD>().eval()*mcd.template triangularView<Lower>());
 | 
			
		||||
//   VERIFY_IS_APPROX(scd*md*mcd.template triangularView<Upper>(), scd*md.template cast<CD>().eval()*mcd.template triangularView<Upper>());
 | 
			
		||||
 | 
			
		||||
  // Not supported yet: symv
 | 
			
		||||
//   VERIFY_IS_APPROX(sd*vcd.adjoint()*md.template selfadjointView<Upper>(),  sd*vcd.adjoint()*md.template cast<CD>().eval().template selfadjointView<Upper>());
 | 
			
		||||
//   VERIFY_IS_APPROX(scd*vcd.adjoint()*md.template selfadjointView<Lower>(), scd*vcd.adjoint()*md.template cast<CD>().eval().template selfadjointView<Lower>());
 | 
			
		||||
//   VERIFY_IS_APPROX(sd*vd.adjoint()*mcd.template selfadjointView<Lower>(),  sd*vd.adjoint().template cast<CD>().eval()*mcd.template selfadjointView<Lower>());
 | 
			
		||||
//   VERIFY_IS_APPROX(scd*vd.adjoint()*mcd.template selfadjointView<Upper>(), scd*vd.adjoint().template cast<CD>().eval()*mcd.template selfadjointView<Upper>());
 | 
			
		||||
 | 
			
		||||
  // Not supported yet: symm
 | 
			
		||||
//   VERIFY_IS_APPROX(sd*vcd.adjoint()*md.template selfadjointView<Upper>(),  sd*vcd.adjoint()*md.template cast<CD>().eval().template selfadjointView<Upper>());
 | 
			
		||||
//   VERIFY_IS_APPROX(scd*vcd.adjoint()*md.template selfadjointView<Upper>(), scd*vcd.adjoint()*md.template cast<CD>().eval().template selfadjointView<Upper>());
 | 
			
		||||
//   VERIFY_IS_APPROX(sd*vd.adjoint()*mcd.template selfadjointView<Upper>(),  sd*vd.adjoint().template cast<CD>().eval()*mcd.template selfadjointView<Upper>());
 | 
			
		||||
//   VERIFY_IS_APPROX(scd*vd.adjoint()*mcd.template selfadjointView<Upper>(), scd*vd.adjoint().template cast<CD>().eval()*mcd.template selfadjointView<Upper>());
 | 
			
		||||
 | 
			
		||||
  rcd.setZero();
 | 
			
		||||
  VERIFY_IS_APPROX(Mat_cd(rcd.template triangularView<Upper>() = sd * mcd * md),
 | 
			
		||||
                   Mat_cd((sd * mcd * md.template cast<CD>().eval()).template triangularView<Upper>()));
 | 
			
		||||
  VERIFY_IS_APPROX(Mat_cd(rcd.template triangularView<Upper>() = sd * md * mcd),
 | 
			
		||||
                   Mat_cd((sd * md.template cast<CD>().eval() * mcd).template triangularView<Upper>()));
 | 
			
		||||
  VERIFY_IS_APPROX(Mat_cd(rcd.template triangularView<Upper>() = scd * mcd * md),
 | 
			
		||||
                   Mat_cd((scd * mcd * md.template cast<CD>().eval()).template triangularView<Upper>()));
 | 
			
		||||
  VERIFY_IS_APPROX(Mat_cd(rcd.template triangularView<Upper>() = scd * md * mcd),
 | 
			
		||||
                   Mat_cd((scd * md.template cast<CD>().eval() * mcd).template triangularView<Upper>()));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX( md.array()  * mcd.array(), md.template cast<CD>().eval().array() * mcd.array() );
 | 
			
		||||
  VERIFY_IS_APPROX( mcd.array() * md.array(),  mcd.array() * md.template cast<CD>().eval().array() );
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX( md.array()  + mcd.array(), md.template cast<CD>().eval().array() + mcd.array() );
 | 
			
		||||
  VERIFY_IS_APPROX( mcd.array() + md.array(),  mcd.array() + md.template cast<CD>().eval().array() );
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX( md.array()  - mcd.array(), md.template cast<CD>().eval().array() - mcd.array() );
 | 
			
		||||
  VERIFY_IS_APPROX( mcd.array() - md.array(),  mcd.array() - md.template cast<CD>().eval().array() );
 | 
			
		||||
 | 
			
		||||
  if(mcd.array().abs().minCoeff()>epsd)
 | 
			
		||||
  {
 | 
			
		||||
    VERIFY_IS_APPROX( md.array() / mcd.array(), md.template cast<CD>().eval().array() / mcd.array() );
 | 
			
		||||
  }
 | 
			
		||||
  if(md.array().abs().minCoeff()>epsd)
 | 
			
		||||
  {
 | 
			
		||||
    VERIFY_IS_APPROX( mcd.array() / md.array(), mcd.array() / md.template cast<CD>().eval().array() );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(md.array().abs().minCoeff()>epsd || mcd.array().abs().minCoeff()>epsd)
 | 
			
		||||
  {
 | 
			
		||||
    VERIFY_IS_APPROX( md.array().pow(mcd.array()), md.template cast<CD>().eval().array().pow(mcd.array()) );
 | 
			
		||||
    VERIFY_IS_APPROX( mcd.array().pow(md.array()),  mcd.array().pow(md.template cast<CD>().eval().array()) );
 | 
			
		||||
 | 
			
		||||
    VERIFY_IS_APPROX( pow(md.array(),mcd.array()), md.template cast<CD>().eval().array().pow(mcd.array()) );
 | 
			
		||||
    VERIFY_IS_APPROX( pow(mcd.array(),md.array()),  mcd.array().pow(md.template cast<CD>().eval().array()) );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  rcd = mcd;
 | 
			
		||||
  VERIFY_IS_APPROX( rcd = md, md.template cast<CD>().eval() );
 | 
			
		||||
  rcd = mcd;
 | 
			
		||||
  VERIFY_IS_APPROX( rcd += md, mcd + md.template cast<CD>().eval() );
 | 
			
		||||
  rcd = mcd;
 | 
			
		||||
  VERIFY_IS_APPROX( rcd -= md, mcd - md.template cast<CD>().eval() );
 | 
			
		||||
  rcd = mcd;
 | 
			
		||||
  VERIFY_IS_APPROX( rcd.array() *= md.array(), mcd.array() * md.template cast<CD>().eval().array() );
 | 
			
		||||
  rcd = mcd;
 | 
			
		||||
  if(md.array().abs().minCoeff()>epsd)
 | 
			
		||||
  {
 | 
			
		||||
    VERIFY_IS_APPROX( rcd.array() /= md.array(), mcd.array() / md.template cast<CD>().eval().array() );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  rcd = mcd;
 | 
			
		||||
  VERIFY_IS_APPROX( rcd.noalias() += md + mcd*md, mcd + (md.template cast<CD>().eval()) + mcd*(md.template cast<CD>().eval()));
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX( rcd.noalias()  = md*md,       ((md*md).eval().template cast<CD>()) );
 | 
			
		||||
  rcd = mcd;
 | 
			
		||||
  VERIFY_IS_APPROX( rcd.noalias() += md*md, mcd + ((md*md).eval().template cast<CD>()) );
 | 
			
		||||
  rcd = mcd;
 | 
			
		||||
  VERIFY_IS_APPROX( rcd.noalias() -= md*md, mcd - ((md*md).eval().template cast<CD>()) );
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX( rcd.noalias()  = mcd + md*md,       mcd + ((md*md).eval().template cast<CD>()) );
 | 
			
		||||
  rcd = mcd;
 | 
			
		||||
  VERIFY_IS_APPROX( rcd.noalias() += mcd + md*md, mcd + mcd + ((md*md).eval().template cast<CD>()) );
 | 
			
		||||
  rcd = mcd;
 | 
			
		||||
  VERIFY_IS_APPROX( rcd.noalias() -= mcd + md*md,           - ((md*md).eval().template cast<CD>()) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_mixingtypes()
 | 
			
		||||
{
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_1(mixingtypes<3>());
 | 
			
		||||
    CALL_SUBTEST_2(mixingtypes<4>());
 | 
			
		||||
    CALL_SUBTEST_3(mixingtypes<Dynamic>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE)));
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_4(mixingtypes<3>());
 | 
			
		||||
    CALL_SUBTEST_5(mixingtypes<4>());
 | 
			
		||||
    CALL_SUBTEST_6(mixingtypes<Dynamic>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE)));
 | 
			
		||||
    CALL_SUBTEST_7(raise_assertion<Dynamic>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE)));
 | 
			
		||||
  }
 | 
			
		||||
  CALL_SUBTEST_7(raise_assertion<0>());
 | 
			
		||||
  CALL_SUBTEST_7(raise_assertion<3>());
 | 
			
		||||
  CALL_SUBTEST_7(raise_assertion<4>());
 | 
			
		||||
  CALL_SUBTEST_7(raise_assertion<Dynamic>(0));
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										22
									
								
								cs440-acg/ext/eigen/test/mpl2only.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								cs440-acg/ext/eigen/test/mpl2only.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2015 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#define EIGEN_MPL2_ONLY
 | 
			
		||||
#include <Eigen/Dense>
 | 
			
		||||
#include <Eigen/SparseCore>
 | 
			
		||||
#include <Eigen/SparseLU>
 | 
			
		||||
#include <Eigen/SparseQR>
 | 
			
		||||
#include <Eigen/Sparse>
 | 
			
		||||
#include <Eigen/IterativeLinearSolvers>
 | 
			
		||||
#include <Eigen/Eigen>
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										107
									
								
								cs440-acg/ext/eigen/test/nesting_ops.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								cs440-acg/ext/eigen/test/nesting_ops.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,107 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2010 Hauke Heibel <hauke.heibel@gmail.com>
 | 
			
		||||
// Copyright (C) 2015 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#define TEST_ENABLE_TEMPORARY_TRACKING
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
 | 
			
		||||
template <int N, typename XprType>
 | 
			
		||||
void use_n_times(const XprType &xpr)
 | 
			
		||||
{
 | 
			
		||||
  typename internal::nested_eval<XprType,N>::type mat(xpr);
 | 
			
		||||
  typename XprType::PlainObject res(mat.rows(), mat.cols());
 | 
			
		||||
  nb_temporaries--; // remove res
 | 
			
		||||
  res.setZero();
 | 
			
		||||
  for(int i=0; i<N; ++i)
 | 
			
		||||
    res += mat;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <int N, typename ReferenceType, typename XprType>
 | 
			
		||||
bool verify_eval_type(const XprType &, const ReferenceType&)
 | 
			
		||||
{
 | 
			
		||||
  typedef typename internal::nested_eval<XprType,N>::type EvalType;
 | 
			
		||||
  return internal::is_same<typename internal::remove_all<EvalType>::type, typename internal::remove_all<ReferenceType>::type>::value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename MatrixType> void run_nesting_ops_1(const MatrixType& _m)
 | 
			
		||||
{
 | 
			
		||||
  typename internal::nested_eval<MatrixType,2>::type m(_m);
 | 
			
		||||
 | 
			
		||||
  // Make really sure that we are in debug mode!
 | 
			
		||||
  VERIFY_RAISES_ASSERT(eigen_assert(false));
 | 
			
		||||
 | 
			
		||||
  // The only intention of these tests is to ensure that this code does
 | 
			
		||||
  // not trigger any asserts or segmentation faults... more to come.
 | 
			
		||||
  VERIFY_IS_APPROX( (m.transpose() * m).diagonal().sum(), (m.transpose() * m).diagonal().sum() );
 | 
			
		||||
  VERIFY_IS_APPROX( (m.transpose() * m).diagonal().array().abs().sum(), (m.transpose() * m).diagonal().array().abs().sum() );
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX( (m.transpose() * m).array().abs().sum(), (m.transpose() * m).array().abs().sum() );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename MatrixType> void run_nesting_ops_2(const MatrixType& _m)
 | 
			
		||||
{
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
  Index rows = _m.rows();
 | 
			
		||||
  Index cols = _m.cols();
 | 
			
		||||
  MatrixType m1 = MatrixType::Random(rows,cols);
 | 
			
		||||
  Matrix<Scalar,MatrixType::RowsAtCompileTime,MatrixType::ColsAtCompileTime,ColMajor> m2;
 | 
			
		||||
 | 
			
		||||
  if((MatrixType::SizeAtCompileTime==Dynamic))
 | 
			
		||||
  {
 | 
			
		||||
    VERIFY_EVALUATION_COUNT( use_n_times<1>(m1 + m1*m1), 1 );
 | 
			
		||||
    VERIFY_EVALUATION_COUNT( use_n_times<10>(m1 + m1*m1), 1 );
 | 
			
		||||
 | 
			
		||||
    VERIFY_EVALUATION_COUNT( use_n_times<1>(m1.template triangularView<Lower>().solve(m1.col(0))), 1 );
 | 
			
		||||
    VERIFY_EVALUATION_COUNT( use_n_times<10>(m1.template triangularView<Lower>().solve(m1.col(0))), 1 );
 | 
			
		||||
 | 
			
		||||
    VERIFY_EVALUATION_COUNT( use_n_times<1>(Scalar(2)*m1.template triangularView<Lower>().solve(m1.col(0))), 2 ); // FIXME could be one by applying the scaling in-place on the solve result
 | 
			
		||||
    VERIFY_EVALUATION_COUNT( use_n_times<1>(m1.col(0)+m1.template triangularView<Lower>().solve(m1.col(0))), 2 ); // FIXME could be one by adding m1.col() inplace
 | 
			
		||||
    VERIFY_EVALUATION_COUNT( use_n_times<10>(m1.col(0)+m1.template triangularView<Lower>().solve(m1.col(0))), 2 );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    VERIFY( verify_eval_type<10>(m1, m1) );
 | 
			
		||||
    if(!NumTraits<Scalar>::IsComplex)
 | 
			
		||||
    {
 | 
			
		||||
      VERIFY( verify_eval_type<3>(2*m1, 2*m1) );
 | 
			
		||||
      VERIFY( verify_eval_type<4>(2*m1, m1) );
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
      VERIFY( verify_eval_type<2>(2*m1, 2*m1) );
 | 
			
		||||
      VERIFY( verify_eval_type<3>(2*m1, m1) );
 | 
			
		||||
    }
 | 
			
		||||
    VERIFY( verify_eval_type<2>(m1+m1, m1+m1) );
 | 
			
		||||
    VERIFY( verify_eval_type<3>(m1+m1, m1) );
 | 
			
		||||
    VERIFY( verify_eval_type<1>(m1*m1.transpose(), m2) );
 | 
			
		||||
    VERIFY( verify_eval_type<1>(m1*(m1+m1).transpose(), m2) );
 | 
			
		||||
    VERIFY( verify_eval_type<2>(m1*m1.transpose(), m2) );
 | 
			
		||||
    VERIFY( verify_eval_type<1>(m1+m1*m1, m1) );
 | 
			
		||||
 | 
			
		||||
    VERIFY( verify_eval_type<1>(m1.template triangularView<Lower>().solve(m1), m1) );
 | 
			
		||||
    VERIFY( verify_eval_type<1>(m1+m1.template triangularView<Lower>().solve(m1), m1) );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void test_nesting_ops()
 | 
			
		||||
{
 | 
			
		||||
  CALL_SUBTEST_1(run_nesting_ops_1(MatrixXf::Random(25,25)));
 | 
			
		||||
  CALL_SUBTEST_2(run_nesting_ops_1(MatrixXcd::Random(25,25)));
 | 
			
		||||
  CALL_SUBTEST_3(run_nesting_ops_1(Matrix4f::Random()));
 | 
			
		||||
  CALL_SUBTEST_4(run_nesting_ops_1(Matrix2d::Random()));
 | 
			
		||||
 | 
			
		||||
  Index s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE);
 | 
			
		||||
  CALL_SUBTEST_1( run_nesting_ops_2(MatrixXf(s,s)) );
 | 
			
		||||
  CALL_SUBTEST_2( run_nesting_ops_2(MatrixXcd(s,s)) );
 | 
			
		||||
  CALL_SUBTEST_3( run_nesting_ops_2(Matrix4f()) );
 | 
			
		||||
  CALL_SUBTEST_4( run_nesting_ops_2(Matrix2d()) );
 | 
			
		||||
  TEST_SET_BUT_UNUSED_VARIABLE(s)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										228
									
								
								cs440-acg/ext/eigen/test/nomalloc.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										228
									
								
								cs440-acg/ext/eigen/test/nomalloc.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,228 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
// discard stack allocation as that too bypasses malloc
 | 
			
		||||
#define EIGEN_STACK_ALLOCATION_LIMIT 0
 | 
			
		||||
// heap allocation will raise an assert if enabled at runtime
 | 
			
		||||
#define EIGEN_RUNTIME_NO_MALLOC
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
#include <Eigen/Cholesky>
 | 
			
		||||
#include <Eigen/Eigenvalues>
 | 
			
		||||
#include <Eigen/LU>
 | 
			
		||||
#include <Eigen/QR>
 | 
			
		||||
#include <Eigen/SVD>
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void nomalloc(const MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  /* this test check no dynamic memory allocation are issued with fixed-size matrices
 | 
			
		||||
  */
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
 | 
			
		||||
  Index rows = m.rows();
 | 
			
		||||
  Index cols = m.cols();
 | 
			
		||||
 | 
			
		||||
  MatrixType m1 = MatrixType::Random(rows, cols),
 | 
			
		||||
             m2 = MatrixType::Random(rows, cols),
 | 
			
		||||
             m3(rows, cols);
 | 
			
		||||
 | 
			
		||||
  Scalar s1 = internal::random<Scalar>();
 | 
			
		||||
 | 
			
		||||
  Index r = internal::random<Index>(0, rows-1),
 | 
			
		||||
        c = internal::random<Index>(0, cols-1);
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX((m1+m2)*s1,              s1*m1+s1*m2);
 | 
			
		||||
  VERIFY_IS_APPROX((m1+m2)(r,c), (m1(r,c))+(m2(r,c)));
 | 
			
		||||
  VERIFY_IS_APPROX(m1.cwiseProduct(m1.block(0,0,rows,cols)), (m1.array()*m1.array()).matrix());
 | 
			
		||||
  VERIFY_IS_APPROX((m1*m1.transpose())*m2,  m1*(m1.transpose()*m2));
 | 
			
		||||
  
 | 
			
		||||
  m2.col(0).noalias() = m1 * m1.col(0);
 | 
			
		||||
  m2.col(0).noalias() -= m1.adjoint() * m1.col(0);
 | 
			
		||||
  m2.col(0).noalias() -= m1 * m1.row(0).adjoint();
 | 
			
		||||
  m2.col(0).noalias() -= m1.adjoint() * m1.row(0).adjoint();
 | 
			
		||||
 | 
			
		||||
  m2.row(0).noalias() = m1.row(0) * m1;
 | 
			
		||||
  m2.row(0).noalias() -= m1.row(0) * m1.adjoint();
 | 
			
		||||
  m2.row(0).noalias() -= m1.col(0).adjoint() * m1;
 | 
			
		||||
  m2.row(0).noalias() -= m1.col(0).adjoint() * m1.adjoint();
 | 
			
		||||
  VERIFY_IS_APPROX(m2,m2);
 | 
			
		||||
  
 | 
			
		||||
  m2.col(0).noalias() = m1.template triangularView<Upper>() * m1.col(0);
 | 
			
		||||
  m2.col(0).noalias() -= m1.adjoint().template triangularView<Upper>() * m1.col(0);
 | 
			
		||||
  m2.col(0).noalias() -= m1.template triangularView<Upper>() * m1.row(0).adjoint();
 | 
			
		||||
  m2.col(0).noalias() -= m1.adjoint().template triangularView<Upper>() * m1.row(0).adjoint();
 | 
			
		||||
 | 
			
		||||
  m2.row(0).noalias() = m1.row(0) * m1.template triangularView<Upper>();
 | 
			
		||||
  m2.row(0).noalias() -= m1.row(0) * m1.adjoint().template triangularView<Upper>();
 | 
			
		||||
  m2.row(0).noalias() -= m1.col(0).adjoint() * m1.template triangularView<Upper>();
 | 
			
		||||
  m2.row(0).noalias() -= m1.col(0).adjoint() * m1.adjoint().template triangularView<Upper>();
 | 
			
		||||
  VERIFY_IS_APPROX(m2,m2);
 | 
			
		||||
  
 | 
			
		||||
  m2.col(0).noalias() = m1.template selfadjointView<Upper>() * m1.col(0);
 | 
			
		||||
  m2.col(0).noalias() -= m1.adjoint().template selfadjointView<Upper>() * m1.col(0);
 | 
			
		||||
  m2.col(0).noalias() -= m1.template selfadjointView<Upper>() * m1.row(0).adjoint();
 | 
			
		||||
  m2.col(0).noalias() -= m1.adjoint().template selfadjointView<Upper>() * m1.row(0).adjoint();
 | 
			
		||||
 | 
			
		||||
  m2.row(0).noalias() = m1.row(0) * m1.template selfadjointView<Upper>();
 | 
			
		||||
  m2.row(0).noalias() -= m1.row(0) * m1.adjoint().template selfadjointView<Upper>();
 | 
			
		||||
  m2.row(0).noalias() -= m1.col(0).adjoint() * m1.template selfadjointView<Upper>();
 | 
			
		||||
  m2.row(0).noalias() -= m1.col(0).adjoint() * m1.adjoint().template selfadjointView<Upper>();
 | 
			
		||||
  VERIFY_IS_APPROX(m2,m2);
 | 
			
		||||
  
 | 
			
		||||
  m2.template selfadjointView<Lower>().rankUpdate(m1.col(0),-1);
 | 
			
		||||
  m2.template selfadjointView<Upper>().rankUpdate(m1.row(0),-1);
 | 
			
		||||
  m2.template selfadjointView<Lower>().rankUpdate(m1.col(0), m1.col(0)); // rank-2
 | 
			
		||||
 | 
			
		||||
  // The following fancy matrix-matrix products are not safe yet regarding static allocation
 | 
			
		||||
  m2.template selfadjointView<Lower>().rankUpdate(m1);
 | 
			
		||||
  m2 += m2.template triangularView<Upper>() * m1;
 | 
			
		||||
  m2.template triangularView<Upper>() = m2 * m2;
 | 
			
		||||
  m1 += m1.template selfadjointView<Lower>() * m2;
 | 
			
		||||
  VERIFY_IS_APPROX(m2,m2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Scalar>
 | 
			
		||||
void ctms_decompositions()
 | 
			
		||||
{
 | 
			
		||||
  const int maxSize = 16;
 | 
			
		||||
  const int size    = 12;
 | 
			
		||||
 | 
			
		||||
  typedef Eigen::Matrix<Scalar,
 | 
			
		||||
                        Eigen::Dynamic, Eigen::Dynamic,
 | 
			
		||||
                        0,
 | 
			
		||||
                        maxSize, maxSize> Matrix;
 | 
			
		||||
 | 
			
		||||
  typedef Eigen::Matrix<Scalar,
 | 
			
		||||
                        Eigen::Dynamic, 1,
 | 
			
		||||
                        0,
 | 
			
		||||
                        maxSize, 1> Vector;
 | 
			
		||||
 | 
			
		||||
  typedef Eigen::Matrix<std::complex<Scalar>,
 | 
			
		||||
                        Eigen::Dynamic, Eigen::Dynamic,
 | 
			
		||||
                        0,
 | 
			
		||||
                        maxSize, maxSize> ComplexMatrix;
 | 
			
		||||
 | 
			
		||||
  const Matrix A(Matrix::Random(size, size)), B(Matrix::Random(size, size));
 | 
			
		||||
  Matrix X(size,size);
 | 
			
		||||
  const ComplexMatrix complexA(ComplexMatrix::Random(size, size));
 | 
			
		||||
  const Matrix saA = A.adjoint() * A;
 | 
			
		||||
  const Vector b(Vector::Random(size));
 | 
			
		||||
  Vector x(size);
 | 
			
		||||
 | 
			
		||||
  // Cholesky module
 | 
			
		||||
  Eigen::LLT<Matrix>  LLT;  LLT.compute(A);
 | 
			
		||||
  X = LLT.solve(B);
 | 
			
		||||
  x = LLT.solve(b);
 | 
			
		||||
  Eigen::LDLT<Matrix> LDLT; LDLT.compute(A);
 | 
			
		||||
  X = LDLT.solve(B);
 | 
			
		||||
  x = LDLT.solve(b);
 | 
			
		||||
 | 
			
		||||
  // Eigenvalues module
 | 
			
		||||
  Eigen::HessenbergDecomposition<ComplexMatrix> hessDecomp;        hessDecomp.compute(complexA);
 | 
			
		||||
  Eigen::ComplexSchur<ComplexMatrix>            cSchur(size);      cSchur.compute(complexA);
 | 
			
		||||
  Eigen::ComplexEigenSolver<ComplexMatrix>      cEigSolver;        cEigSolver.compute(complexA);
 | 
			
		||||
  Eigen::EigenSolver<Matrix>                    eigSolver;         eigSolver.compute(A);
 | 
			
		||||
  Eigen::SelfAdjointEigenSolver<Matrix>         saEigSolver(size); saEigSolver.compute(saA);
 | 
			
		||||
  Eigen::Tridiagonalization<Matrix>             tridiag;           tridiag.compute(saA);
 | 
			
		||||
 | 
			
		||||
  // LU module
 | 
			
		||||
  Eigen::PartialPivLU<Matrix> ppLU; ppLU.compute(A);
 | 
			
		||||
  X = ppLU.solve(B);
 | 
			
		||||
  x = ppLU.solve(b);
 | 
			
		||||
  Eigen::FullPivLU<Matrix>    fpLU; fpLU.compute(A);
 | 
			
		||||
  X = fpLU.solve(B);
 | 
			
		||||
  x = fpLU.solve(b);
 | 
			
		||||
 | 
			
		||||
  // QR module
 | 
			
		||||
  Eigen::HouseholderQR<Matrix>        hQR;  hQR.compute(A);
 | 
			
		||||
  X = hQR.solve(B);
 | 
			
		||||
  x = hQR.solve(b);
 | 
			
		||||
  Eigen::ColPivHouseholderQR<Matrix>  cpQR; cpQR.compute(A);
 | 
			
		||||
  X = cpQR.solve(B);
 | 
			
		||||
  x = cpQR.solve(b);
 | 
			
		||||
  Eigen::FullPivHouseholderQR<Matrix> fpQR; fpQR.compute(A);
 | 
			
		||||
  // FIXME X = fpQR.solve(B);
 | 
			
		||||
  x = fpQR.solve(b);
 | 
			
		||||
 | 
			
		||||
  // SVD module
 | 
			
		||||
  Eigen::JacobiSVD<Matrix> jSVD; jSVD.compute(A, ComputeFullU | ComputeFullV);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_zerosized() {
 | 
			
		||||
  // default constructors:
 | 
			
		||||
  Eigen::MatrixXd A;
 | 
			
		||||
  Eigen::VectorXd v;
 | 
			
		||||
  // explicit zero-sized:
 | 
			
		||||
  Eigen::ArrayXXd A0(0,0);
 | 
			
		||||
  Eigen::ArrayXd v0(0);
 | 
			
		||||
 | 
			
		||||
  // assigning empty objects to each other:
 | 
			
		||||
  A=A0;
 | 
			
		||||
  v=v0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void test_reference(const MatrixType& m) {
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
  enum { Flag          =  MatrixType::IsRowMajor ? Eigen::RowMajor : Eigen::ColMajor};
 | 
			
		||||
  enum { TransposeFlag = !MatrixType::IsRowMajor ? Eigen::RowMajor : Eigen::ColMajor};
 | 
			
		||||
  typename MatrixType::Index rows = m.rows(), cols=m.cols();
 | 
			
		||||
  typedef Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic, Flag         > MatrixX;
 | 
			
		||||
  typedef Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic, TransposeFlag> MatrixXT;
 | 
			
		||||
  // Dynamic reference:
 | 
			
		||||
  typedef Eigen::Ref<const MatrixX  > Ref;
 | 
			
		||||
  typedef Eigen::Ref<const MatrixXT > RefT;
 | 
			
		||||
 | 
			
		||||
  Ref r1(m);
 | 
			
		||||
  Ref r2(m.block(rows/3, cols/4, rows/2, cols/2));
 | 
			
		||||
  RefT r3(m.transpose());
 | 
			
		||||
  RefT r4(m.topLeftCorner(rows/2, cols/2).transpose());
 | 
			
		||||
 | 
			
		||||
  VERIFY_RAISES_ASSERT(RefT r5(m));
 | 
			
		||||
  VERIFY_RAISES_ASSERT(Ref r6(m.transpose()));
 | 
			
		||||
  VERIFY_RAISES_ASSERT(Ref r7(Scalar(2) * m));
 | 
			
		||||
 | 
			
		||||
  // Copy constructors shall also never malloc
 | 
			
		||||
  Ref r8 = r1;
 | 
			
		||||
  RefT r9 = r3;
 | 
			
		||||
 | 
			
		||||
  // Initializing from a compatible Ref shall also never malloc
 | 
			
		||||
  Eigen::Ref<const MatrixX, Unaligned, Stride<Dynamic, Dynamic> > r10=r8, r11=m;
 | 
			
		||||
 | 
			
		||||
  // Initializing from an incompatible Ref will malloc:
 | 
			
		||||
  typedef Eigen::Ref<const MatrixX, Aligned> RefAligned;
 | 
			
		||||
  VERIFY_RAISES_ASSERT(RefAligned r12=r10);
 | 
			
		||||
  VERIFY_RAISES_ASSERT(Ref r13=r10); // r10 has more dynamic strides
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_nomalloc()
 | 
			
		||||
{
 | 
			
		||||
  // create some dynamic objects
 | 
			
		||||
  Eigen::MatrixXd M1 = MatrixXd::Random(3,3);
 | 
			
		||||
  Ref<const MatrixXd> R1 = 2.0*M1; // Ref requires temporary
 | 
			
		||||
 | 
			
		||||
  // from here on prohibit malloc:
 | 
			
		||||
  Eigen::internal::set_is_malloc_allowed(false);
 | 
			
		||||
 | 
			
		||||
  // check that our operator new is indeed called:
 | 
			
		||||
  VERIFY_RAISES_ASSERT(MatrixXd dummy(MatrixXd::Random(3,3)));
 | 
			
		||||
  CALL_SUBTEST_1(nomalloc(Matrix<float, 1, 1>()) );
 | 
			
		||||
  CALL_SUBTEST_2(nomalloc(Matrix4d()) );
 | 
			
		||||
  CALL_SUBTEST_3(nomalloc(Matrix<float,32,32>()) );
 | 
			
		||||
  
 | 
			
		||||
  // Check decomposition modules with dynamic matrices that have a known compile-time max size (ctms)
 | 
			
		||||
  CALL_SUBTEST_4(ctms_decompositions<float>());
 | 
			
		||||
 | 
			
		||||
  CALL_SUBTEST_5(test_zerosized());
 | 
			
		||||
 | 
			
		||||
  CALL_SUBTEST_6(test_reference(Matrix<float,32,32>()));
 | 
			
		||||
  CALL_SUBTEST_7(test_reference(R1));
 | 
			
		||||
  CALL_SUBTEST_8(Ref<MatrixXd> R2 = M1.topRows<2>(); test_reference(R2));
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										304
									
								
								cs440-acg/ext/eigen/test/nullary.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										304
									
								
								cs440-acg/ext/eigen/test/nullary.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,304 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2010-2011 Jitse Niesen <jitse@maths.leeds.ac.uk>
 | 
			
		||||
// Copyright (C) 2016 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType>
 | 
			
		||||
bool equalsIdentity(const MatrixType& A)
 | 
			
		||||
{
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
  Scalar zero = static_cast<Scalar>(0);
 | 
			
		||||
 | 
			
		||||
  bool offDiagOK = true;
 | 
			
		||||
  for (Index i = 0; i < A.rows(); ++i) {
 | 
			
		||||
    for (Index j = i+1; j < A.cols(); ++j) {
 | 
			
		||||
      offDiagOK = offDiagOK && (A(i,j) == zero);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  for (Index i = 0; i < A.rows(); ++i) {
 | 
			
		||||
    for (Index j = 0; j < (std::min)(i, A.cols()); ++j) {
 | 
			
		||||
      offDiagOK = offDiagOK && (A(i,j) == zero);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool diagOK = (A.diagonal().array() == 1).all();
 | 
			
		||||
  return offDiagOK && diagOK;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename VectorType>
 | 
			
		||||
void check_extremity_accuracy(const VectorType &v, const typename VectorType::Scalar &low, const typename VectorType::Scalar &high)
 | 
			
		||||
{
 | 
			
		||||
  typedef typename VectorType::Scalar Scalar;
 | 
			
		||||
  typedef typename VectorType::RealScalar RealScalar;
 | 
			
		||||
 | 
			
		||||
  RealScalar prec = internal::is_same<RealScalar,float>::value ? NumTraits<RealScalar>::dummy_precision()*10 : NumTraits<RealScalar>::dummy_precision()/10;
 | 
			
		||||
  Index size = v.size();
 | 
			
		||||
 | 
			
		||||
  if(size<20)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  for (int i=0; i<size; ++i)
 | 
			
		||||
  {
 | 
			
		||||
    if(i<5 || i>size-6)
 | 
			
		||||
    {
 | 
			
		||||
      Scalar ref = (low*RealScalar(size-i-1))/RealScalar(size-1) + (high*RealScalar(i))/RealScalar(size-1);
 | 
			
		||||
      if(std::abs(ref)>1)
 | 
			
		||||
      {
 | 
			
		||||
        if(!internal::isApprox(v(i), ref, prec))
 | 
			
		||||
          std::cout << v(i) << " != " << ref << "  ; relative error: " << std::abs((v(i)-ref)/ref) << "  ; required precision: " << prec << "  ; range: " << low << "," << high << "  ; i: " << i << "\n";
 | 
			
		||||
        VERIFY(internal::isApprox(v(i), (low*RealScalar(size-i-1))/RealScalar(size-1) + (high*RealScalar(i))/RealScalar(size-1), prec));
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename VectorType>
 | 
			
		||||
void testVectorType(const VectorType& base)
 | 
			
		||||
{
 | 
			
		||||
  typedef typename VectorType::Scalar Scalar;
 | 
			
		||||
  typedef typename VectorType::RealScalar RealScalar;
 | 
			
		||||
 | 
			
		||||
  const Index size = base.size();
 | 
			
		||||
  
 | 
			
		||||
  Scalar high = internal::random<Scalar>(-500,500);
 | 
			
		||||
  Scalar low = (size == 1 ? high : internal::random<Scalar>(-500,500));
 | 
			
		||||
  if (low>high) std::swap(low,high);
 | 
			
		||||
 | 
			
		||||
  // check low==high
 | 
			
		||||
  if(internal::random<float>(0.f,1.f)<0.05f)
 | 
			
		||||
    low = high;
 | 
			
		||||
  // check abs(low) >> abs(high)
 | 
			
		||||
  else if(size>2 && std::numeric_limits<RealScalar>::max_exponent10>0 && internal::random<float>(0.f,1.f)<0.1f)
 | 
			
		||||
    low = -internal::random<Scalar>(1,2) * RealScalar(std::pow(RealScalar(10),std::numeric_limits<RealScalar>::max_exponent10/2));
 | 
			
		||||
 | 
			
		||||
  const Scalar step = ((size == 1) ? 1 : (high-low)/(size-1));
 | 
			
		||||
 | 
			
		||||
  // check whether the result yields what we expect it to do
 | 
			
		||||
  VectorType m(base);
 | 
			
		||||
  m.setLinSpaced(size,low,high);
 | 
			
		||||
 | 
			
		||||
  if(!NumTraits<Scalar>::IsInteger)
 | 
			
		||||
  {
 | 
			
		||||
    VectorType n(size);
 | 
			
		||||
    for (int i=0; i<size; ++i)
 | 
			
		||||
      n(i) = low+i*step;
 | 
			
		||||
    VERIFY_IS_APPROX(m,n);
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST( check_extremity_accuracy(m, low, high) );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if((!NumTraits<Scalar>::IsInteger) || ((high-low)>=size && (Index(high-low)%(size-1))==0) || (Index(high-low+1)<size && (size%Index(high-low+1))==0))
 | 
			
		||||
  {
 | 
			
		||||
    VectorType n(size);
 | 
			
		||||
    if((!NumTraits<Scalar>::IsInteger) || (high-low>=size))
 | 
			
		||||
      for (int i=0; i<size; ++i)
 | 
			
		||||
        n(i) = size==1 ? low : (low + ((high-low)*Scalar(i))/(size-1));
 | 
			
		||||
    else
 | 
			
		||||
      for (int i=0; i<size; ++i)
 | 
			
		||||
        n(i) = size==1 ? low : low + Scalar((double(high-low+1)*double(i))/double(size));
 | 
			
		||||
    VERIFY_IS_APPROX(m,n);
 | 
			
		||||
 | 
			
		||||
    // random access version
 | 
			
		||||
    m = VectorType::LinSpaced(size,low,high);
 | 
			
		||||
    VERIFY_IS_APPROX(m,n);
 | 
			
		||||
    VERIFY( internal::isApprox(m(m.size()-1),high) );
 | 
			
		||||
    VERIFY( size==1 || internal::isApprox(m(0),low) );
 | 
			
		||||
    VERIFY_IS_EQUAL(m(m.size()-1) , high);
 | 
			
		||||
    if(!NumTraits<Scalar>::IsInteger)
 | 
			
		||||
      CALL_SUBTEST( check_extremity_accuracy(m, low, high) );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  VERIFY( m(m.size()-1) <= high );
 | 
			
		||||
  VERIFY( (m.array() <= high).all() );
 | 
			
		||||
  VERIFY( (m.array() >= low).all() );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  VERIFY( m(m.size()-1) >= low );
 | 
			
		||||
  if(size>=1)
 | 
			
		||||
  {
 | 
			
		||||
    VERIFY( internal::isApprox(m(0),low) );
 | 
			
		||||
    VERIFY_IS_EQUAL(m(0) , low);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // check whether everything works with row and col major vectors
 | 
			
		||||
  Matrix<Scalar,Dynamic,1> row_vector(size);
 | 
			
		||||
  Matrix<Scalar,1,Dynamic> col_vector(size);
 | 
			
		||||
  row_vector.setLinSpaced(size,low,high);
 | 
			
		||||
  col_vector.setLinSpaced(size,low,high);
 | 
			
		||||
  // when using the extended precision (e.g., FPU) the relative error might exceed 1 bit
 | 
			
		||||
  // when computing the squared sum in isApprox, thus the 2x factor.
 | 
			
		||||
  VERIFY( row_vector.isApprox(col_vector.transpose(), Scalar(2)*NumTraits<Scalar>::epsilon()));
 | 
			
		||||
 | 
			
		||||
  Matrix<Scalar,Dynamic,1> size_changer(size+50);
 | 
			
		||||
  size_changer.setLinSpaced(size,low,high);
 | 
			
		||||
  VERIFY( size_changer.size() == size );
 | 
			
		||||
 | 
			
		||||
  typedef Matrix<Scalar,1,1> ScalarMatrix;
 | 
			
		||||
  ScalarMatrix scalar;
 | 
			
		||||
  scalar.setLinSpaced(1,low,high);
 | 
			
		||||
  VERIFY_IS_APPROX( scalar, ScalarMatrix::Constant(high) );
 | 
			
		||||
  VERIFY_IS_APPROX( ScalarMatrix::LinSpaced(1,low,high), ScalarMatrix::Constant(high) );
 | 
			
		||||
 | 
			
		||||
  // regression test for bug 526 (linear vectorized transversal)
 | 
			
		||||
  if (size > 1 && (!NumTraits<Scalar>::IsInteger)) {
 | 
			
		||||
    m.tail(size-1).setLinSpaced(low, high);
 | 
			
		||||
    VERIFY_IS_APPROX(m(size-1), high);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // regression test for bug 1383 (LinSpaced with empty size/range)
 | 
			
		||||
  {
 | 
			
		||||
    Index n0 = VectorType::SizeAtCompileTime==Dynamic ? 0 : VectorType::SizeAtCompileTime;
 | 
			
		||||
    low = internal::random<Scalar>();
 | 
			
		||||
    m = VectorType::LinSpaced(n0,low,low-1);
 | 
			
		||||
    VERIFY(m.size()==n0);
 | 
			
		||||
 | 
			
		||||
    if(VectorType::SizeAtCompileTime==Dynamic)
 | 
			
		||||
    {
 | 
			
		||||
      VERIFY_IS_EQUAL(VectorType::LinSpaced(n0,0,Scalar(n0-1)).sum(),Scalar(0));
 | 
			
		||||
      VERIFY_IS_EQUAL(VectorType::LinSpaced(n0,low,low-1).sum(),Scalar(0));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    m.setLinSpaced(n0,0,Scalar(n0-1));
 | 
			
		||||
    VERIFY(m.size()==n0);
 | 
			
		||||
    m.setLinSpaced(n0,low,low-1);
 | 
			
		||||
    VERIFY(m.size()==n0);
 | 
			
		||||
 | 
			
		||||
    // empty range only:
 | 
			
		||||
    VERIFY_IS_APPROX(VectorType::LinSpaced(size,low,low),VectorType::Constant(size,low));
 | 
			
		||||
    m.setLinSpaced(size,low,low);
 | 
			
		||||
    VERIFY_IS_APPROX(m,VectorType::Constant(size,low));
 | 
			
		||||
 | 
			
		||||
    if(NumTraits<Scalar>::IsInteger)
 | 
			
		||||
    {
 | 
			
		||||
      VERIFY_IS_APPROX( VectorType::LinSpaced(size,low,Scalar(low+size-1)), VectorType::LinSpaced(size,Scalar(low+size-1),low).reverse() );
 | 
			
		||||
 | 
			
		||||
      if(VectorType::SizeAtCompileTime==Dynamic)
 | 
			
		||||
      {
 | 
			
		||||
        // Check negative multiplicator path:
 | 
			
		||||
        for(Index k=1; k<5; ++k)
 | 
			
		||||
          VERIFY_IS_APPROX( VectorType::LinSpaced(size,low,Scalar(low+(size-1)*k)), VectorType::LinSpaced(size,Scalar(low+(size-1)*k),low).reverse() );
 | 
			
		||||
        // Check negative divisor path:
 | 
			
		||||
        for(Index k=1; k<5; ++k)
 | 
			
		||||
          VERIFY_IS_APPROX( VectorType::LinSpaced(size*k,low,Scalar(low+size-1)), VectorType::LinSpaced(size*k,Scalar(low+size-1),low).reverse() );
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType>
 | 
			
		||||
void testMatrixType(const MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  using std::abs;
 | 
			
		||||
  const Index rows = m.rows();
 | 
			
		||||
  const Index cols = m.cols();
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
  typedef typename MatrixType::RealScalar RealScalar;
 | 
			
		||||
 | 
			
		||||
  Scalar s1;
 | 
			
		||||
  do {
 | 
			
		||||
    s1 = internal::random<Scalar>();
 | 
			
		||||
  } while(abs(s1)<RealScalar(1e-5) && (!NumTraits<Scalar>::IsInteger));
 | 
			
		||||
 | 
			
		||||
  MatrixType A;
 | 
			
		||||
  A.setIdentity(rows, cols);
 | 
			
		||||
  VERIFY(equalsIdentity(A));
 | 
			
		||||
  VERIFY(equalsIdentity(MatrixType::Identity(rows, cols)));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  A = MatrixType::Constant(rows,cols,s1);
 | 
			
		||||
  Index i = internal::random<Index>(0,rows-1);
 | 
			
		||||
  Index j = internal::random<Index>(0,cols-1);
 | 
			
		||||
  VERIFY_IS_APPROX( MatrixType::Constant(rows,cols,s1)(i,j), s1 );
 | 
			
		||||
  VERIFY_IS_APPROX( MatrixType::Constant(rows,cols,s1).coeff(i,j), s1 );
 | 
			
		||||
  VERIFY_IS_APPROX( A(i,j), s1 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_nullary()
 | 
			
		||||
{
 | 
			
		||||
  CALL_SUBTEST_1( testMatrixType(Matrix2d()) );
 | 
			
		||||
  CALL_SUBTEST_2( testMatrixType(MatrixXcf(internal::random<int>(1,300),internal::random<int>(1,300))) );
 | 
			
		||||
  CALL_SUBTEST_3( testMatrixType(MatrixXf(internal::random<int>(1,300),internal::random<int>(1,300))) );
 | 
			
		||||
  
 | 
			
		||||
  for(int i = 0; i < g_repeat*10; i++) {
 | 
			
		||||
    CALL_SUBTEST_4( testVectorType(VectorXd(internal::random<int>(1,30000))) );
 | 
			
		||||
    CALL_SUBTEST_5( testVectorType(Vector4d()) );  // regression test for bug 232
 | 
			
		||||
    CALL_SUBTEST_6( testVectorType(Vector3d()) );
 | 
			
		||||
    CALL_SUBTEST_7( testVectorType(VectorXf(internal::random<int>(1,30000))) );
 | 
			
		||||
    CALL_SUBTEST_8( testVectorType(Vector3f()) );
 | 
			
		||||
    CALL_SUBTEST_8( testVectorType(Vector4f()) );
 | 
			
		||||
    CALL_SUBTEST_8( testVectorType(Matrix<float,8,1>()) );
 | 
			
		||||
    CALL_SUBTEST_8( testVectorType(Matrix<float,1,1>()) );
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_9( testVectorType(VectorXi(internal::random<int>(1,10))) );
 | 
			
		||||
    CALL_SUBTEST_9( testVectorType(VectorXi(internal::random<int>(9,300))) );
 | 
			
		||||
    CALL_SUBTEST_9( testVectorType(Matrix<int,1,1>()) );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
#ifdef EIGEN_TEST_PART_6
 | 
			
		||||
  // Assignment of a RowVectorXd to a MatrixXd (regression test for bug #79).
 | 
			
		||||
  VERIFY( (MatrixXd(RowVectorXd::LinSpaced(3, 0, 1)) - RowVector3d(0, 0.5, 1)).norm() < std::numeric_limits<double>::epsilon() );
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef EIGEN_TEST_PART_9
 | 
			
		||||
  // Check possible overflow issue
 | 
			
		||||
  {
 | 
			
		||||
    int n = 60000;
 | 
			
		||||
    ArrayXi a1(n), a2(n);
 | 
			
		||||
    a1.setLinSpaced(n, 0, n-1);
 | 
			
		||||
    for(int i=0; i<n; ++i)
 | 
			
		||||
      a2(i) = i;
 | 
			
		||||
    VERIFY_IS_APPROX(a1,a2);
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef EIGEN_TEST_PART_10
 | 
			
		||||
  // check some internal logic
 | 
			
		||||
  VERIFY((  internal::has_nullary_operator<internal::scalar_constant_op<double> >::value ));
 | 
			
		||||
  VERIFY(( !internal::has_unary_operator<internal::scalar_constant_op<double> >::value ));
 | 
			
		||||
  VERIFY(( !internal::has_binary_operator<internal::scalar_constant_op<double> >::value ));
 | 
			
		||||
  VERIFY((  internal::functor_has_linear_access<internal::scalar_constant_op<double> >::ret ));
 | 
			
		||||
 | 
			
		||||
  VERIFY(( !internal::has_nullary_operator<internal::scalar_identity_op<double> >::value ));
 | 
			
		||||
  VERIFY(( !internal::has_unary_operator<internal::scalar_identity_op<double> >::value ));
 | 
			
		||||
  VERIFY((  internal::has_binary_operator<internal::scalar_identity_op<double> >::value ));
 | 
			
		||||
  VERIFY(( !internal::functor_has_linear_access<internal::scalar_identity_op<double> >::ret ));
 | 
			
		||||
 | 
			
		||||
  VERIFY(( !internal::has_nullary_operator<internal::linspaced_op<float,float> >::value ));
 | 
			
		||||
  VERIFY((  internal::has_unary_operator<internal::linspaced_op<float,float> >::value ));
 | 
			
		||||
  VERIFY(( !internal::has_binary_operator<internal::linspaced_op<float,float> >::value ));
 | 
			
		||||
  VERIFY((  internal::functor_has_linear_access<internal::linspaced_op<float,float> >::ret ));
 | 
			
		||||
 | 
			
		||||
  // Regression unit test for a weird MSVC bug.
 | 
			
		||||
  // Search "nullary_wrapper_workaround_msvc" in CoreEvaluators.h for the details.
 | 
			
		||||
  // See also traits<Ref>::match.
 | 
			
		||||
  {
 | 
			
		||||
    MatrixXf A = MatrixXf::Random(3,3);
 | 
			
		||||
    Ref<const MatrixXf> R = 2.0*A;
 | 
			
		||||
    VERIFY_IS_APPROX(R, A+A);
 | 
			
		||||
 | 
			
		||||
    Ref<const MatrixXf> R1 = MatrixXf::Random(3,3)+A;
 | 
			
		||||
 | 
			
		||||
    VectorXi V = VectorXi::Random(3);
 | 
			
		||||
    Ref<const VectorXi> R2 = VectorXi::LinSpaced(3,1,3)+V;
 | 
			
		||||
    VERIFY_IS_APPROX(R2, V+Vector3i(1,2,3));
 | 
			
		||||
 | 
			
		||||
    VERIFY((  internal::has_nullary_operator<internal::scalar_constant_op<float> >::value ));
 | 
			
		||||
    VERIFY(( !internal::has_unary_operator<internal::scalar_constant_op<float> >::value ));
 | 
			
		||||
    VERIFY(( !internal::has_binary_operator<internal::scalar_constant_op<float> >::value ));
 | 
			
		||||
    VERIFY((  internal::functor_has_linear_access<internal::scalar_constant_op<float> >::ret ));
 | 
			
		||||
 | 
			
		||||
    VERIFY(( !internal::has_nullary_operator<internal::linspaced_op<int,int> >::value ));
 | 
			
		||||
    VERIFY((  internal::has_unary_operator<internal::linspaced_op<int,int> >::value ));
 | 
			
		||||
    VERIFY(( !internal::has_binary_operator<internal::linspaced_op<int,int> >::value ));
 | 
			
		||||
    VERIFY((  internal::functor_has_linear_access<internal::linspaced_op<int,int> >::ret ));
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										54
									
								
								cs440-acg/ext/eigen/test/numext.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								cs440-acg/ext/eigen/test/numext.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,54 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2017 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
void check_abs() {
 | 
			
		||||
  typedef typename NumTraits<T>::Real Real;
 | 
			
		||||
  Real zero(0);
 | 
			
		||||
 | 
			
		||||
  if(NumTraits<T>::IsSigned)
 | 
			
		||||
    VERIFY_IS_EQUAL(numext::abs(-T(1)), T(1));
 | 
			
		||||
  VERIFY_IS_EQUAL(numext::abs(T(0)), T(0));
 | 
			
		||||
  VERIFY_IS_EQUAL(numext::abs(T(1)), T(1));
 | 
			
		||||
 | 
			
		||||
  for(int k=0; k<g_repeat*100; ++k)
 | 
			
		||||
  {
 | 
			
		||||
    T x = internal::random<T>();
 | 
			
		||||
    if(!internal::is_same<T,bool>::value)
 | 
			
		||||
      x = x/Real(2);
 | 
			
		||||
    if(NumTraits<T>::IsSigned)
 | 
			
		||||
    {
 | 
			
		||||
      VERIFY_IS_EQUAL(numext::abs(x), numext::abs(-x));
 | 
			
		||||
      VERIFY( numext::abs(-x) >= zero );
 | 
			
		||||
    }
 | 
			
		||||
    VERIFY( numext::abs(x) >= zero );
 | 
			
		||||
    VERIFY_IS_APPROX( numext::abs2(x), numext::abs2(numext::abs(x)) );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_numext() {
 | 
			
		||||
  CALL_SUBTEST( check_abs<bool>() );
 | 
			
		||||
  CALL_SUBTEST( check_abs<signed char>() );
 | 
			
		||||
  CALL_SUBTEST( check_abs<unsigned char>() );
 | 
			
		||||
  CALL_SUBTEST( check_abs<short>() );
 | 
			
		||||
  CALL_SUBTEST( check_abs<unsigned short>() );
 | 
			
		||||
  CALL_SUBTEST( check_abs<int>() );
 | 
			
		||||
  CALL_SUBTEST( check_abs<unsigned int>() );
 | 
			
		||||
  CALL_SUBTEST( check_abs<long>() );
 | 
			
		||||
  CALL_SUBTEST( check_abs<unsigned long>() );
 | 
			
		||||
  CALL_SUBTEST( check_abs<half>() );
 | 
			
		||||
  CALL_SUBTEST( check_abs<float>() );
 | 
			
		||||
  CALL_SUBTEST( check_abs<double>() );
 | 
			
		||||
  CALL_SUBTEST( check_abs<long double>() );
 | 
			
		||||
 | 
			
		||||
  CALL_SUBTEST( check_abs<std::complex<float> >() );
 | 
			
		||||
  CALL_SUBTEST( check_abs<std::complex<double> >() );
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										636
									
								
								cs440-acg/ext/eigen/test/packetmath.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										636
									
								
								cs440-acg/ext/eigen/test/packetmath.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,636 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
#include "unsupported/Eigen/SpecialFunctions"
 | 
			
		||||
 | 
			
		||||
#if defined __GNUC__ && __GNUC__>=6
 | 
			
		||||
  #pragma GCC diagnostic ignored "-Wignored-attributes"
 | 
			
		||||
#endif
 | 
			
		||||
// using namespace Eigen;
 | 
			
		||||
 | 
			
		||||
namespace Eigen {
 | 
			
		||||
namespace internal {
 | 
			
		||||
template<typename T> T negate(const T& x) { return -x; }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NOTE: we disbale inlining for this function to workaround a GCC issue when using -O3 and the i387 FPU.
 | 
			
		||||
template<typename Scalar> EIGEN_DONT_INLINE
 | 
			
		||||
bool isApproxAbs(const Scalar& a, const Scalar& b, const typename NumTraits<Scalar>::Real& refvalue)
 | 
			
		||||
{
 | 
			
		||||
  return internal::isMuchSmallerThan(a-b, refvalue);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Scalar> bool areApproxAbs(const Scalar* a, const Scalar* b, int size, const typename NumTraits<Scalar>::Real& refvalue)
 | 
			
		||||
{
 | 
			
		||||
  for (int i=0; i<size; ++i)
 | 
			
		||||
  {
 | 
			
		||||
    if (!isApproxAbs(a[i],b[i],refvalue))
 | 
			
		||||
    {
 | 
			
		||||
      std::cout << "ref: [" << Map<const Matrix<Scalar,1,Dynamic> >(a,size) << "]" << " != vec: [" << Map<const Matrix<Scalar,1,Dynamic> >(b,size) << "]\n";
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Scalar> bool areApprox(const Scalar* a, const Scalar* b, int size)
 | 
			
		||||
{
 | 
			
		||||
  for (int i=0; i<size; ++i)
 | 
			
		||||
  {
 | 
			
		||||
    if (a[i]!=b[i] && !internal::isApprox(a[i],b[i]))
 | 
			
		||||
    {
 | 
			
		||||
      std::cout << "ref: [" << Map<const Matrix<Scalar,1,Dynamic> >(a,size) << "]" << " != vec: [" << Map<const Matrix<Scalar,1,Dynamic> >(b,size) << "]\n";
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define CHECK_CWISE1(REFOP, POP) { \
 | 
			
		||||
  for (int i=0; i<PacketSize; ++i) \
 | 
			
		||||
    ref[i] = REFOP(data1[i]); \
 | 
			
		||||
  internal::pstore(data2, POP(internal::pload<Packet>(data1))); \
 | 
			
		||||
  VERIFY(areApprox(ref, data2, PacketSize) && #POP); \
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<bool Cond,typename Packet>
 | 
			
		||||
struct packet_helper
 | 
			
		||||
{
 | 
			
		||||
  template<typename T>
 | 
			
		||||
  inline Packet load(const T* from) const { return internal::pload<Packet>(from); }
 | 
			
		||||
 | 
			
		||||
  template<typename T>
 | 
			
		||||
  inline void store(T* to, const Packet& x) const { internal::pstore(to,x); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename Packet>
 | 
			
		||||
struct packet_helper<false,Packet>
 | 
			
		||||
{
 | 
			
		||||
  template<typename T>
 | 
			
		||||
  inline T load(const T* from) const { return *from; }
 | 
			
		||||
 | 
			
		||||
  template<typename T>
 | 
			
		||||
  inline void store(T* to, const T& x) const { *to = x; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define CHECK_CWISE1_IF(COND, REFOP, POP) if(COND) { \
 | 
			
		||||
  packet_helper<COND,Packet> h; \
 | 
			
		||||
  for (int i=0; i<PacketSize; ++i) \
 | 
			
		||||
    ref[i] = REFOP(data1[i]); \
 | 
			
		||||
  h.store(data2, POP(h.load(data1))); \
 | 
			
		||||
  VERIFY(areApprox(ref, data2, PacketSize) && #POP); \
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define CHECK_CWISE2_IF(COND, REFOP, POP) if(COND) { \
 | 
			
		||||
  packet_helper<COND,Packet> h; \
 | 
			
		||||
  for (int i=0; i<PacketSize; ++i) \
 | 
			
		||||
    ref[i] = REFOP(data1[i], data1[i+PacketSize]); \
 | 
			
		||||
  h.store(data2, POP(h.load(data1),h.load(data1+PacketSize))); \
 | 
			
		||||
  VERIFY(areApprox(ref, data2, PacketSize) && #POP); \
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define REF_ADD(a,b) ((a)+(b))
 | 
			
		||||
#define REF_SUB(a,b) ((a)-(b))
 | 
			
		||||
#define REF_MUL(a,b) ((a)*(b))
 | 
			
		||||
#define REF_DIV(a,b) ((a)/(b))
 | 
			
		||||
 | 
			
		||||
template<typename Scalar> void packetmath()
 | 
			
		||||
{
 | 
			
		||||
  using std::abs;
 | 
			
		||||
  typedef internal::packet_traits<Scalar> PacketTraits;
 | 
			
		||||
  typedef typename PacketTraits::type Packet;
 | 
			
		||||
  const int PacketSize = PacketTraits::size;
 | 
			
		||||
  typedef typename NumTraits<Scalar>::Real RealScalar;
 | 
			
		||||
 | 
			
		||||
  const int max_size = PacketSize > 4 ? PacketSize : 4;
 | 
			
		||||
  const int size = PacketSize*max_size;
 | 
			
		||||
  EIGEN_ALIGN_MAX Scalar data1[size];
 | 
			
		||||
  EIGEN_ALIGN_MAX Scalar data2[size];
 | 
			
		||||
  EIGEN_ALIGN_MAX Packet packets[PacketSize*2];
 | 
			
		||||
  EIGEN_ALIGN_MAX Scalar ref[size];
 | 
			
		||||
  RealScalar refvalue = 0;
 | 
			
		||||
  for (int i=0; i<size; ++i)
 | 
			
		||||
  {
 | 
			
		||||
    data1[i] = internal::random<Scalar>()/RealScalar(PacketSize);
 | 
			
		||||
    data2[i] = internal::random<Scalar>()/RealScalar(PacketSize);
 | 
			
		||||
    refvalue = (std::max)(refvalue,abs(data1[i]));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  internal::pstore(data2, internal::pload<Packet>(data1));
 | 
			
		||||
  VERIFY(areApprox(data1, data2, PacketSize) && "aligned load/store");
 | 
			
		||||
 | 
			
		||||
  for (int offset=0; offset<PacketSize; ++offset)
 | 
			
		||||
  {
 | 
			
		||||
    internal::pstore(data2, internal::ploadu<Packet>(data1+offset));
 | 
			
		||||
    VERIFY(areApprox(data1+offset, data2, PacketSize) && "internal::ploadu");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  for (int offset=0; offset<PacketSize; ++offset)
 | 
			
		||||
  {
 | 
			
		||||
    internal::pstoreu(data2+offset, internal::pload<Packet>(data1));
 | 
			
		||||
    VERIFY(areApprox(data1, data2+offset, PacketSize) && "internal::pstoreu");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  for (int offset=0; offset<PacketSize; ++offset)
 | 
			
		||||
  {
 | 
			
		||||
    packets[0] = internal::pload<Packet>(data1);
 | 
			
		||||
    packets[1] = internal::pload<Packet>(data1+PacketSize);
 | 
			
		||||
         if (offset==0) internal::palign<0>(packets[0], packets[1]);
 | 
			
		||||
    else if (offset==1) internal::palign<1>(packets[0], packets[1]);
 | 
			
		||||
    else if (offset==2) internal::palign<2>(packets[0], packets[1]);
 | 
			
		||||
    else if (offset==3) internal::palign<3>(packets[0], packets[1]);
 | 
			
		||||
    else if (offset==4) internal::palign<4>(packets[0], packets[1]);
 | 
			
		||||
    else if (offset==5) internal::palign<5>(packets[0], packets[1]);
 | 
			
		||||
    else if (offset==6) internal::palign<6>(packets[0], packets[1]);
 | 
			
		||||
    else if (offset==7) internal::palign<7>(packets[0], packets[1]);
 | 
			
		||||
    else if (offset==8) internal::palign<8>(packets[0], packets[1]);
 | 
			
		||||
    else if (offset==9) internal::palign<9>(packets[0], packets[1]);
 | 
			
		||||
    else if (offset==10) internal::palign<10>(packets[0], packets[1]);
 | 
			
		||||
    else if (offset==11) internal::palign<11>(packets[0], packets[1]);
 | 
			
		||||
    else if (offset==12) internal::palign<12>(packets[0], packets[1]);
 | 
			
		||||
    else if (offset==13) internal::palign<13>(packets[0], packets[1]);
 | 
			
		||||
    else if (offset==14) internal::palign<14>(packets[0], packets[1]);
 | 
			
		||||
    else if (offset==15) internal::palign<15>(packets[0], packets[1]);
 | 
			
		||||
    internal::pstore(data2, packets[0]);
 | 
			
		||||
 | 
			
		||||
    for (int i=0; i<PacketSize; ++i)
 | 
			
		||||
      ref[i] = data1[i+offset];
 | 
			
		||||
 | 
			
		||||
    VERIFY(areApprox(ref, data2, PacketSize) && "internal::palign");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  VERIFY((!PacketTraits::Vectorizable) || PacketTraits::HasAdd);
 | 
			
		||||
  VERIFY((!PacketTraits::Vectorizable) || PacketTraits::HasSub);
 | 
			
		||||
  VERIFY((!PacketTraits::Vectorizable) || PacketTraits::HasMul);
 | 
			
		||||
  VERIFY((!PacketTraits::Vectorizable) || PacketTraits::HasNegate);
 | 
			
		||||
  VERIFY((internal::is_same<Scalar,int>::value) || (!PacketTraits::Vectorizable) || PacketTraits::HasDiv);
 | 
			
		||||
 | 
			
		||||
  CHECK_CWISE2_IF(PacketTraits::HasAdd, REF_ADD,  internal::padd);
 | 
			
		||||
  CHECK_CWISE2_IF(PacketTraits::HasSub, REF_SUB,  internal::psub);
 | 
			
		||||
  CHECK_CWISE2_IF(PacketTraits::HasMul, REF_MUL,  internal::pmul);
 | 
			
		||||
  CHECK_CWISE2_IF(PacketTraits::HasDiv, REF_DIV, internal::pdiv);
 | 
			
		||||
 | 
			
		||||
  CHECK_CWISE1(internal::negate, internal::pnegate);
 | 
			
		||||
  CHECK_CWISE1(numext::conj, internal::pconj);
 | 
			
		||||
 | 
			
		||||
  for(int offset=0;offset<3;++offset)
 | 
			
		||||
  {
 | 
			
		||||
    for (int i=0; i<PacketSize; ++i)
 | 
			
		||||
      ref[i] = data1[offset];
 | 
			
		||||
    internal::pstore(data2, internal::pset1<Packet>(data1[offset]));
 | 
			
		||||
    VERIFY(areApprox(ref, data2, PacketSize) && "internal::pset1");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    for (int i=0; i<PacketSize*4; ++i)
 | 
			
		||||
      ref[i] = data1[i/PacketSize];
 | 
			
		||||
    Packet A0, A1, A2, A3;
 | 
			
		||||
    internal::pbroadcast4<Packet>(data1, A0, A1, A2, A3);
 | 
			
		||||
    internal::pstore(data2+0*PacketSize, A0);
 | 
			
		||||
    internal::pstore(data2+1*PacketSize, A1);
 | 
			
		||||
    internal::pstore(data2+2*PacketSize, A2);
 | 
			
		||||
    internal::pstore(data2+3*PacketSize, A3);
 | 
			
		||||
    VERIFY(areApprox(ref, data2, 4*PacketSize) && "internal::pbroadcast4");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    for (int i=0; i<PacketSize*2; ++i)
 | 
			
		||||
      ref[i] = data1[i/PacketSize];
 | 
			
		||||
    Packet A0, A1;
 | 
			
		||||
    internal::pbroadcast2<Packet>(data1, A0, A1);
 | 
			
		||||
    internal::pstore(data2+0*PacketSize, A0);
 | 
			
		||||
    internal::pstore(data2+1*PacketSize, A1);
 | 
			
		||||
    VERIFY(areApprox(ref, data2, 2*PacketSize) && "internal::pbroadcast2");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  VERIFY(internal::isApprox(data1[0], internal::pfirst(internal::pload<Packet>(data1))) && "internal::pfirst");
 | 
			
		||||
 | 
			
		||||
  if(PacketSize>1)
 | 
			
		||||
  {
 | 
			
		||||
    for(int offset=0;offset<4;++offset)
 | 
			
		||||
    {
 | 
			
		||||
      for(int i=0;i<PacketSize/2;++i)
 | 
			
		||||
        ref[2*i+0] = ref[2*i+1] = data1[offset+i];
 | 
			
		||||
      internal::pstore(data2,internal::ploaddup<Packet>(data1+offset));
 | 
			
		||||
      VERIFY(areApprox(ref, data2, PacketSize) && "ploaddup");
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(PacketSize>2)
 | 
			
		||||
  {
 | 
			
		||||
    for(int offset=0;offset<4;++offset)
 | 
			
		||||
    {
 | 
			
		||||
      for(int i=0;i<PacketSize/4;++i)
 | 
			
		||||
        ref[4*i+0] = ref[4*i+1] = ref[4*i+2] = ref[4*i+3] = data1[offset+i];
 | 
			
		||||
      internal::pstore(data2,internal::ploadquad<Packet>(data1+offset));
 | 
			
		||||
      VERIFY(areApprox(ref, data2, PacketSize) && "ploadquad");
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ref[0] = 0;
 | 
			
		||||
  for (int i=0; i<PacketSize; ++i)
 | 
			
		||||
    ref[0] += data1[i];
 | 
			
		||||
  VERIFY(isApproxAbs(ref[0], internal::predux(internal::pload<Packet>(data1)), refvalue) && "internal::predux");
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    int newsize = PacketSize>4?PacketSize/2:PacketSize;
 | 
			
		||||
    for (int i=0; i<newsize; ++i)
 | 
			
		||||
      ref[i] = 0;
 | 
			
		||||
    for (int i=0; i<PacketSize; ++i)
 | 
			
		||||
      ref[i%newsize] += data1[i];
 | 
			
		||||
    internal::pstore(data2, internal::predux_downto4(internal::pload<Packet>(data1)));
 | 
			
		||||
    VERIFY(areApprox(ref, data2, newsize) && "internal::predux_downto4");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ref[0] = 1;
 | 
			
		||||
  for (int i=0; i<PacketSize; ++i)
 | 
			
		||||
    ref[0] *= data1[i];
 | 
			
		||||
  VERIFY(internal::isApprox(ref[0], internal::predux_mul(internal::pload<Packet>(data1))) && "internal::predux_mul");
 | 
			
		||||
 | 
			
		||||
  for (int j=0; j<PacketSize; ++j)
 | 
			
		||||
  {
 | 
			
		||||
    ref[j] = 0;
 | 
			
		||||
    for (int i=0; i<PacketSize; ++i)
 | 
			
		||||
      ref[j] += data1[i+j*PacketSize];
 | 
			
		||||
    packets[j] = internal::pload<Packet>(data1+j*PacketSize);
 | 
			
		||||
  }
 | 
			
		||||
  internal::pstore(data2, internal::preduxp(packets));
 | 
			
		||||
  VERIFY(areApproxAbs(ref, data2, PacketSize, refvalue) && "internal::preduxp");
 | 
			
		||||
 | 
			
		||||
  for (int i=0; i<PacketSize; ++i)
 | 
			
		||||
    ref[i] = data1[PacketSize-i-1];
 | 
			
		||||
  internal::pstore(data2, internal::preverse(internal::pload<Packet>(data1)));
 | 
			
		||||
  VERIFY(areApprox(ref, data2, PacketSize) && "internal::preverse");
 | 
			
		||||
 | 
			
		||||
  internal::PacketBlock<Packet> kernel;
 | 
			
		||||
  for (int i=0; i<PacketSize; ++i) {
 | 
			
		||||
    kernel.packet[i] = internal::pload<Packet>(data1+i*PacketSize);
 | 
			
		||||
  }
 | 
			
		||||
  ptranspose(kernel);
 | 
			
		||||
  for (int i=0; i<PacketSize; ++i) {
 | 
			
		||||
    internal::pstore(data2, kernel.packet[i]);
 | 
			
		||||
    for (int j = 0; j < PacketSize; ++j) {
 | 
			
		||||
      VERIFY(isApproxAbs(data2[j], data1[i+j*PacketSize], refvalue) && "ptranspose");
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (PacketTraits::HasBlend) {
 | 
			
		||||
    Packet thenPacket = internal::pload<Packet>(data1);
 | 
			
		||||
    Packet elsePacket = internal::pload<Packet>(data2);
 | 
			
		||||
    EIGEN_ALIGN_MAX internal::Selector<PacketSize> selector;
 | 
			
		||||
    for (int i = 0; i < PacketSize; ++i) {
 | 
			
		||||
      selector.select[i] = i;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Packet blend = internal::pblend(selector, thenPacket, elsePacket);
 | 
			
		||||
    EIGEN_ALIGN_MAX Scalar result[size];
 | 
			
		||||
    internal::pstore(result, blend);
 | 
			
		||||
    for (int i = 0; i < PacketSize; ++i) {
 | 
			
		||||
      VERIFY(isApproxAbs(result[i], (selector.select[i] ? data1[i] : data2[i]), refvalue));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (PacketTraits::HasBlend) {
 | 
			
		||||
    // pinsertfirst
 | 
			
		||||
    for (int i=0; i<PacketSize; ++i)
 | 
			
		||||
      ref[i] = data1[i];
 | 
			
		||||
    Scalar s = internal::random<Scalar>();
 | 
			
		||||
    ref[0] = s;
 | 
			
		||||
    internal::pstore(data2, internal::pinsertfirst(internal::pload<Packet>(data1),s));
 | 
			
		||||
    VERIFY(areApprox(ref, data2, PacketSize) && "internal::pinsertfirst");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (PacketTraits::HasBlend) {
 | 
			
		||||
    // pinsertlast
 | 
			
		||||
    for (int i=0; i<PacketSize; ++i)
 | 
			
		||||
      ref[i] = data1[i];
 | 
			
		||||
    Scalar s = internal::random<Scalar>();
 | 
			
		||||
    ref[PacketSize-1] = s;
 | 
			
		||||
    internal::pstore(data2, internal::pinsertlast(internal::pload<Packet>(data1),s));
 | 
			
		||||
    VERIFY(areApprox(ref, data2, PacketSize) && "internal::pinsertlast");
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Scalar> void packetmath_real()
 | 
			
		||||
{
 | 
			
		||||
  using std::abs;
 | 
			
		||||
  typedef internal::packet_traits<Scalar> PacketTraits;
 | 
			
		||||
  typedef typename PacketTraits::type Packet;
 | 
			
		||||
  const int PacketSize = PacketTraits::size;
 | 
			
		||||
 | 
			
		||||
  const int size = PacketSize*4;
 | 
			
		||||
  EIGEN_ALIGN_MAX Scalar data1[PacketTraits::size*4];
 | 
			
		||||
  EIGEN_ALIGN_MAX Scalar data2[PacketTraits::size*4];
 | 
			
		||||
  EIGEN_ALIGN_MAX Scalar ref[PacketTraits::size*4];
 | 
			
		||||
 | 
			
		||||
  for (int i=0; i<size; ++i)
 | 
			
		||||
  {
 | 
			
		||||
    data1[i] = internal::random<Scalar>(-1,1) * std::pow(Scalar(10), internal::random<Scalar>(-3,3));
 | 
			
		||||
    data2[i] = internal::random<Scalar>(-1,1) * std::pow(Scalar(10), internal::random<Scalar>(-3,3));
 | 
			
		||||
  }
 | 
			
		||||
  CHECK_CWISE1_IF(PacketTraits::HasSin, std::sin, internal::psin);
 | 
			
		||||
  CHECK_CWISE1_IF(PacketTraits::HasCos, std::cos, internal::pcos);
 | 
			
		||||
  CHECK_CWISE1_IF(PacketTraits::HasTan, std::tan, internal::ptan);
 | 
			
		||||
 | 
			
		||||
  CHECK_CWISE1_IF(PacketTraits::HasRound, numext::round, internal::pround);
 | 
			
		||||
  CHECK_CWISE1_IF(PacketTraits::HasCeil, numext::ceil, internal::pceil);
 | 
			
		||||
  CHECK_CWISE1_IF(PacketTraits::HasFloor, numext::floor, internal::pfloor);
 | 
			
		||||
 | 
			
		||||
  for (int i=0; i<size; ++i)
 | 
			
		||||
  {
 | 
			
		||||
    data1[i] = internal::random<Scalar>(-1,1);
 | 
			
		||||
    data2[i] = internal::random<Scalar>(-1,1);
 | 
			
		||||
  }
 | 
			
		||||
  CHECK_CWISE1_IF(PacketTraits::HasASin, std::asin, internal::pasin);
 | 
			
		||||
  CHECK_CWISE1_IF(PacketTraits::HasACos, std::acos, internal::pacos);
 | 
			
		||||
 | 
			
		||||
  for (int i=0; i<size; ++i)
 | 
			
		||||
  {
 | 
			
		||||
    data1[i] = internal::random<Scalar>(-87,88);
 | 
			
		||||
    data2[i] = internal::random<Scalar>(-87,88);
 | 
			
		||||
  }
 | 
			
		||||
  CHECK_CWISE1_IF(PacketTraits::HasExp, std::exp, internal::pexp);
 | 
			
		||||
  for (int i=0; i<size; ++i)
 | 
			
		||||
  {
 | 
			
		||||
    data1[i] = internal::random<Scalar>(-1,1) * std::pow(Scalar(10), internal::random<Scalar>(-6,6));
 | 
			
		||||
    data2[i] = internal::random<Scalar>(-1,1) * std::pow(Scalar(10), internal::random<Scalar>(-6,6));
 | 
			
		||||
  }
 | 
			
		||||
  CHECK_CWISE1_IF(PacketTraits::HasTanh, std::tanh, internal::ptanh);
 | 
			
		||||
  if(PacketTraits::HasExp && PacketTraits::size>=2)
 | 
			
		||||
  {
 | 
			
		||||
    data1[0] = std::numeric_limits<Scalar>::quiet_NaN();
 | 
			
		||||
    data1[1] = std::numeric_limits<Scalar>::epsilon();
 | 
			
		||||
    packet_helper<PacketTraits::HasExp,Packet> h;
 | 
			
		||||
    h.store(data2, internal::pexp(h.load(data1)));
 | 
			
		||||
    VERIFY((numext::isnan)(data2[0]));
 | 
			
		||||
    VERIFY_IS_EQUAL(std::exp(std::numeric_limits<Scalar>::epsilon()), data2[1]);
 | 
			
		||||
 | 
			
		||||
    data1[0] = -std::numeric_limits<Scalar>::epsilon();
 | 
			
		||||
    data1[1] = 0;
 | 
			
		||||
    h.store(data2, internal::pexp(h.load(data1)));
 | 
			
		||||
    VERIFY_IS_EQUAL(std::exp(-std::numeric_limits<Scalar>::epsilon()), data2[0]);
 | 
			
		||||
    VERIFY_IS_EQUAL(std::exp(Scalar(0)), data2[1]);
 | 
			
		||||
 | 
			
		||||
    data1[0] = (std::numeric_limits<Scalar>::min)();
 | 
			
		||||
    data1[1] = -(std::numeric_limits<Scalar>::min)();
 | 
			
		||||
    h.store(data2, internal::pexp(h.load(data1)));
 | 
			
		||||
    VERIFY_IS_EQUAL(std::exp((std::numeric_limits<Scalar>::min)()), data2[0]);
 | 
			
		||||
    VERIFY_IS_EQUAL(std::exp(-(std::numeric_limits<Scalar>::min)()), data2[1]);
 | 
			
		||||
 | 
			
		||||
    data1[0] = std::numeric_limits<Scalar>::denorm_min();
 | 
			
		||||
    data1[1] = -std::numeric_limits<Scalar>::denorm_min();
 | 
			
		||||
    h.store(data2, internal::pexp(h.load(data1)));
 | 
			
		||||
    VERIFY_IS_EQUAL(std::exp(std::numeric_limits<Scalar>::denorm_min()), data2[0]);
 | 
			
		||||
    VERIFY_IS_EQUAL(std::exp(-std::numeric_limits<Scalar>::denorm_min()), data2[1]);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (PacketTraits::HasTanh) {
 | 
			
		||||
    // NOTE this test migh fail with GCC prior to 6.3, see MathFunctionsImpl.h for details.
 | 
			
		||||
    data1[0] = std::numeric_limits<Scalar>::quiet_NaN();
 | 
			
		||||
    packet_helper<internal::packet_traits<Scalar>::HasTanh,Packet> h;
 | 
			
		||||
    h.store(data2, internal::ptanh(h.load(data1)));
 | 
			
		||||
    VERIFY((numext::isnan)(data2[0]));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
#if EIGEN_HAS_C99_MATH
 | 
			
		||||
  {
 | 
			
		||||
    data1[0] = std::numeric_limits<Scalar>::quiet_NaN();
 | 
			
		||||
    packet_helper<internal::packet_traits<Scalar>::HasLGamma,Packet> h;
 | 
			
		||||
    h.store(data2, internal::plgamma(h.load(data1)));
 | 
			
		||||
    VERIFY((numext::isnan)(data2[0]));
 | 
			
		||||
  }
 | 
			
		||||
  {
 | 
			
		||||
    data1[0] = std::numeric_limits<Scalar>::quiet_NaN();
 | 
			
		||||
    packet_helper<internal::packet_traits<Scalar>::HasErf,Packet> h;
 | 
			
		||||
    h.store(data2, internal::perf(h.load(data1)));
 | 
			
		||||
    VERIFY((numext::isnan)(data2[0]));
 | 
			
		||||
  }
 | 
			
		||||
  {
 | 
			
		||||
    data1[0] = std::numeric_limits<Scalar>::quiet_NaN();
 | 
			
		||||
    packet_helper<internal::packet_traits<Scalar>::HasErfc,Packet> h;
 | 
			
		||||
    h.store(data2, internal::perfc(h.load(data1)));
 | 
			
		||||
    VERIFY((numext::isnan)(data2[0]));
 | 
			
		||||
  }
 | 
			
		||||
#endif  // EIGEN_HAS_C99_MATH
 | 
			
		||||
 | 
			
		||||
  for (int i=0; i<size; ++i)
 | 
			
		||||
  {
 | 
			
		||||
    data1[i] = internal::random<Scalar>(0,1) * std::pow(Scalar(10), internal::random<Scalar>(-6,6));
 | 
			
		||||
    data2[i] = internal::random<Scalar>(0,1) * std::pow(Scalar(10), internal::random<Scalar>(-6,6));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(internal::random<float>(0,1)<0.1f)
 | 
			
		||||
    data1[internal::random<int>(0, PacketSize)] = 0;
 | 
			
		||||
  CHECK_CWISE1_IF(PacketTraits::HasSqrt, std::sqrt, internal::psqrt);
 | 
			
		||||
  CHECK_CWISE1_IF(PacketTraits::HasLog, std::log, internal::plog);
 | 
			
		||||
#if EIGEN_HAS_C99_MATH && (__cplusplus > 199711L)
 | 
			
		||||
  CHECK_CWISE1_IF(PacketTraits::HasLog1p, std::log1p, internal::plog1p);
 | 
			
		||||
  CHECK_CWISE1_IF(internal::packet_traits<Scalar>::HasLGamma, std::lgamma, internal::plgamma);
 | 
			
		||||
  CHECK_CWISE1_IF(internal::packet_traits<Scalar>::HasErf, std::erf, internal::perf);
 | 
			
		||||
  CHECK_CWISE1_IF(internal::packet_traits<Scalar>::HasErfc, std::erfc, internal::perfc);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  if(PacketTraits::HasLog && PacketTraits::size>=2)
 | 
			
		||||
  {
 | 
			
		||||
    data1[0] = std::numeric_limits<Scalar>::quiet_NaN();
 | 
			
		||||
    data1[1] = std::numeric_limits<Scalar>::epsilon();
 | 
			
		||||
    packet_helper<PacketTraits::HasLog,Packet> h;
 | 
			
		||||
    h.store(data2, internal::plog(h.load(data1)));
 | 
			
		||||
    VERIFY((numext::isnan)(data2[0]));
 | 
			
		||||
    VERIFY_IS_EQUAL(std::log(std::numeric_limits<Scalar>::epsilon()), data2[1]);
 | 
			
		||||
 | 
			
		||||
    data1[0] = -std::numeric_limits<Scalar>::epsilon();
 | 
			
		||||
    data1[1] = 0;
 | 
			
		||||
    h.store(data2, internal::plog(h.load(data1)));
 | 
			
		||||
    VERIFY((numext::isnan)(data2[0]));
 | 
			
		||||
    VERIFY_IS_EQUAL(std::log(Scalar(0)), data2[1]);
 | 
			
		||||
 | 
			
		||||
    data1[0] = (std::numeric_limits<Scalar>::min)();
 | 
			
		||||
    data1[1] = -(std::numeric_limits<Scalar>::min)();
 | 
			
		||||
    h.store(data2, internal::plog(h.load(data1)));
 | 
			
		||||
    VERIFY_IS_EQUAL(std::log((std::numeric_limits<Scalar>::min)()), data2[0]);
 | 
			
		||||
    VERIFY((numext::isnan)(data2[1]));
 | 
			
		||||
 | 
			
		||||
    data1[0] = std::numeric_limits<Scalar>::denorm_min();
 | 
			
		||||
    data1[1] = -std::numeric_limits<Scalar>::denorm_min();
 | 
			
		||||
    h.store(data2, internal::plog(h.load(data1)));
 | 
			
		||||
    // VERIFY_IS_EQUAL(std::log(std::numeric_limits<Scalar>::denorm_min()), data2[0]);
 | 
			
		||||
    VERIFY((numext::isnan)(data2[1]));
 | 
			
		||||
 | 
			
		||||
    data1[0] = Scalar(-1.0f);
 | 
			
		||||
    h.store(data2, internal::plog(h.load(data1)));
 | 
			
		||||
    VERIFY((numext::isnan)(data2[0]));
 | 
			
		||||
    h.store(data2, internal::psqrt(h.load(data1)));
 | 
			
		||||
    VERIFY((numext::isnan)(data2[0]));
 | 
			
		||||
    VERIFY((numext::isnan)(data2[1]));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Scalar> void packetmath_notcomplex()
 | 
			
		||||
{
 | 
			
		||||
  using std::abs;
 | 
			
		||||
  typedef internal::packet_traits<Scalar> PacketTraits;
 | 
			
		||||
  typedef typename PacketTraits::type Packet;
 | 
			
		||||
  const int PacketSize = PacketTraits::size;
 | 
			
		||||
 | 
			
		||||
  EIGEN_ALIGN_MAX Scalar data1[PacketTraits::size*4];
 | 
			
		||||
  EIGEN_ALIGN_MAX Scalar data2[PacketTraits::size*4];
 | 
			
		||||
  EIGEN_ALIGN_MAX Scalar ref[PacketTraits::size*4];
 | 
			
		||||
 | 
			
		||||
  Array<Scalar,Dynamic,1>::Map(data1, PacketTraits::size*4).setRandom();
 | 
			
		||||
 | 
			
		||||
  ref[0] = data1[0];
 | 
			
		||||
  for (int i=0; i<PacketSize; ++i)
 | 
			
		||||
    ref[0] = (std::min)(ref[0],data1[i]);
 | 
			
		||||
  VERIFY(internal::isApprox(ref[0], internal::predux_min(internal::pload<Packet>(data1))) && "internal::predux_min");
 | 
			
		||||
 | 
			
		||||
  VERIFY((!PacketTraits::Vectorizable) || PacketTraits::HasMin);
 | 
			
		||||
  VERIFY((!PacketTraits::Vectorizable) || PacketTraits::HasMax);
 | 
			
		||||
 | 
			
		||||
  CHECK_CWISE2_IF(PacketTraits::HasMin, (std::min), internal::pmin);
 | 
			
		||||
  CHECK_CWISE2_IF(PacketTraits::HasMax, (std::max), internal::pmax);
 | 
			
		||||
  CHECK_CWISE1(abs, internal::pabs);
 | 
			
		||||
 | 
			
		||||
  ref[0] = data1[0];
 | 
			
		||||
  for (int i=0; i<PacketSize; ++i)
 | 
			
		||||
    ref[0] = (std::max)(ref[0],data1[i]);
 | 
			
		||||
  VERIFY(internal::isApprox(ref[0], internal::predux_max(internal::pload<Packet>(data1))) && "internal::predux_max");
 | 
			
		||||
 | 
			
		||||
  for (int i=0; i<PacketSize; ++i)
 | 
			
		||||
    ref[i] = data1[0]+Scalar(i);
 | 
			
		||||
  internal::pstore(data2, internal::plset<Packet>(data1[0]));
 | 
			
		||||
  VERIFY(areApprox(ref, data2, PacketSize) && "internal::plset");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Scalar,bool ConjLhs,bool ConjRhs> void test_conj_helper(Scalar* data1, Scalar* data2, Scalar* ref, Scalar* pval)
 | 
			
		||||
{
 | 
			
		||||
  typedef internal::packet_traits<Scalar> PacketTraits;
 | 
			
		||||
  typedef typename PacketTraits::type Packet;
 | 
			
		||||
  const int PacketSize = PacketTraits::size;
 | 
			
		||||
 | 
			
		||||
  internal::conj_if<ConjLhs> cj0;
 | 
			
		||||
  internal::conj_if<ConjRhs> cj1;
 | 
			
		||||
  internal::conj_helper<Scalar,Scalar,ConjLhs,ConjRhs> cj;
 | 
			
		||||
  internal::conj_helper<Packet,Packet,ConjLhs,ConjRhs> pcj;
 | 
			
		||||
 | 
			
		||||
  for(int i=0;i<PacketSize;++i)
 | 
			
		||||
  {
 | 
			
		||||
    ref[i] = cj0(data1[i]) * cj1(data2[i]);
 | 
			
		||||
    VERIFY(internal::isApprox(ref[i], cj.pmul(data1[i],data2[i])) && "conj_helper pmul");
 | 
			
		||||
  }
 | 
			
		||||
  internal::pstore(pval,pcj.pmul(internal::pload<Packet>(data1),internal::pload<Packet>(data2)));
 | 
			
		||||
  VERIFY(areApprox(ref, pval, PacketSize) && "conj_helper pmul");
 | 
			
		||||
 | 
			
		||||
  for(int i=0;i<PacketSize;++i)
 | 
			
		||||
  {
 | 
			
		||||
    Scalar tmp = ref[i];
 | 
			
		||||
    ref[i] += cj0(data1[i]) * cj1(data2[i]);
 | 
			
		||||
    VERIFY(internal::isApprox(ref[i], cj.pmadd(data1[i],data2[i],tmp)) && "conj_helper pmadd");
 | 
			
		||||
  }
 | 
			
		||||
  internal::pstore(pval,pcj.pmadd(internal::pload<Packet>(data1),internal::pload<Packet>(data2),internal::pload<Packet>(pval)));
 | 
			
		||||
  VERIFY(areApprox(ref, pval, PacketSize) && "conj_helper pmadd");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Scalar> void packetmath_complex()
 | 
			
		||||
{
 | 
			
		||||
  typedef internal::packet_traits<Scalar> PacketTraits;
 | 
			
		||||
  typedef typename PacketTraits::type Packet;
 | 
			
		||||
  const int PacketSize = PacketTraits::size;
 | 
			
		||||
 | 
			
		||||
  const int size = PacketSize*4;
 | 
			
		||||
  EIGEN_ALIGN_MAX Scalar data1[PacketSize*4];
 | 
			
		||||
  EIGEN_ALIGN_MAX Scalar data2[PacketSize*4];
 | 
			
		||||
  EIGEN_ALIGN_MAX Scalar ref[PacketSize*4];
 | 
			
		||||
  EIGEN_ALIGN_MAX Scalar pval[PacketSize*4];
 | 
			
		||||
 | 
			
		||||
  for (int i=0; i<size; ++i)
 | 
			
		||||
  {
 | 
			
		||||
    data1[i] = internal::random<Scalar>() * Scalar(1e2);
 | 
			
		||||
    data2[i] = internal::random<Scalar>() * Scalar(1e2);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  test_conj_helper<Scalar,false,false> (data1,data2,ref,pval);
 | 
			
		||||
  test_conj_helper<Scalar,false,true>  (data1,data2,ref,pval);
 | 
			
		||||
  test_conj_helper<Scalar,true,false>  (data1,data2,ref,pval);
 | 
			
		||||
  test_conj_helper<Scalar,true,true>   (data1,data2,ref,pval);
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    for(int i=0;i<PacketSize;++i)
 | 
			
		||||
      ref[i] = Scalar(std::imag(data1[i]),std::real(data1[i]));
 | 
			
		||||
    internal::pstore(pval,internal::pcplxflip(internal::pload<Packet>(data1)));
 | 
			
		||||
    VERIFY(areApprox(ref, pval, PacketSize) && "pcplxflip");
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Scalar> void packetmath_scatter_gather()
 | 
			
		||||
{
 | 
			
		||||
  typedef internal::packet_traits<Scalar> PacketTraits;
 | 
			
		||||
  typedef typename PacketTraits::type Packet;
 | 
			
		||||
  typedef typename NumTraits<Scalar>::Real RealScalar;
 | 
			
		||||
  const int PacketSize = PacketTraits::size;
 | 
			
		||||
  EIGEN_ALIGN_MAX Scalar data1[PacketSize];
 | 
			
		||||
  RealScalar refvalue = 0;
 | 
			
		||||
  for (int i=0; i<PacketSize; ++i) {
 | 
			
		||||
    data1[i] = internal::random<Scalar>()/RealScalar(PacketSize);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  int stride = internal::random<int>(1,20);
 | 
			
		||||
 | 
			
		||||
  EIGEN_ALIGN_MAX Scalar buffer[PacketSize*20];
 | 
			
		||||
  memset(buffer, 0, 20*PacketSize*sizeof(Scalar));
 | 
			
		||||
  Packet packet = internal::pload<Packet>(data1);
 | 
			
		||||
  internal::pscatter<Scalar, Packet>(buffer, packet, stride);
 | 
			
		||||
 | 
			
		||||
  for (int i = 0; i < PacketSize*20; ++i) {
 | 
			
		||||
    if ((i%stride) == 0 && i<stride*PacketSize) {
 | 
			
		||||
      VERIFY(isApproxAbs(buffer[i], data1[i/stride], refvalue) && "pscatter");
 | 
			
		||||
    } else {
 | 
			
		||||
      VERIFY(isApproxAbs(buffer[i], Scalar(0), refvalue) && "pscatter");
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  for (int i=0; i<PacketSize*7; ++i) {
 | 
			
		||||
    buffer[i] = internal::random<Scalar>()/RealScalar(PacketSize);
 | 
			
		||||
  }
 | 
			
		||||
  packet = internal::pgather<Scalar, Packet>(buffer, 7);
 | 
			
		||||
  internal::pstore(data1, packet);
 | 
			
		||||
  for (int i = 0; i < PacketSize; ++i) {
 | 
			
		||||
    VERIFY(isApproxAbs(data1[i], buffer[i*7], refvalue) && "pgather");
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_packetmath()
 | 
			
		||||
{
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_1( packetmath<float>() );
 | 
			
		||||
    CALL_SUBTEST_2( packetmath<double>() );
 | 
			
		||||
    CALL_SUBTEST_3( packetmath<int>() );
 | 
			
		||||
    CALL_SUBTEST_4( packetmath<std::complex<float> >() );
 | 
			
		||||
    CALL_SUBTEST_5( packetmath<std::complex<double> >() );
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_1( packetmath_notcomplex<float>() );
 | 
			
		||||
    CALL_SUBTEST_2( packetmath_notcomplex<double>() );
 | 
			
		||||
    CALL_SUBTEST_3( packetmath_notcomplex<int>() );
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_1( packetmath_real<float>() );
 | 
			
		||||
    CALL_SUBTEST_2( packetmath_real<double>() );
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_4( packetmath_complex<std::complex<float> >() );
 | 
			
		||||
    CALL_SUBTEST_5( packetmath_complex<std::complex<double> >() );
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_1( packetmath_scatter_gather<float>() );
 | 
			
		||||
    CALL_SUBTEST_2( packetmath_scatter_gather<double>() );
 | 
			
		||||
    CALL_SUBTEST_3( packetmath_scatter_gather<int>() );
 | 
			
		||||
    CALL_SUBTEST_4( packetmath_scatter_gather<std::complex<float> >() );
 | 
			
		||||
    CALL_SUBTEST_5( packetmath_scatter_gather<std::complex<double> >() );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										29
									
								
								cs440-acg/ext/eigen/test/pardiso_support.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								cs440-acg/ext/eigen/test/pardiso_support.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
			
		||||
/* 
 | 
			
		||||
   Intel Copyright (C) ....
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include "sparse_solver.h"
 | 
			
		||||
#include <Eigen/PardisoSupport>
 | 
			
		||||
 | 
			
		||||
template<typename T> void test_pardiso_T()
 | 
			
		||||
{
 | 
			
		||||
  PardisoLLT < SparseMatrix<T, RowMajor>, Lower> pardiso_llt_lower;
 | 
			
		||||
  PardisoLLT < SparseMatrix<T, RowMajor>, Upper> pardiso_llt_upper;
 | 
			
		||||
  PardisoLDLT < SparseMatrix<T, RowMajor>, Lower> pardiso_ldlt_lower;
 | 
			
		||||
  PardisoLDLT < SparseMatrix<T, RowMajor>, Upper> pardiso_ldlt_upper;
 | 
			
		||||
  PardisoLU  < SparseMatrix<T, RowMajor> > pardiso_lu;
 | 
			
		||||
 | 
			
		||||
  check_sparse_spd_solving(pardiso_llt_lower);
 | 
			
		||||
  check_sparse_spd_solving(pardiso_llt_upper);
 | 
			
		||||
  check_sparse_spd_solving(pardiso_ldlt_lower);
 | 
			
		||||
  check_sparse_spd_solving(pardiso_ldlt_upper);
 | 
			
		||||
  check_sparse_square_solving(pardiso_lu);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_pardiso_support()
 | 
			
		||||
{
 | 
			
		||||
  CALL_SUBTEST_1(test_pardiso_T<float>());
 | 
			
		||||
  CALL_SUBTEST_2(test_pardiso_T<double>());
 | 
			
		||||
  CALL_SUBTEST_3(test_pardiso_T< std::complex<float> >());
 | 
			
		||||
  CALL_SUBTEST_4(test_pardiso_T< std::complex<double> >());
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										54
									
								
								cs440-acg/ext/eigen/test/pastix_support.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								cs440-acg/ext/eigen/test/pastix_support.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,54 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2008-2012 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
// Copyright (C) 2012 Désiré Nuentsa-Wakam <desire.nuentsa_wakam@inria.fr>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#define EIGEN_NO_DEBUG_SMALL_PRODUCT_BLOCKS
 | 
			
		||||
#include "sparse_solver.h"
 | 
			
		||||
#include <Eigen/PaStiXSupport>
 | 
			
		||||
#include <unsupported/Eigen/SparseExtra>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template<typename T> void test_pastix_T()
 | 
			
		||||
{
 | 
			
		||||
  PastixLLT< SparseMatrix<T, ColMajor>, Eigen::Lower > pastix_llt_lower;
 | 
			
		||||
  PastixLDLT< SparseMatrix<T, ColMajor>, Eigen::Lower > pastix_ldlt_lower;
 | 
			
		||||
  PastixLLT< SparseMatrix<T, ColMajor>, Eigen::Upper > pastix_llt_upper;
 | 
			
		||||
  PastixLDLT< SparseMatrix<T, ColMajor>, Eigen::Upper > pastix_ldlt_upper;
 | 
			
		||||
  PastixLU< SparseMatrix<T, ColMajor> > pastix_lu;
 | 
			
		||||
 | 
			
		||||
  check_sparse_spd_solving(pastix_llt_lower);
 | 
			
		||||
  check_sparse_spd_solving(pastix_ldlt_lower);
 | 
			
		||||
  check_sparse_spd_solving(pastix_llt_upper);
 | 
			
		||||
  check_sparse_spd_solving(pastix_ldlt_upper);
 | 
			
		||||
  check_sparse_square_solving(pastix_lu);
 | 
			
		||||
 | 
			
		||||
  // Some compilation check:
 | 
			
		||||
  pastix_llt_lower.iparm();
 | 
			
		||||
  pastix_llt_lower.dparm();
 | 
			
		||||
  pastix_ldlt_lower.iparm();
 | 
			
		||||
  pastix_ldlt_lower.dparm();
 | 
			
		||||
  pastix_lu.iparm();
 | 
			
		||||
  pastix_lu.dparm();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// There is no support for selfadjoint matrices with PaStiX. 
 | 
			
		||||
// Complex symmetric matrices should pass though
 | 
			
		||||
template<typename T> void test_pastix_T_LU()
 | 
			
		||||
{
 | 
			
		||||
  PastixLU< SparseMatrix<T, ColMajor> > pastix_lu;
 | 
			
		||||
  check_sparse_square_solving(pastix_lu);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_pastix_support()
 | 
			
		||||
{
 | 
			
		||||
  CALL_SUBTEST_1(test_pastix_T<float>());
 | 
			
		||||
  CALL_SUBTEST_2(test_pastix_T<double>());
 | 
			
		||||
  CALL_SUBTEST_3( (test_pastix_T_LU<std::complex<float> >()) );
 | 
			
		||||
  CALL_SUBTEST_4(test_pastix_T_LU<std::complex<double> >());
 | 
			
		||||
} 
 | 
			
		||||
							
								
								
									
										167
									
								
								cs440-acg/ext/eigen/test/permutationmatrices.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										167
									
								
								cs440-acg/ext/eigen/test/permutationmatrices.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,167 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#define TEST_ENABLE_TEMPORARY_TRACKING
 | 
			
		||||
  
 | 
			
		||||
#include "main.h"
 | 
			
		||||
 | 
			
		||||
using namespace std;
 | 
			
		||||
template<typename MatrixType> void permutationmatrices(const MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
  enum { Rows = MatrixType::RowsAtCompileTime, Cols = MatrixType::ColsAtCompileTime,
 | 
			
		||||
         Options = MatrixType::Options };
 | 
			
		||||
  typedef PermutationMatrix<Rows> LeftPermutationType;
 | 
			
		||||
  typedef Transpositions<Rows> LeftTranspositionsType;
 | 
			
		||||
  typedef Matrix<int, Rows, 1> LeftPermutationVectorType;
 | 
			
		||||
  typedef Map<LeftPermutationType> MapLeftPerm;
 | 
			
		||||
  typedef PermutationMatrix<Cols> RightPermutationType;
 | 
			
		||||
  typedef Transpositions<Cols> RightTranspositionsType;
 | 
			
		||||
  typedef Matrix<int, Cols, 1> RightPermutationVectorType;
 | 
			
		||||
  typedef Map<RightPermutationType> MapRightPerm;
 | 
			
		||||
 | 
			
		||||
  Index rows = m.rows();
 | 
			
		||||
  Index cols = m.cols();
 | 
			
		||||
 | 
			
		||||
  MatrixType m_original = MatrixType::Random(rows,cols);
 | 
			
		||||
  LeftPermutationVectorType lv;
 | 
			
		||||
  randomPermutationVector(lv, rows);
 | 
			
		||||
  LeftPermutationType lp(lv);
 | 
			
		||||
  RightPermutationVectorType rv;
 | 
			
		||||
  randomPermutationVector(rv, cols);
 | 
			
		||||
  RightPermutationType rp(rv);
 | 
			
		||||
  LeftTranspositionsType lt(lv);
 | 
			
		||||
  RightTranspositionsType rt(rv);
 | 
			
		||||
  MatrixType m_permuted = MatrixType::Random(rows,cols);
 | 
			
		||||
  
 | 
			
		||||
  VERIFY_EVALUATION_COUNT(m_permuted = lp * m_original * rp, 1); // 1 temp for sub expression "lp * m_original"
 | 
			
		||||
 | 
			
		||||
  for (int i=0; i<rows; i++)
 | 
			
		||||
    for (int j=0; j<cols; j++)
 | 
			
		||||
        VERIFY_IS_APPROX(m_permuted(lv(i),j), m_original(i,rv(j)));
 | 
			
		||||
 | 
			
		||||
  Matrix<Scalar,Rows,Rows> lm(lp);
 | 
			
		||||
  Matrix<Scalar,Cols,Cols> rm(rp);
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(m_permuted, lm*m_original*rm);
 | 
			
		||||
  
 | 
			
		||||
  m_permuted = m_original;
 | 
			
		||||
  VERIFY_EVALUATION_COUNT(m_permuted = lp * m_permuted * rp, 1);
 | 
			
		||||
  VERIFY_IS_APPROX(m_permuted, lm*m_original*rm);
 | 
			
		||||
  
 | 
			
		||||
  VERIFY_IS_APPROX(lp.inverse()*m_permuted*rp.inverse(), m_original);
 | 
			
		||||
  VERIFY_IS_APPROX(lv.asPermutation().inverse()*m_permuted*rv.asPermutation().inverse(), m_original);
 | 
			
		||||
  VERIFY_IS_APPROX(MapLeftPerm(lv.data(),lv.size()).inverse()*m_permuted*MapRightPerm(rv.data(),rv.size()).inverse(), m_original);
 | 
			
		||||
  
 | 
			
		||||
  VERIFY((lp*lp.inverse()).toDenseMatrix().isIdentity());
 | 
			
		||||
  VERIFY((lv.asPermutation()*lv.asPermutation().inverse()).toDenseMatrix().isIdentity());
 | 
			
		||||
  VERIFY((MapLeftPerm(lv.data(),lv.size())*MapLeftPerm(lv.data(),lv.size()).inverse()).toDenseMatrix().isIdentity());
 | 
			
		||||
 | 
			
		||||
  LeftPermutationVectorType lv2;
 | 
			
		||||
  randomPermutationVector(lv2, rows);
 | 
			
		||||
  LeftPermutationType lp2(lv2);
 | 
			
		||||
  Matrix<Scalar,Rows,Rows> lm2(lp2);
 | 
			
		||||
  VERIFY_IS_APPROX((lp*lp2).toDenseMatrix().template cast<Scalar>(), lm*lm2);
 | 
			
		||||
  VERIFY_IS_APPROX((lv.asPermutation()*lv2.asPermutation()).toDenseMatrix().template cast<Scalar>(), lm*lm2);
 | 
			
		||||
  VERIFY_IS_APPROX((MapLeftPerm(lv.data(),lv.size())*MapLeftPerm(lv2.data(),lv2.size())).toDenseMatrix().template cast<Scalar>(), lm*lm2);
 | 
			
		||||
 | 
			
		||||
  LeftPermutationType identityp;
 | 
			
		||||
  identityp.setIdentity(rows);
 | 
			
		||||
  VERIFY_IS_APPROX(m_original, identityp*m_original);
 | 
			
		||||
  
 | 
			
		||||
  // check inplace permutations
 | 
			
		||||
  m_permuted = m_original;
 | 
			
		||||
  VERIFY_EVALUATION_COUNT(m_permuted.noalias()= lp.inverse() * m_permuted, 1); // 1 temp to allocate the mask
 | 
			
		||||
  VERIFY_IS_APPROX(m_permuted, lp.inverse()*m_original);
 | 
			
		||||
  
 | 
			
		||||
  m_permuted = m_original;
 | 
			
		||||
  VERIFY_EVALUATION_COUNT(m_permuted.noalias() = m_permuted * rp.inverse(), 1); // 1 temp to allocate the mask
 | 
			
		||||
  VERIFY_IS_APPROX(m_permuted, m_original*rp.inverse());
 | 
			
		||||
  
 | 
			
		||||
  m_permuted = m_original;
 | 
			
		||||
  VERIFY_EVALUATION_COUNT(m_permuted.noalias() = lp * m_permuted, 1); // 1 temp to allocate the mask
 | 
			
		||||
  VERIFY_IS_APPROX(m_permuted, lp*m_original);
 | 
			
		||||
  
 | 
			
		||||
  m_permuted = m_original;
 | 
			
		||||
  VERIFY_EVALUATION_COUNT(m_permuted.noalias() = m_permuted * rp, 1); // 1 temp to allocate the mask
 | 
			
		||||
  VERIFY_IS_APPROX(m_permuted, m_original*rp);
 | 
			
		||||
 | 
			
		||||
  if(rows>1 && cols>1)
 | 
			
		||||
  {
 | 
			
		||||
    lp2 = lp;
 | 
			
		||||
    Index i = internal::random<Index>(0, rows-1);
 | 
			
		||||
    Index j;
 | 
			
		||||
    do j = internal::random<Index>(0, rows-1); while(j==i);
 | 
			
		||||
    lp2.applyTranspositionOnTheLeft(i, j);
 | 
			
		||||
    lm = lp;
 | 
			
		||||
    lm.row(i).swap(lm.row(j));
 | 
			
		||||
    VERIFY_IS_APPROX(lm, lp2.toDenseMatrix().template cast<Scalar>());
 | 
			
		||||
 | 
			
		||||
    RightPermutationType rp2 = rp;
 | 
			
		||||
    i = internal::random<Index>(0, cols-1);
 | 
			
		||||
    do j = internal::random<Index>(0, cols-1); while(j==i);
 | 
			
		||||
    rp2.applyTranspositionOnTheRight(i, j);
 | 
			
		||||
    rm = rp;
 | 
			
		||||
    rm.col(i).swap(rm.col(j));
 | 
			
		||||
    VERIFY_IS_APPROX(rm, rp2.toDenseMatrix().template cast<Scalar>());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    // simple compilation check
 | 
			
		||||
    Matrix<Scalar, Cols, Cols> A = rp;
 | 
			
		||||
    Matrix<Scalar, Cols, Cols> B = rp.transpose();
 | 
			
		||||
    VERIFY_IS_APPROX(A, B.transpose());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  m_permuted = m_original;
 | 
			
		||||
  lp = lt;
 | 
			
		||||
  rp = rt;
 | 
			
		||||
  VERIFY_EVALUATION_COUNT(m_permuted = lt * m_permuted * rt, 1);
 | 
			
		||||
  VERIFY_IS_APPROX(m_permuted, lp*m_original*rp.transpose());
 | 
			
		||||
  
 | 
			
		||||
  VERIFY_IS_APPROX(lt.inverse()*m_permuted*rt.inverse(), m_original);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
void bug890()
 | 
			
		||||
{
 | 
			
		||||
  typedef Matrix<T, Dynamic, Dynamic> MatrixType;
 | 
			
		||||
  typedef Matrix<T, Dynamic, 1> VectorType;
 | 
			
		||||
  typedef Stride<Dynamic,Dynamic> S;
 | 
			
		||||
  typedef Map<MatrixType, Aligned, S> MapType;
 | 
			
		||||
  typedef PermutationMatrix<Dynamic> Perm;
 | 
			
		||||
  
 | 
			
		||||
  VectorType v1(2), v2(2), op(4), rhs(2);
 | 
			
		||||
  v1 << 666,667;
 | 
			
		||||
  op << 1,0,0,1;
 | 
			
		||||
  rhs << 42,42;
 | 
			
		||||
  
 | 
			
		||||
  Perm P(2);
 | 
			
		||||
  P.indices() << 1, 0;
 | 
			
		||||
 | 
			
		||||
  MapType(v1.data(),2,1,S(1,1)) = P * MapType(rhs.data(),2,1,S(1,1));
 | 
			
		||||
  VERIFY_IS_APPROX(v1, (P * rhs).eval());
 | 
			
		||||
  
 | 
			
		||||
  MapType(v1.data(),2,1,S(1,1)) = P.inverse() * MapType(rhs.data(),2,1,S(1,1));
 | 
			
		||||
  VERIFY_IS_APPROX(v1, (P.inverse() * rhs).eval());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_permutationmatrices()
 | 
			
		||||
{
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_1( permutationmatrices(Matrix<float, 1, 1>()) );
 | 
			
		||||
    CALL_SUBTEST_2( permutationmatrices(Matrix3f()) );
 | 
			
		||||
    CALL_SUBTEST_3( permutationmatrices(Matrix<double,3,3,RowMajor>()) );
 | 
			
		||||
    CALL_SUBTEST_4( permutationmatrices(Matrix4d()) );
 | 
			
		||||
    CALL_SUBTEST_5( permutationmatrices(Matrix<double,40,60>()) );
 | 
			
		||||
    CALL_SUBTEST_6( permutationmatrices(Matrix<double,Dynamic,Dynamic,RowMajor>(20, 30)) );
 | 
			
		||||
    CALL_SUBTEST_7( permutationmatrices(MatrixXcf(15, 10)) );
 | 
			
		||||
  }
 | 
			
		||||
  CALL_SUBTEST_5( bug890<double>() );
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										83
									
								
								cs440-acg/ext/eigen/test/prec_inverse_4x4.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								cs440-acg/ext/eigen/test/prec_inverse_4x4.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,83 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
#include <Eigen/LU>
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void inverse_permutation_4x4()
 | 
			
		||||
{
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
  Vector4i indices(0,1,2,3);
 | 
			
		||||
  for(int i = 0; i < 24; ++i)
 | 
			
		||||
  {
 | 
			
		||||
    MatrixType m = PermutationMatrix<4>(indices);
 | 
			
		||||
    MatrixType inv = m.inverse();
 | 
			
		||||
    double error = double( (m*inv-MatrixType::Identity()).norm() / NumTraits<Scalar>::epsilon() );
 | 
			
		||||
    EIGEN_DEBUG_VAR(error)
 | 
			
		||||
    VERIFY(error == 0.0);
 | 
			
		||||
    std::next_permutation(indices.data(),indices.data()+4);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void inverse_general_4x4(int repeat)
 | 
			
		||||
{
 | 
			
		||||
  using std::abs;
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
  typedef typename MatrixType::RealScalar RealScalar;
 | 
			
		||||
  double error_sum = 0., error_max = 0.;
 | 
			
		||||
  for(int i = 0; i < repeat; ++i)
 | 
			
		||||
  {
 | 
			
		||||
    MatrixType m;
 | 
			
		||||
    RealScalar absdet;
 | 
			
		||||
    do {
 | 
			
		||||
      m = MatrixType::Random();
 | 
			
		||||
      absdet = abs(m.determinant());
 | 
			
		||||
    } while(absdet < NumTraits<Scalar>::epsilon());
 | 
			
		||||
    MatrixType inv = m.inverse();
 | 
			
		||||
    double error = double( (m*inv-MatrixType::Identity()).norm() * absdet / NumTraits<Scalar>::epsilon() );
 | 
			
		||||
    error_sum += error;
 | 
			
		||||
    error_max = (std::max)(error_max, error);
 | 
			
		||||
  }
 | 
			
		||||
  std::cerr << "inverse_general_4x4, Scalar = " << type_name<Scalar>() << std::endl;
 | 
			
		||||
  double error_avg = error_sum / repeat;
 | 
			
		||||
  EIGEN_DEBUG_VAR(error_avg);
 | 
			
		||||
  EIGEN_DEBUG_VAR(error_max);
 | 
			
		||||
   // FIXME that 1.25 used to be a 1.0 until the NumTraits changes on 28 April 2010, what's going wrong??
 | 
			
		||||
   // FIXME that 1.25 used to be 1.2 until we tested gcc 4.1 on 30 June 2010 and got 1.21.
 | 
			
		||||
  VERIFY(error_avg < (NumTraits<Scalar>::IsComplex ? 8.0 : 1.25));
 | 
			
		||||
  VERIFY(error_max < (NumTraits<Scalar>::IsComplex ? 64.0 : 20.0));
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    int s = 5;//internal::random<int>(4,10);
 | 
			
		||||
    int i = 0;//internal::random<int>(0,s-4);
 | 
			
		||||
    int j = 0;//internal::random<int>(0,s-4);
 | 
			
		||||
    Matrix<Scalar,5,5> mat(s,s);
 | 
			
		||||
    mat.setRandom();
 | 
			
		||||
    MatrixType submat = mat.template block<4,4>(i,j);
 | 
			
		||||
    MatrixType mat_inv = mat.template block<4,4>(i,j).inverse();
 | 
			
		||||
    VERIFY_IS_APPROX(mat_inv, submat.inverse());
 | 
			
		||||
    mat.template block<4,4>(i,j) = submat.inverse();
 | 
			
		||||
    VERIFY_IS_APPROX(mat_inv, (mat.template block<4,4>(i,j)));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_prec_inverse_4x4()
 | 
			
		||||
{
 | 
			
		||||
  CALL_SUBTEST_1((inverse_permutation_4x4<Matrix4f>()));
 | 
			
		||||
  CALL_SUBTEST_1(( inverse_general_4x4<Matrix4f>(200000 * g_repeat) ));
 | 
			
		||||
  CALL_SUBTEST_1(( inverse_general_4x4<Matrix<float,4,4,RowMajor> >(200000 * g_repeat) ));
 | 
			
		||||
 | 
			
		||||
  CALL_SUBTEST_2((inverse_permutation_4x4<Matrix<double,4,4,RowMajor> >()));
 | 
			
		||||
  CALL_SUBTEST_2(( inverse_general_4x4<Matrix<double,4,4,ColMajor> >(200000 * g_repeat) ));
 | 
			
		||||
  CALL_SUBTEST_2(( inverse_general_4x4<Matrix<double,4,4,RowMajor> >(200000 * g_repeat) ));
 | 
			
		||||
 | 
			
		||||
  CALL_SUBTEST_3((inverse_permutation_4x4<Matrix4cf>()));
 | 
			
		||||
  CALL_SUBTEST_3((inverse_general_4x4<Matrix4cf>(50000 * g_repeat)));
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										257
									
								
								cs440-acg/ext/eigen/test/product.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										257
									
								
								cs440-acg/ext/eigen/test/product.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,257 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
#include <Eigen/QR>
 | 
			
		||||
 | 
			
		||||
template<typename Derived1, typename Derived2>
 | 
			
		||||
bool areNotApprox(const MatrixBase<Derived1>& m1, const MatrixBase<Derived2>& m2, typename Derived1::RealScalar epsilon = NumTraits<typename Derived1::RealScalar>::dummy_precision())
 | 
			
		||||
{
 | 
			
		||||
  return !((m1-m2).cwiseAbs2().maxCoeff() < epsilon * epsilon
 | 
			
		||||
                          * (std::max)(m1.cwiseAbs2().maxCoeff(), m2.cwiseAbs2().maxCoeff()));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void product(const MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  /* this test covers the following files:
 | 
			
		||||
     Identity.h Product.h
 | 
			
		||||
  */
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> RowVectorType;
 | 
			
		||||
  typedef Matrix<Scalar, MatrixType::ColsAtCompileTime, 1> ColVectorType;
 | 
			
		||||
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> RowSquareMatrixType;
 | 
			
		||||
  typedef Matrix<Scalar, MatrixType::ColsAtCompileTime, MatrixType::ColsAtCompileTime> ColSquareMatrixType;
 | 
			
		||||
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::ColsAtCompileTime,
 | 
			
		||||
                         MatrixType::Flags&RowMajorBit?ColMajor:RowMajor> OtherMajorMatrixType;
 | 
			
		||||
 | 
			
		||||
  Index rows = m.rows();
 | 
			
		||||
  Index cols = m.cols();
 | 
			
		||||
 | 
			
		||||
  // this test relies a lot on Random.h, and there's not much more that we can do
 | 
			
		||||
  // to test it, hence I consider that we will have tested Random.h
 | 
			
		||||
  MatrixType m1 = MatrixType::Random(rows, cols),
 | 
			
		||||
             m2 = MatrixType::Random(rows, cols),
 | 
			
		||||
             m3(rows, cols);
 | 
			
		||||
  RowSquareMatrixType
 | 
			
		||||
             identity = RowSquareMatrixType::Identity(rows, rows),
 | 
			
		||||
             square = RowSquareMatrixType::Random(rows, rows),
 | 
			
		||||
             res = RowSquareMatrixType::Random(rows, rows);
 | 
			
		||||
  ColSquareMatrixType
 | 
			
		||||
             square2 = ColSquareMatrixType::Random(cols, cols),
 | 
			
		||||
             res2 = ColSquareMatrixType::Random(cols, cols);
 | 
			
		||||
  RowVectorType v1 = RowVectorType::Random(rows);
 | 
			
		||||
  ColVectorType vc2 = ColVectorType::Random(cols), vcres(cols);
 | 
			
		||||
  OtherMajorMatrixType tm1 = m1;
 | 
			
		||||
 | 
			
		||||
  Scalar s1 = internal::random<Scalar>();
 | 
			
		||||
 | 
			
		||||
  Index r  = internal::random<Index>(0, rows-1),
 | 
			
		||||
        c  = internal::random<Index>(0, cols-1),
 | 
			
		||||
        c2 = internal::random<Index>(0, cols-1);
 | 
			
		||||
 | 
			
		||||
  // begin testing Product.h: only associativity for now
 | 
			
		||||
  // (we use Transpose.h but this doesn't count as a test for it)
 | 
			
		||||
  VERIFY_IS_APPROX((m1*m1.transpose())*m2,  m1*(m1.transpose()*m2));
 | 
			
		||||
  m3 = m1;
 | 
			
		||||
  m3 *= m1.transpose() * m2;
 | 
			
		||||
  VERIFY_IS_APPROX(m3,                      m1 * (m1.transpose()*m2));
 | 
			
		||||
  VERIFY_IS_APPROX(m3,                      m1 * (m1.transpose()*m2));
 | 
			
		||||
 | 
			
		||||
  // continue testing Product.h: distributivity
 | 
			
		||||
  VERIFY_IS_APPROX(square*(m1 + m2),        square*m1+square*m2);
 | 
			
		||||
  VERIFY_IS_APPROX(square*(m1 - m2),        square*m1-square*m2);
 | 
			
		||||
 | 
			
		||||
  // continue testing Product.h: compatibility with ScalarMultiple.h
 | 
			
		||||
  VERIFY_IS_APPROX(s1*(square*m1),          (s1*square)*m1);
 | 
			
		||||
  VERIFY_IS_APPROX(s1*(square*m1),          square*(m1*s1));
 | 
			
		||||
 | 
			
		||||
  // test Product.h together with Identity.h
 | 
			
		||||
  VERIFY_IS_APPROX(v1,                      identity*v1);
 | 
			
		||||
  VERIFY_IS_APPROX(v1.transpose(),          v1.transpose() * identity);
 | 
			
		||||
  // again, test operator() to check const-qualification
 | 
			
		||||
  VERIFY_IS_APPROX(MatrixType::Identity(rows, cols)(r,c), static_cast<Scalar>(r==c));
 | 
			
		||||
 | 
			
		||||
  if (rows!=cols)
 | 
			
		||||
     VERIFY_RAISES_ASSERT(m3 = m1*m1);
 | 
			
		||||
 | 
			
		||||
  // test the previous tests were not screwed up because operator* returns 0
 | 
			
		||||
  // (we use the more accurate default epsilon)
 | 
			
		||||
  if (!NumTraits<Scalar>::IsInteger && (std::min)(rows,cols)>1)
 | 
			
		||||
  {
 | 
			
		||||
    VERIFY(areNotApprox(m1.transpose()*m2,m2.transpose()*m1));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // test optimized operator+= path
 | 
			
		||||
  res = square;
 | 
			
		||||
  res.noalias() += m1 * m2.transpose();
 | 
			
		||||
  VERIFY_IS_APPROX(res, square + m1 * m2.transpose());
 | 
			
		||||
  if (!NumTraits<Scalar>::IsInteger && (std::min)(rows,cols)>1)
 | 
			
		||||
  {
 | 
			
		||||
    VERIFY(areNotApprox(res,square + m2 * m1.transpose()));
 | 
			
		||||
  }
 | 
			
		||||
  vcres = vc2;
 | 
			
		||||
  vcres.noalias() += m1.transpose() * v1;
 | 
			
		||||
  VERIFY_IS_APPROX(vcres, vc2 + m1.transpose() * v1);
 | 
			
		||||
 | 
			
		||||
  // test optimized operator-= path
 | 
			
		||||
  res = square;
 | 
			
		||||
  res.noalias() -= m1 * m2.transpose();
 | 
			
		||||
  VERIFY_IS_APPROX(res, square - (m1 * m2.transpose()));
 | 
			
		||||
  if (!NumTraits<Scalar>::IsInteger && (std::min)(rows,cols)>1)
 | 
			
		||||
  {
 | 
			
		||||
    VERIFY(areNotApprox(res,square - m2 * m1.transpose()));
 | 
			
		||||
  }
 | 
			
		||||
  vcres = vc2;
 | 
			
		||||
  vcres.noalias() -= m1.transpose() * v1;
 | 
			
		||||
  VERIFY_IS_APPROX(vcres, vc2 - m1.transpose() * v1);
 | 
			
		||||
 | 
			
		||||
  // test scaled products
 | 
			
		||||
  res = square;
 | 
			
		||||
  res.noalias() = s1 * m1 * m2.transpose();
 | 
			
		||||
  VERIFY_IS_APPROX(res, ((s1*m1).eval() * m2.transpose()));
 | 
			
		||||
  res = square;
 | 
			
		||||
  res.noalias() += s1 * m1 * m2.transpose();
 | 
			
		||||
  VERIFY_IS_APPROX(res, square + ((s1*m1).eval() * m2.transpose()));
 | 
			
		||||
  res = square;
 | 
			
		||||
  res.noalias() -= s1 * m1 * m2.transpose();
 | 
			
		||||
  VERIFY_IS_APPROX(res, square - ((s1*m1).eval() * m2.transpose()));
 | 
			
		||||
 | 
			
		||||
  // test d ?= a+b*c rules
 | 
			
		||||
  res.noalias() = square + m1 * m2.transpose();
 | 
			
		||||
  VERIFY_IS_APPROX(res, square + m1 * m2.transpose());
 | 
			
		||||
  res.noalias() += square + m1 * m2.transpose();
 | 
			
		||||
  VERIFY_IS_APPROX(res, 2*(square + m1 * m2.transpose()));
 | 
			
		||||
  res.noalias() -= square + m1 * m2.transpose();
 | 
			
		||||
  VERIFY_IS_APPROX(res, square + m1 * m2.transpose());
 | 
			
		||||
 | 
			
		||||
  // test d ?= a-b*c rules
 | 
			
		||||
  res.noalias() = square - m1 * m2.transpose();
 | 
			
		||||
  VERIFY_IS_APPROX(res, square - m1 * m2.transpose());
 | 
			
		||||
  res.noalias() += square - m1 * m2.transpose();
 | 
			
		||||
  VERIFY_IS_APPROX(res, 2*(square - m1 * m2.transpose()));
 | 
			
		||||
  res.noalias() -= square - m1 * m2.transpose();
 | 
			
		||||
  VERIFY_IS_APPROX(res, square - m1 * m2.transpose());
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  tm1 = m1;
 | 
			
		||||
  VERIFY_IS_APPROX(tm1.transpose() * v1, m1.transpose() * v1);
 | 
			
		||||
  VERIFY_IS_APPROX(v1.transpose() * tm1, v1.transpose() * m1);
 | 
			
		||||
 | 
			
		||||
  // test submatrix and matrix/vector product
 | 
			
		||||
  for (int i=0; i<rows; ++i)
 | 
			
		||||
    res.row(i) = m1.row(i) * m2.transpose();
 | 
			
		||||
  VERIFY_IS_APPROX(res, m1 * m2.transpose());
 | 
			
		||||
  // the other way round:
 | 
			
		||||
  for (int i=0; i<rows; ++i)
 | 
			
		||||
    res.col(i) = m1 * m2.transpose().col(i);
 | 
			
		||||
  VERIFY_IS_APPROX(res, m1 * m2.transpose());
 | 
			
		||||
 | 
			
		||||
  res2 = square2;
 | 
			
		||||
  res2.noalias() += m1.transpose() * m2;
 | 
			
		||||
  VERIFY_IS_APPROX(res2, square2 + m1.transpose() * m2);
 | 
			
		||||
  if (!NumTraits<Scalar>::IsInteger && (std::min)(rows,cols)>1)
 | 
			
		||||
  {
 | 
			
		||||
    VERIFY(areNotApprox(res2,square2 + m2.transpose() * m1));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(res.col(r).noalias() = square.adjoint() * square.col(r), (square.adjoint() * square.col(r)).eval());
 | 
			
		||||
  VERIFY_IS_APPROX(res.col(r).noalias() = square * square.col(r), (square * square.col(r)).eval());
 | 
			
		||||
 | 
			
		||||
  // vector at runtime (see bug 1166)
 | 
			
		||||
  {
 | 
			
		||||
    RowSquareMatrixType ref(square);
 | 
			
		||||
    ColSquareMatrixType ref2(square2);
 | 
			
		||||
    ref = res = square;
 | 
			
		||||
    VERIFY_IS_APPROX(res.block(0,0,1,rows).noalias() = m1.col(0).transpose() * square.transpose(),            (ref.row(0) = m1.col(0).transpose() * square.transpose()));
 | 
			
		||||
    VERIFY_IS_APPROX(res.block(0,0,1,rows).noalias() = m1.block(0,0,rows,1).transpose() * square.transpose(), (ref.row(0) = m1.col(0).transpose() * square.transpose()));
 | 
			
		||||
    VERIFY_IS_APPROX(res.block(0,0,1,rows).noalias() = m1.col(0).transpose() * square,                        (ref.row(0) = m1.col(0).transpose() * square));
 | 
			
		||||
    VERIFY_IS_APPROX(res.block(0,0,1,rows).noalias() = m1.block(0,0,rows,1).transpose() * square,             (ref.row(0) = m1.col(0).transpose() * square));
 | 
			
		||||
    ref2 = res2 = square2;
 | 
			
		||||
    VERIFY_IS_APPROX(res2.block(0,0,1,cols).noalias() = m1.row(0) * square2.transpose(),                      (ref2.row(0) = m1.row(0) * square2.transpose()));
 | 
			
		||||
    VERIFY_IS_APPROX(res2.block(0,0,1,cols).noalias() = m1.block(0,0,1,cols) * square2.transpose(),           (ref2.row(0) = m1.row(0) * square2.transpose()));
 | 
			
		||||
    VERIFY_IS_APPROX(res2.block(0,0,1,cols).noalias() = m1.row(0) * square2,                                  (ref2.row(0) = m1.row(0) * square2));
 | 
			
		||||
    VERIFY_IS_APPROX(res2.block(0,0,1,cols).noalias() = m1.block(0,0,1,cols) * square2,                       (ref2.row(0) = m1.row(0) * square2));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // vector.block() (see bug 1283)
 | 
			
		||||
  {
 | 
			
		||||
    RowVectorType w1(rows);
 | 
			
		||||
    VERIFY_IS_APPROX(square * v1.block(0,0,rows,1), square * v1);
 | 
			
		||||
    VERIFY_IS_APPROX(w1.noalias() = square * v1.block(0,0,rows,1), square * v1);
 | 
			
		||||
    VERIFY_IS_APPROX(w1.block(0,0,rows,1).noalias() = square * v1.block(0,0,rows,1), square * v1);
 | 
			
		||||
 | 
			
		||||
    Matrix<Scalar,1,MatrixType::ColsAtCompileTime> w2(cols);
 | 
			
		||||
    VERIFY_IS_APPROX(vc2.block(0,0,cols,1).transpose() * square2, vc2.transpose() * square2);
 | 
			
		||||
    VERIFY_IS_APPROX(w2.noalias() = vc2.block(0,0,cols,1).transpose() * square2, vc2.transpose() * square2);
 | 
			
		||||
    VERIFY_IS_APPROX(w2.block(0,0,1,cols).noalias() = vc2.block(0,0,cols,1).transpose() * square2, vc2.transpose() * square2);
 | 
			
		||||
 | 
			
		||||
    vc2 = square2.block(0,0,1,cols).transpose();
 | 
			
		||||
    VERIFY_IS_APPROX(square2.block(0,0,1,cols) * square2, vc2.transpose() * square2);
 | 
			
		||||
    VERIFY_IS_APPROX(w2.noalias() = square2.block(0,0,1,cols) * square2, vc2.transpose() * square2);
 | 
			
		||||
    VERIFY_IS_APPROX(w2.block(0,0,1,cols).noalias() = square2.block(0,0,1,cols) * square2, vc2.transpose() * square2);
 | 
			
		||||
 | 
			
		||||
    vc2 = square2.block(0,0,cols,1);
 | 
			
		||||
    VERIFY_IS_APPROX(square2.block(0,0,cols,1).transpose() * square2, vc2.transpose() * square2);
 | 
			
		||||
    VERIFY_IS_APPROX(w2.noalias() = square2.block(0,0,cols,1).transpose() * square2, vc2.transpose() * square2);
 | 
			
		||||
    VERIFY_IS_APPROX(w2.block(0,0,1,cols).noalias() = square2.block(0,0,cols,1).transpose() * square2, vc2.transpose() * square2);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // inner product
 | 
			
		||||
  {
 | 
			
		||||
    Scalar x = square2.row(c) * square2.col(c2);
 | 
			
		||||
    VERIFY_IS_APPROX(x, square2.row(c).transpose().cwiseProduct(square2.col(c2)).sum());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // outer product
 | 
			
		||||
  {
 | 
			
		||||
    VERIFY_IS_APPROX(m1.col(c) * m1.row(r), m1.block(0,c,rows,1) * m1.block(r,0,1,cols));
 | 
			
		||||
    VERIFY_IS_APPROX(m1.row(r).transpose() * m1.col(c).transpose(), m1.block(r,0,1,cols).transpose() * m1.block(0,c,rows,1).transpose());
 | 
			
		||||
    VERIFY_IS_APPROX(m1.block(0,c,rows,1) * m1.row(r), m1.block(0,c,rows,1) * m1.block(r,0,1,cols));
 | 
			
		||||
    VERIFY_IS_APPROX(m1.col(c) * m1.block(r,0,1,cols), m1.block(0,c,rows,1) * m1.block(r,0,1,cols));
 | 
			
		||||
    VERIFY_IS_APPROX(m1.leftCols(1) * m1.row(r), m1.block(0,0,rows,1) * m1.block(r,0,1,cols));
 | 
			
		||||
    VERIFY_IS_APPROX(m1.col(c) * m1.topRows(1), m1.block(0,c,rows,1) * m1.block(0,0,1,cols));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Aliasing
 | 
			
		||||
  {
 | 
			
		||||
    ColVectorType x(cols); x.setRandom();
 | 
			
		||||
    ColVectorType z(x);
 | 
			
		||||
    ColVectorType y(cols); y.setZero();
 | 
			
		||||
    ColSquareMatrixType A(cols,cols); A.setRandom();
 | 
			
		||||
    // CwiseBinaryOp
 | 
			
		||||
    VERIFY_IS_APPROX(x = y + A*x, A*z);
 | 
			
		||||
    x = z;
 | 
			
		||||
    // CwiseUnaryOp
 | 
			
		||||
    VERIFY_IS_APPROX(x = Scalar(1.)*(A*x), A*z);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // regression for blas_trais
 | 
			
		||||
  {
 | 
			
		||||
    VERIFY_IS_APPROX(square * (square*square).transpose(), square * square.transpose() * square.transpose());
 | 
			
		||||
    VERIFY_IS_APPROX(square * (-(square*square)), -square * square * square);
 | 
			
		||||
    VERIFY_IS_APPROX(square * (s1*(square*square)), s1 * square * square * square);
 | 
			
		||||
    VERIFY_IS_APPROX(square * (square*square).conjugate(), square * square.conjugate() * square.conjugate());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // destination with a non-default inner-stride
 | 
			
		||||
  // see bug 1741
 | 
			
		||||
  if(!MatrixType::IsRowMajor)
 | 
			
		||||
  {
 | 
			
		||||
    typedef Matrix<Scalar,Dynamic,Dynamic> MatrixX;
 | 
			
		||||
    MatrixX buffer(2*rows,2*rows);
 | 
			
		||||
    Map<RowSquareMatrixType,0,Stride<Dynamic,2> > map1(buffer.data(),rows,rows,Stride<Dynamic,2>(2*rows,2));
 | 
			
		||||
    buffer.setZero();
 | 
			
		||||
    VERIFY_IS_APPROX(map1 = m1 * m2.transpose(), (m1 * m2.transpose()).eval());
 | 
			
		||||
    buffer.setZero();
 | 
			
		||||
    VERIFY_IS_APPROX(map1.noalias() = m1 * m2.transpose(), (m1 * m2.transpose()).eval());
 | 
			
		||||
    buffer.setZero();
 | 
			
		||||
    VERIFY_IS_APPROX(map1.noalias() += m1 * m2.transpose(), (m1 * m2.transpose()).eval());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										374
									
								
								cs440-acg/ext/eigen/test/product_extra.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										374
									
								
								cs440-acg/ext/eigen/test/product_extra.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,374 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void product_extra(const MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
  typedef Matrix<Scalar, 1, Dynamic> RowVectorType;
 | 
			
		||||
  typedef Matrix<Scalar, Dynamic, 1> ColVectorType;
 | 
			
		||||
  typedef Matrix<Scalar, Dynamic, Dynamic,
 | 
			
		||||
                         MatrixType::Flags&RowMajorBit> OtherMajorMatrixType;
 | 
			
		||||
 | 
			
		||||
  Index rows = m.rows();
 | 
			
		||||
  Index cols = m.cols();
 | 
			
		||||
 | 
			
		||||
  MatrixType m1 = MatrixType::Random(rows, cols),
 | 
			
		||||
             m2 = MatrixType::Random(rows, cols),
 | 
			
		||||
             m3(rows, cols),
 | 
			
		||||
             mzero = MatrixType::Zero(rows, cols),
 | 
			
		||||
             identity = MatrixType::Identity(rows, rows),
 | 
			
		||||
             square = MatrixType::Random(rows, rows),
 | 
			
		||||
             res = MatrixType::Random(rows, rows),
 | 
			
		||||
             square2 = MatrixType::Random(cols, cols),
 | 
			
		||||
             res2 = MatrixType::Random(cols, cols);
 | 
			
		||||
  RowVectorType v1 = RowVectorType::Random(rows), vrres(rows);
 | 
			
		||||
  ColVectorType vc2 = ColVectorType::Random(cols), vcres(cols);
 | 
			
		||||
  OtherMajorMatrixType tm1 = m1;
 | 
			
		||||
 | 
			
		||||
  Scalar s1 = internal::random<Scalar>(),
 | 
			
		||||
         s2 = internal::random<Scalar>(),
 | 
			
		||||
         s3 = internal::random<Scalar>();
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(m3.noalias() = m1 * m2.adjoint(),                 m1 * m2.adjoint().eval());
 | 
			
		||||
  VERIFY_IS_APPROX(m3.noalias() = m1.adjoint() * square.adjoint(),   m1.adjoint().eval() * square.adjoint().eval());
 | 
			
		||||
  VERIFY_IS_APPROX(m3.noalias() = m1.adjoint() * m2,                 m1.adjoint().eval() * m2);
 | 
			
		||||
  VERIFY_IS_APPROX(m3.noalias() = (s1 * m1.adjoint()) * m2,          (s1 * m1.adjoint()).eval() * m2);
 | 
			
		||||
  VERIFY_IS_APPROX(m3.noalias() = ((s1 * m1).adjoint()) * m2,        (numext::conj(s1) * m1.adjoint()).eval() * m2);
 | 
			
		||||
  VERIFY_IS_APPROX(m3.noalias() = (- m1.adjoint() * s1) * (s3 * m2), (- m1.adjoint()  * s1).eval() * (s3 * m2).eval());
 | 
			
		||||
  VERIFY_IS_APPROX(m3.noalias() = (s2 * m1.adjoint() * s1) * m2,     (s2 * m1.adjoint()  * s1).eval() * m2);
 | 
			
		||||
  VERIFY_IS_APPROX(m3.noalias() = (-m1*s2) * s1*m2.adjoint(),        (-m1*s2).eval() * (s1*m2.adjoint()).eval());
 | 
			
		||||
 | 
			
		||||
  // a very tricky case where a scale factor has to be automatically conjugated:
 | 
			
		||||
  VERIFY_IS_APPROX( m1.adjoint() * (s1*m2).conjugate(), (m1.adjoint()).eval() * ((s1*m2).conjugate()).eval());
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  // test all possible conjugate combinations for the four matrix-vector product cases:
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX((-m1.conjugate() * s2) * (s1 * vc2),
 | 
			
		||||
                   (-m1.conjugate()*s2).eval() * (s1 * vc2).eval());
 | 
			
		||||
  VERIFY_IS_APPROX((-m1 * s2) * (s1 * vc2.conjugate()),
 | 
			
		||||
                   (-m1*s2).eval() * (s1 * vc2.conjugate()).eval());
 | 
			
		||||
  VERIFY_IS_APPROX((-m1.conjugate() * s2) * (s1 * vc2.conjugate()),
 | 
			
		||||
                   (-m1.conjugate()*s2).eval() * (s1 * vc2.conjugate()).eval());
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX((s1 * vc2.transpose()) * (-m1.adjoint() * s2),
 | 
			
		||||
                   (s1 * vc2.transpose()).eval() * (-m1.adjoint()*s2).eval());
 | 
			
		||||
  VERIFY_IS_APPROX((s1 * vc2.adjoint()) * (-m1.transpose() * s2),
 | 
			
		||||
                   (s1 * vc2.adjoint()).eval() * (-m1.transpose()*s2).eval());
 | 
			
		||||
  VERIFY_IS_APPROX((s1 * vc2.adjoint()) * (-m1.adjoint() * s2),
 | 
			
		||||
                   (s1 * vc2.adjoint()).eval() * (-m1.adjoint()*s2).eval());
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX((-m1.adjoint() * s2) * (s1 * v1.transpose()),
 | 
			
		||||
                   (-m1.adjoint()*s2).eval() * (s1 * v1.transpose()).eval());
 | 
			
		||||
  VERIFY_IS_APPROX((-m1.transpose() * s2) * (s1 * v1.adjoint()),
 | 
			
		||||
                   (-m1.transpose()*s2).eval() * (s1 * v1.adjoint()).eval());
 | 
			
		||||
  VERIFY_IS_APPROX((-m1.adjoint() * s2) * (s1 * v1.adjoint()),
 | 
			
		||||
                   (-m1.adjoint()*s2).eval() * (s1 * v1.adjoint()).eval());
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX((s1 * v1) * (-m1.conjugate() * s2),
 | 
			
		||||
                   (s1 * v1).eval() * (-m1.conjugate()*s2).eval());
 | 
			
		||||
  VERIFY_IS_APPROX((s1 * v1.conjugate()) * (-m1 * s2),
 | 
			
		||||
                   (s1 * v1.conjugate()).eval() * (-m1*s2).eval());
 | 
			
		||||
  VERIFY_IS_APPROX((s1 * v1.conjugate()) * (-m1.conjugate() * s2),
 | 
			
		||||
                   (s1 * v1.conjugate()).eval() * (-m1.conjugate()*s2).eval());
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX((-m1.adjoint() * s2) * (s1 * v1.adjoint()),
 | 
			
		||||
                   (-m1.adjoint()*s2).eval() * (s1 * v1.adjoint()).eval());
 | 
			
		||||
 | 
			
		||||
  // test the vector-matrix product with non aligned starts
 | 
			
		||||
  Index i = internal::random<Index>(0,m1.rows()-2);
 | 
			
		||||
  Index j = internal::random<Index>(0,m1.cols()-2);
 | 
			
		||||
  Index r = internal::random<Index>(1,m1.rows()-i);
 | 
			
		||||
  Index c = internal::random<Index>(1,m1.cols()-j);
 | 
			
		||||
  Index i2 = internal::random<Index>(0,m1.rows()-1);
 | 
			
		||||
  Index j2 = internal::random<Index>(0,m1.cols()-1);
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(m1.col(j2).adjoint() * m1.block(0,j,m1.rows(),c), m1.col(j2).adjoint().eval() * m1.block(0,j,m1.rows(),c).eval());
 | 
			
		||||
  VERIFY_IS_APPROX(m1.block(i,0,r,m1.cols()) * m1.row(i2).adjoint(), m1.block(i,0,r,m1.cols()).eval() * m1.row(i2).adjoint().eval());
 | 
			
		||||
  
 | 
			
		||||
  // regression test
 | 
			
		||||
  MatrixType tmp = m1 * m1.adjoint() * s1;
 | 
			
		||||
  VERIFY_IS_APPROX(tmp, m1 * m1.adjoint() * s1);
 | 
			
		||||
 | 
			
		||||
  // regression test for bug 1343, assignment to arrays
 | 
			
		||||
  Array<Scalar,Dynamic,1> a1 = m1 * vc2;
 | 
			
		||||
  VERIFY_IS_APPROX(a1.matrix(),m1*vc2);
 | 
			
		||||
  Array<Scalar,Dynamic,1> a2 = s1 * (m1 * vc2);
 | 
			
		||||
  VERIFY_IS_APPROX(a2.matrix(),s1*m1*vc2);
 | 
			
		||||
  Array<Scalar,1,Dynamic> a3 = v1 * m1;
 | 
			
		||||
  VERIFY_IS_APPROX(a3.matrix(),v1*m1);
 | 
			
		||||
  Array<Scalar,Dynamic,Dynamic> a4 = m1 * m2.adjoint();
 | 
			
		||||
  VERIFY_IS_APPROX(a4.matrix(),m1*m2.adjoint());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Regression test for bug reported at http://forum.kde.org/viewtopic.php?f=74&t=96947
 | 
			
		||||
void mat_mat_scalar_scalar_product()
 | 
			
		||||
{
 | 
			
		||||
  Eigen::Matrix2Xd dNdxy(2, 3);
 | 
			
		||||
  dNdxy << -0.5, 0.5, 0,
 | 
			
		||||
           -0.3, 0, 0.3;
 | 
			
		||||
  double det = 6.0, wt = 0.5;
 | 
			
		||||
  VERIFY_IS_APPROX(dNdxy.transpose()*dNdxy*det*wt, det*wt*dNdxy.transpose()*dNdxy);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename MatrixType> 
 | 
			
		||||
void zero_sized_objects(const MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
  const int PacketSize  = internal::packet_traits<Scalar>::size;
 | 
			
		||||
  const int PacketSize1 = PacketSize>1 ?  PacketSize-1 : 1;
 | 
			
		||||
  Index rows = m.rows();
 | 
			
		||||
  Index cols = m.cols();
 | 
			
		||||
  
 | 
			
		||||
  {
 | 
			
		||||
    MatrixType res, a(rows,0), b(0,cols);
 | 
			
		||||
    VERIFY_IS_APPROX( (res=a*b), MatrixType::Zero(rows,cols) );
 | 
			
		||||
    VERIFY_IS_APPROX( (res=a*a.transpose()), MatrixType::Zero(rows,rows) );
 | 
			
		||||
    VERIFY_IS_APPROX( (res=b.transpose()*b), MatrixType::Zero(cols,cols) );
 | 
			
		||||
    VERIFY_IS_APPROX( (res=b.transpose()*a.transpose()), MatrixType::Zero(cols,rows) );
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  {
 | 
			
		||||
    MatrixType res, a(rows,cols), b(cols,0);
 | 
			
		||||
    res = a*b;
 | 
			
		||||
    VERIFY(res.rows()==rows && res.cols()==0);
 | 
			
		||||
    b.resize(0,rows);
 | 
			
		||||
    res = b*a;
 | 
			
		||||
    VERIFY(res.rows()==0 && res.cols()==cols);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  {
 | 
			
		||||
    Matrix<Scalar,PacketSize,0> a;
 | 
			
		||||
    Matrix<Scalar,0,1> b;
 | 
			
		||||
    Matrix<Scalar,PacketSize,1> res;
 | 
			
		||||
    VERIFY_IS_APPROX( (res=a*b), MatrixType::Zero(PacketSize,1) );
 | 
			
		||||
    VERIFY_IS_APPROX( (res=a.lazyProduct(b)), MatrixType::Zero(PacketSize,1) );
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  {
 | 
			
		||||
    Matrix<Scalar,PacketSize1,0> a;
 | 
			
		||||
    Matrix<Scalar,0,1> b;
 | 
			
		||||
    Matrix<Scalar,PacketSize1,1> res;
 | 
			
		||||
    VERIFY_IS_APPROX( (res=a*b), MatrixType::Zero(PacketSize1,1) );
 | 
			
		||||
    VERIFY_IS_APPROX( (res=a.lazyProduct(b)), MatrixType::Zero(PacketSize1,1) );
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  {
 | 
			
		||||
    Matrix<Scalar,PacketSize,Dynamic> a(PacketSize,0);
 | 
			
		||||
    Matrix<Scalar,Dynamic,1> b(0,1);
 | 
			
		||||
    Matrix<Scalar,PacketSize,1> res;
 | 
			
		||||
    VERIFY_IS_APPROX( (res=a*b), MatrixType::Zero(PacketSize,1) );
 | 
			
		||||
    VERIFY_IS_APPROX( (res=a.lazyProduct(b)), MatrixType::Zero(PacketSize,1) );
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  {
 | 
			
		||||
    Matrix<Scalar,PacketSize1,Dynamic> a(PacketSize1,0);
 | 
			
		||||
    Matrix<Scalar,Dynamic,1> b(0,1);
 | 
			
		||||
    Matrix<Scalar,PacketSize1,1> res;
 | 
			
		||||
    VERIFY_IS_APPROX( (res=a*b), MatrixType::Zero(PacketSize1,1) );
 | 
			
		||||
    VERIFY_IS_APPROX( (res=a.lazyProduct(b)), MatrixType::Zero(PacketSize1,1) );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<int>
 | 
			
		||||
void bug_127()
 | 
			
		||||
{
 | 
			
		||||
  // Bug 127
 | 
			
		||||
  //
 | 
			
		||||
  // a product of the form lhs*rhs with
 | 
			
		||||
  //
 | 
			
		||||
  // lhs:
 | 
			
		||||
  // rows = 1, cols = 4
 | 
			
		||||
  // RowsAtCompileTime = 1, ColsAtCompileTime = -1
 | 
			
		||||
  // MaxRowsAtCompileTime = 1, MaxColsAtCompileTime = 5
 | 
			
		||||
  //
 | 
			
		||||
  // rhs:
 | 
			
		||||
  // rows = 4, cols = 0
 | 
			
		||||
  // RowsAtCompileTime = -1, ColsAtCompileTime = -1
 | 
			
		||||
  // MaxRowsAtCompileTime = 5, MaxColsAtCompileTime = 1
 | 
			
		||||
  //
 | 
			
		||||
  // was failing on a runtime assertion, because it had been mis-compiled as a dot product because Product.h was using the
 | 
			
		||||
  // max-sizes to detect size 1 indicating vectors, and that didn't account for 0-sized object with max-size 1.
 | 
			
		||||
 | 
			
		||||
  Matrix<float,1,Dynamic,RowMajor,1,5> a(1,4);
 | 
			
		||||
  Matrix<float,Dynamic,Dynamic,ColMajor,5,1> b(4,0);
 | 
			
		||||
  a*b;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<int> void bug_817()
 | 
			
		||||
{
 | 
			
		||||
  ArrayXXf B = ArrayXXf::Random(10,10), C;
 | 
			
		||||
  VectorXf x = VectorXf::Random(10);
 | 
			
		||||
  C = (x.transpose()*B.matrix());
 | 
			
		||||
  B = (x.transpose()*B.matrix());
 | 
			
		||||
  VERIFY_IS_APPROX(B,C);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<int>
 | 
			
		||||
void unaligned_objects()
 | 
			
		||||
{
 | 
			
		||||
  // Regression test for the bug reported here:
 | 
			
		||||
  // http://forum.kde.org/viewtopic.php?f=74&t=107541
 | 
			
		||||
  // Recall the matrix*vector kernel avoid unaligned loads by loading two packets and then reassemble then.
 | 
			
		||||
  // There was a mistake in the computation of the valid range for fully unaligned objects: in some rare cases,
 | 
			
		||||
  // memory was read outside the allocated matrix memory. Though the values were not used, this might raise segfault.
 | 
			
		||||
  for(int m=450;m<460;++m)
 | 
			
		||||
  {
 | 
			
		||||
    for(int n=8;n<12;++n)
 | 
			
		||||
    {
 | 
			
		||||
      MatrixXf M(m, n);
 | 
			
		||||
      VectorXf v1(n), r1(500);
 | 
			
		||||
      RowVectorXf v2(m), r2(16);
 | 
			
		||||
 | 
			
		||||
      M.setRandom();
 | 
			
		||||
      v1.setRandom();
 | 
			
		||||
      v2.setRandom();
 | 
			
		||||
      for(int o=0; o<4; ++o)
 | 
			
		||||
      {
 | 
			
		||||
        r1.segment(o,m).noalias() = M * v1;
 | 
			
		||||
        VERIFY_IS_APPROX(r1.segment(o,m), M * MatrixXf(v1));
 | 
			
		||||
        r2.segment(o,n).noalias() = v2 * M;
 | 
			
		||||
        VERIFY_IS_APPROX(r2.segment(o,n), MatrixXf(v2) * M);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
EIGEN_DONT_INLINE
 | 
			
		||||
Index test_compute_block_size(Index m, Index n, Index k)
 | 
			
		||||
{
 | 
			
		||||
  Index mc(m), nc(n), kc(k);
 | 
			
		||||
  internal::computeProductBlockingSizes<T,T>(kc, mc, nc);
 | 
			
		||||
  return kc+mc+nc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
Index compute_block_size()
 | 
			
		||||
{
 | 
			
		||||
  Index ret = 0;
 | 
			
		||||
  ret += test_compute_block_size<T>(0,1,1);
 | 
			
		||||
  ret += test_compute_block_size<T>(1,0,1);
 | 
			
		||||
  ret += test_compute_block_size<T>(1,1,0);
 | 
			
		||||
  ret += test_compute_block_size<T>(0,0,1);
 | 
			
		||||
  ret += test_compute_block_size<T>(0,1,0);
 | 
			
		||||
  ret += test_compute_block_size<T>(1,0,0);
 | 
			
		||||
  ret += test_compute_block_size<T>(0,0,0);
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename>
 | 
			
		||||
void aliasing_with_resize()
 | 
			
		||||
{
 | 
			
		||||
  Index m = internal::random<Index>(10,50);
 | 
			
		||||
  Index n = internal::random<Index>(10,50);
 | 
			
		||||
  MatrixXd A, B, C(m,n), D(m,m);
 | 
			
		||||
  VectorXd a, b, c(n);
 | 
			
		||||
  C.setRandom();
 | 
			
		||||
  D.setRandom();
 | 
			
		||||
  c.setRandom();
 | 
			
		||||
  double s = internal::random<double>(1,10);
 | 
			
		||||
 | 
			
		||||
  A = C;
 | 
			
		||||
  B = A * A.transpose();
 | 
			
		||||
  A = A * A.transpose();
 | 
			
		||||
  VERIFY_IS_APPROX(A,B);
 | 
			
		||||
 | 
			
		||||
  A = C;
 | 
			
		||||
  B = (A * A.transpose())/s;
 | 
			
		||||
  A = (A * A.transpose())/s;
 | 
			
		||||
  VERIFY_IS_APPROX(A,B);
 | 
			
		||||
 | 
			
		||||
  A = C;
 | 
			
		||||
  B = (A * A.transpose()) + D;
 | 
			
		||||
  A = (A * A.transpose()) + D;
 | 
			
		||||
  VERIFY_IS_APPROX(A,B);
 | 
			
		||||
 | 
			
		||||
  A = C;
 | 
			
		||||
  B = D + (A * A.transpose());
 | 
			
		||||
  A = D + (A * A.transpose());
 | 
			
		||||
  VERIFY_IS_APPROX(A,B);
 | 
			
		||||
 | 
			
		||||
  A = C;
 | 
			
		||||
  B = s * (A * A.transpose());
 | 
			
		||||
  A = s * (A * A.transpose());
 | 
			
		||||
  VERIFY_IS_APPROX(A,B);
 | 
			
		||||
 | 
			
		||||
  A = C;
 | 
			
		||||
  a = c;
 | 
			
		||||
  b = (A * a)/s;
 | 
			
		||||
  a = (A * a)/s;
 | 
			
		||||
  VERIFY_IS_APPROX(a,b);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<int>
 | 
			
		||||
void bug_1308()
 | 
			
		||||
{
 | 
			
		||||
  int n = 10;
 | 
			
		||||
  MatrixXd r(n,n);
 | 
			
		||||
  VectorXd v = VectorXd::Random(n);
 | 
			
		||||
  r = v * RowVectorXd::Ones(n);
 | 
			
		||||
  VERIFY_IS_APPROX(r, v.rowwise().replicate(n));
 | 
			
		||||
  r = VectorXd::Ones(n) * v.transpose();
 | 
			
		||||
  VERIFY_IS_APPROX(r, v.rowwise().replicate(n).transpose());
 | 
			
		||||
 | 
			
		||||
  Matrix4d ones44 = Matrix4d::Ones();
 | 
			
		||||
  Matrix4d m44 = Matrix4d::Ones() * Matrix4d::Ones();
 | 
			
		||||
  VERIFY_IS_APPROX(m44,Matrix4d::Constant(4));
 | 
			
		||||
  VERIFY_IS_APPROX(m44.noalias()=ones44*Matrix4d::Ones(), Matrix4d::Constant(4));
 | 
			
		||||
  VERIFY_IS_APPROX(m44.noalias()=ones44.transpose()*Matrix4d::Ones(), Matrix4d::Constant(4));
 | 
			
		||||
  VERIFY_IS_APPROX(m44.noalias()=Matrix4d::Ones()*ones44, Matrix4d::Constant(4));
 | 
			
		||||
  VERIFY_IS_APPROX(m44.noalias()=Matrix4d::Ones()*ones44.transpose(), Matrix4d::Constant(4));
 | 
			
		||||
 | 
			
		||||
  typedef Matrix<double,4,4,RowMajor> RMatrix4d;
 | 
			
		||||
  RMatrix4d r44 = Matrix4d::Ones() * Matrix4d::Ones();
 | 
			
		||||
  VERIFY_IS_APPROX(r44,Matrix4d::Constant(4));
 | 
			
		||||
  VERIFY_IS_APPROX(r44.noalias()=ones44*Matrix4d::Ones(), Matrix4d::Constant(4));
 | 
			
		||||
  VERIFY_IS_APPROX(r44.noalias()=ones44.transpose()*Matrix4d::Ones(), Matrix4d::Constant(4));
 | 
			
		||||
  VERIFY_IS_APPROX(r44.noalias()=Matrix4d::Ones()*ones44, Matrix4d::Constant(4));
 | 
			
		||||
  VERIFY_IS_APPROX(r44.noalias()=Matrix4d::Ones()*ones44.transpose(), Matrix4d::Constant(4));
 | 
			
		||||
  VERIFY_IS_APPROX(r44.noalias()=ones44*RMatrix4d::Ones(), Matrix4d::Constant(4));
 | 
			
		||||
  VERIFY_IS_APPROX(r44.noalias()=ones44.transpose()*RMatrix4d::Ones(), Matrix4d::Constant(4));
 | 
			
		||||
  VERIFY_IS_APPROX(r44.noalias()=RMatrix4d::Ones()*ones44, Matrix4d::Constant(4));
 | 
			
		||||
  VERIFY_IS_APPROX(r44.noalias()=RMatrix4d::Ones()*ones44.transpose(), Matrix4d::Constant(4));
 | 
			
		||||
 | 
			
		||||
//   RowVector4d r4;
 | 
			
		||||
  m44.setOnes();
 | 
			
		||||
  r44.setZero();
 | 
			
		||||
  VERIFY_IS_APPROX(r44.noalias() += m44.row(0).transpose() * RowVector4d::Ones(), ones44);
 | 
			
		||||
  r44.setZero();
 | 
			
		||||
  VERIFY_IS_APPROX(r44.noalias() += m44.col(0) * RowVector4d::Ones(), ones44);
 | 
			
		||||
  r44.setZero();
 | 
			
		||||
  VERIFY_IS_APPROX(r44.noalias() += Vector4d::Ones() * m44.row(0), ones44);
 | 
			
		||||
  r44.setZero();
 | 
			
		||||
  VERIFY_IS_APPROX(r44.noalias() += Vector4d::Ones() * m44.col(0).transpose(), ones44);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_product_extra()
 | 
			
		||||
{
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_1( product_extra(MatrixXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
    CALL_SUBTEST_2( product_extra(MatrixXd(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
    CALL_SUBTEST_2( mat_mat_scalar_scalar_product() );
 | 
			
		||||
    CALL_SUBTEST_3( product_extra(MatrixXcf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2), internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2))) );
 | 
			
		||||
    CALL_SUBTEST_4( product_extra(MatrixXcd(internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2), internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2))) );
 | 
			
		||||
    CALL_SUBTEST_1( zero_sized_objects(MatrixXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
  }
 | 
			
		||||
  CALL_SUBTEST_5( bug_127<0>() );
 | 
			
		||||
  CALL_SUBTEST_5( bug_817<0>() );
 | 
			
		||||
  CALL_SUBTEST_5( bug_1308<0>() );
 | 
			
		||||
  CALL_SUBTEST_6( unaligned_objects<0>() );
 | 
			
		||||
  CALL_SUBTEST_7( compute_block_size<float>() );
 | 
			
		||||
  CALL_SUBTEST_7( compute_block_size<double>() );
 | 
			
		||||
  CALL_SUBTEST_7( compute_block_size<std::complex<double> >() );
 | 
			
		||||
  CALL_SUBTEST_8( aliasing_with_resize<void>() );
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										109
									
								
								cs440-acg/ext/eigen/test/product_large.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								cs440-acg/ext/eigen/test/product_large.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,109 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "product.h"
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
void test_aliasing()
 | 
			
		||||
{
 | 
			
		||||
  int rows = internal::random<int>(1,12);
 | 
			
		||||
  int cols = internal::random<int>(1,12);
 | 
			
		||||
  typedef Matrix<T,Dynamic,Dynamic> MatrixType;
 | 
			
		||||
  typedef Matrix<T,Dynamic,1> VectorType;
 | 
			
		||||
  VectorType x(cols); x.setRandom();
 | 
			
		||||
  VectorType z(x);
 | 
			
		||||
  VectorType y(rows); y.setZero();
 | 
			
		||||
  MatrixType A(rows,cols); A.setRandom();
 | 
			
		||||
  // CwiseBinaryOp
 | 
			
		||||
  VERIFY_IS_APPROX(x = y + A*x, A*z);     // OK because "y + A*x" is marked as "assume-aliasing"
 | 
			
		||||
  x = z;
 | 
			
		||||
  // CwiseUnaryOp
 | 
			
		||||
  VERIFY_IS_APPROX(x = T(1.)*(A*x), A*z); // OK because 1*(A*x) is replaced by (1*A*x) which is a Product<> expression
 | 
			
		||||
  x = z;
 | 
			
		||||
  // VERIFY_IS_APPROX(x = y-A*x, -A*z);   // Not OK in 3.3 because x is resized before A*x gets evaluated
 | 
			
		||||
  x = z;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_product_large()
 | 
			
		||||
{
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_1( product(MatrixXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
    CALL_SUBTEST_2( product(MatrixXd(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
    CALL_SUBTEST_2( product(MatrixXd(internal::random<int>(1,10), internal::random<int>(1,10))) );
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_3( product(MatrixXi(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
    CALL_SUBTEST_4( product(MatrixXcf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2), internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2))) );
 | 
			
		||||
    CALL_SUBTEST_5( product(Matrix<float,Dynamic,Dynamic,RowMajor>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_1( test_aliasing<float>() );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
#if defined EIGEN_TEST_PART_6
 | 
			
		||||
  {
 | 
			
		||||
    // test a specific issue in DiagonalProduct
 | 
			
		||||
    int N = 1000000;
 | 
			
		||||
    VectorXf v = VectorXf::Ones(N);
 | 
			
		||||
    MatrixXf m = MatrixXf::Ones(N,3);
 | 
			
		||||
    m = (v+v).asDiagonal() * m;
 | 
			
		||||
    VERIFY_IS_APPROX(m, MatrixXf::Constant(N,3,2));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    // test deferred resizing in Matrix::operator=
 | 
			
		||||
    MatrixXf a = MatrixXf::Random(10,4), b = MatrixXf::Random(4,10), c = a;
 | 
			
		||||
    VERIFY_IS_APPROX((a = a * b), (c * b).eval());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    // check the functions to setup blocking sizes compile and do not segfault
 | 
			
		||||
    // FIXME check they do what they are supposed to do !!
 | 
			
		||||
    std::ptrdiff_t l1 = internal::random<int>(10000,20000);
 | 
			
		||||
    std::ptrdiff_t l2 = internal::random<int>(100000,200000);
 | 
			
		||||
    std::ptrdiff_t l3 = internal::random<int>(1000000,2000000);
 | 
			
		||||
    setCpuCacheSizes(l1,l2,l3);
 | 
			
		||||
    VERIFY(l1==l1CacheSize());
 | 
			
		||||
    VERIFY(l2==l2CacheSize());
 | 
			
		||||
    std::ptrdiff_t k1 = internal::random<int>(10,100)*16;
 | 
			
		||||
    std::ptrdiff_t m1 = internal::random<int>(10,100)*16;
 | 
			
		||||
    std::ptrdiff_t n1 = internal::random<int>(10,100)*16;
 | 
			
		||||
    // only makes sure it compiles fine
 | 
			
		||||
    internal::computeProductBlockingSizes<float,float,std::ptrdiff_t>(k1,m1,n1,1);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    // test regression in row-vector by matrix (bad Map type)
 | 
			
		||||
    MatrixXf mat1(10,32); mat1.setRandom();
 | 
			
		||||
    MatrixXf mat2(32,32); mat2.setRandom();
 | 
			
		||||
    MatrixXf r1 = mat1.row(2)*mat2.transpose();
 | 
			
		||||
    VERIFY_IS_APPROX(r1, (mat1.row(2)*mat2.transpose()).eval());
 | 
			
		||||
 | 
			
		||||
    MatrixXf r2 = mat1.row(2)*mat2;
 | 
			
		||||
    VERIFY_IS_APPROX(r2, (mat1.row(2)*mat2).eval());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    Eigen::MatrixXd A(10,10), B, C;
 | 
			
		||||
    A.setRandom();
 | 
			
		||||
    C = A;
 | 
			
		||||
    for(int k=0; k<79; ++k)
 | 
			
		||||
      C = C * A;
 | 
			
		||||
    B.noalias() = (((A*A)*(A*A))*((A*A)*(A*A))*((A*A)*(A*A))*((A*A)*(A*A))*((A*A)*(A*A)) * ((A*A)*(A*A))*((A*A)*(A*A))*((A*A)*(A*A))*((A*A)*(A*A))*((A*A)*(A*A)))
 | 
			
		||||
                * (((A*A)*(A*A))*((A*A)*(A*A))*((A*A)*(A*A))*((A*A)*(A*A))*((A*A)*(A*A)) * ((A*A)*(A*A))*((A*A)*(A*A))*((A*A)*(A*A))*((A*A)*(A*A))*((A*A)*(A*A)));
 | 
			
		||||
    VERIFY_IS_APPROX(B,C);
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  // Regression test for bug 714:
 | 
			
		||||
#if defined EIGEN_HAS_OPENMP
 | 
			
		||||
  omp_set_dynamic(1);
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_6( product(Matrix<float,Dynamic,Dynamic>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										106
									
								
								cs440-acg/ext/eigen/test/product_mmtr.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								cs440-acg/ext/eigen/test/product_mmtr.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,106 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2010-2017 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
 | 
			
		||||
#define CHECK_MMTR(DEST, TRI, OP) {                   \
 | 
			
		||||
    ref3 = DEST;                                      \
 | 
			
		||||
    ref2 = ref1 = DEST;                               \
 | 
			
		||||
    DEST.template triangularView<TRI>() OP;           \
 | 
			
		||||
    ref1 OP;                                          \
 | 
			
		||||
    ref2.template triangularView<TRI>()               \
 | 
			
		||||
      = ref1.template triangularView<TRI>();          \
 | 
			
		||||
    VERIFY_IS_APPROX(DEST,ref2);                      \
 | 
			
		||||
    \
 | 
			
		||||
    DEST = ref3;                                      \
 | 
			
		||||
    ref3 = ref2;                                      \
 | 
			
		||||
    ref3.diagonal() = DEST.diagonal();                \
 | 
			
		||||
    DEST.template triangularView<TRI|ZeroDiag>() OP;  \
 | 
			
		||||
    VERIFY_IS_APPROX(DEST,ref3);                      \
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
template<typename Scalar> void mmtr(int size)
 | 
			
		||||
{
 | 
			
		||||
  typedef Matrix<Scalar,Dynamic,Dynamic,ColMajor> MatrixColMaj;
 | 
			
		||||
  typedef Matrix<Scalar,Dynamic,Dynamic,RowMajor> MatrixRowMaj;
 | 
			
		||||
 | 
			
		||||
  DenseIndex othersize = internal::random<DenseIndex>(1,200);
 | 
			
		||||
  
 | 
			
		||||
  MatrixColMaj matc = MatrixColMaj::Zero(size, size);
 | 
			
		||||
  MatrixRowMaj matr = MatrixRowMaj::Zero(size, size);
 | 
			
		||||
  MatrixColMaj ref1(size, size), ref2(size, size), ref3(size,size);
 | 
			
		||||
  
 | 
			
		||||
  MatrixColMaj soc(size,othersize); soc.setRandom();
 | 
			
		||||
  MatrixColMaj osc(othersize,size); osc.setRandom();
 | 
			
		||||
  MatrixRowMaj sor(size,othersize); sor.setRandom();
 | 
			
		||||
  MatrixRowMaj osr(othersize,size); osr.setRandom();
 | 
			
		||||
  MatrixColMaj sqc(size,size); sqc.setRandom();
 | 
			
		||||
  MatrixRowMaj sqr(size,size); sqr.setRandom();
 | 
			
		||||
  
 | 
			
		||||
  Scalar s = internal::random<Scalar>();
 | 
			
		||||
  
 | 
			
		||||
  CHECK_MMTR(matc, Lower, = s*soc*sor.adjoint());
 | 
			
		||||
  CHECK_MMTR(matc, Upper, = s*(soc*soc.adjoint()));
 | 
			
		||||
  CHECK_MMTR(matr, Lower, = s*soc*soc.adjoint());
 | 
			
		||||
  CHECK_MMTR(matr, Upper, = soc*(s*sor.adjoint()));
 | 
			
		||||
  
 | 
			
		||||
  CHECK_MMTR(matc, Lower, += s*soc*soc.adjoint());
 | 
			
		||||
  CHECK_MMTR(matc, Upper, += s*(soc*sor.transpose()));
 | 
			
		||||
  CHECK_MMTR(matr, Lower, += s*sor*soc.adjoint());
 | 
			
		||||
  CHECK_MMTR(matr, Upper, += soc*(s*soc.adjoint()));
 | 
			
		||||
  
 | 
			
		||||
  CHECK_MMTR(matc, Lower, -= s*soc*soc.adjoint());
 | 
			
		||||
  CHECK_MMTR(matc, Upper, -= s*(osc.transpose()*osc.conjugate()));
 | 
			
		||||
  CHECK_MMTR(matr, Lower, -= s*soc*soc.adjoint());
 | 
			
		||||
  CHECK_MMTR(matr, Upper, -= soc*(s*soc.adjoint()));
 | 
			
		||||
  
 | 
			
		||||
  CHECK_MMTR(matc, Lower, -= s*sqr*sqc.template triangularView<Upper>());
 | 
			
		||||
  CHECK_MMTR(matc, Upper, = s*sqc*sqr.template triangularView<Upper>());
 | 
			
		||||
  CHECK_MMTR(matc, Lower, += s*sqr*sqc.template triangularView<Lower>());
 | 
			
		||||
  CHECK_MMTR(matc, Upper, = s*sqc*sqc.template triangularView<Lower>());
 | 
			
		||||
  
 | 
			
		||||
  CHECK_MMTR(matc, Lower, = (s*sqr).template triangularView<Upper>()*sqc);
 | 
			
		||||
  CHECK_MMTR(matc, Upper, -= (s*sqc).template triangularView<Upper>()*sqc);
 | 
			
		||||
  CHECK_MMTR(matc, Lower, = (s*sqr).template triangularView<Lower>()*sqc);
 | 
			
		||||
  CHECK_MMTR(matc, Upper, += (s*sqc).template triangularView<Lower>()*sqc);
 | 
			
		||||
 | 
			
		||||
  // check aliasing
 | 
			
		||||
  ref2 = ref1 = matc;
 | 
			
		||||
  ref1 = sqc.adjoint() * matc * sqc;
 | 
			
		||||
  ref2.template triangularView<Upper>() = ref1.template triangularView<Upper>();
 | 
			
		||||
  matc.template triangularView<Upper>() = sqc.adjoint() * matc * sqc;
 | 
			
		||||
  VERIFY_IS_APPROX(matc, ref2);
 | 
			
		||||
 | 
			
		||||
  ref2 = ref1 = matc;
 | 
			
		||||
  ref1 = sqc * matc * sqc.adjoint();
 | 
			
		||||
  ref2.template triangularView<Lower>() = ref1.template triangularView<Lower>();
 | 
			
		||||
  matc.template triangularView<Lower>() = sqc * matc * sqc.adjoint();
 | 
			
		||||
  VERIFY_IS_APPROX(matc, ref2);
 | 
			
		||||
 | 
			
		||||
  // destination with a non-default inner-stride
 | 
			
		||||
  // see bug 1741
 | 
			
		||||
  {
 | 
			
		||||
    typedef Matrix<Scalar,Dynamic,Dynamic> MatrixX;
 | 
			
		||||
    MatrixX buffer(2*size,2*size);
 | 
			
		||||
    Map<MatrixColMaj,0,Stride<Dynamic,Dynamic> > map1(buffer.data(),size,size,Stride<Dynamic,Dynamic>(2*size,2));
 | 
			
		||||
    buffer.setZero();
 | 
			
		||||
    CHECK_MMTR(map1, Lower, = s*soc*sor.adjoint());
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_product_mmtr()
 | 
			
		||||
{
 | 
			
		||||
  for(int i = 0; i < g_repeat ; i++)
 | 
			
		||||
  {
 | 
			
		||||
    CALL_SUBTEST_1((mmtr<float>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE))));
 | 
			
		||||
    CALL_SUBTEST_2((mmtr<double>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE))));
 | 
			
		||||
    CALL_SUBTEST_3((mmtr<std::complex<float> >(internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2))));
 | 
			
		||||
    CALL_SUBTEST_4((mmtr<std::complex<double> >(internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2))));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										159
									
								
								cs440-acg/ext/eigen/test/product_notemporary.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										159
									
								
								cs440-acg/ext/eigen/test/product_notemporary.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,159 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#define TEST_ENABLE_TEMPORARY_TRACKING
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void product_notemporary(const MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  /* This test checks the number of temporaries created
 | 
			
		||||
   * during the evaluation of a complex expression */
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
  typedef typename MatrixType::RealScalar RealScalar;
 | 
			
		||||
  typedef Matrix<Scalar, 1, Dynamic> RowVectorType;
 | 
			
		||||
  typedef Matrix<Scalar, Dynamic, 1> ColVectorType;
 | 
			
		||||
  typedef Matrix<Scalar, Dynamic, Dynamic, ColMajor> ColMajorMatrixType;
 | 
			
		||||
  typedef Matrix<Scalar, Dynamic, Dynamic, RowMajor> RowMajorMatrixType;
 | 
			
		||||
 | 
			
		||||
  Index rows = m.rows();
 | 
			
		||||
  Index cols = m.cols();
 | 
			
		||||
 | 
			
		||||
  ColMajorMatrixType m1 = MatrixType::Random(rows, cols),
 | 
			
		||||
                     m2 = MatrixType::Random(rows, cols),
 | 
			
		||||
                     m3(rows, cols);
 | 
			
		||||
  RowVectorType rv1 = RowVectorType::Random(rows), rvres(rows);
 | 
			
		||||
  ColVectorType cv1 = ColVectorType::Random(cols), cvres(cols);
 | 
			
		||||
  RowMajorMatrixType rm3(rows, cols);
 | 
			
		||||
 | 
			
		||||
  Scalar s1 = internal::random<Scalar>(),
 | 
			
		||||
         s2 = internal::random<Scalar>(),
 | 
			
		||||
         s3 = internal::random<Scalar>();
 | 
			
		||||
 | 
			
		||||
  Index c0 = internal::random<Index>(4,cols-8),
 | 
			
		||||
        c1 = internal::random<Index>(8,cols-c0),
 | 
			
		||||
        r0 = internal::random<Index>(4,cols-8),
 | 
			
		||||
        r1 = internal::random<Index>(8,rows-r0);
 | 
			
		||||
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( m3 = (m1 * m2.adjoint()), 1);
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( m3 = (m1 * m2.adjoint()).transpose(), 1);
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( m3.noalias() = m1 * m2.adjoint(), 0);
 | 
			
		||||
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( m3 = s1 * (m1 * m2.transpose()), 1);
 | 
			
		||||
//   VERIFY_EVALUATION_COUNT( m3 = m3 + s1 * (m1 * m2.transpose()), 1);
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( m3.noalias() = s1 * (m1 * m2.transpose()), 0);
 | 
			
		||||
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( m3 = m3 + (m1 * m2.adjoint()), 1);
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( m3 = m3 - (m1 * m2.adjoint()), 1);
 | 
			
		||||
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( m3 = m3 + (m1 * m2.adjoint()).transpose(), 1);
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( m3.noalias() = m3 + m1 * m2.transpose(), 0);
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( m3.noalias() += m3 + m1 * m2.transpose(), 0);
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( m3.noalias() -= m3 + m1 * m2.transpose(), 0);
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( m3.noalias() =  m3 - m1 * m2.transpose(), 0);
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( m3.noalias() += m3 - m1 * m2.transpose(), 0);
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( m3.noalias() -= m3 - m1 * m2.transpose(), 0);
 | 
			
		||||
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( m3.noalias() = s1 * m1 * s2 * m2.adjoint(), 0);
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( m3.noalias() = s1 * m1 * s2 * (m1*s3+m2*s2).adjoint(), 1);
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( m3.noalias() = (s1 * m1).adjoint() * s2 * m2, 0);
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( m3.noalias() += s1 * (-m1*s3).adjoint() * (s2 * m2 * s3), 0);
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( m3.noalias() -= s1 * (m1.transpose() * m2), 0);
 | 
			
		||||
 | 
			
		||||
  VERIFY_EVALUATION_COUNT(( m3.block(r0,r0,r1,r1).noalias() += -m1.block(r0,c0,r1,c1) * (s2*m2.block(r0,c0,r1,c1)).adjoint() ), 0);
 | 
			
		||||
  VERIFY_EVALUATION_COUNT(( m3.block(r0,r0,r1,r1).noalias() -= s1 * m1.block(r0,c0,r1,c1) * m2.block(c0,r0,c1,r1) ), 0);
 | 
			
		||||
 | 
			
		||||
  // NOTE this is because the Block expression is not handled yet by our expression analyser
 | 
			
		||||
  VERIFY_EVALUATION_COUNT(( m3.block(r0,r0,r1,r1).noalias() = s1 * m1.block(r0,c0,r1,c1) * (s1*m2).block(c0,r0,c1,r1) ), 1);
 | 
			
		||||
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( m3.noalias() -= (s1 * m1).template triangularView<Lower>() * m2, 0);
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( rm3.noalias() = (s1 * m1.adjoint()).template triangularView<Upper>() * (m2+m2), 1);
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( rm3.noalias() = (s1 * m1.adjoint()).template triangularView<UnitUpper>() * m2.adjoint(), 0);
 | 
			
		||||
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( m3.template triangularView<Upper>() = (m1 * m2.adjoint()), 0);
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( m3.template triangularView<Upper>() -= (m1 * m2.adjoint()), 0);
 | 
			
		||||
 | 
			
		||||
  // NOTE this is because the blas_traits require innerstride==1 to avoid a temporary, but that doesn't seem to be actually needed for the triangular products
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( rm3.col(c0).noalias() = (s1 * m1.adjoint()).template triangularView<UnitUpper>() * (s2*m2.row(c0)).adjoint(), 1);
 | 
			
		||||
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( m1.template triangularView<Lower>().solveInPlace(m3), 0);
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( m1.adjoint().template triangularView<Lower>().solveInPlace(m3.transpose()), 0);
 | 
			
		||||
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( m3.noalias() -= (s1 * m1).adjoint().template selfadjointView<Lower>() * (-m2*s3).adjoint(), 0);
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( m3.noalias() = s2 * m2.adjoint() * (s1 * m1.adjoint()).template selfadjointView<Upper>(), 0);
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( rm3.noalias() = (s1 * m1.adjoint()).template selfadjointView<Lower>() * m2.adjoint(), 0);
 | 
			
		||||
 | 
			
		||||
  // NOTE this is because the blas_traits require innerstride==1 to avoid a temporary, but that doesn't seem to be actually needed for the triangular products
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( m3.col(c0).noalias() = (s1 * m1).adjoint().template selfadjointView<Lower>() * (-m2.row(c0)*s3).adjoint(), 1);
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( m3.col(c0).noalias() -= (s1 * m1).adjoint().template selfadjointView<Upper>() * (-m2.row(c0)*s3).adjoint(), 1);
 | 
			
		||||
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( m3.block(r0,c0,r1,c1).noalias() += m1.block(r0,r0,r1,r1).template selfadjointView<Upper>() * (s1*m2.block(r0,c0,r1,c1)), 0);
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( m3.block(r0,c0,r1,c1).noalias() = m1.block(r0,r0,r1,r1).template selfadjointView<Upper>() * m2.block(r0,c0,r1,c1), 0);
 | 
			
		||||
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( m3.template selfadjointView<Lower>().rankUpdate(m2.adjoint()), 0);
 | 
			
		||||
 | 
			
		||||
  // Here we will get 1 temporary for each resize operation of the lhs operator; resize(r1,c1) would lead to zero temporaries
 | 
			
		||||
  m3.resize(1,1);
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( m3.noalias() = m1.block(r0,r0,r1,r1).template selfadjointView<Lower>() * m2.block(r0,c0,r1,c1), 1);
 | 
			
		||||
  m3.resize(1,1);
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( m3.noalias() = m1.block(r0,r0,r1,r1).template triangularView<UnitUpper>()  * m2.block(r0,c0,r1,c1), 1);
 | 
			
		||||
 | 
			
		||||
  // Zero temporaries for lazy products ...
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( Scalar tmp = 0; tmp += Scalar(RealScalar(1)) /  (m3.transpose().lazyProduct(m3)).diagonal().sum(), 0 );
 | 
			
		||||
 | 
			
		||||
  // ... and even no temporary for even deeply (>=2) nested products
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( Scalar tmp = 0; tmp += Scalar(RealScalar(1)) /  (m3.transpose() * m3).diagonal().sum(), 0 );
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( Scalar tmp = 0; tmp += Scalar(RealScalar(1)) /  (m3.transpose() * m3).diagonal().array().abs().sum(), 0 );
 | 
			
		||||
 | 
			
		||||
  // Zero temporaries for ... CoeffBasedProductMode
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( m3.col(0).template head<5>() * m3.col(0).transpose() + m3.col(0).template head<5>() * m3.col(0).transpose(), 0 );
 | 
			
		||||
 | 
			
		||||
  // Check matrix * vectors
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( cvres.noalias() = m1 * cv1, 0 );
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( cvres.noalias() -= m1 * cv1, 0 );
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( cvres.noalias() -= m1 * m2.col(0), 0 );
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( cvres.noalias() -= m1 * rv1.adjoint(), 0 );
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( cvres.noalias() -= m1 * m2.row(0).transpose(), 0 );
 | 
			
		||||
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( cvres.noalias() = (m1+m1) * cv1, 0 );
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( cvres.noalias() = (rm3+rm3) * cv1, 0 );
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( cvres.noalias() = (m1+m1) * (m1*cv1), 1 );
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( cvres.noalias() = (rm3+rm3) * (m1*cv1), 1 );
 | 
			
		||||
 | 
			
		||||
  // Check outer products
 | 
			
		||||
  m3 = cv1 * rv1;
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( m3.noalias() = cv1 * rv1, 0 );
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( m3.noalias() = (cv1+cv1) * (rv1+rv1), 1 );
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( m3.noalias() = (m1*cv1) * (rv1), 1 );
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( m3.noalias() += (m1*cv1) * (rv1), 1 );
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( rm3.noalias() = (cv1) * (rv1 * m1), 1 );
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( rm3.noalias() -= (cv1) * (rv1 * m1), 1 );
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( rm3.noalias() = (m1*cv1) * (rv1 * m1), 2 );
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( rm3.noalias() += (m1*cv1) * (rv1 * m1), 2 );
 | 
			
		||||
 | 
			
		||||
  // Check nested products
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( cvres.noalias() = m1.adjoint() * m1 * cv1, 1 );
 | 
			
		||||
  VERIFY_EVALUATION_COUNT( rvres.noalias() = rv1 * (m1 * m2.adjoint()), 1 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_product_notemporary()
 | 
			
		||||
{
 | 
			
		||||
  int s;
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    s = internal::random<int>(16,EIGEN_TEST_MAX_SIZE);
 | 
			
		||||
    CALL_SUBTEST_1( product_notemporary(MatrixXf(s, s)) );
 | 
			
		||||
    CALL_SUBTEST_2( product_notemporary(MatrixXd(s, s)) );
 | 
			
		||||
    TEST_SET_BUT_UNUSED_VARIABLE(s)
 | 
			
		||||
    
 | 
			
		||||
    s = internal::random<int>(16,EIGEN_TEST_MAX_SIZE/2);
 | 
			
		||||
    CALL_SUBTEST_3( product_notemporary(MatrixXcf(s,s)) );
 | 
			
		||||
    CALL_SUBTEST_4( product_notemporary(MatrixXcd(s,s)) );
 | 
			
		||||
    TEST_SET_BUT_UNUSED_VARIABLE(s)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										86
									
								
								cs440-acg/ext/eigen/test/product_selfadjoint.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								cs440-acg/ext/eigen/test/product_selfadjoint.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,86 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void product_selfadjoint(const MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;
 | 
			
		||||
  typedef Matrix<Scalar, 1, MatrixType::RowsAtCompileTime> RowVectorType;
 | 
			
		||||
 | 
			
		||||
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, Dynamic, RowMajor> RhsMatrixType;
 | 
			
		||||
 | 
			
		||||
  Index rows = m.rows();
 | 
			
		||||
  Index cols = m.cols();
 | 
			
		||||
 | 
			
		||||
  MatrixType m1 = MatrixType::Random(rows, cols),
 | 
			
		||||
             m2 = MatrixType::Random(rows, cols),
 | 
			
		||||
             m3;
 | 
			
		||||
  VectorType v1 = VectorType::Random(rows),
 | 
			
		||||
             v2 = VectorType::Random(rows),
 | 
			
		||||
             v3(rows);
 | 
			
		||||
  RowVectorType r1 = RowVectorType::Random(rows),
 | 
			
		||||
                r2 = RowVectorType::Random(rows);
 | 
			
		||||
  RhsMatrixType m4 = RhsMatrixType::Random(rows,10);
 | 
			
		||||
 | 
			
		||||
  Scalar s1 = internal::random<Scalar>(),
 | 
			
		||||
         s2 = internal::random<Scalar>(),
 | 
			
		||||
         s3 = internal::random<Scalar>();
 | 
			
		||||
 | 
			
		||||
  m1 = (m1.adjoint() + m1).eval();
 | 
			
		||||
 | 
			
		||||
  // rank2 update
 | 
			
		||||
  m2 = m1.template triangularView<Lower>();
 | 
			
		||||
  m2.template selfadjointView<Lower>().rankUpdate(v1,v2);
 | 
			
		||||
  VERIFY_IS_APPROX(m2, (m1 + v1 * v2.adjoint()+ v2 * v1.adjoint()).template triangularView<Lower>().toDenseMatrix());
 | 
			
		||||
 | 
			
		||||
  m2 = m1.template triangularView<Upper>();
 | 
			
		||||
  m2.template selfadjointView<Upper>().rankUpdate(-v1,s2*v2,s3);
 | 
			
		||||
  VERIFY_IS_APPROX(m2, (m1 + (s3*(-v1)*(s2*v2).adjoint()+numext::conj(s3)*(s2*v2)*(-v1).adjoint())).template triangularView<Upper>().toDenseMatrix());
 | 
			
		||||
 | 
			
		||||
  m2 = m1.template triangularView<Upper>();
 | 
			
		||||
  m2.template selfadjointView<Upper>().rankUpdate(-s2*r1.adjoint(),r2.adjoint()*s3,s1);
 | 
			
		||||
  VERIFY_IS_APPROX(m2, (m1 + s1*(-s2*r1.adjoint())*(r2.adjoint()*s3).adjoint() + numext::conj(s1)*(r2.adjoint()*s3) * (-s2*r1.adjoint()).adjoint()).template triangularView<Upper>().toDenseMatrix());
 | 
			
		||||
 | 
			
		||||
  if (rows>1)
 | 
			
		||||
  {
 | 
			
		||||
    m2 = m1.template triangularView<Lower>();
 | 
			
		||||
    m2.block(1,1,rows-1,cols-1).template selfadjointView<Lower>().rankUpdate(v1.tail(rows-1),v2.head(cols-1));
 | 
			
		||||
    m3 = m1;
 | 
			
		||||
    m3.block(1,1,rows-1,cols-1) += v1.tail(rows-1) * v2.head(cols-1).adjoint()+ v2.head(cols-1) * v1.tail(rows-1).adjoint();
 | 
			
		||||
    VERIFY_IS_APPROX(m2, m3.template triangularView<Lower>().toDenseMatrix());
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_product_selfadjoint()
 | 
			
		||||
{
 | 
			
		||||
  int s = 0;
 | 
			
		||||
  for(int i = 0; i < g_repeat ; i++) {
 | 
			
		||||
    CALL_SUBTEST_1( product_selfadjoint(Matrix<float, 1, 1>()) );
 | 
			
		||||
    CALL_SUBTEST_2( product_selfadjoint(Matrix<float, 2, 2>()) );
 | 
			
		||||
    CALL_SUBTEST_3( product_selfadjoint(Matrix3d()) );
 | 
			
		||||
    
 | 
			
		||||
    s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2);
 | 
			
		||||
    CALL_SUBTEST_4( product_selfadjoint(MatrixXcf(s, s)) );
 | 
			
		||||
    TEST_SET_BUT_UNUSED_VARIABLE(s)
 | 
			
		||||
    
 | 
			
		||||
    s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2);
 | 
			
		||||
    CALL_SUBTEST_5( product_selfadjoint(MatrixXcd(s,s)) );
 | 
			
		||||
    TEST_SET_BUT_UNUSED_VARIABLE(s)
 | 
			
		||||
    
 | 
			
		||||
    s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE);
 | 
			
		||||
    CALL_SUBTEST_6( product_selfadjoint(MatrixXd(s,s)) );
 | 
			
		||||
    TEST_SET_BUT_UNUSED_VARIABLE(s)
 | 
			
		||||
    
 | 
			
		||||
    s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE);
 | 
			
		||||
    CALL_SUBTEST_7( product_selfadjoint(Matrix<float,Dynamic,Dynamic,RowMajor>(s,s)) );
 | 
			
		||||
    TEST_SET_BUT_UNUSED_VARIABLE(s)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										293
									
								
								cs440-acg/ext/eigen/test/product_small.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										293
									
								
								cs440-acg/ext/eigen/test/product_small.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,293 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#define EIGEN_NO_STATIC_ASSERT
 | 
			
		||||
#include "product.h"
 | 
			
		||||
#include <Eigen/LU>
 | 
			
		||||
 | 
			
		||||
// regression test for bug 447
 | 
			
		||||
template<int>
 | 
			
		||||
void product1x1()
 | 
			
		||||
{
 | 
			
		||||
  Matrix<float,1,3> matAstatic;
 | 
			
		||||
  Matrix<float,3,1> matBstatic;
 | 
			
		||||
  matAstatic.setRandom();
 | 
			
		||||
  matBstatic.setRandom();
 | 
			
		||||
  VERIFY_IS_APPROX( (matAstatic * matBstatic).coeff(0,0), 
 | 
			
		||||
                    matAstatic.cwiseProduct(matBstatic.transpose()).sum() );
 | 
			
		||||
 | 
			
		||||
  MatrixXf matAdynamic(1,3);
 | 
			
		||||
  MatrixXf matBdynamic(3,1);
 | 
			
		||||
  matAdynamic.setRandom();
 | 
			
		||||
  matBdynamic.setRandom();
 | 
			
		||||
  VERIFY_IS_APPROX( (matAdynamic * matBdynamic).coeff(0,0), 
 | 
			
		||||
                    matAdynamic.cwiseProduct(matBdynamic.transpose()).sum() );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename TC, typename TA, typename TB>
 | 
			
		||||
const TC& ref_prod(TC &C, const TA &A, const TB &B)
 | 
			
		||||
{
 | 
			
		||||
  for(Index i=0;i<C.rows();++i)
 | 
			
		||||
    for(Index j=0;j<C.cols();++j)
 | 
			
		||||
      for(Index k=0;k<A.cols();++k)
 | 
			
		||||
        C.coeffRef(i,j) += A.coeff(i,k) * B.coeff(k,j);
 | 
			
		||||
  return C;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T, int Rows, int Cols, int Depth, int OC, int OA, int OB>
 | 
			
		||||
typename internal::enable_if<! ( (Rows ==1&&Depth!=1&&OA==ColMajor)
 | 
			
		||||
                              || (Depth==1&&Rows !=1&&OA==RowMajor)
 | 
			
		||||
                              || (Cols ==1&&Depth!=1&&OB==RowMajor)
 | 
			
		||||
                              || (Depth==1&&Cols !=1&&OB==ColMajor)
 | 
			
		||||
                              || (Rows ==1&&Cols !=1&&OC==ColMajor)
 | 
			
		||||
                              || (Cols ==1&&Rows !=1&&OC==RowMajor)),void>::type
 | 
			
		||||
test_lazy_single(int rows, int cols, int depth)
 | 
			
		||||
{
 | 
			
		||||
  Matrix<T,Rows,Depth,OA> A(rows,depth); A.setRandom();
 | 
			
		||||
  Matrix<T,Depth,Cols,OB> B(depth,cols); B.setRandom();
 | 
			
		||||
  Matrix<T,Rows,Cols,OC>  C(rows,cols);  C.setRandom();
 | 
			
		||||
  Matrix<T,Rows,Cols,OC>  D(C);
 | 
			
		||||
  VERIFY_IS_APPROX(C+=A.lazyProduct(B), ref_prod(D,A,B));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T, int Rows, int Cols, int Depth, int OC, int OA, int OB>
 | 
			
		||||
typename internal::enable_if<  ( (Rows ==1&&Depth!=1&&OA==ColMajor)
 | 
			
		||||
                              || (Depth==1&&Rows !=1&&OA==RowMajor)
 | 
			
		||||
                              || (Cols ==1&&Depth!=1&&OB==RowMajor)
 | 
			
		||||
                              || (Depth==1&&Cols !=1&&OB==ColMajor)
 | 
			
		||||
                              || (Rows ==1&&Cols !=1&&OC==ColMajor)
 | 
			
		||||
                              || (Cols ==1&&Rows !=1&&OC==RowMajor)),void>::type
 | 
			
		||||
test_lazy_single(int, int, int)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T, int Rows, int Cols, int Depth>
 | 
			
		||||
void test_lazy_all_layout(int rows=Rows, int cols=Cols, int depth=Depth)
 | 
			
		||||
{
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_single<T,Rows,Cols,Depth,ColMajor,ColMajor,ColMajor>(rows,cols,depth) ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_single<T,Rows,Cols,Depth,RowMajor,ColMajor,ColMajor>(rows,cols,depth) ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_single<T,Rows,Cols,Depth,ColMajor,RowMajor,ColMajor>(rows,cols,depth) ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_single<T,Rows,Cols,Depth,RowMajor,RowMajor,ColMajor>(rows,cols,depth) ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_single<T,Rows,Cols,Depth,ColMajor,ColMajor,RowMajor>(rows,cols,depth) ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_single<T,Rows,Cols,Depth,RowMajor,ColMajor,RowMajor>(rows,cols,depth) ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_single<T,Rows,Cols,Depth,ColMajor,RowMajor,RowMajor>(rows,cols,depth) ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_single<T,Rows,Cols,Depth,RowMajor,RowMajor,RowMajor>(rows,cols,depth) ));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
void test_lazy_l1()
 | 
			
		||||
{
 | 
			
		||||
  int rows = internal::random<int>(1,12);
 | 
			
		||||
  int cols = internal::random<int>(1,12);
 | 
			
		||||
  int depth = internal::random<int>(1,12);
 | 
			
		||||
 | 
			
		||||
  // Inner
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,1,1,1>() ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,1,1,2>() ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,1,1,3>() ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,1,1,8>() ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,1,1,9>() ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,1,1,-1>(1,1,depth) ));
 | 
			
		||||
 | 
			
		||||
  // Outer
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,2,1,1>() ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,1,2,1>() ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,2,2,1>() ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,3,3,1>() ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,4,4,1>() ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,4,8,1>() ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,4,-1,1>(4,cols) ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,7,-1,1>(7,cols) ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,-1,8,1>(rows) ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,-1,3,1>(rows) ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,-1,-1,1>(rows,cols) ));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
void test_lazy_l2()
 | 
			
		||||
{
 | 
			
		||||
  int rows = internal::random<int>(1,12);
 | 
			
		||||
  int cols = internal::random<int>(1,12);
 | 
			
		||||
  int depth = internal::random<int>(1,12);
 | 
			
		||||
 | 
			
		||||
  // mat-vec
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,2,1,2>() ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,2,1,4>() ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,4,1,2>() ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,4,1,4>() ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,5,1,4>() ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,4,1,5>() ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,4,1,6>() ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,6,1,4>() ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,8,1,8>() ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,-1,1,4>(rows) ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,4,1,-1>(4,1,depth) ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,-1,1,-1>(rows,1,depth) ));
 | 
			
		||||
 | 
			
		||||
  // vec-mat
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,1,2,2>() ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,1,2,4>() ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,1,4,2>() ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,1,4,4>() ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,1,5,4>() ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,1,4,5>() ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,1,4,6>() ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,1,6,4>() ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,1,8,8>() ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,1,-1, 4>(1,cols) ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,1, 4,-1>(1,4,depth) ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,1,-1,-1>(1,cols,depth) ));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
void test_lazy_l3()
 | 
			
		||||
{
 | 
			
		||||
  int rows = internal::random<int>(1,12);
 | 
			
		||||
  int cols = internal::random<int>(1,12);
 | 
			
		||||
  int depth = internal::random<int>(1,12);
 | 
			
		||||
  // mat-mat
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,2,4,2>() ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,2,6,4>() ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,4,3,2>() ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,4,8,4>() ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,5,6,4>() ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,4,2,5>() ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,4,7,6>() ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,6,8,4>() ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,8,3,8>() ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,-1,6,4>(rows) ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,4,3,-1>(4,3,depth) ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,-1,6,-1>(rows,6,depth) ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,8,2,2>() ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,5,2,4>() ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,4,4,2>() ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,8,4,4>() ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,6,5,4>() ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,4,4,5>() ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,3,4,6>() ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,2,6,4>() ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,7,8,8>() ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,8,-1, 4>(8,cols) ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,3, 4,-1>(3,4,depth) ));
 | 
			
		||||
  CALL_SUBTEST(( test_lazy_all_layout<T,4,-1,-1>(4,cols,depth) ));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T,int N,int M,int K>
 | 
			
		||||
void test_linear_but_not_vectorizable()
 | 
			
		||||
{
 | 
			
		||||
  // Check tricky cases for which the result of the product is a vector and thus must exhibit the LinearBit flag,
 | 
			
		||||
  // but is not vectorizable along the linear dimension.
 | 
			
		||||
  Index n = N==Dynamic ? internal::random<Index>(1,32) : N;
 | 
			
		||||
  Index m = M==Dynamic ? internal::random<Index>(1,32) : M;
 | 
			
		||||
  Index k = K==Dynamic ? internal::random<Index>(1,32) : K;
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    Matrix<T,N,M+1> A; A.setRandom(n,m+1);
 | 
			
		||||
    Matrix<T,M*2,K> B; B.setRandom(m*2,k);
 | 
			
		||||
    Matrix<T,1,K> C;
 | 
			
		||||
    Matrix<T,1,K> R;
 | 
			
		||||
 | 
			
		||||
    C.noalias() = A.template topLeftCorner<1,M>() * (B.template topRows<M>()+B.template bottomRows<M>());
 | 
			
		||||
    R.noalias() = A.template topLeftCorner<1,M>() * (B.template topRows<M>()+B.template bottomRows<M>()).eval();
 | 
			
		||||
    VERIFY_IS_APPROX(C,R);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    Matrix<T,M+1,N,RowMajor> A; A.setRandom(m+1,n);
 | 
			
		||||
    Matrix<T,K,M*2,RowMajor> B; B.setRandom(k,m*2);
 | 
			
		||||
    Matrix<T,K,1> C;
 | 
			
		||||
    Matrix<T,K,1> R;
 | 
			
		||||
 | 
			
		||||
    C.noalias() = (B.template leftCols<M>()+B.template rightCols<M>())        * A.template topLeftCorner<M,1>();
 | 
			
		||||
    R.noalias() = (B.template leftCols<M>()+B.template rightCols<M>()).eval() * A.template topLeftCorner<M,1>();
 | 
			
		||||
    VERIFY_IS_APPROX(C,R);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<int Rows>
 | 
			
		||||
void bug_1311()
 | 
			
		||||
{
 | 
			
		||||
  Matrix< double, Rows, 2 > A;  A.setRandom();
 | 
			
		||||
  Vector2d b = Vector2d::Random() ;
 | 
			
		||||
  Matrix<double,Rows,1> res;
 | 
			
		||||
  res.noalias() = 1. * (A * b);
 | 
			
		||||
  VERIFY_IS_APPROX(res, A*b);
 | 
			
		||||
  res.noalias() = 1.*A * b;
 | 
			
		||||
  VERIFY_IS_APPROX(res, A*b);
 | 
			
		||||
  res.noalias() = (1.*A).lazyProduct(b);
 | 
			
		||||
  VERIFY_IS_APPROX(res, A*b);
 | 
			
		||||
  res.noalias() = (1.*A).lazyProduct(1.*b);
 | 
			
		||||
  VERIFY_IS_APPROX(res, A*b);
 | 
			
		||||
  res.noalias() = (A).lazyProduct(1.*b);
 | 
			
		||||
  VERIFY_IS_APPROX(res, A*b);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_product_small()
 | 
			
		||||
{
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_1( product(Matrix<float, 3, 2>()) );
 | 
			
		||||
    CALL_SUBTEST_2( product(Matrix<int, 3, 17>()) );
 | 
			
		||||
    CALL_SUBTEST_8( product(Matrix<double, 3, 17>()) );
 | 
			
		||||
    CALL_SUBTEST_3( product(Matrix3d()) );
 | 
			
		||||
    CALL_SUBTEST_4( product(Matrix4d()) );
 | 
			
		||||
    CALL_SUBTEST_5( product(Matrix4f()) );
 | 
			
		||||
    CALL_SUBTEST_6( product1x1<0>() );
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_11( test_lazy_l1<float>() );
 | 
			
		||||
    CALL_SUBTEST_12( test_lazy_l2<float>() );
 | 
			
		||||
    CALL_SUBTEST_13( test_lazy_l3<float>() );
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_21( test_lazy_l1<double>() );
 | 
			
		||||
    CALL_SUBTEST_22( test_lazy_l2<double>() );
 | 
			
		||||
    CALL_SUBTEST_23( test_lazy_l3<double>() );
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_31( test_lazy_l1<std::complex<float> >() );
 | 
			
		||||
    CALL_SUBTEST_32( test_lazy_l2<std::complex<float> >() );
 | 
			
		||||
    CALL_SUBTEST_33( test_lazy_l3<std::complex<float> >() );
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_41( test_lazy_l1<std::complex<double> >() );
 | 
			
		||||
    CALL_SUBTEST_42( test_lazy_l2<std::complex<double> >() );
 | 
			
		||||
    CALL_SUBTEST_43( test_lazy_l3<std::complex<double> >() );
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_7(( test_linear_but_not_vectorizable<float,2,1,Dynamic>() ));
 | 
			
		||||
    CALL_SUBTEST_7(( test_linear_but_not_vectorizable<float,3,1,Dynamic>() ));
 | 
			
		||||
    CALL_SUBTEST_7(( test_linear_but_not_vectorizable<float,2,1,16>() ));
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_6( bug_1311<3>() );
 | 
			
		||||
    CALL_SUBTEST_6( bug_1311<5>() );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
#ifdef EIGEN_TEST_PART_6
 | 
			
		||||
  {
 | 
			
		||||
    // test compilation of (outer_product) * vector
 | 
			
		||||
    Vector3f v = Vector3f::Random();
 | 
			
		||||
    VERIFY_IS_APPROX( (v * v.transpose()) * v, (v * v.transpose()).eval() * v);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  {
 | 
			
		||||
    // regression test for pull-request #93
 | 
			
		||||
    Eigen::Matrix<double, 1, 1> A;  A.setRandom();
 | 
			
		||||
    Eigen::Matrix<double, 18, 1> B; B.setRandom();
 | 
			
		||||
    Eigen::Matrix<double, 1, 18> C; C.setRandom();
 | 
			
		||||
    VERIFY_IS_APPROX(B * A.inverse(), B * A.inverse()[0]);
 | 
			
		||||
    VERIFY_IS_APPROX(A.inverse() * C, A.inverse()[0] * C);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    Eigen::Matrix<double, 10, 10> A, B, C;
 | 
			
		||||
    A.setRandom();
 | 
			
		||||
    C = A;
 | 
			
		||||
    for(int k=0; k<79; ++k)
 | 
			
		||||
      C = C * A;
 | 
			
		||||
    B.noalias() = (((A*A)*(A*A))*((A*A)*(A*A))*((A*A)*(A*A))*((A*A)*(A*A))*((A*A)*(A*A)) * ((A*A)*(A*A))*((A*A)*(A*A))*((A*A)*(A*A))*((A*A)*(A*A))*((A*A)*(A*A)))
 | 
			
		||||
                * (((A*A)*(A*A))*((A*A)*(A*A))*((A*A)*(A*A))*((A*A)*(A*A))*((A*A)*(A*A)) * ((A*A)*(A*A))*((A*A)*(A*A))*((A*A)*(A*A))*((A*A)*(A*A))*((A*A)*(A*A)));
 | 
			
		||||
    VERIFY_IS_APPROX(B,C);
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										125
									
								
								cs440-acg/ext/eigen/test/product_symm.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										125
									
								
								cs440-acg/ext/eigen/test/product_symm.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,125 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
 | 
			
		||||
template<typename Scalar, int Size, int OtherSize> void symm(int size = Size, int othersize = OtherSize)
 | 
			
		||||
{
 | 
			
		||||
  typedef Matrix<Scalar, Size, Size> MatrixType;
 | 
			
		||||
  typedef Matrix<Scalar, Size, OtherSize> Rhs1;
 | 
			
		||||
  typedef Matrix<Scalar, OtherSize, Size> Rhs2;
 | 
			
		||||
  enum { order = OtherSize==1 ? 0 : RowMajor };
 | 
			
		||||
  typedef Matrix<Scalar, Size, OtherSize,order> Rhs3;
 | 
			
		||||
 | 
			
		||||
  Index rows = size;
 | 
			
		||||
  Index cols = size;
 | 
			
		||||
 | 
			
		||||
  MatrixType m1 = MatrixType::Random(rows, cols),
 | 
			
		||||
             m2 = MatrixType::Random(rows, cols), m3;
 | 
			
		||||
 | 
			
		||||
  m1 = (m1+m1.adjoint()).eval();
 | 
			
		||||
 | 
			
		||||
  Rhs1 rhs1 = Rhs1::Random(cols, othersize), rhs12(cols, othersize), rhs13(cols, othersize);
 | 
			
		||||
  Rhs2 rhs2 = Rhs2::Random(othersize, rows), rhs22(othersize, rows), rhs23(othersize, rows);
 | 
			
		||||
  Rhs3 rhs3 = Rhs3::Random(cols, othersize), rhs32(cols, othersize), rhs33(cols, othersize);
 | 
			
		||||
 | 
			
		||||
  Scalar s1 = internal::random<Scalar>(),
 | 
			
		||||
         s2 = internal::random<Scalar>();
 | 
			
		||||
 | 
			
		||||
  m2 = m1.template triangularView<Lower>();
 | 
			
		||||
  m3 = m2.template selfadjointView<Lower>();
 | 
			
		||||
  VERIFY_IS_EQUAL(m1, m3);
 | 
			
		||||
  VERIFY_IS_APPROX(rhs12 = (s1*m2).template selfadjointView<Lower>() * (s2*rhs1),
 | 
			
		||||
                   rhs13 = (s1*m1) * (s2*rhs1));
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(rhs12 = (s1*m2).transpose().template selfadjointView<Upper>() * (s2*rhs1),
 | 
			
		||||
                   rhs13 = (s1*m1.transpose()) * (s2*rhs1));
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(rhs12 = (s1*m2).template selfadjointView<Lower>().transpose() * (s2*rhs1),
 | 
			
		||||
                   rhs13 = (s1*m1.transpose()) * (s2*rhs1));
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(rhs12 = (s1*m2).conjugate().template selfadjointView<Lower>() * (s2*rhs1),
 | 
			
		||||
                   rhs13 = (s1*m1).conjugate() * (s2*rhs1));
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(rhs12 = (s1*m2).template selfadjointView<Lower>().conjugate() * (s2*rhs1),
 | 
			
		||||
                   rhs13 = (s1*m1).conjugate() * (s2*rhs1));
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(rhs12 = (s1*m2).adjoint().template selfadjointView<Upper>() * (s2*rhs1),
 | 
			
		||||
                   rhs13 = (s1*m1).adjoint() * (s2*rhs1));
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(rhs12 = (s1*m2).template selfadjointView<Lower>().adjoint() * (s2*rhs1),
 | 
			
		||||
                   rhs13 = (s1*m1).adjoint() * (s2*rhs1));
 | 
			
		||||
 | 
			
		||||
  m2 = m1.template triangularView<Upper>(); rhs12.setRandom(); rhs13 = rhs12;
 | 
			
		||||
  m3 = m2.template selfadjointView<Upper>();
 | 
			
		||||
  VERIFY_IS_EQUAL(m1, m3);
 | 
			
		||||
  VERIFY_IS_APPROX(rhs12 += (s1*m2).template selfadjointView<Upper>() * (s2*rhs1),
 | 
			
		||||
                   rhs13 += (s1*m1) * (s2*rhs1));
 | 
			
		||||
 | 
			
		||||
  m2 = m1.template triangularView<Lower>();
 | 
			
		||||
  VERIFY_IS_APPROX(rhs12 = (s1*m2).template selfadjointView<Lower>() * (s2*rhs2.adjoint()),
 | 
			
		||||
                   rhs13 = (s1*m1) * (s2*rhs2.adjoint()));
 | 
			
		||||
 | 
			
		||||
  m2 = m1.template triangularView<Upper>();
 | 
			
		||||
  VERIFY_IS_APPROX(rhs12 = (s1*m2).template selfadjointView<Upper>() * (s2*rhs2.adjoint()),
 | 
			
		||||
                   rhs13 = (s1*m1) * (s2*rhs2.adjoint()));
 | 
			
		||||
 | 
			
		||||
  m2 = m1.template triangularView<Upper>();
 | 
			
		||||
  VERIFY_IS_APPROX(rhs12 = (s1*m2.adjoint()).template selfadjointView<Lower>() * (s2*rhs2.adjoint()),
 | 
			
		||||
                   rhs13 = (s1*m1.adjoint()) * (s2*rhs2.adjoint()));
 | 
			
		||||
 | 
			
		||||
  // test row major = <...>
 | 
			
		||||
  m2 = m1.template triangularView<Lower>(); rhs32.setRandom(); rhs13 = rhs32;
 | 
			
		||||
  VERIFY_IS_APPROX(rhs32.noalias() -= (s1*m2).template selfadjointView<Lower>() * (s2*rhs3),
 | 
			
		||||
                   rhs13 -= (s1*m1) * (s2 * rhs3));
 | 
			
		||||
 | 
			
		||||
  m2 = m1.template triangularView<Upper>();
 | 
			
		||||
  VERIFY_IS_APPROX(rhs32.noalias() = (s1*m2.adjoint()).template selfadjointView<Lower>() * (s2*rhs3).conjugate(),
 | 
			
		||||
                   rhs13 = (s1*m1.adjoint()) * (s2*rhs3).conjugate());
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  m2 = m1.template triangularView<Upper>(); rhs13 = rhs12;
 | 
			
		||||
  VERIFY_IS_APPROX(rhs12.noalias() += s1 * ((m2.adjoint()).template selfadjointView<Lower>() * (s2*rhs3).conjugate()),
 | 
			
		||||
                   rhs13 += (s1*m1.adjoint()) * (s2*rhs3).conjugate());
 | 
			
		||||
 | 
			
		||||
  m2 = m1.template triangularView<Lower>();
 | 
			
		||||
  VERIFY_IS_APPROX(rhs22 = (rhs2) * (m2).template selfadjointView<Lower>(), rhs23 = (rhs2) * (m1));
 | 
			
		||||
  VERIFY_IS_APPROX(rhs22 = (s2*rhs2) * (s1*m2).template selfadjointView<Lower>(), rhs23 = (s2*rhs2) * (s1*m1));
 | 
			
		||||
 | 
			
		||||
  // destination with a non-default inner-stride
 | 
			
		||||
  // see bug 1741
 | 
			
		||||
  {
 | 
			
		||||
    typedef Matrix<Scalar,Dynamic,Dynamic> MatrixX;
 | 
			
		||||
    MatrixX buffer(2*cols,2*othersize);
 | 
			
		||||
    Map<Rhs1,0,Stride<Dynamic,2> > map1(buffer.data(),cols,othersize,Stride<Dynamic,2>(2*rows,2));
 | 
			
		||||
    buffer.setZero();
 | 
			
		||||
    VERIFY_IS_APPROX( map1.noalias()  = (s1*m2).template selfadjointView<Lower>() * (s2*rhs1),
 | 
			
		||||
                      rhs13 = (s1*m1) * (s2*rhs1));
 | 
			
		||||
 | 
			
		||||
    Map<Rhs2,0,Stride<Dynamic,2> > map2(buffer.data(),rhs22.rows(),rhs22.cols(),Stride<Dynamic,2>(2*rhs22.outerStride(),2));
 | 
			
		||||
    buffer.setZero();
 | 
			
		||||
    VERIFY_IS_APPROX(map2 = (rhs2) * (m2).template selfadjointView<Lower>(), rhs23 = (rhs2) * (m1));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_product_symm()
 | 
			
		||||
{
 | 
			
		||||
  for(int i = 0; i < g_repeat ; i++)
 | 
			
		||||
  {
 | 
			
		||||
    CALL_SUBTEST_1(( symm<float,Dynamic,Dynamic>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE),internal::random<int>(1,EIGEN_TEST_MAX_SIZE)) ));
 | 
			
		||||
    CALL_SUBTEST_2(( symm<double,Dynamic,Dynamic>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE),internal::random<int>(1,EIGEN_TEST_MAX_SIZE)) ));
 | 
			
		||||
    CALL_SUBTEST_3(( symm<std::complex<float>,Dynamic,Dynamic>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2),internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2)) ));
 | 
			
		||||
    CALL_SUBTEST_4(( symm<std::complex<double>,Dynamic,Dynamic>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2),internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2)) ));
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST_5(( symm<float,Dynamic,1>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE)) ));
 | 
			
		||||
    CALL_SUBTEST_6(( symm<double,Dynamic,1>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE)) ));
 | 
			
		||||
    CALL_SUBTEST_7(( symm<std::complex<float>,Dynamic,1>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE)) ));
 | 
			
		||||
    CALL_SUBTEST_8(( symm<std::complex<double>,Dynamic,1>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE)) ));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										146
									
								
								cs440-acg/ext/eigen/test/product_syrk.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										146
									
								
								cs440-acg/ext/eigen/test/product_syrk.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,146 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void syrk(const MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::ColsAtCompileTime, RowMajor> RMatrixType;
 | 
			
		||||
  typedef Matrix<Scalar, MatrixType::ColsAtCompileTime, Dynamic> Rhs1;
 | 
			
		||||
  typedef Matrix<Scalar, Dynamic, MatrixType::RowsAtCompileTime> Rhs2;
 | 
			
		||||
  typedef Matrix<Scalar, MatrixType::ColsAtCompileTime, Dynamic,RowMajor> Rhs3;
 | 
			
		||||
 | 
			
		||||
  Index rows = m.rows();
 | 
			
		||||
  Index cols = m.cols();
 | 
			
		||||
 | 
			
		||||
  MatrixType m1 = MatrixType::Random(rows, cols),
 | 
			
		||||
             m2 = MatrixType::Random(rows, cols),
 | 
			
		||||
             m3 = MatrixType::Random(rows, cols);
 | 
			
		||||
  RMatrixType rm2 = MatrixType::Random(rows, cols);
 | 
			
		||||
 | 
			
		||||
  Rhs1 rhs1 = Rhs1::Random(internal::random<int>(1,320), cols); Rhs1 rhs11 = Rhs1::Random(rhs1.rows(), cols);
 | 
			
		||||
  Rhs2 rhs2 = Rhs2::Random(rows, internal::random<int>(1,320)); Rhs2 rhs22 = Rhs2::Random(rows, rhs2.cols());
 | 
			
		||||
  Rhs3 rhs3 = Rhs3::Random(internal::random<int>(1,320), rows);
 | 
			
		||||
 | 
			
		||||
  Scalar s1 = internal::random<Scalar>();
 | 
			
		||||
  
 | 
			
		||||
  Index c = internal::random<Index>(0,cols-1);
 | 
			
		||||
 | 
			
		||||
  m2.setZero();
 | 
			
		||||
  VERIFY_IS_APPROX((m2.template selfadjointView<Lower>().rankUpdate(rhs2,s1)._expression()),
 | 
			
		||||
                   ((s1 * rhs2 * rhs2.adjoint()).eval().template triangularView<Lower>().toDenseMatrix()));
 | 
			
		||||
  m2.setZero();
 | 
			
		||||
  VERIFY_IS_APPROX(((m2.template triangularView<Lower>() += s1 * rhs2  * rhs22.adjoint()).nestedExpression()),
 | 
			
		||||
                   ((s1 * rhs2 * rhs22.adjoint()).eval().template triangularView<Lower>().toDenseMatrix()));
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
  m2.setZero();
 | 
			
		||||
  VERIFY_IS_APPROX(m2.template selfadjointView<Upper>().rankUpdate(rhs2,s1)._expression(),
 | 
			
		||||
                   (s1 * rhs2 * rhs2.adjoint()).eval().template triangularView<Upper>().toDenseMatrix());
 | 
			
		||||
  m2.setZero();
 | 
			
		||||
  VERIFY_IS_APPROX((m2.template triangularView<Upper>() += s1 * rhs22 * rhs2.adjoint()).nestedExpression(),
 | 
			
		||||
                   (s1 * rhs22 * rhs2.adjoint()).eval().template triangularView<Upper>().toDenseMatrix());
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
  m2.setZero();
 | 
			
		||||
  VERIFY_IS_APPROX(m2.template selfadjointView<Lower>().rankUpdate(rhs1.adjoint(),s1)._expression(),
 | 
			
		||||
                   (s1 * rhs1.adjoint() * rhs1).eval().template triangularView<Lower>().toDenseMatrix());
 | 
			
		||||
  m2.setZero();
 | 
			
		||||
  VERIFY_IS_APPROX((m2.template triangularView<Lower>() += s1 * rhs11.adjoint() * rhs1).nestedExpression(),
 | 
			
		||||
                   (s1 * rhs11.adjoint() * rhs1).eval().template triangularView<Lower>().toDenseMatrix());
 | 
			
		||||
  
 | 
			
		||||
  
 | 
			
		||||
  m2.setZero();
 | 
			
		||||
  VERIFY_IS_APPROX(m2.template selfadjointView<Upper>().rankUpdate(rhs1.adjoint(),s1)._expression(),
 | 
			
		||||
                   (s1 * rhs1.adjoint() * rhs1).eval().template triangularView<Upper>().toDenseMatrix());
 | 
			
		||||
  VERIFY_IS_APPROX((m2.template triangularView<Upper>() = s1 * rhs1.adjoint() * rhs11).nestedExpression(),
 | 
			
		||||
                   (s1 * rhs1.adjoint() * rhs11).eval().template triangularView<Upper>().toDenseMatrix());
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
  m2.setZero();
 | 
			
		||||
  VERIFY_IS_APPROX(m2.template selfadjointView<Lower>().rankUpdate(rhs3.adjoint(),s1)._expression(),
 | 
			
		||||
                   (s1 * rhs3.adjoint() * rhs3).eval().template triangularView<Lower>().toDenseMatrix());
 | 
			
		||||
 | 
			
		||||
  m2.setZero();
 | 
			
		||||
  VERIFY_IS_APPROX(m2.template selfadjointView<Upper>().rankUpdate(rhs3.adjoint(),s1)._expression(),
 | 
			
		||||
                   (s1 * rhs3.adjoint() * rhs3).eval().template triangularView<Upper>().toDenseMatrix());
 | 
			
		||||
                   
 | 
			
		||||
  m2.setZero();
 | 
			
		||||
  VERIFY_IS_APPROX((m2.template selfadjointView<Lower>().rankUpdate(m1.col(c),s1)._expression()),
 | 
			
		||||
                   ((s1 * m1.col(c) * m1.col(c).adjoint()).eval().template triangularView<Lower>().toDenseMatrix()));
 | 
			
		||||
                   
 | 
			
		||||
  m2.setZero();
 | 
			
		||||
  VERIFY_IS_APPROX((m2.template selfadjointView<Upper>().rankUpdate(m1.col(c),s1)._expression()),
 | 
			
		||||
                   ((s1 * m1.col(c) * m1.col(c).adjoint()).eval().template triangularView<Upper>().toDenseMatrix()));
 | 
			
		||||
  rm2.setZero();
 | 
			
		||||
  VERIFY_IS_APPROX((rm2.template selfadjointView<Upper>().rankUpdate(m1.col(c),s1)._expression()),
 | 
			
		||||
                   ((s1 * m1.col(c) * m1.col(c).adjoint()).eval().template triangularView<Upper>().toDenseMatrix()));
 | 
			
		||||
  m2.setZero();
 | 
			
		||||
  VERIFY_IS_APPROX((m2.template triangularView<Upper>() += s1 * m3.col(c) * m1.col(c).adjoint()).nestedExpression(),
 | 
			
		||||
                   ((s1 * m3.col(c) * m1.col(c).adjoint()).eval().template triangularView<Upper>().toDenseMatrix()));
 | 
			
		||||
  rm2.setZero();
 | 
			
		||||
  VERIFY_IS_APPROX((rm2.template triangularView<Upper>() += s1 * m1.col(c) * m3.col(c).adjoint()).nestedExpression(),
 | 
			
		||||
                   ((s1 * m1.col(c) * m3.col(c).adjoint()).eval().template triangularView<Upper>().toDenseMatrix()));
 | 
			
		||||
  
 | 
			
		||||
  m2.setZero();
 | 
			
		||||
  VERIFY_IS_APPROX((m2.template selfadjointView<Lower>().rankUpdate(m1.col(c).conjugate(),s1)._expression()),
 | 
			
		||||
                   ((s1 * m1.col(c).conjugate() * m1.col(c).conjugate().adjoint()).eval().template triangularView<Lower>().toDenseMatrix()));
 | 
			
		||||
                   
 | 
			
		||||
  m2.setZero();
 | 
			
		||||
  VERIFY_IS_APPROX((m2.template selfadjointView<Upper>().rankUpdate(m1.col(c).conjugate(),s1)._expression()),
 | 
			
		||||
                   ((s1 * m1.col(c).conjugate() * m1.col(c).conjugate().adjoint()).eval().template triangularView<Upper>().toDenseMatrix()));
 | 
			
		||||
  
 | 
			
		||||
  
 | 
			
		||||
  m2.setZero();
 | 
			
		||||
  VERIFY_IS_APPROX((m2.template selfadjointView<Lower>().rankUpdate(m1.row(c),s1)._expression()),
 | 
			
		||||
                   ((s1 * m1.row(c).transpose() * m1.row(c).transpose().adjoint()).eval().template triangularView<Lower>().toDenseMatrix()));
 | 
			
		||||
  rm2.setZero();
 | 
			
		||||
  VERIFY_IS_APPROX((rm2.template selfadjointView<Lower>().rankUpdate(m1.row(c),s1)._expression()),
 | 
			
		||||
                   ((s1 * m1.row(c).transpose() * m1.row(c).transpose().adjoint()).eval().template triangularView<Lower>().toDenseMatrix()));
 | 
			
		||||
  m2.setZero();
 | 
			
		||||
  VERIFY_IS_APPROX((m2.template triangularView<Lower>() += s1 * m3.row(c).transpose() * m1.row(c).transpose().adjoint()).nestedExpression(),
 | 
			
		||||
                   ((s1 * m3.row(c).transpose() * m1.row(c).transpose().adjoint()).eval().template triangularView<Lower>().toDenseMatrix()));
 | 
			
		||||
  rm2.setZero();
 | 
			
		||||
  VERIFY_IS_APPROX((rm2.template triangularView<Lower>() += s1 * m3.row(c).transpose() * m1.row(c).transpose().adjoint()).nestedExpression(),
 | 
			
		||||
                   ((s1 * m3.row(c).transpose() * m1.row(c).transpose().adjoint()).eval().template triangularView<Lower>().toDenseMatrix()));
 | 
			
		||||
  
 | 
			
		||||
  
 | 
			
		||||
  m2.setZero();
 | 
			
		||||
  VERIFY_IS_APPROX((m2.template selfadjointView<Upper>().rankUpdate(m1.row(c).adjoint(),s1)._expression()),
 | 
			
		||||
                   ((s1 * m1.row(c).adjoint() * m1.row(c).adjoint().adjoint()).eval().template triangularView<Upper>().toDenseMatrix()));
 | 
			
		||||
 | 
			
		||||
  // destination with a non-default inner-stride
 | 
			
		||||
  // see bug 1741
 | 
			
		||||
  {
 | 
			
		||||
    typedef Matrix<Scalar,Dynamic,Dynamic> MatrixX;
 | 
			
		||||
    MatrixX buffer(2*rows,2*cols);
 | 
			
		||||
    Map<MatrixType,0,Stride<Dynamic,2> > map1(buffer.data(),rows,cols,Stride<Dynamic,2>(2*rows,2));
 | 
			
		||||
    buffer.setZero();
 | 
			
		||||
    VERIFY_IS_APPROX((map1.template selfadjointView<Lower>().rankUpdate(rhs2,s1)._expression()),
 | 
			
		||||
                      ((s1 * rhs2 * rhs2.adjoint()).eval().template triangularView<Lower>().toDenseMatrix()));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_product_syrk()
 | 
			
		||||
{
 | 
			
		||||
  for(int i = 0; i < g_repeat ; i++)
 | 
			
		||||
  {
 | 
			
		||||
    int s;
 | 
			
		||||
    s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE);
 | 
			
		||||
    CALL_SUBTEST_1( syrk(MatrixXf(s, s)) );
 | 
			
		||||
    CALL_SUBTEST_2( syrk(MatrixXd(s, s)) );
 | 
			
		||||
    TEST_SET_BUT_UNUSED_VARIABLE(s)
 | 
			
		||||
    
 | 
			
		||||
    s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2);
 | 
			
		||||
    CALL_SUBTEST_3( syrk(MatrixXcf(s, s)) );
 | 
			
		||||
    CALL_SUBTEST_4( syrk(MatrixXcd(s, s)) );
 | 
			
		||||
    TEST_SET_BUT_UNUSED_VARIABLE(s)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										137
									
								
								cs440-acg/ext/eigen/test/product_trmm.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										137
									
								
								cs440-acg/ext/eigen/test/product_trmm.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,137 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
int get_random_size()
 | 
			
		||||
{
 | 
			
		||||
  const int factor = NumTraits<T>::ReadCost;
 | 
			
		||||
  const int max_test_size = EIGEN_TEST_MAX_SIZE>2*factor ? EIGEN_TEST_MAX_SIZE/factor : EIGEN_TEST_MAX_SIZE;
 | 
			
		||||
  return internal::random<int>(1,max_test_size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Scalar, int Mode, int TriOrder, int OtherOrder, int ResOrder, int OtherCols>
 | 
			
		||||
void trmm(int rows=get_random_size<Scalar>(),
 | 
			
		||||
          int cols=get_random_size<Scalar>(),
 | 
			
		||||
          int otherCols = OtherCols==Dynamic?get_random_size<Scalar>():OtherCols)
 | 
			
		||||
{
 | 
			
		||||
  typedef Matrix<Scalar,Dynamic,Dynamic,TriOrder> TriMatrix;
 | 
			
		||||
  typedef Matrix<Scalar,Dynamic,OtherCols,OtherCols==1?ColMajor:OtherOrder> OnTheRight;
 | 
			
		||||
  typedef Matrix<Scalar,OtherCols,Dynamic,OtherCols==1?RowMajor:OtherOrder> OnTheLeft;
 | 
			
		||||
  
 | 
			
		||||
  typedef Matrix<Scalar,Dynamic,OtherCols,OtherCols==1?ColMajor:ResOrder> ResXS;
 | 
			
		||||
  typedef Matrix<Scalar,OtherCols,Dynamic,OtherCols==1?RowMajor:ResOrder> ResSX;
 | 
			
		||||
 | 
			
		||||
  TriMatrix  mat(rows,cols), tri(rows,cols), triTr(cols,rows), s1tri(rows,cols), s1triTr(cols,rows);
 | 
			
		||||
  
 | 
			
		||||
  OnTheRight  ge_right(cols,otherCols);
 | 
			
		||||
  OnTheLeft   ge_left(otherCols,rows);
 | 
			
		||||
  ResSX       ge_sx, ge_sx_save;
 | 
			
		||||
  ResXS       ge_xs, ge_xs_save;
 | 
			
		||||
 | 
			
		||||
  Scalar s1 = internal::random<Scalar>(),
 | 
			
		||||
         s2 = internal::random<Scalar>();
 | 
			
		||||
 | 
			
		||||
  mat.setRandom();
 | 
			
		||||
  tri = mat.template triangularView<Mode>();
 | 
			
		||||
  triTr = mat.transpose().template triangularView<Mode>();
 | 
			
		||||
  s1tri = (s1*mat).template triangularView<Mode>();
 | 
			
		||||
  s1triTr = (s1*mat).transpose().template triangularView<Mode>();
 | 
			
		||||
  ge_right.setRandom();
 | 
			
		||||
  ge_left.setRandom();
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX( ge_xs = mat.template triangularView<Mode>() * ge_right, tri * ge_right);
 | 
			
		||||
  VERIFY_IS_APPROX( ge_sx = ge_left * mat.template triangularView<Mode>(), ge_left * tri);
 | 
			
		||||
  
 | 
			
		||||
  VERIFY_IS_APPROX( ge_xs.noalias() = mat.template triangularView<Mode>() * ge_right, tri * ge_right);
 | 
			
		||||
  VERIFY_IS_APPROX( ge_sx.noalias() = ge_left * mat.template triangularView<Mode>(), ge_left * tri);
 | 
			
		||||
 | 
			
		||||
  if((Mode&UnitDiag)==0)
 | 
			
		||||
    VERIFY_IS_APPROX( ge_xs.noalias() = (s1*mat.adjoint()).template triangularView<Mode>() * (s2*ge_left.transpose()), s1*triTr.conjugate() * (s2*ge_left.transpose()));
 | 
			
		||||
  
 | 
			
		||||
  VERIFY_IS_APPROX( ge_xs.noalias() = (s1*mat.transpose()).template triangularView<Mode>() * (s2*ge_left.transpose()), s1triTr * (s2*ge_left.transpose()));
 | 
			
		||||
  VERIFY_IS_APPROX( ge_sx.noalias() = (s2*ge_left) * (s1*mat).template triangularView<Mode>(), (s2*ge_left)*s1tri);
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX( ge_sx.noalias() = ge_right.transpose() * mat.adjoint().template triangularView<Mode>(), ge_right.transpose() * triTr.conjugate());
 | 
			
		||||
  VERIFY_IS_APPROX( ge_sx.noalias() = ge_right.adjoint() * mat.adjoint().template triangularView<Mode>(), ge_right.adjoint() * triTr.conjugate());
 | 
			
		||||
  
 | 
			
		||||
  ge_xs_save = ge_xs;
 | 
			
		||||
  if((Mode&UnitDiag)==0)
 | 
			
		||||
    VERIFY_IS_APPROX( (ge_xs_save + s1*triTr.conjugate() * (s2*ge_left.adjoint())).eval(), ge_xs.noalias() += (s1*mat.adjoint()).template triangularView<Mode>() * (s2*ge_left.adjoint()) );
 | 
			
		||||
  ge_xs_save = ge_xs;
 | 
			
		||||
  VERIFY_IS_APPROX( (ge_xs_save + s1triTr * (s2*ge_left.adjoint())).eval(), ge_xs.noalias() += (s1*mat.transpose()).template triangularView<Mode>() * (s2*ge_left.adjoint()) );
 | 
			
		||||
  ge_sx.setRandom();
 | 
			
		||||
  ge_sx_save = ge_sx;
 | 
			
		||||
  if((Mode&UnitDiag)==0)
 | 
			
		||||
    VERIFY_IS_APPROX( ge_sx_save - (ge_right.adjoint() * (-s1 * triTr).conjugate()).eval(), ge_sx.noalias() -= (ge_right.adjoint() * (-s1 * mat).adjoint().template triangularView<Mode>()).eval());
 | 
			
		||||
  
 | 
			
		||||
  if((Mode&UnitDiag)==0)
 | 
			
		||||
    VERIFY_IS_APPROX( ge_xs = (s1*mat).adjoint().template triangularView<Mode>() * ge_left.adjoint(), numext::conj(s1) * triTr.conjugate() * ge_left.adjoint());
 | 
			
		||||
  VERIFY_IS_APPROX( ge_xs = (s1*mat).transpose().template triangularView<Mode>() * ge_left.adjoint(), s1triTr * ge_left.adjoint());
 | 
			
		||||
 | 
			
		||||
  // TODO check with sub-matrix expressions ?
 | 
			
		||||
 | 
			
		||||
  // destination with a non-default inner-stride
 | 
			
		||||
  // see bug 1741
 | 
			
		||||
  {
 | 
			
		||||
    VERIFY_IS_APPROX( ge_xs.noalias() = mat.template triangularView<Mode>() * ge_right, tri * ge_right);
 | 
			
		||||
    typedef Matrix<Scalar,Dynamic,Dynamic> MatrixX;
 | 
			
		||||
    MatrixX buffer(2*ge_xs.rows(),2*ge_xs.cols());
 | 
			
		||||
    Map<ResXS,0,Stride<Dynamic,2> > map1(buffer.data(),ge_xs.rows(),ge_xs.cols(),Stride<Dynamic,2>(2*ge_xs.outerStride(),2));
 | 
			
		||||
    buffer.setZero();
 | 
			
		||||
    VERIFY_IS_APPROX( map1.noalias() = mat.template triangularView<Mode>() * ge_right, tri * ge_right);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Scalar, int Mode, int TriOrder>
 | 
			
		||||
void trmv(int rows=get_random_size<Scalar>(), int cols=get_random_size<Scalar>())
 | 
			
		||||
{
 | 
			
		||||
  trmm<Scalar,Mode,TriOrder,ColMajor,ColMajor,1>(rows,cols,1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Scalar, int Mode, int TriOrder, int OtherOrder, int ResOrder>
 | 
			
		||||
void trmm(int rows=get_random_size<Scalar>(), int cols=get_random_size<Scalar>(), int otherCols = get_random_size<Scalar>())
 | 
			
		||||
{
 | 
			
		||||
  trmm<Scalar,Mode,TriOrder,OtherOrder,ResOrder,Dynamic>(rows,cols,otherCols);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define CALL_ALL_ORDERS(NB,SCALAR,MODE)                                             \
 | 
			
		||||
  EIGEN_CAT(CALL_SUBTEST_,NB)((trmm<SCALAR, MODE, ColMajor,ColMajor,ColMajor>()));  \
 | 
			
		||||
  EIGEN_CAT(CALL_SUBTEST_,NB)((trmm<SCALAR, MODE, ColMajor,ColMajor,RowMajor>()));  \
 | 
			
		||||
  EIGEN_CAT(CALL_SUBTEST_,NB)((trmm<SCALAR, MODE, ColMajor,RowMajor,ColMajor>()));  \
 | 
			
		||||
  EIGEN_CAT(CALL_SUBTEST_,NB)((trmm<SCALAR, MODE, ColMajor,RowMajor,RowMajor>()));  \
 | 
			
		||||
  EIGEN_CAT(CALL_SUBTEST_,NB)((trmm<SCALAR, MODE, RowMajor,ColMajor,ColMajor>()));  \
 | 
			
		||||
  EIGEN_CAT(CALL_SUBTEST_,NB)((trmm<SCALAR, MODE, RowMajor,ColMajor,RowMajor>()));  \
 | 
			
		||||
  EIGEN_CAT(CALL_SUBTEST_,NB)((trmm<SCALAR, MODE, RowMajor,RowMajor,ColMajor>()));  \
 | 
			
		||||
  EIGEN_CAT(CALL_SUBTEST_,NB)((trmm<SCALAR, MODE, RowMajor,RowMajor,RowMajor>()));  \
 | 
			
		||||
  \
 | 
			
		||||
  EIGEN_CAT(CALL_SUBTEST_1,NB)((trmv<SCALAR, MODE, ColMajor>()));                   \
 | 
			
		||||
  EIGEN_CAT(CALL_SUBTEST_1,NB)((trmv<SCALAR, MODE, RowMajor>()));
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
#define CALL_ALL(NB,SCALAR)                 \
 | 
			
		||||
  CALL_ALL_ORDERS(EIGEN_CAT(1,NB),SCALAR,Upper)          \
 | 
			
		||||
  CALL_ALL_ORDERS(EIGEN_CAT(2,NB),SCALAR,UnitUpper)      \
 | 
			
		||||
  CALL_ALL_ORDERS(EIGEN_CAT(3,NB),SCALAR,StrictlyUpper)  \
 | 
			
		||||
  CALL_ALL_ORDERS(EIGEN_CAT(1,NB),SCALAR,Lower)          \
 | 
			
		||||
  CALL_ALL_ORDERS(EIGEN_CAT(2,NB),SCALAR,UnitLower)      \
 | 
			
		||||
  CALL_ALL_ORDERS(EIGEN_CAT(3,NB),SCALAR,StrictlyLower)
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
void test_product_trmm()
 | 
			
		||||
{
 | 
			
		||||
  for(int i = 0; i < g_repeat ; i++)
 | 
			
		||||
  {
 | 
			
		||||
    CALL_ALL(1,float);                //  EIGEN_SUFFIXES;11;111;21;121;31;131
 | 
			
		||||
    CALL_ALL(2,double);               //  EIGEN_SUFFIXES;12;112;22;122;32;132
 | 
			
		||||
    CALL_ALL(3,std::complex<float>);  //  EIGEN_SUFFIXES;13;113;23;123;33;133
 | 
			
		||||
    CALL_ALL(4,std::complex<double>); //  EIGEN_SUFFIXES;14;114;24;124;34;134
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										90
									
								
								cs440-acg/ext/eigen/test/product_trmv.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								cs440-acg/ext/eigen/test/product_trmv.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,90 @@
 | 
			
		||||
// This file is triangularView of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void trmv(const MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
  typedef typename NumTraits<Scalar>::Real RealScalar;
 | 
			
		||||
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;
 | 
			
		||||
 | 
			
		||||
  RealScalar largerEps = 10*test_precision<RealScalar>();
 | 
			
		||||
 | 
			
		||||
  Index rows = m.rows();
 | 
			
		||||
  Index cols = m.cols();
 | 
			
		||||
 | 
			
		||||
  MatrixType m1 = MatrixType::Random(rows, cols),
 | 
			
		||||
             m3(rows, cols);
 | 
			
		||||
  VectorType v1 = VectorType::Random(rows);
 | 
			
		||||
 | 
			
		||||
  Scalar s1 = internal::random<Scalar>();
 | 
			
		||||
 | 
			
		||||
  m1 = MatrixType::Random(rows, cols);
 | 
			
		||||
 | 
			
		||||
  // check with a column-major matrix
 | 
			
		||||
  m3 = m1.template triangularView<Eigen::Lower>();
 | 
			
		||||
  VERIFY((m3 * v1).isApprox(m1.template triangularView<Eigen::Lower>() * v1, largerEps));
 | 
			
		||||
  m3 = m1.template triangularView<Eigen::Upper>();
 | 
			
		||||
  VERIFY((m3 * v1).isApprox(m1.template triangularView<Eigen::Upper>() * v1, largerEps));
 | 
			
		||||
  m3 = m1.template triangularView<Eigen::UnitLower>();
 | 
			
		||||
  VERIFY((m3 * v1).isApprox(m1.template triangularView<Eigen::UnitLower>() * v1, largerEps));
 | 
			
		||||
  m3 = m1.template triangularView<Eigen::UnitUpper>();
 | 
			
		||||
  VERIFY((m3 * v1).isApprox(m1.template triangularView<Eigen::UnitUpper>() * v1, largerEps));
 | 
			
		||||
 | 
			
		||||
  // check conjugated and scalar multiple expressions (col-major)
 | 
			
		||||
  m3 = m1.template triangularView<Eigen::Lower>();
 | 
			
		||||
  VERIFY(((s1*m3).conjugate() * v1).isApprox((s1*m1).conjugate().template triangularView<Eigen::Lower>() * v1, largerEps));
 | 
			
		||||
  m3 = m1.template triangularView<Eigen::Upper>();
 | 
			
		||||
  VERIFY((m3.conjugate() * v1.conjugate()).isApprox(m1.conjugate().template triangularView<Eigen::Upper>() * v1.conjugate(), largerEps));
 | 
			
		||||
 | 
			
		||||
  // check with a row-major matrix
 | 
			
		||||
  m3 = m1.template triangularView<Eigen::Upper>();
 | 
			
		||||
  VERIFY((m3.transpose() * v1).isApprox(m1.transpose().template triangularView<Eigen::Lower>() * v1, largerEps));
 | 
			
		||||
  m3 = m1.template triangularView<Eigen::Lower>();
 | 
			
		||||
  VERIFY((m3.transpose() * v1).isApprox(m1.transpose().template triangularView<Eigen::Upper>() * v1, largerEps));
 | 
			
		||||
  m3 = m1.template triangularView<Eigen::UnitUpper>();
 | 
			
		||||
  VERIFY((m3.transpose() * v1).isApprox(m1.transpose().template triangularView<Eigen::UnitLower>() * v1, largerEps));
 | 
			
		||||
  m3 = m1.template triangularView<Eigen::UnitLower>();
 | 
			
		||||
  VERIFY((m3.transpose() * v1).isApprox(m1.transpose().template triangularView<Eigen::UnitUpper>() * v1, largerEps));
 | 
			
		||||
 | 
			
		||||
  // check conjugated and scalar multiple expressions (row-major)
 | 
			
		||||
  m3 = m1.template triangularView<Eigen::Upper>();
 | 
			
		||||
  VERIFY((m3.adjoint() * v1).isApprox(m1.adjoint().template triangularView<Eigen::Lower>() * v1, largerEps));
 | 
			
		||||
  m3 = m1.template triangularView<Eigen::Lower>();
 | 
			
		||||
  VERIFY((m3.adjoint() * (s1*v1.conjugate())).isApprox(m1.adjoint().template triangularView<Eigen::Upper>() * (s1*v1.conjugate()), largerEps));
 | 
			
		||||
  m3 = m1.template triangularView<Eigen::UnitUpper>();
 | 
			
		||||
 | 
			
		||||
  // check transposed cases:
 | 
			
		||||
  m3 = m1.template triangularView<Eigen::Lower>();
 | 
			
		||||
  VERIFY((v1.transpose() * m3).isApprox(v1.transpose() * m1.template triangularView<Eigen::Lower>(), largerEps));
 | 
			
		||||
  VERIFY((v1.adjoint() * m3).isApprox(v1.adjoint() * m1.template triangularView<Eigen::Lower>(), largerEps));
 | 
			
		||||
  VERIFY((v1.adjoint() * m3.adjoint()).isApprox(v1.adjoint() * m1.template triangularView<Eigen::Lower>().adjoint(), largerEps));
 | 
			
		||||
 | 
			
		||||
  // TODO check with sub-matrices
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_product_trmv()
 | 
			
		||||
{
 | 
			
		||||
  int s = 0;
 | 
			
		||||
  for(int i = 0; i < g_repeat ; i++) {
 | 
			
		||||
    CALL_SUBTEST_1( trmv(Matrix<float, 1, 1>()) );
 | 
			
		||||
    CALL_SUBTEST_2( trmv(Matrix<float, 2, 2>()) );
 | 
			
		||||
    CALL_SUBTEST_3( trmv(Matrix3d()) );
 | 
			
		||||
    
 | 
			
		||||
    s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2);
 | 
			
		||||
    CALL_SUBTEST_4( trmv(MatrixXcf(s,s)) );
 | 
			
		||||
    CALL_SUBTEST_5( trmv(MatrixXcd(s,s)) );
 | 
			
		||||
    TEST_SET_BUT_UNUSED_VARIABLE(s)
 | 
			
		||||
    
 | 
			
		||||
    s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE);
 | 
			
		||||
    CALL_SUBTEST_6( trmv(Matrix<float,Dynamic,Dynamic,RowMajor>(s, s)) );
 | 
			
		||||
    TEST_SET_BUT_UNUSED_VARIABLE(s)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										127
									
								
								cs440-acg/ext/eigen/test/product_trsolve.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								cs440-acg/ext/eigen/test/product_trsolve.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,127 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
 | 
			
		||||
#define VERIFY_TRSM(TRI,XB) { \
 | 
			
		||||
    (XB).setRandom(); ref = (XB); \
 | 
			
		||||
    (TRI).solveInPlace(XB); \
 | 
			
		||||
    VERIFY_IS_APPROX((TRI).toDenseMatrix() * (XB), ref); \
 | 
			
		||||
    (XB).setRandom(); ref = (XB); \
 | 
			
		||||
    (XB) = (TRI).solve(XB); \
 | 
			
		||||
    VERIFY_IS_APPROX((TRI).toDenseMatrix() * (XB), ref); \
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
#define VERIFY_TRSM_ONTHERIGHT(TRI,XB) { \
 | 
			
		||||
    (XB).setRandom(); ref = (XB); \
 | 
			
		||||
    (TRI).transpose().template solveInPlace<OnTheRight>(XB.transpose()); \
 | 
			
		||||
    VERIFY_IS_APPROX((XB).transpose() * (TRI).transpose().toDenseMatrix(), ref.transpose()); \
 | 
			
		||||
    (XB).setRandom(); ref = (XB); \
 | 
			
		||||
    (XB).transpose() = (TRI).transpose().template solve<OnTheRight>(XB.transpose()); \
 | 
			
		||||
    VERIFY_IS_APPROX((XB).transpose() * (TRI).transpose().toDenseMatrix(), ref.transpose()); \
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
template<typename Scalar,int Size, int Cols> void trsolve(int size=Size,int cols=Cols)
 | 
			
		||||
{
 | 
			
		||||
  typedef typename NumTraits<Scalar>::Real RealScalar;
 | 
			
		||||
 | 
			
		||||
  Matrix<Scalar,Size,Size,ColMajor> cmLhs(size,size);
 | 
			
		||||
  Matrix<Scalar,Size,Size,RowMajor> rmLhs(size,size);
 | 
			
		||||
 | 
			
		||||
  enum {  colmajor = Size==1 ? RowMajor : ColMajor,
 | 
			
		||||
          rowmajor = Cols==1 ? ColMajor : RowMajor };
 | 
			
		||||
  Matrix<Scalar,Size,Cols,colmajor> cmRhs(size,cols);
 | 
			
		||||
  Matrix<Scalar,Size,Cols,rowmajor> rmRhs(size,cols);
 | 
			
		||||
  Matrix<Scalar,Dynamic,Dynamic,colmajor> ref(size,cols);
 | 
			
		||||
 | 
			
		||||
  cmLhs.setRandom(); cmLhs *= static_cast<RealScalar>(0.1); cmLhs.diagonal().array() += static_cast<RealScalar>(1);
 | 
			
		||||
  rmLhs.setRandom(); rmLhs *= static_cast<RealScalar>(0.1); rmLhs.diagonal().array() += static_cast<RealScalar>(1);
 | 
			
		||||
 | 
			
		||||
  VERIFY_TRSM(cmLhs.conjugate().template triangularView<Lower>(), cmRhs);
 | 
			
		||||
  VERIFY_TRSM(cmLhs.adjoint()  .template triangularView<Lower>(), cmRhs);
 | 
			
		||||
  VERIFY_TRSM(cmLhs            .template triangularView<Upper>(), cmRhs);
 | 
			
		||||
  VERIFY_TRSM(cmLhs            .template triangularView<Lower>(), rmRhs);
 | 
			
		||||
  VERIFY_TRSM(cmLhs.conjugate().template triangularView<Upper>(), rmRhs);
 | 
			
		||||
  VERIFY_TRSM(cmLhs.adjoint()  .template triangularView<Upper>(), rmRhs);
 | 
			
		||||
 | 
			
		||||
  VERIFY_TRSM(cmLhs.conjugate().template triangularView<UnitLower>(), cmRhs);
 | 
			
		||||
  VERIFY_TRSM(cmLhs            .template triangularView<UnitUpper>(), rmRhs);
 | 
			
		||||
 | 
			
		||||
  VERIFY_TRSM(rmLhs            .template triangularView<Lower>(), cmRhs);
 | 
			
		||||
  VERIFY_TRSM(rmLhs.conjugate().template triangularView<UnitUpper>(), rmRhs);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  VERIFY_TRSM_ONTHERIGHT(cmLhs.conjugate().template triangularView<Lower>(), cmRhs);
 | 
			
		||||
  VERIFY_TRSM_ONTHERIGHT(cmLhs            .template triangularView<Upper>(), cmRhs);
 | 
			
		||||
  VERIFY_TRSM_ONTHERIGHT(cmLhs            .template triangularView<Lower>(), rmRhs);
 | 
			
		||||
  VERIFY_TRSM_ONTHERIGHT(cmLhs.conjugate().template triangularView<Upper>(), rmRhs);
 | 
			
		||||
 | 
			
		||||
  VERIFY_TRSM_ONTHERIGHT(cmLhs.conjugate().template triangularView<UnitLower>(), cmRhs);
 | 
			
		||||
  VERIFY_TRSM_ONTHERIGHT(cmLhs            .template triangularView<UnitUpper>(), rmRhs);
 | 
			
		||||
 | 
			
		||||
  VERIFY_TRSM_ONTHERIGHT(rmLhs            .template triangularView<Lower>(), cmRhs);
 | 
			
		||||
  VERIFY_TRSM_ONTHERIGHT(rmLhs.conjugate().template triangularView<UnitUpper>(), rmRhs);
 | 
			
		||||
 | 
			
		||||
  int c = internal::random<int>(0,cols-1);
 | 
			
		||||
  VERIFY_TRSM(rmLhs.template triangularView<Lower>(), rmRhs.col(c));
 | 
			
		||||
  VERIFY_TRSM(cmLhs.template triangularView<Lower>(), rmRhs.col(c));
 | 
			
		||||
 | 
			
		||||
  // destination with a non-default inner-stride
 | 
			
		||||
  // see bug 1741
 | 
			
		||||
  {
 | 
			
		||||
    typedef Matrix<Scalar,Dynamic,Dynamic> MatrixX;
 | 
			
		||||
    MatrixX buffer(2*cmRhs.rows(),2*cmRhs.cols());
 | 
			
		||||
    Map<Matrix<Scalar,Size,Cols,colmajor>,0,Stride<Dynamic,2> > map1(buffer.data(),cmRhs.rows(),cmRhs.cols(),Stride<Dynamic,2>(2*cmRhs.outerStride(),2));
 | 
			
		||||
    Map<Matrix<Scalar,Size,Cols,rowmajor>,0,Stride<Dynamic,2> > map2(buffer.data(),rmRhs.rows(),rmRhs.cols(),Stride<Dynamic,2>(2*rmRhs.outerStride(),2));
 | 
			
		||||
    buffer.setZero();
 | 
			
		||||
    VERIFY_TRSM(cmLhs.conjugate().template triangularView<Lower>(), map1);
 | 
			
		||||
    buffer.setZero();
 | 
			
		||||
    VERIFY_TRSM(cmLhs            .template triangularView<Lower>(), map2);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(Size==Dynamic)
 | 
			
		||||
  {
 | 
			
		||||
    cmLhs.resize(0,0);
 | 
			
		||||
    cmRhs.resize(0,cmRhs.cols());
 | 
			
		||||
    Matrix<Scalar,Size,Cols,colmajor> res = cmLhs.template triangularView<Lower>().solve(cmRhs);
 | 
			
		||||
    VERIFY_IS_EQUAL(res.rows(),0);
 | 
			
		||||
    VERIFY_IS_EQUAL(res.cols(),cmRhs.cols());
 | 
			
		||||
    res = cmRhs;
 | 
			
		||||
    cmLhs.template triangularView<Lower>().solveInPlace(res);
 | 
			
		||||
    VERIFY_IS_EQUAL(res.rows(),0);
 | 
			
		||||
    VERIFY_IS_EQUAL(res.cols(),cmRhs.cols());
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_product_trsolve()
 | 
			
		||||
{
 | 
			
		||||
  for(int i = 0; i < g_repeat ; i++)
 | 
			
		||||
  {
 | 
			
		||||
    // matrices
 | 
			
		||||
    CALL_SUBTEST_1((trsolve<float,Dynamic,Dynamic>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE),internal::random<int>(1,EIGEN_TEST_MAX_SIZE))));
 | 
			
		||||
    CALL_SUBTEST_2((trsolve<double,Dynamic,Dynamic>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE),internal::random<int>(1,EIGEN_TEST_MAX_SIZE))));
 | 
			
		||||
    CALL_SUBTEST_3((trsolve<std::complex<float>,Dynamic,Dynamic>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2),internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2))));
 | 
			
		||||
    CALL_SUBTEST_4((trsolve<std::complex<double>,Dynamic,Dynamic>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2),internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2))));
 | 
			
		||||
 | 
			
		||||
    // vectors
 | 
			
		||||
    CALL_SUBTEST_5((trsolve<float,Dynamic,1>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE))));
 | 
			
		||||
    CALL_SUBTEST_6((trsolve<double,Dynamic,1>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE))));
 | 
			
		||||
    CALL_SUBTEST_7((trsolve<std::complex<float>,Dynamic,1>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE))));
 | 
			
		||||
    CALL_SUBTEST_8((trsolve<std::complex<double>,Dynamic,1>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE))));
 | 
			
		||||
    
 | 
			
		||||
    // meta-unrollers
 | 
			
		||||
    CALL_SUBTEST_9((trsolve<float,4,1>()));
 | 
			
		||||
    CALL_SUBTEST_10((trsolve<double,4,1>()));
 | 
			
		||||
    CALL_SUBTEST_11((trsolve<std::complex<float>,4,1>()));
 | 
			
		||||
    CALL_SUBTEST_12((trsolve<float,1,1>()));
 | 
			
		||||
    CALL_SUBTEST_13((trsolve<float,1,2>()));
 | 
			
		||||
    CALL_SUBTEST_14((trsolve<float,3,1>()));
 | 
			
		||||
    
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										130
									
								
								cs440-acg/ext/eigen/test/qr.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								cs440-acg/ext/eigen/test/qr.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,130 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
#include <Eigen/QR>
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void qr(const MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  Index rows = m.rows();
 | 
			
		||||
  Index cols = m.cols();
 | 
			
		||||
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> MatrixQType;
 | 
			
		||||
 | 
			
		||||
  MatrixType a = MatrixType::Random(rows,cols);
 | 
			
		||||
  HouseholderQR<MatrixType> qrOfA(a);
 | 
			
		||||
 | 
			
		||||
  MatrixQType q = qrOfA.householderQ();
 | 
			
		||||
  VERIFY_IS_UNITARY(q);
 | 
			
		||||
 | 
			
		||||
  MatrixType r = qrOfA.matrixQR().template triangularView<Upper>();
 | 
			
		||||
  VERIFY_IS_APPROX(a, qrOfA.householderQ() * r);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType, int Cols2> void qr_fixedsize()
 | 
			
		||||
{
 | 
			
		||||
  enum { Rows = MatrixType::RowsAtCompileTime, Cols = MatrixType::ColsAtCompileTime };
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
  Matrix<Scalar,Rows,Cols> m1 = Matrix<Scalar,Rows,Cols>::Random();
 | 
			
		||||
  HouseholderQR<Matrix<Scalar,Rows,Cols> > qr(m1);
 | 
			
		||||
 | 
			
		||||
  Matrix<Scalar,Rows,Cols> r = qr.matrixQR();
 | 
			
		||||
  // FIXME need better way to construct trapezoid
 | 
			
		||||
  for(int i = 0; i < Rows; i++) for(int j = 0; j < Cols; j++) if(i>j) r(i,j) = Scalar(0);
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(m1, qr.householderQ() * r);
 | 
			
		||||
 | 
			
		||||
  Matrix<Scalar,Cols,Cols2> m2 = Matrix<Scalar,Cols,Cols2>::Random(Cols,Cols2);
 | 
			
		||||
  Matrix<Scalar,Rows,Cols2> m3 = m1*m2;
 | 
			
		||||
  m2 = Matrix<Scalar,Cols,Cols2>::Random(Cols,Cols2);
 | 
			
		||||
  m2 = qr.solve(m3);
 | 
			
		||||
  VERIFY_IS_APPROX(m3, m1*m2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void qr_invertible()
 | 
			
		||||
{
 | 
			
		||||
  using std::log;
 | 
			
		||||
  using std::abs;
 | 
			
		||||
  using std::pow;
 | 
			
		||||
  using std::max;
 | 
			
		||||
  typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
 | 
			
		||||
  int size = internal::random<int>(10,50);
 | 
			
		||||
 | 
			
		||||
  MatrixType m1(size, size), m2(size, size), m3(size, size);
 | 
			
		||||
  m1 = MatrixType::Random(size,size);
 | 
			
		||||
 | 
			
		||||
  if (internal::is_same<RealScalar,float>::value)
 | 
			
		||||
  {
 | 
			
		||||
    // let's build a matrix more stable to inverse
 | 
			
		||||
    MatrixType a = MatrixType::Random(size,size*4);
 | 
			
		||||
    m1 += a * a.adjoint();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  HouseholderQR<MatrixType> qr(m1);
 | 
			
		||||
  m3 = MatrixType::Random(size,size);
 | 
			
		||||
  m2 = qr.solve(m3);
 | 
			
		||||
  VERIFY_IS_APPROX(m3, m1*m2);
 | 
			
		||||
 | 
			
		||||
  // now construct a matrix with prescribed determinant
 | 
			
		||||
  m1.setZero();
 | 
			
		||||
  for(int i = 0; i < size; i++) m1(i,i) = internal::random<Scalar>();
 | 
			
		||||
  RealScalar absdet = abs(m1.diagonal().prod());
 | 
			
		||||
  m3 = qr.householderQ(); // get a unitary
 | 
			
		||||
  m1 = m3 * m1 * m3;
 | 
			
		||||
  qr.compute(m1);
 | 
			
		||||
  VERIFY_IS_APPROX(log(absdet), qr.logAbsDeterminant());
 | 
			
		||||
  // This test is tricky if the determinant becomes too small.
 | 
			
		||||
  // Since we generate random numbers with magnitude rrange [0,1], the average determinant is 0.5^size
 | 
			
		||||
  VERIFY_IS_MUCH_SMALLER_THAN( abs(absdet-qr.absDeterminant()), numext::maxi(RealScalar(pow(0.5,size)),numext::maxi<RealScalar>(abs(absdet),abs(qr.absDeterminant()))) );
 | 
			
		||||
  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void qr_verify_assert()
 | 
			
		||||
{
 | 
			
		||||
  MatrixType tmp;
 | 
			
		||||
 | 
			
		||||
  HouseholderQR<MatrixType> qr;
 | 
			
		||||
  VERIFY_RAISES_ASSERT(qr.matrixQR())
 | 
			
		||||
  VERIFY_RAISES_ASSERT(qr.solve(tmp))
 | 
			
		||||
  VERIFY_RAISES_ASSERT(qr.householderQ())
 | 
			
		||||
  VERIFY_RAISES_ASSERT(qr.absDeterminant())
 | 
			
		||||
  VERIFY_RAISES_ASSERT(qr.logAbsDeterminant())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_qr()
 | 
			
		||||
{
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
   CALL_SUBTEST_1( qr(MatrixXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE),internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
 | 
			
		||||
   CALL_SUBTEST_2( qr(MatrixXcd(internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2),internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2))) );
 | 
			
		||||
   CALL_SUBTEST_3(( qr_fixedsize<Matrix<float,3,4>, 2 >() ));
 | 
			
		||||
   CALL_SUBTEST_4(( qr_fixedsize<Matrix<double,6,2>, 4 >() ));
 | 
			
		||||
   CALL_SUBTEST_5(( qr_fixedsize<Matrix<double,2,5>, 7 >() ));
 | 
			
		||||
   CALL_SUBTEST_11( qr(Matrix<float,1,1>()) );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_1( qr_invertible<MatrixXf>() );
 | 
			
		||||
    CALL_SUBTEST_6( qr_invertible<MatrixXd>() );
 | 
			
		||||
    CALL_SUBTEST_7( qr_invertible<MatrixXcf>() );
 | 
			
		||||
    CALL_SUBTEST_8( qr_invertible<MatrixXcd>() );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  CALL_SUBTEST_9(qr_verify_assert<Matrix3f>());
 | 
			
		||||
  CALL_SUBTEST_10(qr_verify_assert<Matrix3d>());
 | 
			
		||||
  CALL_SUBTEST_1(qr_verify_assert<MatrixXf>());
 | 
			
		||||
  CALL_SUBTEST_6(qr_verify_assert<MatrixXd>());
 | 
			
		||||
  CALL_SUBTEST_7(qr_verify_assert<MatrixXcf>());
 | 
			
		||||
  CALL_SUBTEST_8(qr_verify_assert<MatrixXcd>());
 | 
			
		||||
 | 
			
		||||
  // Test problem size constructors
 | 
			
		||||
  CALL_SUBTEST_12(HouseholderQR<MatrixXf>(10, 20));
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										338
									
								
								cs440-acg/ext/eigen/test/qr_colpivoting.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										338
									
								
								cs440-acg/ext/eigen/test/qr_colpivoting.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,338 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
#include <Eigen/QR>
 | 
			
		||||
#include <Eigen/SVD>
 | 
			
		||||
 | 
			
		||||
template <typename MatrixType>
 | 
			
		||||
void cod() {
 | 
			
		||||
  Index rows = internal::random<Index>(2, EIGEN_TEST_MAX_SIZE);
 | 
			
		||||
  Index cols = internal::random<Index>(2, EIGEN_TEST_MAX_SIZE);
 | 
			
		||||
  Index cols2 = internal::random<Index>(2, EIGEN_TEST_MAX_SIZE);
 | 
			
		||||
  Index rank = internal::random<Index>(1, (std::min)(rows, cols) - 1);
 | 
			
		||||
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime,
 | 
			
		||||
                 MatrixType::RowsAtCompileTime>
 | 
			
		||||
      MatrixQType;
 | 
			
		||||
  MatrixType matrix;
 | 
			
		||||
  createRandomPIMatrixOfRank(rank, rows, cols, matrix);
 | 
			
		||||
  CompleteOrthogonalDecomposition<MatrixType> cod(matrix);
 | 
			
		||||
  VERIFY(rank == cod.rank());
 | 
			
		||||
  VERIFY(cols - cod.rank() == cod.dimensionOfKernel());
 | 
			
		||||
  VERIFY(!cod.isInjective());
 | 
			
		||||
  VERIFY(!cod.isInvertible());
 | 
			
		||||
  VERIFY(!cod.isSurjective());
 | 
			
		||||
 | 
			
		||||
  MatrixQType q = cod.householderQ();
 | 
			
		||||
  VERIFY_IS_UNITARY(q);
 | 
			
		||||
 | 
			
		||||
  MatrixType z = cod.matrixZ();
 | 
			
		||||
  VERIFY_IS_UNITARY(z);
 | 
			
		||||
 | 
			
		||||
  MatrixType t;
 | 
			
		||||
  t.setZero(rows, cols);
 | 
			
		||||
  t.topLeftCorner(rank, rank) =
 | 
			
		||||
      cod.matrixT().topLeftCorner(rank, rank).template triangularView<Upper>();
 | 
			
		||||
 | 
			
		||||
  MatrixType c = q * t * z * cod.colsPermutation().inverse();
 | 
			
		||||
  VERIFY_IS_APPROX(matrix, c);
 | 
			
		||||
 | 
			
		||||
  MatrixType exact_solution = MatrixType::Random(cols, cols2);
 | 
			
		||||
  MatrixType rhs = matrix * exact_solution;
 | 
			
		||||
  MatrixType cod_solution = cod.solve(rhs);
 | 
			
		||||
  VERIFY_IS_APPROX(rhs, matrix * cod_solution);
 | 
			
		||||
 | 
			
		||||
  // Verify that we get the same minimum-norm solution as the SVD.
 | 
			
		||||
  JacobiSVD<MatrixType> svd(matrix, ComputeThinU | ComputeThinV);
 | 
			
		||||
  MatrixType svd_solution = svd.solve(rhs);
 | 
			
		||||
  VERIFY_IS_APPROX(cod_solution, svd_solution);
 | 
			
		||||
 | 
			
		||||
  MatrixType pinv = cod.pseudoInverse();
 | 
			
		||||
  VERIFY_IS_APPROX(cod_solution, pinv * rhs);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename MatrixType, int Cols2>
 | 
			
		||||
void cod_fixedsize() {
 | 
			
		||||
  enum {
 | 
			
		||||
    Rows = MatrixType::RowsAtCompileTime,
 | 
			
		||||
    Cols = MatrixType::ColsAtCompileTime
 | 
			
		||||
  };
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
  int rank = internal::random<int>(1, (std::min)(int(Rows), int(Cols)) - 1);
 | 
			
		||||
  Matrix<Scalar, Rows, Cols> matrix;
 | 
			
		||||
  createRandomPIMatrixOfRank(rank, Rows, Cols, matrix);
 | 
			
		||||
  CompleteOrthogonalDecomposition<Matrix<Scalar, Rows, Cols> > cod(matrix);
 | 
			
		||||
  VERIFY(rank == cod.rank());
 | 
			
		||||
  VERIFY(Cols - cod.rank() == cod.dimensionOfKernel());
 | 
			
		||||
  VERIFY(cod.isInjective() == (rank == Rows));
 | 
			
		||||
  VERIFY(cod.isSurjective() == (rank == Cols));
 | 
			
		||||
  VERIFY(cod.isInvertible() == (cod.isInjective() && cod.isSurjective()));
 | 
			
		||||
 | 
			
		||||
  Matrix<Scalar, Cols, Cols2> exact_solution;
 | 
			
		||||
  exact_solution.setRandom(Cols, Cols2);
 | 
			
		||||
  Matrix<Scalar, Rows, Cols2> rhs = matrix * exact_solution;
 | 
			
		||||
  Matrix<Scalar, Cols, Cols2> cod_solution = cod.solve(rhs);
 | 
			
		||||
  VERIFY_IS_APPROX(rhs, matrix * cod_solution);
 | 
			
		||||
 | 
			
		||||
  // Verify that we get the same minimum-norm solution as the SVD.
 | 
			
		||||
  JacobiSVD<MatrixType> svd(matrix, ComputeFullU | ComputeFullV);
 | 
			
		||||
  Matrix<Scalar, Cols, Cols2> svd_solution = svd.solve(rhs);
 | 
			
		||||
  VERIFY_IS_APPROX(cod_solution, svd_solution);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void qr()
 | 
			
		||||
{
 | 
			
		||||
  using std::sqrt;
 | 
			
		||||
 | 
			
		||||
  Index rows = internal::random<Index>(2,EIGEN_TEST_MAX_SIZE), cols = internal::random<Index>(2,EIGEN_TEST_MAX_SIZE), cols2 = internal::random<Index>(2,EIGEN_TEST_MAX_SIZE);
 | 
			
		||||
  Index rank = internal::random<Index>(1, (std::min)(rows, cols)-1);
 | 
			
		||||
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
  typedef typename MatrixType::RealScalar RealScalar;
 | 
			
		||||
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> MatrixQType;
 | 
			
		||||
  MatrixType m1;
 | 
			
		||||
  createRandomPIMatrixOfRank(rank,rows,cols,m1);
 | 
			
		||||
  ColPivHouseholderQR<MatrixType> qr(m1);
 | 
			
		||||
  VERIFY_IS_EQUAL(rank, qr.rank());
 | 
			
		||||
  VERIFY_IS_EQUAL(cols - qr.rank(), qr.dimensionOfKernel());
 | 
			
		||||
  VERIFY(!qr.isInjective());
 | 
			
		||||
  VERIFY(!qr.isInvertible());
 | 
			
		||||
  VERIFY(!qr.isSurjective());
 | 
			
		||||
 | 
			
		||||
  MatrixQType q = qr.householderQ();
 | 
			
		||||
  VERIFY_IS_UNITARY(q);
 | 
			
		||||
 | 
			
		||||
  MatrixType r = qr.matrixQR().template triangularView<Upper>();
 | 
			
		||||
  MatrixType c = q * r * qr.colsPermutation().inverse();
 | 
			
		||||
  VERIFY_IS_APPROX(m1, c);
 | 
			
		||||
 | 
			
		||||
  // Verify that the absolute value of the diagonal elements in R are
 | 
			
		||||
  // non-increasing until they reach the singularity threshold.
 | 
			
		||||
  RealScalar threshold =
 | 
			
		||||
      sqrt(RealScalar(rows)) * numext::abs(r(0, 0)) * NumTraits<Scalar>::epsilon();
 | 
			
		||||
  for (Index i = 0; i < (std::min)(rows, cols) - 1; ++i) {
 | 
			
		||||
    RealScalar x = numext::abs(r(i, i));
 | 
			
		||||
    RealScalar y = numext::abs(r(i + 1, i + 1));
 | 
			
		||||
    if (x < threshold && y < threshold) continue;
 | 
			
		||||
    if (!test_isApproxOrLessThan(y, x)) {
 | 
			
		||||
      for (Index j = 0; j < (std::min)(rows, cols); ++j) {
 | 
			
		||||
        std::cout << "i = " << j << ", |r_ii| = " << numext::abs(r(j, j)) << std::endl;
 | 
			
		||||
      }
 | 
			
		||||
      std::cout << "Failure at i=" << i << ", rank=" << rank
 | 
			
		||||
                << ", threshold=" << threshold << std::endl;
 | 
			
		||||
    }
 | 
			
		||||
    VERIFY_IS_APPROX_OR_LESS_THAN(y, x);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  MatrixType m2 = MatrixType::Random(cols,cols2);
 | 
			
		||||
  MatrixType m3 = m1*m2;
 | 
			
		||||
  m2 = MatrixType::Random(cols,cols2);
 | 
			
		||||
  m2 = qr.solve(m3);
 | 
			
		||||
  VERIFY_IS_APPROX(m3, m1*m2);
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    Index size = rows;
 | 
			
		||||
    do {
 | 
			
		||||
      m1 = MatrixType::Random(size,size);
 | 
			
		||||
      qr.compute(m1);
 | 
			
		||||
    } while(!qr.isInvertible());
 | 
			
		||||
    MatrixType m1_inv = qr.inverse();
 | 
			
		||||
    m3 = m1 * MatrixType::Random(size,cols2);
 | 
			
		||||
    m2 = qr.solve(m3);
 | 
			
		||||
    VERIFY_IS_APPROX(m2, m1_inv*m3);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType, int Cols2> void qr_fixedsize()
 | 
			
		||||
{
 | 
			
		||||
  using std::sqrt;
 | 
			
		||||
  using std::abs;
 | 
			
		||||
  enum { Rows = MatrixType::RowsAtCompileTime, Cols = MatrixType::ColsAtCompileTime };
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
  typedef typename MatrixType::RealScalar RealScalar;
 | 
			
		||||
  int rank = internal::random<int>(1, (std::min)(int(Rows), int(Cols))-1);
 | 
			
		||||
  Matrix<Scalar,Rows,Cols> m1;
 | 
			
		||||
  createRandomPIMatrixOfRank(rank,Rows,Cols,m1);
 | 
			
		||||
  ColPivHouseholderQR<Matrix<Scalar,Rows,Cols> > qr(m1);
 | 
			
		||||
  VERIFY_IS_EQUAL(rank, qr.rank());
 | 
			
		||||
  VERIFY_IS_EQUAL(Cols - qr.rank(), qr.dimensionOfKernel());
 | 
			
		||||
  VERIFY_IS_EQUAL(qr.isInjective(), (rank == Rows));
 | 
			
		||||
  VERIFY_IS_EQUAL(qr.isSurjective(), (rank == Cols));
 | 
			
		||||
  VERIFY_IS_EQUAL(qr.isInvertible(), (qr.isInjective() && qr.isSurjective()));
 | 
			
		||||
 | 
			
		||||
  Matrix<Scalar,Rows,Cols> r = qr.matrixQR().template triangularView<Upper>();
 | 
			
		||||
  Matrix<Scalar,Rows,Cols> c = qr.householderQ() * r * qr.colsPermutation().inverse();
 | 
			
		||||
  VERIFY_IS_APPROX(m1, c);
 | 
			
		||||
 | 
			
		||||
  Matrix<Scalar,Cols,Cols2> m2 = Matrix<Scalar,Cols,Cols2>::Random(Cols,Cols2);
 | 
			
		||||
  Matrix<Scalar,Rows,Cols2> m3 = m1*m2;
 | 
			
		||||
  m2 = Matrix<Scalar,Cols,Cols2>::Random(Cols,Cols2);
 | 
			
		||||
  m2 = qr.solve(m3);
 | 
			
		||||
  VERIFY_IS_APPROX(m3, m1*m2);
 | 
			
		||||
  // Verify that the absolute value of the diagonal elements in R are
 | 
			
		||||
  // non-increasing until they reache the singularity threshold.
 | 
			
		||||
  RealScalar threshold =
 | 
			
		||||
      sqrt(RealScalar(Rows)) * (std::abs)(r(0, 0)) * NumTraits<Scalar>::epsilon();
 | 
			
		||||
  for (Index i = 0; i < (std::min)(int(Rows), int(Cols)) - 1; ++i) {
 | 
			
		||||
    RealScalar x = numext::abs(r(i, i));
 | 
			
		||||
    RealScalar y = numext::abs(r(i + 1, i + 1));
 | 
			
		||||
    if (x < threshold && y < threshold) continue;
 | 
			
		||||
    if (!test_isApproxOrLessThan(y, x)) {
 | 
			
		||||
      for (Index j = 0; j < (std::min)(int(Rows), int(Cols)); ++j) {
 | 
			
		||||
        std::cout << "i = " << j << ", |r_ii| = " << numext::abs(r(j, j)) << std::endl;
 | 
			
		||||
      }
 | 
			
		||||
      std::cout << "Failure at i=" << i << ", rank=" << rank
 | 
			
		||||
                << ", threshold=" << threshold << std::endl;
 | 
			
		||||
    }
 | 
			
		||||
    VERIFY_IS_APPROX_OR_LESS_THAN(y, x);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// This test is meant to verify that pivots are chosen such that
 | 
			
		||||
// even for a graded matrix, the diagonal of R falls of roughly
 | 
			
		||||
// monotonically until it reaches the threshold for singularity.
 | 
			
		||||
// We use the so-called Kahan matrix, which is a famous counter-example
 | 
			
		||||
// for rank-revealing QR. See
 | 
			
		||||
// http://www.netlib.org/lapack/lawnspdf/lawn176.pdf
 | 
			
		||||
// page 3 for more detail.
 | 
			
		||||
template<typename MatrixType> void qr_kahan_matrix()
 | 
			
		||||
{
 | 
			
		||||
  using std::sqrt;
 | 
			
		||||
  using std::abs;
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
  typedef typename MatrixType::RealScalar RealScalar;
 | 
			
		||||
 | 
			
		||||
  Index rows = 300, cols = rows;
 | 
			
		||||
 | 
			
		||||
  MatrixType m1;
 | 
			
		||||
  m1.setZero(rows,cols);
 | 
			
		||||
  RealScalar s = std::pow(NumTraits<RealScalar>::epsilon(), 1.0 / rows);
 | 
			
		||||
  RealScalar c = std::sqrt(1 - s*s);
 | 
			
		||||
  RealScalar pow_s_i(1.0); // pow(s,i)
 | 
			
		||||
  for (Index i = 0; i < rows; ++i) {
 | 
			
		||||
    m1(i, i) = pow_s_i;
 | 
			
		||||
    m1.row(i).tail(rows - i - 1) = -pow_s_i * c * MatrixType::Ones(1, rows - i - 1);
 | 
			
		||||
    pow_s_i *= s;
 | 
			
		||||
  }
 | 
			
		||||
  m1 = (m1 + m1.transpose()).eval();
 | 
			
		||||
  ColPivHouseholderQR<MatrixType> qr(m1);
 | 
			
		||||
  MatrixType r = qr.matrixQR().template triangularView<Upper>();
 | 
			
		||||
 | 
			
		||||
  RealScalar threshold =
 | 
			
		||||
      std::sqrt(RealScalar(rows)) * numext::abs(r(0, 0)) * NumTraits<Scalar>::epsilon();
 | 
			
		||||
  for (Index i = 0; i < (std::min)(rows, cols) - 1; ++i) {
 | 
			
		||||
    RealScalar x = numext::abs(r(i, i));
 | 
			
		||||
    RealScalar y = numext::abs(r(i + 1, i + 1));
 | 
			
		||||
    if (x < threshold && y < threshold) continue;
 | 
			
		||||
    if (!test_isApproxOrLessThan(y, x)) {
 | 
			
		||||
      for (Index j = 0; j < (std::min)(rows, cols); ++j) {
 | 
			
		||||
        std::cout << "i = " << j << ", |r_ii| = " << numext::abs(r(j, j)) << std::endl;
 | 
			
		||||
      }
 | 
			
		||||
      std::cout << "Failure at i=" << i << ", rank=" << qr.rank()
 | 
			
		||||
                << ", threshold=" << threshold << std::endl;
 | 
			
		||||
    }
 | 
			
		||||
    VERIFY_IS_APPROX_OR_LESS_THAN(y, x);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void qr_invertible()
 | 
			
		||||
{
 | 
			
		||||
  using std::log;
 | 
			
		||||
  using std::abs;
 | 
			
		||||
  typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
 | 
			
		||||
  int size = internal::random<int>(10,50);
 | 
			
		||||
 | 
			
		||||
  MatrixType m1(size, size), m2(size, size), m3(size, size);
 | 
			
		||||
  m1 = MatrixType::Random(size,size);
 | 
			
		||||
 | 
			
		||||
  if (internal::is_same<RealScalar,float>::value)
 | 
			
		||||
  {
 | 
			
		||||
    // let's build a matrix more stable to inverse
 | 
			
		||||
    MatrixType a = MatrixType::Random(size,size*2);
 | 
			
		||||
    m1 += a * a.adjoint();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ColPivHouseholderQR<MatrixType> qr(m1);
 | 
			
		||||
  m3 = MatrixType::Random(size,size);
 | 
			
		||||
  m2 = qr.solve(m3);
 | 
			
		||||
  //VERIFY_IS_APPROX(m3, m1*m2);
 | 
			
		||||
 | 
			
		||||
  // now construct a matrix with prescribed determinant
 | 
			
		||||
  m1.setZero();
 | 
			
		||||
  for(int i = 0; i < size; i++) m1(i,i) = internal::random<Scalar>();
 | 
			
		||||
  RealScalar absdet = abs(m1.diagonal().prod());
 | 
			
		||||
  m3 = qr.householderQ(); // get a unitary
 | 
			
		||||
  m1 = m3 * m1 * m3;
 | 
			
		||||
  qr.compute(m1);
 | 
			
		||||
  VERIFY_IS_APPROX(absdet, qr.absDeterminant());
 | 
			
		||||
  VERIFY_IS_APPROX(log(absdet), qr.logAbsDeterminant());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void qr_verify_assert()
 | 
			
		||||
{
 | 
			
		||||
  MatrixType tmp;
 | 
			
		||||
 | 
			
		||||
  ColPivHouseholderQR<MatrixType> qr;
 | 
			
		||||
  VERIFY_RAISES_ASSERT(qr.matrixQR())
 | 
			
		||||
  VERIFY_RAISES_ASSERT(qr.solve(tmp))
 | 
			
		||||
  VERIFY_RAISES_ASSERT(qr.householderQ())
 | 
			
		||||
  VERIFY_RAISES_ASSERT(qr.dimensionOfKernel())
 | 
			
		||||
  VERIFY_RAISES_ASSERT(qr.isInjective())
 | 
			
		||||
  VERIFY_RAISES_ASSERT(qr.isSurjective())
 | 
			
		||||
  VERIFY_RAISES_ASSERT(qr.isInvertible())
 | 
			
		||||
  VERIFY_RAISES_ASSERT(qr.inverse())
 | 
			
		||||
  VERIFY_RAISES_ASSERT(qr.absDeterminant())
 | 
			
		||||
  VERIFY_RAISES_ASSERT(qr.logAbsDeterminant())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_qr_colpivoting()
 | 
			
		||||
{
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_1( qr<MatrixXf>() );
 | 
			
		||||
    CALL_SUBTEST_2( qr<MatrixXd>() );
 | 
			
		||||
    CALL_SUBTEST_3( qr<MatrixXcd>() );
 | 
			
		||||
    CALL_SUBTEST_4(( qr_fixedsize<Matrix<float,3,5>, 4 >() ));
 | 
			
		||||
    CALL_SUBTEST_5(( qr_fixedsize<Matrix<double,6,2>, 3 >() ));
 | 
			
		||||
    CALL_SUBTEST_5(( qr_fixedsize<Matrix<double,1,1>, 1 >() ));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_1( cod<MatrixXf>() );
 | 
			
		||||
    CALL_SUBTEST_2( cod<MatrixXd>() );
 | 
			
		||||
    CALL_SUBTEST_3( cod<MatrixXcd>() );
 | 
			
		||||
    CALL_SUBTEST_4(( cod_fixedsize<Matrix<float,3,5>, 4 >() ));
 | 
			
		||||
    CALL_SUBTEST_5(( cod_fixedsize<Matrix<double,6,2>, 3 >() ));
 | 
			
		||||
    CALL_SUBTEST_5(( cod_fixedsize<Matrix<double,1,1>, 1 >() ));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_1( qr_invertible<MatrixXf>() );
 | 
			
		||||
    CALL_SUBTEST_2( qr_invertible<MatrixXd>() );
 | 
			
		||||
    CALL_SUBTEST_6( qr_invertible<MatrixXcf>() );
 | 
			
		||||
    CALL_SUBTEST_3( qr_invertible<MatrixXcd>() );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  CALL_SUBTEST_7(qr_verify_assert<Matrix3f>());
 | 
			
		||||
  CALL_SUBTEST_8(qr_verify_assert<Matrix3d>());
 | 
			
		||||
  CALL_SUBTEST_1(qr_verify_assert<MatrixXf>());
 | 
			
		||||
  CALL_SUBTEST_2(qr_verify_assert<MatrixXd>());
 | 
			
		||||
  CALL_SUBTEST_6(qr_verify_assert<MatrixXcf>());
 | 
			
		||||
  CALL_SUBTEST_3(qr_verify_assert<MatrixXcd>());
 | 
			
		||||
 | 
			
		||||
  // Test problem size constructors
 | 
			
		||||
  CALL_SUBTEST_9(ColPivHouseholderQR<MatrixXf>(10, 20));
 | 
			
		||||
 | 
			
		||||
  CALL_SUBTEST_1( qr_kahan_matrix<MatrixXf>() );
 | 
			
		||||
  CALL_SUBTEST_2( qr_kahan_matrix<MatrixXd>() );
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										157
									
								
								cs440-acg/ext/eigen/test/qr_fullpivoting.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										157
									
								
								cs440-acg/ext/eigen/test/qr_fullpivoting.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,157 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
#include <Eigen/QR>
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void qr()
 | 
			
		||||
{
 | 
			
		||||
  Index max_size = EIGEN_TEST_MAX_SIZE;
 | 
			
		||||
  Index min_size = numext::maxi(1,EIGEN_TEST_MAX_SIZE/10);
 | 
			
		||||
  Index rows  = internal::random<Index>(min_size,max_size),
 | 
			
		||||
        cols  = internal::random<Index>(min_size,max_size),
 | 
			
		||||
        cols2 = internal::random<Index>(min_size,max_size),
 | 
			
		||||
        rank  = internal::random<Index>(1, (std::min)(rows, cols)-1);
 | 
			
		||||
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> MatrixQType;
 | 
			
		||||
  MatrixType m1;
 | 
			
		||||
  createRandomPIMatrixOfRank(rank,rows,cols,m1);
 | 
			
		||||
  FullPivHouseholderQR<MatrixType> qr(m1);
 | 
			
		||||
  VERIFY_IS_EQUAL(rank, qr.rank());
 | 
			
		||||
  VERIFY_IS_EQUAL(cols - qr.rank(), qr.dimensionOfKernel());
 | 
			
		||||
  VERIFY(!qr.isInjective());
 | 
			
		||||
  VERIFY(!qr.isInvertible());
 | 
			
		||||
  VERIFY(!qr.isSurjective());
 | 
			
		||||
 | 
			
		||||
  MatrixType r = qr.matrixQR();
 | 
			
		||||
  
 | 
			
		||||
  MatrixQType q = qr.matrixQ();
 | 
			
		||||
  VERIFY_IS_UNITARY(q);
 | 
			
		||||
  
 | 
			
		||||
  // FIXME need better way to construct trapezoid
 | 
			
		||||
  for(int i = 0; i < rows; i++) for(int j = 0; j < cols; j++) if(i>j) r(i,j) = Scalar(0);
 | 
			
		||||
 | 
			
		||||
  MatrixType c = qr.matrixQ() * r * qr.colsPermutation().inverse();
 | 
			
		||||
 | 
			
		||||
  VERIFY_IS_APPROX(m1, c);
 | 
			
		||||
  
 | 
			
		||||
  // stress the ReturnByValue mechanism
 | 
			
		||||
  MatrixType tmp;
 | 
			
		||||
  VERIFY_IS_APPROX(tmp.noalias() = qr.matrixQ() * r, (qr.matrixQ() * r).eval());
 | 
			
		||||
  
 | 
			
		||||
  MatrixType m2 = MatrixType::Random(cols,cols2);
 | 
			
		||||
  MatrixType m3 = m1*m2;
 | 
			
		||||
  m2 = MatrixType::Random(cols,cols2);
 | 
			
		||||
  m2 = qr.solve(m3);
 | 
			
		||||
  VERIFY_IS_APPROX(m3, m1*m2);
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    Index size = rows;
 | 
			
		||||
    do {
 | 
			
		||||
      m1 = MatrixType::Random(size,size);
 | 
			
		||||
      qr.compute(m1);
 | 
			
		||||
    } while(!qr.isInvertible());
 | 
			
		||||
    MatrixType m1_inv = qr.inverse();
 | 
			
		||||
    m3 = m1 * MatrixType::Random(size,cols2);
 | 
			
		||||
    m2 = qr.solve(m3);
 | 
			
		||||
    VERIFY_IS_APPROX(m2, m1_inv*m3);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void qr_invertible()
 | 
			
		||||
{
 | 
			
		||||
  using std::log;
 | 
			
		||||
  using std::abs;
 | 
			
		||||
  typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
 | 
			
		||||
  Index max_size = numext::mini(50,EIGEN_TEST_MAX_SIZE);
 | 
			
		||||
  Index min_size = numext::maxi(1,EIGEN_TEST_MAX_SIZE/10);
 | 
			
		||||
  Index size = internal::random<Index>(min_size,max_size);
 | 
			
		||||
 | 
			
		||||
  MatrixType m1(size, size), m2(size, size), m3(size, size);
 | 
			
		||||
  m1 = MatrixType::Random(size,size);
 | 
			
		||||
 | 
			
		||||
  if (internal::is_same<RealScalar,float>::value)
 | 
			
		||||
  {
 | 
			
		||||
    // let's build a matrix more stable to inverse
 | 
			
		||||
    MatrixType a = MatrixType::Random(size,size*2);
 | 
			
		||||
    m1 += a * a.adjoint();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  FullPivHouseholderQR<MatrixType> qr(m1);
 | 
			
		||||
  VERIFY(qr.isInjective());
 | 
			
		||||
  VERIFY(qr.isInvertible());
 | 
			
		||||
  VERIFY(qr.isSurjective());
 | 
			
		||||
 | 
			
		||||
  m3 = MatrixType::Random(size,size);
 | 
			
		||||
  m2 = qr.solve(m3);
 | 
			
		||||
  VERIFY_IS_APPROX(m3, m1*m2);
 | 
			
		||||
 | 
			
		||||
  // now construct a matrix with prescribed determinant
 | 
			
		||||
  m1.setZero();
 | 
			
		||||
  for(int i = 0; i < size; i++) m1(i,i) = internal::random<Scalar>();
 | 
			
		||||
  RealScalar absdet = abs(m1.diagonal().prod());
 | 
			
		||||
  m3 = qr.matrixQ(); // get a unitary
 | 
			
		||||
  m1 = m3 * m1 * m3;
 | 
			
		||||
  qr.compute(m1);
 | 
			
		||||
  VERIFY_IS_APPROX(absdet, qr.absDeterminant());
 | 
			
		||||
  VERIFY_IS_APPROX(log(absdet), qr.logAbsDeterminant());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void qr_verify_assert()
 | 
			
		||||
{
 | 
			
		||||
  MatrixType tmp;
 | 
			
		||||
 | 
			
		||||
  FullPivHouseholderQR<MatrixType> qr;
 | 
			
		||||
  VERIFY_RAISES_ASSERT(qr.matrixQR())
 | 
			
		||||
  VERIFY_RAISES_ASSERT(qr.solve(tmp))
 | 
			
		||||
  VERIFY_RAISES_ASSERT(qr.matrixQ())
 | 
			
		||||
  VERIFY_RAISES_ASSERT(qr.dimensionOfKernel())
 | 
			
		||||
  VERIFY_RAISES_ASSERT(qr.isInjective())
 | 
			
		||||
  VERIFY_RAISES_ASSERT(qr.isSurjective())
 | 
			
		||||
  VERIFY_RAISES_ASSERT(qr.isInvertible())
 | 
			
		||||
  VERIFY_RAISES_ASSERT(qr.inverse())
 | 
			
		||||
  VERIFY_RAISES_ASSERT(qr.absDeterminant())
 | 
			
		||||
  VERIFY_RAISES_ASSERT(qr.logAbsDeterminant())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_qr_fullpivoting()
 | 
			
		||||
{
 | 
			
		||||
 for(int i = 0; i < 1; i++) {
 | 
			
		||||
    // FIXME : very weird bug here
 | 
			
		||||
//     CALL_SUBTEST(qr(Matrix2f()) );
 | 
			
		||||
    CALL_SUBTEST_1( qr<MatrixXf>() );
 | 
			
		||||
    CALL_SUBTEST_2( qr<MatrixXd>() );
 | 
			
		||||
    CALL_SUBTEST_3( qr<MatrixXcd>() );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_1( qr_invertible<MatrixXf>() );
 | 
			
		||||
    CALL_SUBTEST_2( qr_invertible<MatrixXd>() );
 | 
			
		||||
    CALL_SUBTEST_4( qr_invertible<MatrixXcf>() );
 | 
			
		||||
    CALL_SUBTEST_3( qr_invertible<MatrixXcd>() );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  CALL_SUBTEST_5(qr_verify_assert<Matrix3f>());
 | 
			
		||||
  CALL_SUBTEST_6(qr_verify_assert<Matrix3d>());
 | 
			
		||||
  CALL_SUBTEST_1(qr_verify_assert<MatrixXf>());
 | 
			
		||||
  CALL_SUBTEST_2(qr_verify_assert<MatrixXd>());
 | 
			
		||||
  CALL_SUBTEST_4(qr_verify_assert<MatrixXcf>());
 | 
			
		||||
  CALL_SUBTEST_3(qr_verify_assert<MatrixXcd>());
 | 
			
		||||
 | 
			
		||||
  // Test problem size constructors
 | 
			
		||||
  CALL_SUBTEST_7(FullPivHouseholderQR<MatrixXf>(10, 20));
 | 
			
		||||
  CALL_SUBTEST_7((FullPivHouseholderQR<Matrix<float,10,20> >(10,20)));
 | 
			
		||||
  CALL_SUBTEST_7((FullPivHouseholderQR<Matrix<float,10,20> >(Matrix<float,10,20>::Random())));
 | 
			
		||||
  CALL_SUBTEST_7((FullPivHouseholderQR<Matrix<float,20,10> >(20,10)));
 | 
			
		||||
  CALL_SUBTEST_7((FullPivHouseholderQR<Matrix<float,20,10> >(Matrix<float,20,10>::Random())));
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										156
									
								
								cs440-acg/ext/eigen/test/qtvector.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										156
									
								
								cs440-acg/ext/eigen/test/qtvector.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,156 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#define EIGEN_WORK_AROUND_QT_BUG_CALLING_WRONG_OPERATOR_NEW_FIXED_IN_QT_4_5
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
#include <QtCore/QVector>
 | 
			
		||||
#include <Eigen/Geometry>
 | 
			
		||||
#include <Eigen/QtAlignedMalloc>
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType>
 | 
			
		||||
void check_qtvector_matrix(const MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  Index rows = m.rows();
 | 
			
		||||
  Index cols = m.cols();
 | 
			
		||||
  MatrixType x = MatrixType::Random(rows,cols), y = MatrixType::Random(rows,cols);
 | 
			
		||||
  QVector<MatrixType> v(10, MatrixType(rows,cols)), w(20, y);
 | 
			
		||||
  for(int i = 0; i < 20; i++)
 | 
			
		||||
  {
 | 
			
		||||
    VERIFY_IS_APPROX(w[i], y);
 | 
			
		||||
  }
 | 
			
		||||
  v[5] = x;
 | 
			
		||||
  w[6] = v[5];
 | 
			
		||||
  VERIFY_IS_APPROX(w[6], v[5]);
 | 
			
		||||
  v = w;
 | 
			
		||||
  for(int i = 0; i < 20; i++)
 | 
			
		||||
  {
 | 
			
		||||
    VERIFY_IS_APPROX(w[i], v[i]);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  v.resize(21);
 | 
			
		||||
  v[20] = x;
 | 
			
		||||
  VERIFY_IS_APPROX(v[20], x);
 | 
			
		||||
  v.fill(y,22);
 | 
			
		||||
  VERIFY_IS_APPROX(v[21], y);
 | 
			
		||||
  v.push_back(x);
 | 
			
		||||
  VERIFY_IS_APPROX(v[22], x);
 | 
			
		||||
  VERIFY((size_t)&(v[22]) == (size_t)&(v[21]) + sizeof(MatrixType));
 | 
			
		||||
 | 
			
		||||
  // do a lot of push_back such that the vector gets internally resized
 | 
			
		||||
  // (with memory reallocation)
 | 
			
		||||
  MatrixType* ref = &w[0];
 | 
			
		||||
  for(int i=0; i<30 || ((ref==&w[0]) && i<300); ++i)
 | 
			
		||||
    v.push_back(w[i%w.size()]);
 | 
			
		||||
  for(int i=23; i<v.size(); ++i)
 | 
			
		||||
  {
 | 
			
		||||
    VERIFY(v[i]==w[(i-23)%w.size()]);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename TransformType>
 | 
			
		||||
void check_qtvector_transform(const TransformType&)
 | 
			
		||||
{
 | 
			
		||||
  typedef typename TransformType::MatrixType MatrixType;
 | 
			
		||||
  TransformType x(MatrixType::Random()), y(MatrixType::Random());
 | 
			
		||||
  QVector<TransformType> v(10), w(20, y);
 | 
			
		||||
  v[5] = x;
 | 
			
		||||
  w[6] = v[5];
 | 
			
		||||
  VERIFY_IS_APPROX(w[6], v[5]);
 | 
			
		||||
  v = w;
 | 
			
		||||
  for(int i = 0; i < 20; i++)
 | 
			
		||||
  {
 | 
			
		||||
    VERIFY_IS_APPROX(w[i], v[i]);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  v.resize(21);
 | 
			
		||||
  v[20] = x;
 | 
			
		||||
  VERIFY_IS_APPROX(v[20], x);
 | 
			
		||||
  v.fill(y,22);
 | 
			
		||||
  VERIFY_IS_APPROX(v[21], y);
 | 
			
		||||
  v.push_back(x);
 | 
			
		||||
  VERIFY_IS_APPROX(v[22], x);
 | 
			
		||||
  VERIFY((size_t)&(v[22]) == (size_t)&(v[21]) + sizeof(TransformType));
 | 
			
		||||
 | 
			
		||||
  // do a lot of push_back such that the vector gets internally resized
 | 
			
		||||
  // (with memory reallocation)
 | 
			
		||||
  TransformType* ref = &w[0];
 | 
			
		||||
  for(int i=0; i<30 || ((ref==&w[0]) && i<300); ++i)
 | 
			
		||||
    v.push_back(w[i%w.size()]);
 | 
			
		||||
  for(unsigned int i=23; int(i)<v.size(); ++i)
 | 
			
		||||
  {
 | 
			
		||||
    VERIFY(v[i].matrix()==w[(i-23)%w.size()].matrix());
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename QuaternionType>
 | 
			
		||||
void check_qtvector_quaternion(const QuaternionType&)
 | 
			
		||||
{
 | 
			
		||||
  typedef typename QuaternionType::Coefficients Coefficients;
 | 
			
		||||
  QuaternionType x(Coefficients::Random()), y(Coefficients::Random());
 | 
			
		||||
  QVector<QuaternionType> v(10), w(20, y);
 | 
			
		||||
  v[5] = x;
 | 
			
		||||
  w[6] = v[5];
 | 
			
		||||
  VERIFY_IS_APPROX(w[6], v[5]);
 | 
			
		||||
  v = w;
 | 
			
		||||
  for(int i = 0; i < 20; i++)
 | 
			
		||||
  {
 | 
			
		||||
    VERIFY_IS_APPROX(w[i], v[i]);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  v.resize(21);
 | 
			
		||||
  v[20] = x;
 | 
			
		||||
  VERIFY_IS_APPROX(v[20], x);
 | 
			
		||||
  v.fill(y,22);
 | 
			
		||||
  VERIFY_IS_APPROX(v[21], y);
 | 
			
		||||
  v.push_back(x);
 | 
			
		||||
  VERIFY_IS_APPROX(v[22], x);
 | 
			
		||||
  VERIFY((size_t)&(v[22]) == (size_t)&(v[21]) + sizeof(QuaternionType));
 | 
			
		||||
 | 
			
		||||
  // do a lot of push_back such that the vector gets internally resized
 | 
			
		||||
  // (with memory reallocation)
 | 
			
		||||
  QuaternionType* ref = &w[0];
 | 
			
		||||
  for(int i=0; i<30 || ((ref==&w[0]) && i<300); ++i)
 | 
			
		||||
    v.push_back(w[i%w.size()]);
 | 
			
		||||
  for(unsigned int i=23; int(i)<v.size(); ++i)
 | 
			
		||||
  {
 | 
			
		||||
    VERIFY(v[i].coeffs()==w[(i-23)%w.size()].coeffs());
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_qtvector()
 | 
			
		||||
{
 | 
			
		||||
  // some non vectorizable fixed sizes
 | 
			
		||||
  CALL_SUBTEST(check_qtvector_matrix(Vector2f()));
 | 
			
		||||
  CALL_SUBTEST(check_qtvector_matrix(Matrix3f()));
 | 
			
		||||
  CALL_SUBTEST(check_qtvector_matrix(Matrix3d()));
 | 
			
		||||
 | 
			
		||||
  // some vectorizable fixed sizes
 | 
			
		||||
  CALL_SUBTEST(check_qtvector_matrix(Matrix2f()));
 | 
			
		||||
  CALL_SUBTEST(check_qtvector_matrix(Vector4f()));
 | 
			
		||||
  CALL_SUBTEST(check_qtvector_matrix(Matrix4f()));
 | 
			
		||||
  CALL_SUBTEST(check_qtvector_matrix(Matrix4d()));
 | 
			
		||||
 | 
			
		||||
  // some dynamic sizes
 | 
			
		||||
  CALL_SUBTEST(check_qtvector_matrix(MatrixXd(1,1)));
 | 
			
		||||
  CALL_SUBTEST(check_qtvector_matrix(VectorXd(20)));
 | 
			
		||||
  CALL_SUBTEST(check_qtvector_matrix(RowVectorXf(20)));
 | 
			
		||||
  CALL_SUBTEST(check_qtvector_matrix(MatrixXcf(10,10)));
 | 
			
		||||
 | 
			
		||||
  // some Transform
 | 
			
		||||
  CALL_SUBTEST(check_qtvector_transform(Affine2f()));
 | 
			
		||||
  CALL_SUBTEST(check_qtvector_transform(Affine3f()));
 | 
			
		||||
  CALL_SUBTEST(check_qtvector_transform(Affine3d()));
 | 
			
		||||
  //CALL_SUBTEST(check_qtvector_transform(Transform4d()));
 | 
			
		||||
 | 
			
		||||
  // some Quaternion
 | 
			
		||||
  CALL_SUBTEST(check_qtvector_quaternion(Quaternionf()));
 | 
			
		||||
  CALL_SUBTEST(check_qtvector_quaternion(Quaternionf()));
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										118
									
								
								cs440-acg/ext/eigen/test/rand.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								cs440-acg/ext/eigen/test/rand.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,118 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2015 Gael Guennebaud <gael.guennebaud@inria.fr>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
 | 
			
		||||
typedef long long int64;
 | 
			
		||||
 | 
			
		||||
template<typename Scalar> Scalar check_in_range(Scalar x, Scalar y)
 | 
			
		||||
{
 | 
			
		||||
  Scalar r = internal::random<Scalar>(x,y);
 | 
			
		||||
  VERIFY(r>=x);
 | 
			
		||||
  if(y>=x)
 | 
			
		||||
  {
 | 
			
		||||
    VERIFY(r<=y);
 | 
			
		||||
  }
 | 
			
		||||
  return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Scalar> void check_all_in_range(Scalar x, Scalar y)
 | 
			
		||||
{
 | 
			
		||||
  Array<int,1,Dynamic> mask(y-x+1);
 | 
			
		||||
  mask.fill(0);
 | 
			
		||||
  long n = (y-x+1)*32;
 | 
			
		||||
  for(long k=0; k<n; ++k)
 | 
			
		||||
  {
 | 
			
		||||
    mask( check_in_range(x,y)-x )++;
 | 
			
		||||
  }
 | 
			
		||||
  for(Index i=0; i<mask.size(); ++i)
 | 
			
		||||
    if(mask(i)==0)
 | 
			
		||||
      std::cout << "WARNING: value " << x+i << " not reached." << std::endl;
 | 
			
		||||
  VERIFY( (mask>0).all() );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Scalar> void check_histogram(Scalar x, Scalar y, int bins)
 | 
			
		||||
{
 | 
			
		||||
  Array<int,1,Dynamic> hist(bins);
 | 
			
		||||
  hist.fill(0);
 | 
			
		||||
  int f = 100000;
 | 
			
		||||
  int n = bins*f;
 | 
			
		||||
  int64 range = int64(y)-int64(x);
 | 
			
		||||
  int divisor = int((range+1)/bins);
 | 
			
		||||
  assert(((range+1)%bins)==0);
 | 
			
		||||
  for(int k=0; k<n; ++k)
 | 
			
		||||
  {
 | 
			
		||||
    Scalar r = check_in_range(x,y);
 | 
			
		||||
    hist( int((int64(r)-int64(x))/divisor) )++;
 | 
			
		||||
  }
 | 
			
		||||
  VERIFY( (((hist.cast<double>()/double(f))-1.0).abs()<0.02).all() );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_rand()
 | 
			
		||||
{
 | 
			
		||||
  long long_ref = NumTraits<long>::highest()/10;
 | 
			
		||||
  signed char char_offset = (std::min)(g_repeat,64);
 | 
			
		||||
  signed char short_offset = (std::min)(g_repeat,16000);
 | 
			
		||||
 | 
			
		||||
  for(int i = 0; i < g_repeat*10000; i++) {
 | 
			
		||||
    CALL_SUBTEST(check_in_range<float>(10,11));
 | 
			
		||||
    CALL_SUBTEST(check_in_range<float>(1.24234523,1.24234523));
 | 
			
		||||
    CALL_SUBTEST(check_in_range<float>(-1,1));
 | 
			
		||||
    CALL_SUBTEST(check_in_range<float>(-1432.2352,-1432.2352));
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST(check_in_range<double>(10,11));
 | 
			
		||||
    CALL_SUBTEST(check_in_range<double>(1.24234523,1.24234523));
 | 
			
		||||
    CALL_SUBTEST(check_in_range<double>(-1,1));
 | 
			
		||||
    CALL_SUBTEST(check_in_range<double>(-1432.2352,-1432.2352));
 | 
			
		||||
 | 
			
		||||
    CALL_SUBTEST(check_in_range<int>(0,-1));
 | 
			
		||||
    CALL_SUBTEST(check_in_range<short>(0,-1));
 | 
			
		||||
    CALL_SUBTEST(check_in_range<long>(0,-1));
 | 
			
		||||
    CALL_SUBTEST(check_in_range<int>(-673456,673456));
 | 
			
		||||
    CALL_SUBTEST(check_in_range<int>(-RAND_MAX+10,RAND_MAX-10));
 | 
			
		||||
    CALL_SUBTEST(check_in_range<short>(-24345,24345));
 | 
			
		||||
    CALL_SUBTEST(check_in_range<long>(-long_ref,long_ref));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  CALL_SUBTEST(check_all_in_range<signed char>(11,11));
 | 
			
		||||
  CALL_SUBTEST(check_all_in_range<signed char>(11,11+char_offset));
 | 
			
		||||
  CALL_SUBTEST(check_all_in_range<signed char>(-5,5));
 | 
			
		||||
  CALL_SUBTEST(check_all_in_range<signed char>(-11-char_offset,-11));
 | 
			
		||||
  CALL_SUBTEST(check_all_in_range<signed char>(-126,-126+char_offset));
 | 
			
		||||
  CALL_SUBTEST(check_all_in_range<signed char>(126-char_offset,126));
 | 
			
		||||
  CALL_SUBTEST(check_all_in_range<signed char>(-126,126));
 | 
			
		||||
 | 
			
		||||
  CALL_SUBTEST(check_all_in_range<short>(11,11));
 | 
			
		||||
  CALL_SUBTEST(check_all_in_range<short>(11,11+short_offset));
 | 
			
		||||
  CALL_SUBTEST(check_all_in_range<short>(-5,5));
 | 
			
		||||
  CALL_SUBTEST(check_all_in_range<short>(-11-short_offset,-11));
 | 
			
		||||
  CALL_SUBTEST(check_all_in_range<short>(-24345,-24345+short_offset));
 | 
			
		||||
  CALL_SUBTEST(check_all_in_range<short>(24345,24345+short_offset));
 | 
			
		||||
 | 
			
		||||
  CALL_SUBTEST(check_all_in_range<int>(11,11));
 | 
			
		||||
  CALL_SUBTEST(check_all_in_range<int>(11,11+g_repeat));
 | 
			
		||||
  CALL_SUBTEST(check_all_in_range<int>(-5,5));
 | 
			
		||||
  CALL_SUBTEST(check_all_in_range<int>(-11-g_repeat,-11));
 | 
			
		||||
  CALL_SUBTEST(check_all_in_range<int>(-673456,-673456+g_repeat));
 | 
			
		||||
  CALL_SUBTEST(check_all_in_range<int>(673456,673456+g_repeat));
 | 
			
		||||
 | 
			
		||||
  CALL_SUBTEST(check_all_in_range<long>(11,11));
 | 
			
		||||
  CALL_SUBTEST(check_all_in_range<long>(11,11+g_repeat));
 | 
			
		||||
  CALL_SUBTEST(check_all_in_range<long>(-5,5));
 | 
			
		||||
  CALL_SUBTEST(check_all_in_range<long>(-11-g_repeat,-11));
 | 
			
		||||
  CALL_SUBTEST(check_all_in_range<long>(-long_ref,-long_ref+g_repeat));
 | 
			
		||||
  CALL_SUBTEST(check_all_in_range<long>( long_ref, long_ref+g_repeat));
 | 
			
		||||
 | 
			
		||||
  CALL_SUBTEST(check_histogram<int>(-5,5,11));
 | 
			
		||||
  int bins = 100;
 | 
			
		||||
  CALL_SUBTEST(check_histogram<int>(-3333,-3333+bins*(3333/bins)-1,bins));
 | 
			
		||||
  bins = 1000;
 | 
			
		||||
  CALL_SUBTEST(check_histogram<int>(-RAND_MAX+10,-RAND_MAX+10+bins*(RAND_MAX/bins)-1,bins));
 | 
			
		||||
  CALL_SUBTEST(check_histogram<int>(-RAND_MAX+10,-int64(RAND_MAX)+10+bins*(2*int64(RAND_MAX)/bins)-1,bins));
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										94
									
								
								cs440-acg/ext/eigen/test/real_qz.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								cs440-acg/ext/eigen/test/real_qz.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,94 @@
 | 
			
		||||
// This file is part of Eigen, a lightweight C++ template library
 | 
			
		||||
// for linear algebra.
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2012 Alexey Korepanov <kaikaikai@yandex.ru>
 | 
			
		||||
//
 | 
			
		||||
// This Source Code Form is subject to the terms of the Mozilla
 | 
			
		||||
// Public License v. 2.0. If a copy of the MPL was not distributed
 | 
			
		||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 | 
			
		||||
#define EIGEN_RUNTIME_NO_MALLOC
 | 
			
		||||
#include "main.h"
 | 
			
		||||
#include <limits>
 | 
			
		||||
#include <Eigen/Eigenvalues>
 | 
			
		||||
 | 
			
		||||
template<typename MatrixType> void real_qz(const MatrixType& m)
 | 
			
		||||
{
 | 
			
		||||
  /* this test covers the following files:
 | 
			
		||||
     RealQZ.h
 | 
			
		||||
  */
 | 
			
		||||
  using std::abs;
 | 
			
		||||
  typedef typename MatrixType::Scalar Scalar;
 | 
			
		||||
  
 | 
			
		||||
  Index dim = m.cols();
 | 
			
		||||
  
 | 
			
		||||
  MatrixType A = MatrixType::Random(dim,dim),
 | 
			
		||||
             B = MatrixType::Random(dim,dim);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  // Regression test for bug 985: Randomly set rows or columns to zero
 | 
			
		||||
  Index k=internal::random<Index>(0, dim-1);
 | 
			
		||||
  switch(internal::random<int>(0,10)) {
 | 
			
		||||
  case 0:
 | 
			
		||||
    A.row(k).setZero(); break;
 | 
			
		||||
  case 1:
 | 
			
		||||
    A.col(k).setZero(); break;
 | 
			
		||||
  case 2:
 | 
			
		||||
    B.row(k).setZero(); break;
 | 
			
		||||
  case 3:
 | 
			
		||||
    B.col(k).setZero(); break;
 | 
			
		||||
  default:
 | 
			
		||||
    break;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  RealQZ<MatrixType> qz(dim);
 | 
			
		||||
  // TODO enable full-prealocation of required memory, this probably requires an in-place mode for HessenbergDecomposition
 | 
			
		||||
  //Eigen::internal::set_is_malloc_allowed(false);
 | 
			
		||||
  qz.compute(A,B);
 | 
			
		||||
  //Eigen::internal::set_is_malloc_allowed(true);
 | 
			
		||||
  
 | 
			
		||||
  VERIFY_IS_EQUAL(qz.info(), Success);
 | 
			
		||||
  // check for zeros
 | 
			
		||||
  bool all_zeros = true;
 | 
			
		||||
  for (Index i=0; i<A.cols(); i++)
 | 
			
		||||
    for (Index j=0; j<i; j++) {
 | 
			
		||||
      if (abs(qz.matrixT()(i,j))!=Scalar(0.0))
 | 
			
		||||
      {
 | 
			
		||||
        std::cerr << "Error: T(" << i << "," << j << ") = " << qz.matrixT()(i,j) << std::endl;
 | 
			
		||||
        all_zeros = false;
 | 
			
		||||
      }
 | 
			
		||||
      if (j<i-1 && abs(qz.matrixS()(i,j))!=Scalar(0.0))
 | 
			
		||||
      {
 | 
			
		||||
        std::cerr << "Error: S(" << i << "," << j << ") = " << qz.matrixS()(i,j) << std::endl;
 | 
			
		||||
        all_zeros = false;
 | 
			
		||||
      }
 | 
			
		||||
      if (j==i-1 && j>0 && abs(qz.matrixS()(i,j))!=Scalar(0.0) && abs(qz.matrixS()(i-1,j-1))!=Scalar(0.0))
 | 
			
		||||
      {
 | 
			
		||||
        std::cerr << "Error: S(" << i << "," << j << ") = " << qz.matrixS()(i,j)  << " && S(" << i-1 << "," << j-1 << ") = " << qz.matrixS()(i-1,j-1) << std::endl;
 | 
			
		||||
        all_zeros = false;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  VERIFY_IS_EQUAL(all_zeros, true);
 | 
			
		||||
  VERIFY_IS_APPROX(qz.matrixQ()*qz.matrixS()*qz.matrixZ(), A);
 | 
			
		||||
  VERIFY_IS_APPROX(qz.matrixQ()*qz.matrixT()*qz.matrixZ(), B);
 | 
			
		||||
  VERIFY_IS_APPROX(qz.matrixQ()*qz.matrixQ().adjoint(), MatrixType::Identity(dim,dim));
 | 
			
		||||
  VERIFY_IS_APPROX(qz.matrixZ()*qz.matrixZ().adjoint(), MatrixType::Identity(dim,dim));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_real_qz()
 | 
			
		||||
{
 | 
			
		||||
  int s = 0;
 | 
			
		||||
  for(int i = 0; i < g_repeat; i++) {
 | 
			
		||||
    CALL_SUBTEST_1( real_qz(Matrix4f()) );
 | 
			
		||||
    s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/4);
 | 
			
		||||
    CALL_SUBTEST_2( real_qz(MatrixXd(s,s)) );
 | 
			
		||||
 | 
			
		||||
    // some trivial but implementation-wise tricky cases
 | 
			
		||||
    CALL_SUBTEST_2( real_qz(MatrixXd(1,1)) );
 | 
			
		||||
    CALL_SUBTEST_2( real_qz(MatrixXd(2,2)) );
 | 
			
		||||
    CALL_SUBTEST_3( real_qz(Matrix<double,1,1>()) );
 | 
			
		||||
    CALL_SUBTEST_4( real_qz(Matrix2d()) );
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  TEST_SET_BUT_UNUSED_VARIABLE(s)
 | 
			
		||||
}
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user