Skip to content
Merged
4 changes: 2 additions & 2 deletions Code/Source/solver/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -177,15 +177,15 @@ if(ENABLE_COVERAGE)
endif()

add_subdirectory(Core)
add_subdirectory(common/math)
add_subdirectory(FE/Common)
add_subdirectory(FE/Math)
add_subdirectory(FE/Quadrature)
add_subdirectory(FE/Basis)

set(SVMP_ARCHITECTURE_TARGETS
svmp_core
svmp_fe_common
svmp_fe_math
svmp_math
svmp_fe_basis
svmp_fe_quadrature
)
Expand Down
4 changes: 2 additions & 2 deletions Code/Source/solver/FE/Basis/BasisFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@

#include "BasisExceptions.h"
#include "BasisTraits.h"
#include "Math/Matrix.h"
#include "Math/Vector.h"
#include "math/Matrix.h"
#include "math/Vector.h"
#include "Types.h"

#include <cstddef>
Expand Down
2 changes: 1 addition & 1 deletion Code/Source/solver/FE/Basis/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ target_include_directories(svmp_fe_basis PUBLIC

target_link_libraries(svmp_fe_basis PUBLIC
svmp_fe_common
svmp_fe_math
svmp_math
svmp_fe_quadrature
)
2 changes: 1 addition & 1 deletion Code/Source/solver/FE/Basis/NodeOrderingConventions.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#define SVMP_FE_BASIS_NODEORDERINGCONVENTIONS_H

#include "BasisTraits.h"
#include "Math/Vector.h"
#include "math/Vector.h"
#include "Types.h"

#include <array>
Expand Down
11 changes: 6 additions & 5 deletions Code/Source/solver/FE/Basis/SerendipityBasis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@

#include "SerendipityBasis.h"
#include "NodeOrderingConventions.h"
#include "Math/DenseLinearAlgebra.h"
#include "Core/Exception.h"
#include "math/DenseLinearAlgebra.h"

#include <algorithm>
#include <array>
Expand Down Expand Up @@ -195,21 +196,21 @@ std::vector<double> build_inverse_vandermonde(
// too.
const double norm_v = matrix_norm_inf(vandermonde, n);

// invert_dense_matrix raises a generic FEException if the Vandermonde is
// invert_dense_matrix raises a generic CoreException if the Vandermonde is
// exactly singular (a rank-deficient pivot). For a serendipity family that
// means the node set is not unisolvent at this order -- a construction failure
// in basis terms -- so translate it to BasisConstructionException, presenting
// the singular and the ill-conditioned cases (below) as one catchable type in
// one vocabulary. The matrix was just built n-by-n from n modes, so a
// size-mismatch FEException cannot originate here; rank deficiency is the only
// FEException this call can raise. (Defensive: the supported node sets are
// size-mismatch CoreException cannot originate here; rank deficiency is the only
// CoreException this call can raise. (Defensive: the supported node sets are
// provably unisolvent, so this branch is not reachable for the shipped orders.)
std::vector<double> inverse;
try {
inverse = math::invert_dense_matrix(
std::move(vandermonde), n,
"SerendipityBasis interpolation matrix for " + label);
} catch (const FEException&) {
} catch (const CoreException&) {
svmp::raise<BasisConstructionException>("SerendipityBasis: " + label +
" interpolation matrix is singular; the serendipity node set is not "
"unisolvent at the requested order");
Expand Down
2 changes: 1 addition & 1 deletion Code/Source/solver/FE/FE.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
* This header intentionally contains no declarations. It gives Doxygen a
* header-based home for the top-level FE group; submodule groups attach to it
* from their own headers, including FE_Basis (Basis/BasisFunction.h),
* FE_Common (Common/Types.h), FE_Math (Math/Vector.h), and FE_Quadrature
* FE_Common (Common/Types.h), shared Math (math/Vector.h), and FE_Quadrature
* (Quadrature/QuadratureRule.h).
*/

Expand Down
23 changes: 0 additions & 23 deletions Code/Source/solver/FE/Math/CMakeLists.txt

This file was deleted.

2 changes: 1 addition & 1 deletion Code/Source/solver/FE/Quadrature/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@ target_include_directories(svmp_fe_quadrature PUBLIC

target_link_libraries(svmp_fe_quadrature PUBLIC
svmp_fe_common
svmp_fe_math
svmp_math
)
2 changes: 1 addition & 1 deletion Code/Source/solver/FE/Quadrature/QuadratureRule.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
*/

#include "FE/Common/Types.h"
#include "FE/Math/Vector.h"
#include "math/Vector.h"

#include <cstddef>
#include <span>
Expand Down
22 changes: 22 additions & 0 deletions Code/Source/solver/common/math/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
file(GLOB_RECURSE SVMP_MATH_FILES CONFIGURE_DEPENDS
"${CMAKE_CURRENT_SOURCE_DIR}/include/*.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/*.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/include/*.inl"
"${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp"
)

add_library(svmp_math OBJECT
${SVMP_MATH_FILES}
)

target_compile_features(svmp_math PUBLIC cxx_std_20)

target_include_directories(svmp_math PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/include
${SV_SOURCE_DIR}/ThirdParty/eigen/include
${SV_SOURCE_DIR}/ThirdParty/eigen/include/eigen3
)

target_link_libraries(svmp_math PUBLIC
svmp_core
)
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
// SPDX-FileCopyrightText: Copyright (c) Stanford University, The Regents of the University of California, and others.
// SPDX-License-Identifier: BSD-3-Clause

#ifndef SVMP_FE_MATH_DENSELINEARALGEBRA_H
#define SVMP_FE_MATH_DENSELINEARALGEBRA_H

#include "Types.h"
#ifndef SVMP_COMMON_MATH_DENSELINEARALGEBRA_H
#define SVMP_COMMON_MATH_DENSELINEARALGEBRA_H

#include <cstddef>
#include <limits>
Expand All @@ -14,7 +12,7 @@
#include <string_view>
#include <vector>

namespace svmp::FE::math {
namespace svmp::math {

// Dense solve, inverse, rank, and pseudo-inverse support for FE construction
// utilities. Matrices are row-major: matrix[row * cols + col]. The
Expand All @@ -23,15 +21,15 @@ namespace svmp::FE::math {

/**
* @brief Largest absolute entry of a dense matrix.
* @ingroup FE_Math
* @ingroup SVMP_Math
* @param matrix Row-major matrix entries.
* @return Maximum of |entry| over all entries, or 0 for an empty matrix.
*/
[[nodiscard]] double dense_matrix_max_abs(std::span<const double> matrix) noexcept;

/**
* @brief Scale-aware pivot tolerance for dense factorization.
* @ingroup FE_Math
* @ingroup SVMP_Math
*
* @details Proportional to machine epsilon scaled by the matrix size and
* magnitude; pivots below it are treated as rank-deficient.
Expand All @@ -49,7 +47,7 @@ namespace svmp::FE::math {

/**
* @brief Scale-aware singular-value tolerance for rank decisions.
* @ingroup FE_Math
* @ingroup SVMP_Math
*
* @details Singular values at or below the returned tolerance are treated as
* zero when computing rank or a pseudo-inverse.
Expand All @@ -65,7 +63,7 @@ namespace svmp::FE::math {
double largest_singular_value,
double multiplier = double(64)) noexcept;

/** @brief Result of a rank-revealing pseudo-inverse. @ingroup FE_Math */
/** @brief Result of a rank-revealing pseudo-inverse. @ingroup SVMP_Math */
struct DensePseudoInverseResult {
std::vector<double> inverse; ///< Row-major pseudo-inverse.
std::size_t rank{0}; ///< Numerical rank at the chosen tolerance.
Expand All @@ -74,7 +72,7 @@ struct DensePseudoInverseResult {
double smallest_retained_singular_value{0}; ///< Smallest singular value kept.
};

/** @brief SVD-based conditioning and rank diagnostics for a dense matrix. @ingroup FE_Math */
/** @brief SVD-based conditioning and rank diagnostics for a dense matrix. @ingroup SVMP_Math */
struct DenseMatrixDiagnostics {
std::size_t rank{0}; ///< Numerical rank at @ref tolerance.
double tolerance{0}; ///< Singular-value tolerance used.
Expand All @@ -83,7 +81,7 @@ struct DenseMatrixDiagnostics {
double condition_estimate{std::numeric_limits<double>::infinity()}; ///< Condition estimate; infinite when rank-deficient.
};

/** @brief A dense inverse together with its diagnostics. @ingroup FE_Math */
/** @brief A dense inverse together with its diagnostics. @ingroup SVMP_Math */
struct DenseInverseResult {
std::vector<double> inverse; ///< Row-major inverse.
DenseMatrixDiagnostics diagnostics; ///< Conditioning/rank diagnostics of the input.
Expand All @@ -92,20 +90,20 @@ struct DenseInverseResult {

/**
* @brief Condition estimate above which the inverse switches to an SVD fallback.
* @ingroup FE_Math
* @ingroup SVMP_Math
* @return The fallback condition-number threshold.
*/
[[nodiscard]] double dense_matrix_condition_fallback_threshold() noexcept;
/**
* @brief Condition estimate above which validation rejects a dense inverse.
* @ingroup FE_Math
* @ingroup SVMP_Math
* @return The error condition-number threshold.
*/
[[nodiscard]] double dense_matrix_condition_error_threshold() noexcept;

/**
* @brief LU factorization of a dense square matrix with a cached pivot summary.
* @ingroup FE_Math
* @ingroup SVMP_Math
*
* @details Produced by factor_dense_matrix(); move-only because it owns the Eigen
* factorization. @ref error_message_label prefixes the messages of exceptions
Expand Down Expand Up @@ -159,13 +157,13 @@ struct DenseLUSolver {

/**
* @brief SVD-based rank and conditioning diagnostics for a dense matrix.
* @ingroup FE_Math
* @ingroup SVMP_Math
* @param matrix Row-major matrix of size rows * cols.
* @param rows Row count.
* @param cols Column count.
* @param error_message_label Prefix for the message of any exception thrown.
* @return Rank, tolerance, singular-value, and condition diagnostics.
* @throws FEException If the matrix size is inconsistent or the matrix is empty.
* @throws CoreException If the matrix size is inconsistent or the matrix is empty.
*/
[[nodiscard]] DenseMatrixDiagnostics dense_matrix_diagnostics(
std::span<const double> matrix,
Expand All @@ -175,25 +173,25 @@ struct DenseLUSolver {

/**
* @brief LU-factor a dense square matrix.
* @ingroup FE_Math
* @ingroup SVMP_Math
* @param matrix Row-major n * n matrix (consumed).
* @param n Matrix dimension.
* @param error_message_label Prefix for the message of any exception thrown.
* @return The factorization.
* @throws FEException If the size is inconsistent or the matrix is rank-deficient.
* @throws CoreException If the size is inconsistent or the matrix is rank-deficient.
*/
[[nodiscard]] DenseLUSolver factor_dense_matrix(std::vector<double> matrix,
std::size_t n,
std::string_view error_message_label = "dense matrix");

/**
* @brief Invert a dense square matrix.
* @ingroup FE_Math
* @ingroup SVMP_Math
* @param matrix Row-major n * n matrix (consumed).
* @param n Matrix dimension.
* @param error_message_label Prefix for the message of any exception thrown.
* @return Row-major inverse of size n * n.
* @throws FEException If the size is inconsistent or the matrix is singular.
* @throws CoreException If the size is inconsistent or the matrix is singular.
*/
[[nodiscard]] std::vector<double> invert_dense_matrix(std::vector<double> matrix,
std::size_t n,
Expand All @@ -202,12 +200,12 @@ struct DenseLUSolver {
/**
* @brief Invert a dense square matrix with diagnostics, using an SVD fallback for
* high-condition matrices.
* @ingroup FE_Math
* @ingroup SVMP_Math
* @param matrix Row-major n * n matrix (consumed).
* @param n Matrix dimension.
* @param error_message_label Prefix for the message of any exception thrown.
* @return Inverse plus diagnostics and whether the SVD fallback was used.
* @throws FEException If the size is inconsistent or the matrix is rank-deficient.
* @throws CoreException If the size is inconsistent or the matrix is rank-deficient.
*/
[[nodiscard]] DenseInverseResult invert_dense_matrix_with_diagnostics(
std::vector<double> matrix,
Expand All @@ -216,12 +214,12 @@ struct DenseLUSolver {

/**
* @brief Validate that a dense inverse has full rank and acceptable conditioning.
* @ingroup FE_Math
* @ingroup SVMP_Math
* @param result Result from invert_dense_matrix_with_diagnostics().
* @param expected_rank Required (full) rank.
* @param error_message_label Prefix for the message of any exception thrown.
* @param max_condition Largest acceptable condition estimate.
* @throws FEException If the rank is below expected_rank or the condition exceeds max_condition.
* @throws CoreException If the rank is below expected_rank or the condition exceeds max_condition.
*/
void validate_dense_inverse_diagnostics(
const DenseInverseResult& result,
Expand All @@ -231,33 +229,33 @@ void validate_dense_inverse_diagnostics(

/**
* @brief Numerical rank of a dense matrix from its singular values.
* @ingroup FE_Math
* @ingroup SVMP_Math
* @param matrix Row-major matrix of size rows * cols (consumed).
* @param rows Row count.
* @param cols Column count.
* @return Number of singular values above the scale-aware tolerance.
* @throws FEException If the matrix size is inconsistent.
* @throws CoreException If the matrix size is inconsistent.
*/
[[nodiscard]] std::size_t dense_matrix_rank(std::vector<double> matrix,
std::size_t rows,
std::size_t cols);

/**
* @brief Moore-Penrose pseudo-inverse via a rank-revealing SVD.
* @ingroup FE_Math
* @ingroup SVMP_Math
* @param matrix Row-major matrix of size rows * cols.
* @param rows Row count.
* @param cols Column count.
* @param error_message_label Prefix for the message of any exception thrown.
* @return Row-major pseudo-inverse (cols * rows) plus rank/tolerance diagnostics.
* @throws FEException If the matrix size is inconsistent or the matrix is empty.
* @throws CoreException If the matrix size is inconsistent or the matrix is empty.
*/
[[nodiscard]] DensePseudoInverseResult rank_revealing_pseudo_inverse(
std::span<const double> matrix,
std::size_t rows,
std::size_t cols,
std::string_view error_message_label = "dense matrix");

} // namespace svmp::FE::math
} // namespace svmp::math

#endif // SVMP_FE_MATH_DENSELINEARALGEBRA_H
#endif // SVMP_COMMON_MATH_DENSELINEARALGEBRA_H
Loading
Loading