fix: LA support fixed

This commit is contained in:
Mateusz Pusz
2023-05-12 11:25:54 +02:00
parent 27d6180579
commit e3f641c2bb
13 changed files with 162 additions and 495 deletions

View File

@@ -78,7 +78,11 @@ class MPUnitsConan(ConanFile):
@property @property
def _build_all(self): def _build_all(self):
return bool(self.conf.get("user.build:all", default=True)) return bool(self.conf.get("user.build:all", default=False))
@property
def _skip_la(self):
return bool(self.conf.get("user.build:skip_la", default=False))
@property @property
def _skip_docs(self): def _skip_docs(self):
@@ -114,9 +118,10 @@ class MPUnitsConan(ConanFile):
def build_requirements(self): def build_requirements(self):
if self._build_all: if self._build_all:
self.test_requires("catch2/3.1.0") self.test_requires("catch2/3.1.0")
self.test_requires("wg21-linear_algebra/0.7.3") if not self._skip_la:
if not self._skip_docs: self.test_requires("wg21-linear_algebra/0.7.3")
self.tool_requires("doxygen/1.9.4") if not self._skip_docs:
self.tool_requires("doxygen/1.9.4")
def validate(self): def validate(self):
check_min_cppstd(self, self._min_cppstd) check_min_cppstd(self, self._min_cppstd)
@@ -140,6 +145,7 @@ class MPUnitsConan(ConanFile):
def generate(self): def generate(self):
tc = CMakeToolchain(self) tc = CMakeToolchain(self)
tc.variables["UNITS_DOWNCAST_MODE"] = str(self.options.downcast_mode).upper() tc.variables["UNITS_DOWNCAST_MODE"] = str(self.options.downcast_mode).upper()
tc.variables["UNITS_BUILD_LA"] = self._build_all and not self._skip_la
tc.variables["UNITS_BUILD_DOCS"] = self._build_all and not self._skip_docs tc.variables["UNITS_BUILD_DOCS"] = self._build_all and not self._skip_docs
tc.variables["UNITS_USE_LIBFMT"] = self._use_libfmt tc.variables["UNITS_USE_LIBFMT"] = self._use_libfmt
tc.generate() tc.generate()

View File

@@ -146,8 +146,8 @@ Specifies how :ref:`design/downcasting:The Downcasting Facility` works:
Conan Configuration Properties Conan Configuration Properties
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
build_all user.build:all
+++++++++ ++++++++++++++
**Values**: ``True``/``False`` **Values**: ``True``/``False``
@@ -158,14 +158,24 @@ To support this it requires some additional Conan build dependencies described i
`Repository Structure and Dependencies`_. `Repository Structure and Dependencies`_.
It also runs unit tests during Conan build (unless ``tools.build:skip_test`` configuration property is set to ``True``) It also runs unit tests during Conan build (unless ``tools.build:skip_test`` configuration property is set to ``True``)
skip_docs user.build:skip_la
+++++++++ ++++++++++++++++++
**Values**: ``True``/``False`` **Values**: ``True``/``False``
**Defaulted to**: ``False`` **Defaulted to**: ``False``
If `build_all`_ is enabled, among others, Conan installs the documentation generation dependencies (i.e. doxygen) and If `user.build:all`_ is enabled, among others, Conan installs the external `wg21-linear_algebra<https://conan.io/center/wg21-linear_algebra>`_
dependency and enables compilation of linear algebra based usage examples. Such behavior can be disabled with this option.
user.build:skip_docs
++++++++++++++++++++
**Values**: ``True``/``False``
**Defaulted to**: ``False``
If `user.build:all`_ is enabled, among others, Conan installs the documentation generation dependencies (i.e. doxygen) and
turns on the project documentation generation. Such behavior can be disabled with this option. turns on the project documentation generation. Such behavior can be disabled with this option.
CMake Options CMake Options
@@ -181,6 +191,16 @@ UNITS_AS_SYSTEM_HEADERS
Exports library as system headers. Exports library as system headers.
UNITS_BUILD_LA
++++++++++++++
**Values**: ``ON``/``OFF``
**Defaulted to**: ``ON``
Enables building code depending on the linear algebra library.
UNITS_BUILD_DOCS UNITS_BUILD_DOCS
++++++++++++++++ ++++++++++++++++
@@ -414,8 +434,8 @@ In case you would like to build all the source code (with unit tests and example
you should: you should:
1. Use the *CMakeLists.txt* from the top-level directory. 1. Use the *CMakeLists.txt* from the top-level directory.
2. Run Conan with `build_all`_ = ``True`` 2. Run Conan with `user.build:all`_ = ``True``
(use ``-o build_docs=False`` if you want to skip the documentation generation). (use ``-c user.build:skip_docs=True`` if you want to skip the documentation generation).
.. code-block:: shell .. code-block:: shell
@@ -443,7 +463,7 @@ In case you would like to build the project's documentation, you should:
1. Use the *CMakeLists.txt* from the top-level directory. 1. Use the *CMakeLists.txt* from the top-level directory.
2. Obtain Python dependencies. 2. Obtain Python dependencies.
3. Run Conan with `build_all`_ = ``True``. 3. Run Conan with `user.build:all`_ = ``True``.
.. code-block:: shell .. code-block:: shell

View File

@@ -14,7 +14,7 @@ enough to be used with other Linear Algebra libraries existing on the market.
or `Conan <https://conan.io/center/wg21-linear_algebra>`_. or `Conan <https://conan.io/center/wg21-linear_algebra>`_.
Also, to simplify the examples all of them assume:: Also, to simplify the examples all of them assume::
using namespace std::math; using namespace STD_LA;
Linear Algebra of Quantities Linear Algebra of Quantities
@@ -27,16 +27,16 @@ The official :term:`quantity` definition states:
So the most common use case would be to create a vector or matrix of quantities:: So the most common use case would be to create a vector or matrix of quantities::
fs_vector<si::length<si::metre>, 3> v = { 1 * m, 2 * m, 3 * m }; fixed_size_column_vector<si::length<si::metre>, 3> v = { 1 * m, 2 * m, 3 * m };
fs_vector<si::length<si::metre>, 3> u = { 3 * m, 2 * m, 1 * m }; fixed_size_column_vector<si::length<si::metre>, 3> u = { 3 * m, 2 * m, 1 * m };
fs_vector<si::length<si::kilometre>, 3> t = { 3 * km, 2 * km, 1 * km }; fixed_size_column_vector<si::length<si::kilometre>, 3> t = { 3 * km, 2 * km, 1 * km };
Having such definitions we can perform full dimensional analysis operations for the operations Having such definitions we can perform full dimensional analysis operations for the operations
allowed by the Linear Algebra rules. For example:: allowed by the Linear Algebra rules. For example::
std::cout << "v + u = " << v + u << "\n"; std::cout << "v + u = " << v + u << "\n";
std::cout << "v + t = " << v + t << "\n"; std::cout << "v + t = " << v + t << "\n";
std::cout << "t[m] = " << fs_vector<si::length<si::metre>, 3>(t) << "\n"; std::cout << "t[m] = " << fixed_size_column_vector<si::length<si::metre>, 3>(t) << "\n";
std::cout << "v * u = " << v * u << "\n"; std::cout << "v * u = " << v * u << "\n";
std::cout << "2 * m * v = " << 2 * m * v << "\n"; std::cout << "2 * m * v = " << 2 * m * v << "\n";
@@ -66,9 +66,9 @@ types provided to a `quantity` class template.
With this the above vector definitions can be rewritten as follows:: With this the above vector definitions can be rewritten as follows::
si::length<si::metre, fs_vector<int, 3>> v(fs_vector<int, 3>{ 1, 2, 3 }); si::length<si::metre, fixed_size_column_vector<int, 3>> v(fixed_size_column_vector<int, 3>{ 1, 2, 3 });
si::length<si::metre, fs_vector<int, 3>> u(fs_vector<int, 3>{ 3, 2, 1 }); si::length<si::metre, fixed_size_column_vector<int, 3>> u(fixed_size_column_vector<int, 3>{ 3, 2, 1 });
si::length<si::kilometre, fs_vector<int, 3>> t(fs_vector<int, 3>{ 3, 2, 1 }); si::length<si::kilometre, fixed_size_column_vector<int, 3>> t(fixed_size_column_vector<int, 3>{ 3, 2, 1 });
Now the same code doing basic Linear Algebra operations will provide the following Now the same code doing basic Linear Algebra operations will provide the following
output: output:

View File

@@ -57,8 +57,9 @@ if(NOT ${projectPrefix}LIBCXX)
glide_computer_example-aliases PRIVATE ${projectPrefix}NO_LITERALS ${projectPrefix}NO_REFERENCES glide_computer_example-aliases PRIVATE ${projectPrefix}NO_LITERALS ${projectPrefix}NO_REFERENCES
) )
# TODO uncomment the below when recipes in ConanCenter are fixed if(${projectPrefix}BUILD_LA)
# find_package(wg21_linear_algebra CONFIG REQUIRED) find_package(wg21_linear_algebra CONFIG REQUIRED)
# add_example(linear_algebra mp-units::core-fmt mp-units::core-io mp-units::si) add_example(linear_algebra mp-units::core-fmt mp-units::core-io mp-units::si)
# target_link_libraries(linear_algebra-aliases PRIVATE wg21_linear_algebra::wg21_linear_algebra) target_link_libraries(linear_algebra-aliases PRIVATE wg21_linear_algebra::wg21_linear_algebra)
endif()
endif() endif()

View File

@@ -27,12 +27,18 @@
#include <units/isq/si/speed.h> // IWYU pragma: keep #include <units/isq/si/speed.h> // IWYU pragma: keep
#include <units/quantity_io.h> #include <units/quantity_io.h>
#include <iostream> #include <iostream>
#include <linear_algebra.hpp> #include <matrix>
template<typename Rep = double>
using vector = STD_LA::fixed_size_column_vector<Rep, 3>;
template<typename Rep = double>
using matrix = STD_LA::fixed_size_matrix<Rep, 3, 3>;
namespace STD_LA { namespace STD_LA {
template<class ET, class OT> template<typename Rep>
std::ostream& operator<<(std::ostream& os, const vector<ET, OT>& v) std::ostream& operator<<(std::ostream& os, const ::vector<Rep>& v)
{ {
os << "|"; os << "|";
for (auto i = 0U; i < v.size(); ++i) { for (auto i = 0U; i < v.size(); ++i) {
@@ -42,8 +48,8 @@ std::ostream& operator<<(std::ostream& os, const vector<ET, OT>& v)
return os; return os;
} }
template<class ET, class OT> template<typename Rep>
std::ostream& operator<<(std::ostream& os, const matrix<ET, OT>& v) std::ostream& operator<<(std::ostream& os, const ::matrix<Rep>& v)
{ {
for (auto i = 0U; i < v.rows(); ++i) { for (auto i = 0U; i < v.rows(); ++i) {
os << "|"; os << "|";
@@ -61,18 +67,11 @@ namespace {
using namespace units::aliases::isq::si; using namespace units::aliases::isq::si;
template<typename Rep = double>
using vector = std::math::fs_vector<Rep, 3>;
template<typename Rep = double>
using matrix = std::math::fs_matrix<Rep, 3, 3>;
void vector_of_quantity_add() void vector_of_quantity_add()
{ {
std::cout << "\nvector_of_quantity_add:\n"; std::cout << "\nvector_of_quantity_add:\n";
vector<length::m<>> v = {m<>(1), m<>(2), m<>(3)}; vector<length::m<>> v = {m<>(4), m<>(8), m<>(12)};
vector<length::m<>> u = {m<>(3), m<>(2), m<>(1)}; vector<length::m<>> u = {m<>(3), m<>(2), m<>(1)};
vector<length::km<>> t = {km<>(3), km<>(2), km<>(1)}; vector<length::km<>> t = {km<>(3), km<>(2), km<>(1)};
@@ -85,35 +84,6 @@ void vector_of_quantity_add()
std::cout << "t[m] = " << vector<length::m<>>(t) << "\n"; std::cout << "t[m] = " << vector<length::m<>>(t) << "\n";
} }
void vector_of_quantity_multiply_same()
{
std::cout << "\nvector_of_quantity_multiply_same:\n";
vector<length::m<>> v = {m<>(1), m<>(2), m<>(3)};
vector<length::m<>> u = {m<>(3), m<>(2), m<>(1)};
std::cout << "v = " << v << "\n";
std::cout << "u = " << u << "\n";
std::cout << "v * u = " << v * u << "\n";
std::cout << "m<>(2) * v = " << m<>(2.) * v << "\n";
}
void vector_of_quantity_multiply_different()
{
std::cout << "\nvector_of_quantity_multiply_different:\n";
vector<force::N<>> v = {N<>(1), N<>(2), N<>(3)};
vector<length::m<>> u = {m<>(3), m<>(2), m<>(1)};
std::cout << "v = " << v << "\n";
std::cout << "u = " << u << "\n";
std::cout << "v * u = " << v * u << "\n";
std::cout << "N<>(2) * u = " << N<>(2.) * u << "\n";
std::cout << "2 * u = " << 2 * u << "\n";
}
void vector_of_quantity_divide_by_scalar() void vector_of_quantity_divide_by_scalar()
{ {
std::cout << "\nvector_of_quantity_divide_by_scalar:\n"; std::cout << "\nvector_of_quantity_divide_by_scalar:\n";
@@ -122,16 +92,13 @@ void vector_of_quantity_divide_by_scalar()
std::cout << "v = " << v << "\n"; std::cout << "v = " << v << "\n";
// TODO Uncomment when bug in the LA is fixed std::cout << "v / s<>(2) = " << v / s<>(2) << "\n";
// std::cout << "v / s<>(2) = " << v / s<>(2) << "\n"; std::cout << "v / 2 = " << v / 2 << "\n";
// std::cout << "v / 2 = " << v / 2 << "\n";
} }
void vector_of_quantity_tests() void vector_of_quantity_tests()
{ {
vector_of_quantity_add(); vector_of_quantity_add();
vector_of_quantity_multiply_same();
vector_of_quantity_multiply_different();
vector_of_quantity_divide_by_scalar(); vector_of_quantity_divide_by_scalar();
} }
@@ -150,37 +117,7 @@ void matrix_of_quantity_add()
std::cout << "v + u =\n" << v + u << "\n"; std::cout << "v + u =\n" << v + u << "\n";
std::cout << "v + t =\n" << v + t << "\n"; std::cout << "v + t =\n" << v + t << "\n";
// TODO Uncomment when fixed in the LA lib std::cout << "v[mm] =\n" << matrix<length::mm<>>(v) << "\n";
// std::cout << "v[mm] =\n" << matrix<length::mm<>>(v) << "\n";
}
void matrix_of_quantity_multiply_same()
{
std::cout << "\nmatrix_of_quantity_multiply_same:\n";
matrix<length::m<>> v = {{m<>(1), m<>(2), m<>(3)}, {m<>(4), m<>(5), m<>(6)}, {m<>(7), m<>(8), m<>(9)}};
vector<length::m<>> u = {m<>(3), m<>(2), m<>(1)};
std::cout << "v =\n" << v << "\n";
std::cout << "u =\n" << u << "\n";
std::cout << "v * u =\n" << v * u << "\n";
std::cout << "m<>(2) * u =\n" << m<>(2.) * u << "\n";
}
void matrix_of_quantity_multiply_different()
{
std::cout << "\nmatrix_of_quantity_multiply_different:\n";
vector<force::N<>> v = {N<>(1), N<>(2), N<>(3)};
matrix<length::m<>> u = {{m<>(1), m<>(2), m<>(3)}, {m<>(4), m<>(5), m<>(6)}, {m<>(7), m<>(8), m<>(9)}};
std::cout << "v =\n" << v << "\n";
std::cout << "u =\n" << u << "\n";
std::cout << "v * u =\n" << v * u << "\n";
std::cout << "N<>(2) * u =\n" << N<>(2.) * u << "\n";
std::cout << "2 * u =\n" << 2 * u << "\n";
} }
void matrix_of_quantity_divide_by_scalar() void matrix_of_quantity_divide_by_scalar()
@@ -191,16 +128,13 @@ void matrix_of_quantity_divide_by_scalar()
std::cout << "v =\n" << v << "\n"; std::cout << "v =\n" << v << "\n";
// TODO Uncomment when bug in the LA is fixed std::cout << "v / s<>(2) =\n" << v / s<>(2) << "\n";
// std::cout << "v / s<>(2) =\n" << v / s<>(2) << "\n"; std::cout << "v / 2 =\n" << v / 2 << "\n";
// std::cout << "v / 2 =\n" << v / 2 << "\n";
} }
void matrix_of_quantity_tests() void matrix_of_quantity_tests()
{ {
matrix_of_quantity_add(); matrix_of_quantity_add();
matrix_of_quantity_multiply_same();
matrix_of_quantity_multiply_different();
matrix_of_quantity_divide_by_scalar(); matrix_of_quantity_divide_by_scalar();
} }
@@ -216,7 +150,7 @@ void quantity_of_vector_add()
{ {
std::cout << "\nquantity_of_vector_add:\n"; std::cout << "\nquantity_of_vector_add:\n";
length_v<> v(vector<>{1, 2, 3}); length_v<> v(vector<>{4, 8, 12});
length_v<> u(vector<>{3, 2, 1}); length_v<> u(vector<>{3, 2, 1});
length_v<si::kilometre> t(vector<>{3, 2, 1}); length_v<si::kilometre> t(vector<>{3, 2, 1});
@@ -229,35 +163,6 @@ void quantity_of_vector_add()
std::cout << "t[m] = " << quantity_cast<si::metre>(t) << "\n"; std::cout << "t[m] = " << quantity_cast<si::metre>(t) << "\n";
} }
void quantity_of_vector_multiply_same()
{
std::cout << "\nquantity_of_vector_multiply_same:\n";
length_v<> v(vector<>{1, 2, 3});
length_v<> u(vector<>{3, 2, 1});
std::cout << "v = " << v << "\n";
std::cout << "u = " << u << "\n";
std::cout << "v * u = " << v * u << "\n";
std::cout << "m<>(2) * v = " << m<>(2.) * v << "\n";
}
void quantity_of_vector_multiply_different()
{
std::cout << "\nquantity_of_vector_multiply_different:\n";
force_v<> v(vector<>{1, 2, 3});
length_v<> u(vector<>{3, 2, 1});
std::cout << "v = " << v << "\n";
std::cout << "u = " << u << "\n";
std::cout << "v * u = " << v * u << "\n";
std::cout << "N<>(2) * u = " << N<>(2.) * u << "\n";
std::cout << "2 * u = " << 2 * u << "\n";
}
void quantity_of_vector_divide_by_scalar() void quantity_of_vector_divide_by_scalar()
{ {
std::cout << "\nquantity_of_vector_divide_by_scalar:\n"; std::cout << "\nquantity_of_vector_divide_by_scalar:\n";
@@ -266,16 +171,13 @@ void quantity_of_vector_divide_by_scalar()
std::cout << "v = " << v << "\n"; std::cout << "v = " << v << "\n";
// TODO Uncomment when bug in the LA is fixed std::cout << "v / s<>(2) = " << v / s<>(2) << "\n";
// std::cout << "v / s<>(2) = " << v / s<>(2) << "\n"; std::cout << "v / 2 = " << v / 2 << "\n";
// std::cout << "v / 2 = " << v / 2 << "\n";
} }
void quantity_of_vector_tests() void quantity_of_vector_tests()
{ {
quantity_of_vector_add(); quantity_of_vector_add();
quantity_of_vector_multiply_same();
quantity_of_vector_multiply_different();
quantity_of_vector_divide_by_scalar(); quantity_of_vector_divide_by_scalar();
} }
@@ -297,39 +199,10 @@ void quantity_of_matrix_add()
std::cout << "v + u =\n" << v + u << "\n"; std::cout << "v + u =\n" << v + u << "\n";
std::cout << "v + t =\n" << v + t << "\n"; std::cout << "v + t =\n" << v + t << "\n";
// TODO Uncomment when fixed in the LA lib // TODO Fix it
// std::cout << "v[mm] =\n" << matrix<length::mm<>>(v) << "\n"; // std::cout << "v[mm] =\n" << matrix<length::mm<>>(v) << "\n";
} }
void quantity_of_matrix_multiply_same()
{
std::cout << "\nquantity_of_matrix_multiply_same:\n";
length_m<> v(matrix<>{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}});
length_v<> u(vector<>{3, 2, 1});
std::cout << "v =\n" << v << "\n";
std::cout << "u =\n" << u << "\n";
std::cout << "v * u =\n" << v * u << "\n";
std::cout << "m<>(2) * u =\n" << m<>(2.) * u << "\n";
}
void quantity_of_matrix_multiply_different()
{
std::cout << "\nquantity_of_matrix_multiply_different:\n";
force_v<> v(vector<>{1, 2, 3});
length_m<> u(matrix<>{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}});
std::cout << "v =\n" << v << "\n";
std::cout << "u =\n" << u << "\n";
std::cout << "v * u =\n" << v * u << "\n";
std::cout << "N<>(2) * u =\n" << N<>(2.) * u << "\n";
std::cout << "2 * u =\n" << 2 * u << "\n";
}
void quantity_of_matrix_divide_by_scalar() void quantity_of_matrix_divide_by_scalar()
{ {
std::cout << "\nquantity_of_matrix_divide_by_scalar:\n"; std::cout << "\nquantity_of_matrix_divide_by_scalar:\n";
@@ -338,16 +211,13 @@ void quantity_of_matrix_divide_by_scalar()
std::cout << "v =\n" << v << "\n"; std::cout << "v =\n" << v << "\n";
// TODO Uncomment when bug in the LA is fixed std::cout << "v / s<>(2) =\n" << v / s<>(2) << "\n";
// std::cout << "v / s<>(2) =\n" << v / s<>(2) << "\n"; std::cout << "v / 2 =\n" << v / 2 << "\n";
// std::cout << "v / 2 =\n" << v / 2 << "\n";
} }
void quantity_of_matrix_tests() void quantity_of_matrix_tests()
{ {
quantity_of_matrix_add(); quantity_of_matrix_add();
quantity_of_matrix_multiply_same();
quantity_of_matrix_multiply_different();
quantity_of_matrix_divide_by_scalar(); quantity_of_matrix_divide_by_scalar();
} }

View File

@@ -56,8 +56,9 @@ if(NOT ${projectPrefix}LIBCXX)
glide_computer_example-literals PRIVATE ${projectPrefix}NO_REFERENCES ${projectPrefix}NO_ALIASES glide_computer_example-literals PRIVATE ${projectPrefix}NO_REFERENCES ${projectPrefix}NO_ALIASES
) )
# TODO uncomment the below when recipes in ConanCenter are fixed if(${projectPrefix}BUILD_LA)
# find_package(wg21_linear_algebra CONFIG REQUIRED) find_package(wg21_linear_algebra CONFIG REQUIRED)
# add_example(linear_algebra mp-units::core-fmt mp-units::core-io mp-units::si) add_example(linear_algebra mp-units::core-fmt mp-units::core-io mp-units::si)
# target_link_libraries(linear_algebra-literals PRIVATE wg21_linear_algebra::wg21_linear_algebra) target_link_libraries(linear_algebra-literals PRIVATE wg21_linear_algebra::wg21_linear_algebra)
endif()
endif() endif()

View File

@@ -27,12 +27,18 @@
#include <units/isq/si/speed.h> // IWYU pragma: keep #include <units/isq/si/speed.h> // IWYU pragma: keep
#include <units/quantity_io.h> #include <units/quantity_io.h>
#include <iostream> #include <iostream>
#include <linear_algebra.hpp> #include <matrix>
template<typename Rep = double>
using vector = STD_LA::fixed_size_column_vector<Rep, 3>;
template<typename Rep = double>
using matrix = STD_LA::fixed_size_matrix<Rep, 3, 3>;
namespace STD_LA { namespace STD_LA {
template<class ET, class OT> template<typename Rep>
std::ostream& operator<<(std::ostream& os, const vector<ET, OT>& v) std::ostream& operator<<(std::ostream& os, const ::vector<Rep>& v)
{ {
os << "|"; os << "|";
for (auto i = 0U; i < v.size(); ++i) { for (auto i = 0U; i < v.size(); ++i) {
@@ -42,8 +48,8 @@ std::ostream& operator<<(std::ostream& os, const vector<ET, OT>& v)
return os; return os;
} }
template<class ET, class OT> template<typename Rep>
std::ostream& operator<<(std::ostream& os, const matrix<ET, OT>& v) std::ostream& operator<<(std::ostream& os, const ::matrix<Rep>& v)
{ {
for (auto i = 0U; i < v.rows(); ++i) { for (auto i = 0U; i < v.rows(); ++i) {
os << "|"; os << "|";
@@ -62,18 +68,11 @@ namespace {
using namespace units::isq; using namespace units::isq;
using namespace units::isq::si::literals; using namespace units::isq::si::literals;
template<typename Rep = double>
using vector = std::math::fs_vector<Rep, 3>;
template<typename Rep = double>
using matrix = std::math::fs_matrix<Rep, 3, 3>;
void vector_of_quantity_add() void vector_of_quantity_add()
{ {
std::cout << "\nvector_of_quantity_add:\n"; std::cout << "\nvector_of_quantity_add:\n";
vector<si::length<si::metre>> v = {1_q_m, 2_q_m, 3_q_m}; vector<si::length<si::metre>> v = {4_q_m, 8_q_m, 12_q_m};
vector<si::length<si::metre>> u = {3_q_m, 2_q_m, 1_q_m}; vector<si::length<si::metre>> u = {3_q_m, 2_q_m, 1_q_m};
vector<si::length<si::kilometre>> t = {3_q_km, 2_q_km, 1_q_km}; vector<si::length<si::kilometre>> t = {3_q_km, 2_q_km, 1_q_km};
@@ -86,35 +85,6 @@ void vector_of_quantity_add()
std::cout << "t[m] = " << vector<si::length<si::metre>>(t) << "\n"; std::cout << "t[m] = " << vector<si::length<si::metre>>(t) << "\n";
} }
void vector_of_quantity_multiply_same()
{
std::cout << "\nvector_of_quantity_multiply_same:\n";
vector<si::length<si::metre>> v = {1_q_m, 2_q_m, 3_q_m};
vector<si::length<si::metre>> u = {3_q_m, 2_q_m, 1_q_m};
std::cout << "v = " << v << "\n";
std::cout << "u = " << u << "\n";
std::cout << "v * u = " << v * u << "\n";
std::cout << "2_q_m * v = " << 2._q_m * v << "\n";
}
void vector_of_quantity_multiply_different()
{
std::cout << "\nvector_of_quantity_multiply_different:\n";
vector<si::force<si::newton>> v = {1_q_N, 2_q_N, 3_q_N};
vector<si::length<si::metre>> u = {3_q_m, 2_q_m, 1_q_m};
std::cout << "v = " << v << "\n";
std::cout << "u = " << u << "\n";
std::cout << "v * u = " << v * u << "\n";
std::cout << "2_q_N * u = " << 2._q_N * u << "\n";
std::cout << "2 * u = " << 2 * u << "\n";
}
void vector_of_quantity_divide_by_scalar() void vector_of_quantity_divide_by_scalar()
{ {
std::cout << "\nvector_of_quantity_divide_by_scalar:\n"; std::cout << "\nvector_of_quantity_divide_by_scalar:\n";
@@ -123,16 +93,13 @@ void vector_of_quantity_divide_by_scalar()
std::cout << "v = " << v << "\n"; std::cout << "v = " << v << "\n";
// TODO Uncomment when bug in the LA is fixed std::cout << "v / 2_q_s = " << v / quantity_cast<double>(2_q_s) << "\n";
// std::cout << "v / 2_q_s = " << v / 2_q_s << "\n"; std::cout << "v / 2 = " << v / 2 << "\n";
// std::cout << "v / 2 = " << v / 2 << "\n";
} }
void vector_of_quantity_tests() void vector_of_quantity_tests()
{ {
vector_of_quantity_add(); vector_of_quantity_add();
vector_of_quantity_multiply_same();
vector_of_quantity_multiply_different();
vector_of_quantity_divide_by_scalar(); vector_of_quantity_divide_by_scalar();
} }
@@ -151,37 +118,7 @@ void matrix_of_quantity_add()
std::cout << "v + u =\n" << v + u << "\n"; std::cout << "v + u =\n" << v + u << "\n";
std::cout << "v + t =\n" << v + t << "\n"; std::cout << "v + t =\n" << v + t << "\n";
// TODO Uncomment when fixed in the LA lib std::cout << "v[mm] =\n" << matrix<si::length<si::millimetre>>(v) << "\n";
// std::cout << "v[mm] =\n" << matrix<si::length<si::millimetre>>(v) << "\n";
}
void matrix_of_quantity_multiply_same()
{
std::cout << "\nmatrix_of_quantity_multiply_same:\n";
matrix<si::length<si::metre>> v = {{1_q_m, 2_q_m, 3_q_m}, {4_q_m, 5_q_m, 6_q_m}, {7_q_m, 8_q_m, 9_q_m}};
vector<si::length<si::metre>> u = {3_q_m, 2_q_m, 1_q_m};
std::cout << "v =\n" << v << "\n";
std::cout << "u =\n" << u << "\n";
std::cout << "v * u =\n" << v * u << "\n";
std::cout << "2_q_m * u =\n" << 2._q_m * u << "\n";
}
void matrix_of_quantity_multiply_different()
{
std::cout << "\nmatrix_of_quantity_multiply_different:\n";
vector<si::force<si::newton>> v = {1_q_N, 2_q_N, 3_q_N};
matrix<si::length<si::metre>> u = {{1_q_m, 2_q_m, 3_q_m}, {4_q_m, 5_q_m, 6_q_m}, {7_q_m, 8_q_m, 9_q_m}};
std::cout << "v =\n" << v << "\n";
std::cout << "u =\n" << u << "\n";
std::cout << "v * u =\n" << v * u << "\n";
std::cout << "2_q_N * u =\n" << 2._q_N * u << "\n";
std::cout << "2 * u =\n" << 2 * u << "\n";
} }
void matrix_of_quantity_divide_by_scalar() void matrix_of_quantity_divide_by_scalar()
@@ -192,16 +129,13 @@ void matrix_of_quantity_divide_by_scalar()
std::cout << "v =\n" << v << "\n"; std::cout << "v =\n" << v << "\n";
// TODO Uncomment when bug in the LA is fixed std::cout << "v / 2_q_s =\n" << v / quantity_cast<double>(2_q_s) << "\n";
// std::cout << "v / 2_q_s =\n" << v / 2_q_s << "\n"; std::cout << "v / 2 =\n" << v / 2 << "\n";
// std::cout << "v / 2 =\n" << v / 2 << "\n";
} }
void matrix_of_quantity_tests() void matrix_of_quantity_tests()
{ {
matrix_of_quantity_add(); matrix_of_quantity_add();
matrix_of_quantity_multiply_same();
matrix_of_quantity_multiply_different();
matrix_of_quantity_divide_by_scalar(); matrix_of_quantity_divide_by_scalar();
} }
@@ -215,7 +149,7 @@ void quantity_of_vector_add()
{ {
std::cout << "\nquantity_of_vector_add:\n"; std::cout << "\nquantity_of_vector_add:\n";
length_v<> v(vector<>{1, 2, 3}); length_v<> v(vector<>{4, 8, 12});
length_v<> u(vector<>{3, 2, 1}); length_v<> u(vector<>{3, 2, 1});
length_v<si::kilometre> t(vector<>{3, 2, 1}); length_v<si::kilometre> t(vector<>{3, 2, 1});
@@ -228,35 +162,6 @@ void quantity_of_vector_add()
std::cout << "t[m] = " << quantity_cast<si::metre>(t) << "\n"; std::cout << "t[m] = " << quantity_cast<si::metre>(t) << "\n";
} }
void quantity_of_vector_multiply_same()
{
std::cout << "\nquantity_of_vector_multiply_same:\n";
length_v<> v(vector<>{1, 2, 3});
length_v<> u(vector<>{3, 2, 1});
std::cout << "v = " << v << "\n";
std::cout << "u = " << u << "\n";
std::cout << "v * u = " << v * u << "\n";
std::cout << "2_q_m * v = " << 2._q_m * v << "\n";
}
void quantity_of_vector_multiply_different()
{
std::cout << "\nquantity_of_vector_multiply_different:\n";
force_v<> v(vector<>{1, 2, 3});
length_v<> u(vector<>{3, 2, 1});
std::cout << "v = " << v << "\n";
std::cout << "u = " << u << "\n";
std::cout << "v * u = " << v * u << "\n";
std::cout << "2_q_N * u = " << 2._q_N * u << "\n";
std::cout << "2 * u = " << 2 * u << "\n";
}
void quantity_of_vector_divide_by_scalar() void quantity_of_vector_divide_by_scalar()
{ {
std::cout << "\nquantity_of_vector_divide_by_scalar:\n"; std::cout << "\nquantity_of_vector_divide_by_scalar:\n";
@@ -265,16 +170,13 @@ void quantity_of_vector_divide_by_scalar()
std::cout << "v = " << v << "\n"; std::cout << "v = " << v << "\n";
// TODO Uncomment when bug in the LA is fixed std::cout << "v / 2_q_s = " << v / 2_q_s << "\n";
// std::cout << "v / 2_q_s = " << v / 2_q_s << "\n"; std::cout << "v / 2 = " << v / 2 << "\n";
// std::cout << "v / 2 = " << v / 2 << "\n";
} }
void quantity_of_vector_tests() void quantity_of_vector_tests()
{ {
quantity_of_vector_add(); quantity_of_vector_add();
quantity_of_vector_multiply_same();
quantity_of_vector_multiply_different();
quantity_of_vector_divide_by_scalar(); quantity_of_vector_divide_by_scalar();
} }
@@ -296,39 +198,10 @@ void quantity_of_matrix_add()
std::cout << "v + u =\n" << v + u << "\n"; std::cout << "v + u =\n" << v + u << "\n";
std::cout << "v + t =\n" << v + t << "\n"; std::cout << "v + t =\n" << v + t << "\n";
// TODO Uncomment when fixed in the LA lib // TODO Fix it
// std::cout << "v[mm] =\n" << matrix<si::length<si::millimetre>>(v) << "\n"; // std::cout << "v[mm] =\n" << matrix<si::length<si::millimetre>>(v) << "\n";
} }
void quantity_of_matrix_multiply_same()
{
std::cout << "\nquantity_of_matrix_multiply_same:\n";
length_m<> v(matrix<>{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}});
length_v<> u(vector<>{3, 2, 1});
std::cout << "v =\n" << v << "\n";
std::cout << "u =\n" << u << "\n";
std::cout << "v * u =\n" << v * u << "\n";
std::cout << "2_q_m * u =\n" << 2._q_m * u << "\n";
}
void quantity_of_matrix_multiply_different()
{
std::cout << "\nquantity_of_matrix_multiply_different:\n";
force_v<> v(vector<>{1, 2, 3});
length_m<> u(matrix<>{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}});
std::cout << "v =\n" << v << "\n";
std::cout << "u =\n" << u << "\n";
std::cout << "v * u =\n" << v * u << "\n";
std::cout << "2_q_N * u =\n" << 2._q_N * u << "\n";
std::cout << "2 * u =\n" << 2 * u << "\n";
}
void quantity_of_matrix_divide_by_scalar() void quantity_of_matrix_divide_by_scalar()
{ {
std::cout << "\nquantity_of_matrix_divide_by_scalar:\n"; std::cout << "\nquantity_of_matrix_divide_by_scalar:\n";
@@ -337,16 +210,13 @@ void quantity_of_matrix_divide_by_scalar()
std::cout << "v =\n" << v << "\n"; std::cout << "v =\n" << v << "\n";
// TODO Uncomment when bug in the LA is fixed std::cout << "v / 2_q_s =\n" << v / 2_q_s << "\n";
// std::cout << "v / 2_q_s =\n" << v / 2_q_s << "\n"; std::cout << "v / 2 =\n" << v / 2 << "\n";
// std::cout << "v / 2 =\n" << v / 2 << "\n";
} }
void quantity_of_matrix_tests() void quantity_of_matrix_tests()
{ {
quantity_of_matrix_add(); quantity_of_matrix_add();
quantity_of_matrix_multiply_same();
quantity_of_matrix_multiply_different();
quantity_of_matrix_divide_by_scalar(); quantity_of_matrix_divide_by_scalar();
} }

View File

@@ -56,8 +56,9 @@ if(NOT ${projectPrefix}LIBCXX)
glide_computer_example-references PRIVATE ${projectPrefix}NO_LITERALS ${projectPrefix}NO_ALIASES glide_computer_example-references PRIVATE ${projectPrefix}NO_LITERALS ${projectPrefix}NO_ALIASES
) )
# TODO uncomment the below when recipes in ConanCenter are fixed if(${projectPrefix}BUILD_LA)
# find_package(wg21_linear_algebra CONFIG REQUIRED) find_package(wg21_linear_algebra CONFIG REQUIRED)
# add_example(linear_algebra mp-units::core-fmt mp-units::core-io mp-units::si) add_example(linear_algebra mp-units::core-fmt mp-units::core-io mp-units::si)
# target_link_libraries(linear_algebra-references PRIVATE wg21_linear_algebra::wg21_linear_algebra) target_link_libraries(linear_algebra-references PRIVATE wg21_linear_algebra::wg21_linear_algebra)
endif()
endif() endif()

View File

@@ -27,12 +27,18 @@
#include <units/isq/si/speed.h> // IWYU pragma: keep #include <units/isq/si/speed.h> // IWYU pragma: keep
#include <units/quantity_io.h> #include <units/quantity_io.h>
#include <iostream> #include <iostream>
#include <linear_algebra.hpp> #include <matrix>
template<typename Rep = double>
using vector = STD_LA::fixed_size_column_vector<Rep, 3>;
template<typename Rep = double>
using matrix = STD_LA::fixed_size_matrix<Rep, 3, 3>;
namespace STD_LA { namespace STD_LA {
template<class ET, class OT> template<typename Rep>
std::ostream& operator<<(std::ostream& os, const vector<ET, OT>& v) std::ostream& operator<<(std::ostream& os, const ::vector<Rep>& v)
{ {
os << "|"; os << "|";
for (auto i = 0U; i < v.size(); ++i) { for (auto i = 0U; i < v.size(); ++i) {
@@ -42,8 +48,8 @@ std::ostream& operator<<(std::ostream& os, const vector<ET, OT>& v)
return os; return os;
} }
template<class ET, class OT> template<typename Rep>
std::ostream& operator<<(std::ostream& os, const matrix<ET, OT>& v) std::ostream& operator<<(std::ostream& os, const ::matrix<Rep>& v)
{ {
for (auto i = 0U; i < v.rows(); ++i) { for (auto i = 0U; i < v.rows(); ++i) {
os << "|"; os << "|";
@@ -61,19 +67,13 @@ namespace {
using namespace units::isq; using namespace units::isq;
using namespace units::isq::si::length_references; using namespace units::isq::si::length_references;
using namespace units::isq::si::force_references; using namespace units::isq::si::time_references;
template<typename Rep = double>
using vector = std::math::fs_vector<Rep, 3>;
template<typename Rep = double>
using matrix = std::math::fs_matrix<Rep, 3, 3>;
void vector_of_quantity_add() void vector_of_quantity_add()
{ {
std::cout << "\nvector_of_quantity_add:\n"; std::cout << "\nvector_of_quantity_add:\n";
vector<si::length<si::metre>> v = {1 * m, 2 * m, 3 * m}; vector<si::length<si::metre>> v = {4 * m, 8 * m, 12 * m};
vector<si::length<si::metre>> u = {3 * m, 2 * m, 1 * m}; vector<si::length<si::metre>> u = {3 * m, 2 * m, 1 * m};
vector<si::length<si::kilometre>> t = {3 * km, 2 * km, 1 * km}; vector<si::length<si::kilometre>> t = {3 * km, 2 * km, 1 * km};
@@ -86,35 +86,6 @@ void vector_of_quantity_add()
std::cout << "t[m] = " << vector<si::length<si::metre>>(t) << "\n"; std::cout << "t[m] = " << vector<si::length<si::metre>>(t) << "\n";
} }
void vector_of_quantity_multiply_same()
{
std::cout << "\nvector_of_quantity_multiply_same:\n";
vector<si::length<si::metre>> v = {1 * m, 2 * m, 3 * m};
vector<si::length<si::metre>> u = {3 * m, 2 * m, 1 * m};
std::cout << "v = " << v << "\n";
std::cout << "u = " << u << "\n";
std::cout << "v * u = " << v * u << "\n";
std::cout << "2 * m * v = " << 2. * m * v << "\n";
}
void vector_of_quantity_multiply_different()
{
std::cout << "\nvector_of_quantity_multiply_different:\n";
vector<si::force<si::newton>> v = {1 * N, 2 * N, 3 * N};
vector<si::length<si::metre>> u = {3 * m, 2 * m, 1 * m};
std::cout << "v = " << v << "\n";
std::cout << "u = " << u << "\n";
std::cout << "v * u = " << v * u << "\n";
std::cout << "2 * N * u = " << 2. * N * u << "\n";
std::cout << "2 * u = " << 2 * u << "\n";
}
void vector_of_quantity_divide_by_scalar() void vector_of_quantity_divide_by_scalar()
{ {
std::cout << "\nvector_of_quantity_divide_by_scalar:\n"; std::cout << "\nvector_of_quantity_divide_by_scalar:\n";
@@ -123,16 +94,13 @@ void vector_of_quantity_divide_by_scalar()
std::cout << "v = " << v << "\n"; std::cout << "v = " << v << "\n";
// TODO Uncomment when bug in the LA is fixed std::cout << "v / (2 * s) = " << v / (2 * s) << "\n";
// std::cout << "v / (2 * s) = " << v / (2 * s) << "\n"; std::cout << "v / 2 = " << v / 2 << "\n";
// std::cout << "v / 2 = " << v / 2 << "\n";
} }
void vector_of_quantity_tests() void vector_of_quantity_tests()
{ {
vector_of_quantity_add(); vector_of_quantity_add();
vector_of_quantity_multiply_same();
vector_of_quantity_multiply_different();
vector_of_quantity_divide_by_scalar(); vector_of_quantity_divide_by_scalar();
} }
@@ -151,37 +119,7 @@ void matrix_of_quantity_add()
std::cout << "v + u =\n" << v + u << "\n"; std::cout << "v + u =\n" << v + u << "\n";
std::cout << "v + t =\n" << v + t << "\n"; std::cout << "v + t =\n" << v + t << "\n";
// TODO Uncomment when fixed in the LA lib std::cout << "v[mm] =\n" << matrix<si::length<si::millimetre>>(v) << "\n";
// std::cout << "v[mm] =\n" << matrix<si::length<si::millimetre>>(v) << "\n";
}
void matrix_of_quantity_multiply_same()
{
std::cout << "\nmatrix_of_quantity_multiply_same:\n";
matrix<si::length<si::metre>> v = {{1 * m, 2 * m, 3 * m}, {4 * m, 5 * m, 6 * m}, {7 * m, 8 * m, 9 * m}};
vector<si::length<si::metre>> u = {3 * m, 2 * m, 1 * m};
std::cout << "v =\n" << v << "\n";
std::cout << "u =\n" << u << "\n";
std::cout << "v * u =\n" << v * u << "\n";
std::cout << "2 * m * u =\n" << 2. * m * u << "\n";
}
void matrix_of_quantity_multiply_different()
{
std::cout << "\nmatrix_of_quantity_multiply_different:\n";
vector<si::force<si::newton>> v = {1 * N, 2 * N, 3 * N};
matrix<si::length<si::metre>> u = {{1 * m, 2 * m, 3 * m}, {4 * m, 5 * m, 6 * m}, {7 * m, 8 * m, 9 * m}};
std::cout << "v =\n" << v << "\n";
std::cout << "u =\n" << u << "\n";
std::cout << "v * u =\n" << v * u << "\n";
std::cout << "2 * N * u =\n" << 2. * N * u << "\n";
std::cout << "2 * u =\n" << 2 * u << "\n";
} }
void matrix_of_quantity_divide_by_scalar() void matrix_of_quantity_divide_by_scalar()
@@ -192,16 +130,13 @@ void matrix_of_quantity_divide_by_scalar()
std::cout << "v =\n" << v << "\n"; std::cout << "v =\n" << v << "\n";
// TODO Uncomment when bug in the LA is fixed std::cout << "v / (2 * s) =\n" << v / (2 * s) << "\n";
// std::cout << "v / (2 * s) =\n" << v / (2 * s) << "\n"; std::cout << "v / 2 =\n" << v / 2 << "\n";
// std::cout << "v / 2 =\n" << v / 2 << "\n";
} }
void matrix_of_quantity_tests() void matrix_of_quantity_tests()
{ {
matrix_of_quantity_add(); matrix_of_quantity_add();
matrix_of_quantity_multiply_same();
matrix_of_quantity_multiply_different();
matrix_of_quantity_divide_by_scalar(); matrix_of_quantity_divide_by_scalar();
} }
@@ -215,7 +150,7 @@ void quantity_of_vector_add()
{ {
std::cout << "\nquantity_of_vector_add:\n"; std::cout << "\nquantity_of_vector_add:\n";
length_v<> v(vector<>{1, 2, 3}); length_v<> v(vector<>{4, 8, 12});
length_v<> u(vector<>{3, 2, 1}); length_v<> u(vector<>{3, 2, 1});
length_v<si::kilometre> t(vector<>{3, 2, 1}); length_v<si::kilometre> t(vector<>{3, 2, 1});
@@ -228,35 +163,6 @@ void quantity_of_vector_add()
std::cout << "t[m] = " << quantity_cast<si::metre>(t) << "\n"; std::cout << "t[m] = " << quantity_cast<si::metre>(t) << "\n";
} }
void quantity_of_vector_multiply_same()
{
std::cout << "\nquantity_of_vector_multiply_same:\n";
length_v<> v(vector<>{1, 2, 3});
length_v<> u(vector<>{3, 2, 1});
std::cout << "v = " << v << "\n";
std::cout << "u = " << u << "\n";
std::cout << "v * u = " << v * u << "\n";
std::cout << "2 * m * v = " << 2. * m * v << "\n";
}
void quantity_of_vector_multiply_different()
{
std::cout << "\nquantity_of_vector_multiply_different:\n";
force_v<> v(vector<>{1, 2, 3});
length_v<> u(vector<>{3, 2, 1});
std::cout << "v = " << v << "\n";
std::cout << "u = " << u << "\n";
std::cout << "v * u = " << v * u << "\n";
std::cout << "2 * N * u = " << 2. * N * u << "\n";
std::cout << "2 * u = " << 2 * u << "\n";
}
void quantity_of_vector_divide_by_scalar() void quantity_of_vector_divide_by_scalar()
{ {
std::cout << "\nquantity_of_vector_divide_by_scalar:\n"; std::cout << "\nquantity_of_vector_divide_by_scalar:\n";
@@ -265,16 +171,13 @@ void quantity_of_vector_divide_by_scalar()
std::cout << "v = " << v << "\n"; std::cout << "v = " << v << "\n";
// TODO Uncomment when bug in the LA is fixed std::cout << "v / (2 * s) = " << v / (2 * s) << "\n";
// std::cout << "v / 2 * s = " << v / 2 * s << "\n"; std::cout << "v / 2 = " << v / 2 << "\n";
// std::cout << "v / 2 = " << v / 2 << "\n";
} }
void quantity_of_vector_tests() void quantity_of_vector_tests()
{ {
quantity_of_vector_add(); quantity_of_vector_add();
quantity_of_vector_multiply_same();
quantity_of_vector_multiply_different();
quantity_of_vector_divide_by_scalar(); quantity_of_vector_divide_by_scalar();
} }
@@ -296,39 +199,10 @@ void quantity_of_matrix_add()
std::cout << "v + u =\n" << v + u << "\n"; std::cout << "v + u =\n" << v + u << "\n";
std::cout << "v + t =\n" << v + t << "\n"; std::cout << "v + t =\n" << v + t << "\n";
// TODO Uncomment when fixed in the LA lib // TODO Fix it
// std::cout << "v[mm] =\n" << matrix<si::length<si::millimetre>>(v) << "\n"; // std::cout << "v[mm] =\n" << matrix<si::length<si::millimetre>>(v) << "\n";
} }
void quantity_of_matrix_multiply_same()
{
std::cout << "\nquantity_of_matrix_multiply_same:\n";
length_m<> v(matrix<>{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}});
length_v<> u(vector<>{3, 2, 1});
std::cout << "v =\n" << v << "\n";
std::cout << "u =\n" << u << "\n";
std::cout << "v * u =\n" << v * u << "\n";
std::cout << "2 * m * u =\n" << 2. * m * u << "\n";
}
void quantity_of_matrix_multiply_different()
{
std::cout << "\nquantity_of_matrix_multiply_different:\n";
force_v<> v(vector<>{1, 2, 3});
length_m<> u(matrix<>{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}});
std::cout << "v =\n" << v << "\n";
std::cout << "u =\n" << u << "\n";
std::cout << "v * u =\n" << v * u << "\n";
std::cout << "2 * N * u =\n" << 2. * N * u << "\n";
std::cout << "2 * u =\n" << 2 * u << "\n";
}
void quantity_of_matrix_divide_by_scalar() void quantity_of_matrix_divide_by_scalar()
{ {
std::cout << "\nquantity_of_matrix_divide_by_scalar:\n"; std::cout << "\nquantity_of_matrix_divide_by_scalar:\n";
@@ -337,16 +211,13 @@ void quantity_of_matrix_divide_by_scalar()
std::cout << "v =\n" << v << "\n"; std::cout << "v =\n" << v << "\n";
// TODO Uncomment when bug in the LA is fixed std::cout << "v / (2 * s) =\n" << v / (2 * s) << "\n";
// std::cout << "v / (2 * s) =\n" << v / (2 * s) << "\n"; std::cout << "v / 2 =\n" << v / 2 << "\n";
// std::cout << "v / 2 =\n" << v / 2 << "\n";
} }
void quantity_of_matrix_tests() void quantity_of_matrix_tests()
{ {
quantity_of_matrix_add(); quantity_of_matrix_add();
quantity_of_matrix_multiply_same();
quantity_of_matrix_multiply_different();
quantity_of_matrix_divide_by_scalar(); quantity_of_matrix_divide_by_scalar();
} }

View File

@@ -28,6 +28,9 @@ set(projectPrefix UNITS_)
option(${projectPrefix}AS_SYSTEM_HEADERS "Exports library as system headers" OFF) option(${projectPrefix}AS_SYSTEM_HEADERS "Exports library as system headers" OFF)
message(STATUS "${projectPrefix}AS_SYSTEM_HEADERS: ${${projectPrefix}AS_SYSTEM_HEADERS}") message(STATUS "${projectPrefix}AS_SYSTEM_HEADERS: ${${projectPrefix}AS_SYSTEM_HEADERS}")
option(${projectPrefix}BUILD_LA "Build code depending on the linear algebra library" ON)
message(STATUS "${projectPrefix}BUILD_LA: ${${projectPrefix}BUILD_LA}")
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake") list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
include(AddUnitsModule) include(AddUnitsModule)

View File

@@ -401,8 +401,11 @@ concept castable_number_ = // exposition only
template<typename T> template<typename T>
concept scalable_ = // exposition only concept scalable_ = // exposition only
castable_number_<T> || (requires { typename T::value_type; } && castable_number_<typename T::value_type> && castable_number_<T> ||
scalable_number_<T, std::common_type_t<typename T::value_type, std::intmax_t>>); (requires { typename T::value_type; } && castable_number_<typename T::value_type> &&
scalable_number_<T, std::common_type_t<typename T::value_type, std::intmax_t>>) ||
(requires { typename T::element_type; } && castable_number_<typename T::element_type> &&
scalable_number_<T, std::common_type_t<typename T::element_type, std::intmax_t>>);
template<typename T, typename U> template<typename T, typename U>
concept scalable_with_ = // exposition only concept scalable_with_ = // exposition only
@@ -420,6 +423,12 @@ inline constexpr bool is_wrapped_quantity<T> =
Quantity<typename T::value_type> || QuantityLike<typename T::value_type> || Quantity<typename T::value_type> || QuantityLike<typename T::value_type> ||
is_wrapped_quantity<typename T::value_type>; is_wrapped_quantity<typename T::value_type>;
template<typename T>
requires requires { typename T::element_type; }
inline constexpr bool is_wrapped_quantity<T> =
Quantity<typename T::element_type> || QuantityLike<typename T::element_type> ||
is_wrapped_quantity<typename T::element_type>;
template<typename T> template<typename T>
requires requires { typename T::quantity_type; } requires requires { typename T::quantity_type; }
inline constexpr bool is_wrapped_quantity<T> = Quantity<typename T::quantity_type>; inline constexpr bool is_wrapped_quantity<T> = Quantity<typename T::quantity_type>;
@@ -429,8 +438,9 @@ inline constexpr bool is_wrapped_quantity<T> = Quantity<typename T::quantity_typ
/** /**
* @brief A concept matching types that wrap quantity objects. * @brief A concept matching types that wrap quantity objects.
* *
* Satisfied by all wrapper types that satisfy `Quantity<typename T::value_type>` * Satisfied by all wrapper types that satisfy `Quantity<typename T::value_type>` or
* recursively (i.e. `std::optional<si::length<si::metre>>`). * `Quantity<typename T::element_type>` recursively
* (i.e. `std::optional<si::length<si::metre>>`).
*/ */
template<typename T> template<typename T>
concept wrapped_quantity_ = // exposition only concept wrapped_quantity_ = // exposition only

View File

@@ -44,6 +44,10 @@ template<typename T>
requires requires { typename T::value_type; } requires requires { typename T::value_type; }
inline constexpr bool treat_as_floating_point<T> = treat_as_floating_point<typename T::value_type>; inline constexpr bool treat_as_floating_point<T> = treat_as_floating_point<typename T::value_type>;
template<typename T>
requires requires { typename T::element_type; }
inline constexpr bool treat_as_floating_point<T> = treat_as_floating_point<typename T::element_type>;
/** /**
* @brief A type trait that defines zero, one, min, and max for a representation type * @brief A type trait that defines zero, one, min, and max for a representation type
* *

View File

@@ -83,6 +83,16 @@ struct cast_traits<From, To> {
using rep_type = std::common_type_t<From, To>; using rep_type = std::common_type_t<From, To>;
}; };
template<typename From, typename To>
requires(!common_type_with_<std::common_type_t<From, To>, std::intmax_t> &&
scalable_number_<std::common_type_t<From, To>, std::intmax_t> &&
requires { typename std::common_type_t<From, To>::element_type; } &&
common_type_with_<typename std::common_type_t<From, To>::element_type, std::intmax_t>)
struct cast_traits<From, To> {
using ratio_type = std::common_type_t<typename std::common_type_t<From, To>::element_type, std::intmax_t>;
using rep_type = std::common_type_t<From, To>;
};
} // namespace detail } // namespace detail
/** /**