Skip to content

Commit

Permalink
completed changelog, small fixes and deprecations
Browse files Browse the repository at this point in the history
  • Loading branch information
petiaccja committed Sep 17, 2024
1 parent 9be7d64 commit 9e787ea
Show file tree
Hide file tree
Showing 6 changed files with 127 additions and 113 deletions.
133 changes: 78 additions & 55 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,60 +1,83 @@
### Version 2.0 (?)
# Changelog

Changes:
- Refactored utility folder structure and code (`Common/*`)
- Refactored vector folder structure and code (`Vector/*`)
- Refactored matrix folder structure and code (`Matrix/*`)
- Refactored quaternion folder structure and code (`Quaternion/*`)
- Refactored geometry header and code (`Geometry/*`)
- `Vector`s:
- Memory representation:
- Removed undefined behavior due to swizzle unions
- Named accessors (i.e. `.x`) are now `Swizzle`s instead of `T&`
- CTAD for `Vector` constructors
- Better support for heterogeneous types (i.e. adding vector of `double` plus vector of `float`)
- Better support and testing for `std::complex`
- Functions:
- `IsNullvector`: removed due to questionable meaning / use-cases
- `IsNormalized`: removed due to questionable meaning / use-cases
- `SafeNormalize`: renamed to `NormalizePrecise`
- Homogeneous downcast now performs perspective division
- Added several new functions
- `Matrix`es:
- Removed submatrices
- Added accessors for rows and columns
- Better support for heterogeneous types (i.e. adding matrix of `double` plus matrix of `float`)
- Better support and testing for `std::complex`
- Matrix casts:
- Constructors now handle more casts
- Casts are now utility functions mainly for internal use
- Functions:
- Added several new functions
- `Quaternion`s:
- Memory representation:
- New Layout template param to specify sijk or ijks
- Removed undefined behavior due to swizzle unions
- Named accessors (i.e. `.x`) are now `Swizzle`s instead of `T&`
- Better support for heterogeneous types (i.e. adding quaternion of `double` plus quaternion of `float`)
- Functions:
- Deprecated `ScalarPart` and `VectorPart`:
- Migrate to the new .scalar and .vector swizzlers instead
- Removed converion operator to Vector<3>: questionable meaning / use-cases (use q.vector instead)
- Renamed `Conjugate` to `Conj` (in line with STL)
- Fixed `Inverse` (q^-1) working only for unit quaternions
## 2.0.0

- Version 2.0.0 is a complete overhaul:
- The interfaces stayed mostly the same (especially the common ones)
- The internals have been completely rewriten and/or refactored
- Migrating from 1.x.x:
- Read this changelog
- Spam recompile until it works
- Folder structure and library organization:
- Changes to the top-level headers:
- `<Mathter/Matrix.hpp>` no longer includes decompositions (include decompositions individually)
- `<Mathter/Matrix.hpp>` no longer includes transforms (include `<Mathter/Transforms.hpp>`)
- The internals (e.g. `<Mathter/Vector/*.hpp>`) have been completely refactored
- Vectors:
- New data structure:
- No more union abuse, `reinterpret_cast`, and UB
- Named accessors (e.g. `.x`) are no longer T&, but are implemented as swizzlers
- Homogeneous downcast now performs perspective division
- CTAD support added to some constructors
- Deprecated concatenation by the pipe (`|`) operator
- Use concatenating constructor with CTAD instead
- `IsNullvector`: removed due to questionable meaning / use-cases
- `IsNormalized`: removed due to questionable meaning / use-cases
- `SafeNormalize`: renamed to `NormalizePrecise`
- Matrices:
- Added additional converting constructors (switch order, layout, and scalar type)
- Removed casting utilities:
- Use the converting constructors instead
- Similar utilities in `Cast.hpp` (warning: not intended for end users)
- Removed submatrices / matrix views
- Added `Row` and `Column` accessors (these are layout-agnostic)
- Added `Extract` and `Insert` accessors (these replace sub-matrices)
- Quaternions:
- Added template parameter to select memory layout:
- Choose between SIJK and IJKS ordering
- New data structure:
- Deprecated `VectorPart` and `ScalarPart`
- Use the swizzlers `.scalar` and `.vector`
- Named accessors (e.g. `.s`) are no longer T&, but are implemented as swizzlers
- `Axis` and `Angle` are now free functions
- Renamed `Conjugate` to `Conj` (it's different from the quaternion inverse)
- `Inverse` does actual inverse (same as conjugation **only** for unit quaternions)
- Removed conversion to `Vector<T, 3>` (ambiguous semantics)
- Deprecated `operator*(Quaternion, Vector)`:
- Use `Quaternion::operator()(Vector)` to apply rotations to vectors
- Transforms:
- Minimal changes to interface
- New transforms:
- Random, general shear
- Now also applicable to vectors: zero, random
- Generalized shear
- Random (this is not really a transform though)
- Transforms applicable to more types (e.g. `Vector<float, 3> v = Zero()` is now valid)
- Geometry:
- Complete overhaul of intersections
- All intersections now return `std::optional<Vector>` for the intersection point
- Only small changes to objects
- The intersections have been completely reworked
- Use `Intersect(a, b)`: returns an `optional` of the intersection's coordinate
- Decompositions:
- QR:
- Added LQ to support wide matrices
- SVD: unchanged
- LU/LUP: unchanged
- All decompositions have a uniform interface:
- Solve: solve system of equations / least squares if applicable
- Inverse: compute matrix inverse / pseudoinverse if applicable
- Unified interface for the different decompositions:
- `Solve`: solve one/many equation systems & least squares problems
- `Inverse`: compute inverse and pseudoinverse
- Get factors via structured bindings
- QR:
- Added LQ decomposition
- SVD:
- Added 1-sided Jacobi algorithm (alongside existing 2-sided)
- IoStream:
- Complete rewrite (old implementation was mostly a quick and dirty utility)
- Changed formatting to Python's array syntax
- General:
- Mixed precision now widely permitted (e.g. adding vector or doubles to vector of complex floats returns a vector of complex doubles)
- Full support for complex numbers:
- Vectors and matrices now fully support complex numbers
- Methods (like `Dot`) have been adapted
- Algorithms (like decompositions) have been adapted
- Improved testing:
- More accurately (and conservatively) measuring coverage
- Raised coverage above 90%, with conservative estimates
- More template parameter combinations are tested (e.g. complex numbers, mixed matrix layouts)
- Many new mathematical functions: most on vectors and matrices, a few on quaternions
- Performance:
- Added many new benchmarks
- Documentation:
- Added an examples folder with a mini project
- Rewrote the guide
38 changes: 7 additions & 31 deletions include/Mathter/Utility.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,8 @@
#pragma once

#include "Common/TypeTraits.hpp"
#include "Common/Types.hpp"
#include "Vector/Math.hpp"
#include "Vector/Vector.hpp"

#include <algorithm>
#include <type_traits>


namespace mathter {
Expand All @@ -26,12 +22,12 @@ namespace mathter {
template <class Scalar>
class Constants {
public:
static constexpr auto Pi = Scalar(3.1415926535897932384626433832795028841971693993751);
static constexpr auto PiHalf = Scalar(1.5707963267948966192313216916397514420985846996876);
static constexpr auto PiFourth = Scalar(0.78539816339744830961566084581987572104929234984378);
static constexpr auto E = Scalar(2.7182818284590452353602874713526624977572470937);
static constexpr auto Sqrt2 = Scalar(1.4142135623730950488016887242096980785696718753769);
static constexpr auto SqrtHalf = Scalar(0.70710678118654752440084436210484903928483593768847);
static constexpr auto Pi = Scalar(3.1415926535897932384626433832795028841971693993751L);
static constexpr auto PiHalf = Scalar(1.5707963267948966192313216916397514420985846996876L);
static constexpr auto PiFourth = Scalar(0.78539816339744830961566084581987572104929234984378L);
static constexpr auto E = Scalar(2.7182818284590452353602874713526624977572470937L);
static constexpr auto Sqrt2 = Scalar(1.4142135623730950488016887242096980785696718753769L);
static constexpr auto SqrtHalf = Scalar(0.70710678118654752440084436210484903928483593768847L);
};


Expand Down Expand Up @@ -62,30 +58,10 @@ Scalar Clamp(Scalar arg, Scalar lower, Scalar upper) {
return std::clamp(arg, lower, upper);
}

/// <summary> Clamps all elements of the vector according to the scalar clamp. </summary>
template <class T, int Dim, bool Packed>
Vector<T, Dim, Packed> Clamp(const Vector<T, Dim, Packed>& arg, T lower, T upper);

/// <summary> Clamps argument into range [0,1]. </summary>
/// <summary> Clamps argument into range [0, 1]. </summary>
template <class Scalar>
Scalar Saturate(Scalar arg) {
return Clamp(arg, Scalar(0), Scalar(1));
}

/// <summary> Clamps all elements into range [0,1]. </summary>
template <class T, int Dim, bool Packed>
Vector<T, Dim, Packed> Saturate(const Vector<T, Dim, Packed>& arg);


template <class T, int Dim, bool Packed>
Vector<T, Dim, Packed> Clamp(const Vector<T, Dim, Packed>& arg, T lower, T upper) {
using Vec = Vector<T, Dim, Packed>;
return Min(Max(arg, Vec(lower)), Vec(upper));
}

template <class T, int Dim, bool Packed>
Vector<T, Dim, Packed> Saturate(const Vector<T, Dim, Packed>& arg) {
return Clamp(arg, T(0), T(1));
}

} // namespace mathter
2 changes: 1 addition & 1 deletion include/Mathter/Vector/Concat.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@
namespace mathter {

/// <summary> Concatenates the arguments, and returns the concatenated parts as a vector. </summary>

template <class Left,
class Right,
std::enable_if_t<is_vector_v<std::decay_t<Left>>
|| is_vector_v<std::decay_t<Right>>
|| is_swizzle_v<std::decay_t<Left>>
|| is_swizzle_v<std::decay_t<Right>>,
int> = 0>
[[deprecated("use concatenating ctor with CTAD")]]
auto operator|(Left&& lhs, Right&& rhs) {
return Vector(std::forward<Left>(lhs), std::forward<Right>(rhs));
}
Expand Down
15 changes: 15 additions & 0 deletions include/Mathter/Vector/Math.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,21 @@ T Max(const Vector<T, Dim, Packed>& v) {
}


/// <summary> Clamps all elements into range [lower, upper]. </summary>
template <class T, int Dim, bool Packed>
Vector<T, Dim, Packed> Clamp(const Vector<T, Dim, Packed>& arg, T lower, T upper) {
using Vec = Vector<T, Dim, Packed>;
return Min(Max(arg, Vec(lower)), Vec(upper));
}


/// <summary> Clamps all elements into range [0, 1]. </summary>
template <class T, int Dim, bool Packed>
Vector<T, Dim, Packed> Saturate(const Vector<T, Dim, Packed>& arg) {
return Clamp(arg, T(0), T(1));
}


/// <summary> Computes a divisor that scales the vector so that its largest element is close to 1. </summary>
/// <remarks> This is similar to dividing by the infinity norm, but it's much faster and
/// less accurate for complex numbers. </summary>
Expand Down
26 changes: 0 additions & 26 deletions test/TestUtility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,30 +67,4 @@ TEMPLATE_LIST_TEST_CASE("Utility: Saturate / scalar", "[Utility]",
SECTION("Between") {
REQUIRE(Saturate(Scalar(0.5)) == Scalar(0.5));
}
}


TEMPLATE_LIST_TEST_CASE("Utility: Clamp / vector", "[Utility]",
decltype(VectorCaseList<ScalarsFloating, PackingsAll>{})) {
using Vec = typename TestType::template Vector<3>;
using Scalar = scalar_type_t<Vec>;
const Scalar lower(-3);
const Scalar upper(3);
const Vec value = { -4, 4, 2 };
const auto result = Clamp(value, lower, upper);
REQUIRE(result[0] == lower);
REQUIRE(result[1] == upper);
REQUIRE(result[2] == value[2]);
}


TEMPLATE_LIST_TEST_CASE("Utility: Saturate / vector", "[Utility]",
decltype(VectorCaseList<ScalarsFloating, PackingsAll>{})) {
using Vec = typename TestType::template Vector<3>;
using Scalar = scalar_type_t<Vec>;
const Vec value = { -1, 2, 0.5f };
const auto result = Saturate(value);
REQUIRE(result[0] == Scalar(0));
REQUIRE(result[1] == Scalar(1));
REQUIRE(result[2] == value[2]);
}
26 changes: 26 additions & 0 deletions test/Vector/TestMath.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,32 @@ TEMPLATE_LIST_TEST_CASE("Vector - Min / Max (reduction)", "[Vector]",
}


TEMPLATE_LIST_TEST_CASE("Vector - Clamp / vector", "[Vector]",
decltype(VectorCaseList<ScalarsFloating, PackingsAll>{})) {
using Vec = typename TestType::template Vector<3>;
using Scalar = scalar_type_t<Vec>;
const Scalar lower(-3);
const Scalar upper(3);
const Vec value = { -4, 4, 2 };
const auto result = Clamp(value, lower, upper);
REQUIRE(result[0] == lower);
REQUIRE(result[1] == upper);
REQUIRE(result[2] == value[2]);
}


TEMPLATE_LIST_TEST_CASE("Vector - Saturate / vector", "[Vector]",
decltype(VectorCaseList<ScalarsFloating, PackingsAll>{})) {
using Vec = typename TestType::template Vector<3>;
using Scalar = scalar_type_t<Vec>;
const Vec value = { -1, 2, 0.5f };
const auto result = Saturate(value);
REQUIRE(result[0] == Scalar(0));
REQUIRE(result[1] == Scalar(1));
REQUIRE(result[2] == value[2]);
}


TEMPLATE_LIST_TEST_CASE("Vector - Abs (real)", "[Vector]",
decltype(VectorCaseList<ScalarsFloatAndInt32, PackingsAll>{})) {
using Vec = typename TestType::template Vector<3>;
Expand Down

0 comments on commit 9e787ea

Please sign in to comment.