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
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
def _skip_docs(self):
@@ -114,9 +118,10 @@ class MPUnitsConan(ConanFile):
def build_requirements(self):
if self._build_all:
self.test_requires("catch2/3.1.0")
self.test_requires("wg21-linear_algebra/0.7.3")
if not self._skip_docs:
self.tool_requires("doxygen/1.9.4")
if not self._skip_la:
self.test_requires("wg21-linear_algebra/0.7.3")
if not self._skip_docs:
self.tool_requires("doxygen/1.9.4")
def validate(self):
check_min_cppstd(self, self._min_cppstd)
@@ -140,6 +145,7 @@ class MPUnitsConan(ConanFile):
def generate(self):
tc = CMakeToolchain(self)
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_USE_LIBFMT"] = self._use_libfmt
tc.generate()

View File

@@ -146,8 +146,8 @@ Specifies how :ref:`design/downcasting:The Downcasting Facility` works:
Conan Configuration Properties
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
build_all
+++++++++
user.build:all
++++++++++++++
**Values**: ``True``/``False``
@@ -158,14 +158,24 @@ To support this it requires some additional Conan build dependencies described i
`Repository Structure and Dependencies`_.
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``
**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.
CMake Options
@@ -181,6 +191,16 @@ UNITS_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
++++++++++++++++
@@ -414,8 +434,8 @@ In case you would like to build all the source code (with unit tests and example
you should:
1. Use the *CMakeLists.txt* from the top-level directory.
2. Run Conan with `build_all`_ = ``True``
(use ``-o build_docs=False`` if you want to skip the documentation generation).
2. Run Conan with `user.build:all`_ = ``True``
(use ``-c user.build:skip_docs=True`` if you want to skip the documentation generation).
.. 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.
2. Obtain Python dependencies.
3. Run Conan with `build_all`_ = ``True``.
3. Run Conan with `user.build:all`_ = ``True``.
.. 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>`_.
Also, to simplify the examples all of them assume::
using namespace std::math;
using namespace STD_LA;
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::
fs_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 };
fs_vector<si::length<si::kilometre>, 3> t = { 3 * km, 2 * km, 1 * km };
fixed_size_column_vector<si::length<si::metre>, 3> v = { 1 * m, 2 * m, 3 * m };
fixed_size_column_vector<si::length<si::metre>, 3> u = { 3 * m, 2 * m, 1 * m };
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
allowed by the Linear Algebra rules. For example::
std::cout << "v + u = " << v + u << "\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 << "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::
si::length<si::metre, fs_vector<int, 3>> v(fs_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::kilometre, fs_vector<int, 3>> t(fs_vector<int, 3>{ 3, 2, 1 });
si::length<si::metre, fixed_size_column_vector<int, 3>> v(fixed_size_column_vector<int, 3>{ 1, 2, 3 });
si::length<si::metre, fixed_size_column_vector<int, 3>> u(fixed_size_column_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
output:

View File

@@ -57,8 +57,9 @@ if(NOT ${projectPrefix}LIBCXX)
glide_computer_example-aliases PRIVATE ${projectPrefix}NO_LITERALS ${projectPrefix}NO_REFERENCES
)
# TODO uncomment the below when recipes in ConanCenter are fixed
# find_package(wg21_linear_algebra CONFIG REQUIRED)
# 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)
if(${projectPrefix}BUILD_LA)
find_package(wg21_linear_algebra CONFIG REQUIRED)
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)
endif()
endif()

View File

@@ -27,12 +27,18 @@
#include <units/isq/si/speed.h> // IWYU pragma: keep
#include <units/quantity_io.h>
#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 {
template<class ET, class OT>
std::ostream& operator<<(std::ostream& os, const vector<ET, OT>& v)
template<typename Rep>
std::ostream& operator<<(std::ostream& os, const ::vector<Rep>& v)
{
os << "|";
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;
}
template<class ET, class OT>
std::ostream& operator<<(std::ostream& os, const matrix<ET, OT>& v)
template<typename Rep>
std::ostream& operator<<(std::ostream& os, const ::matrix<Rep>& v)
{
for (auto i = 0U; i < v.rows(); ++i) {
os << "|";
@@ -61,18 +67,11 @@ namespace {
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()
{
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::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";
}
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()
{
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";
// TODO Uncomment when bug in the LA is fixed
// std::cout << "v / s<>(2) = " << v / s<>(2) << "\n";
// std::cout << "v / 2 = " << v / 2 << "\n";
std::cout << "v / s<>(2) = " << v / s<>(2) << "\n";
std::cout << "v / 2 = " << v / 2 << "\n";
}
void vector_of_quantity_tests()
{
vector_of_quantity_add();
vector_of_quantity_multiply_same();
vector_of_quantity_multiply_different();
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 + t =\n" << v + t << "\n";
// TODO Uncomment when fixed in the LA lib
// 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";
std::cout << "v[mm] =\n" << matrix<length::mm<>>(v) << "\n";
}
void matrix_of_quantity_divide_by_scalar()
@@ -191,16 +128,13 @@ void matrix_of_quantity_divide_by_scalar()
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 / 2 =\n" << v / 2 << "\n";
std::cout << "v / s<>(2) =\n" << v / s<>(2) << "\n";
std::cout << "v / 2 =\n" << v / 2 << "\n";
}
void matrix_of_quantity_tests()
{
matrix_of_quantity_add();
matrix_of_quantity_multiply_same();
matrix_of_quantity_multiply_different();
matrix_of_quantity_divide_by_scalar();
}
@@ -216,7 +150,7 @@ void quantity_of_vector_add()
{
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<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";
}
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()
{
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";
// TODO Uncomment when bug in the LA is fixed
// std::cout << "v / s<>(2) = " << v / s<>(2) << "\n";
// std::cout << "v / 2 = " << v / 2 << "\n";
std::cout << "v / s<>(2) = " << v / s<>(2) << "\n";
std::cout << "v / 2 = " << v / 2 << "\n";
}
void quantity_of_vector_tests()
{
quantity_of_vector_add();
quantity_of_vector_multiply_same();
quantity_of_vector_multiply_different();
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 + 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";
}
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()
{
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";
// TODO Uncomment when bug in the LA is fixed
// std::cout << "v / s<>(2) =\n" << v / s<>(2) << "\n";
// std::cout << "v / 2 =\n" << v / 2 << "\n";
std::cout << "v / s<>(2) =\n" << v / s<>(2) << "\n";
std::cout << "v / 2 =\n" << v / 2 << "\n";
}
void quantity_of_matrix_tests()
{
quantity_of_matrix_add();
quantity_of_matrix_multiply_same();
quantity_of_matrix_multiply_different();
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
)
# TODO uncomment the below when recipes in ConanCenter are fixed
# find_package(wg21_linear_algebra CONFIG REQUIRED)
# 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)
if(${projectPrefix}BUILD_LA)
find_package(wg21_linear_algebra CONFIG REQUIRED)
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)
endif()
endif()

View File

@@ -27,12 +27,18 @@
#include <units/isq/si/speed.h> // IWYU pragma: keep
#include <units/quantity_io.h>
#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 {
template<class ET, class OT>
std::ostream& operator<<(std::ostream& os, const vector<ET, OT>& v)
template<typename Rep>
std::ostream& operator<<(std::ostream& os, const ::vector<Rep>& v)
{
os << "|";
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;
}
template<class ET, class OT>
std::ostream& operator<<(std::ostream& os, const matrix<ET, OT>& v)
template<typename Rep>
std::ostream& operator<<(std::ostream& os, const ::matrix<Rep>& v)
{
for (auto i = 0U; i < v.rows(); ++i) {
os << "|";
@@ -62,18 +68,11 @@ namespace {
using namespace units::isq;
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()
{
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::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";
}
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()
{
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";
// TODO Uncomment when bug in the LA is fixed
// std::cout << "v / 2_q_s = " << v / 2_q_s << "\n";
// std::cout << "v / 2 = " << v / 2 << "\n";
std::cout << "v / 2_q_s = " << v / quantity_cast<double>(2_q_s) << "\n";
std::cout << "v / 2 = " << v / 2 << "\n";
}
void vector_of_quantity_tests()
{
vector_of_quantity_add();
vector_of_quantity_multiply_same();
vector_of_quantity_multiply_different();
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 + 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";
}
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";
std::cout << "v[mm] =\n" << matrix<si::length<si::millimetre>>(v) << "\n";
}
void matrix_of_quantity_divide_by_scalar()
@@ -192,16 +129,13 @@ void matrix_of_quantity_divide_by_scalar()
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 =\n" << v / 2 << "\n";
std::cout << "v / 2_q_s =\n" << v / quantity_cast<double>(2_q_s) << "\n";
std::cout << "v / 2 =\n" << v / 2 << "\n";
}
void matrix_of_quantity_tests()
{
matrix_of_quantity_add();
matrix_of_quantity_multiply_same();
matrix_of_quantity_multiply_different();
matrix_of_quantity_divide_by_scalar();
}
@@ -215,7 +149,7 @@ void quantity_of_vector_add()
{
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<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";
}
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()
{
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";
// TODO Uncomment when bug in the LA is fixed
// std::cout << "v / 2_q_s = " << v / 2_q_s << "\n";
// std::cout << "v / 2 = " << v / 2 << "\n";
std::cout << "v / 2_q_s = " << v / 2_q_s << "\n";
std::cout << "v / 2 = " << v / 2 << "\n";
}
void quantity_of_vector_tests()
{
quantity_of_vector_add();
quantity_of_vector_multiply_same();
quantity_of_vector_multiply_different();
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 + 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";
}
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()
{
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";
// 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 =\n" << v / 2 << "\n";
std::cout << "v / 2_q_s =\n" << v / 2_q_s << "\n";
std::cout << "v / 2 =\n" << v / 2 << "\n";
}
void quantity_of_matrix_tests()
{
quantity_of_matrix_add();
quantity_of_matrix_multiply_same();
quantity_of_matrix_multiply_different();
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
)
# TODO uncomment the below when recipes in ConanCenter are fixed
# find_package(wg21_linear_algebra CONFIG REQUIRED)
# 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)
if(${projectPrefix}BUILD_LA)
find_package(wg21_linear_algebra CONFIG REQUIRED)
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)
endif()
endif()

View File

@@ -27,12 +27,18 @@
#include <units/isq/si/speed.h> // IWYU pragma: keep
#include <units/quantity_io.h>
#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 {
template<class ET, class OT>
std::ostream& operator<<(std::ostream& os, const vector<ET, OT>& v)
template<typename Rep>
std::ostream& operator<<(std::ostream& os, const ::vector<Rep>& v)
{
os << "|";
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;
}
template<class ET, class OT>
std::ostream& operator<<(std::ostream& os, const matrix<ET, OT>& v)
template<typename Rep>
std::ostream& operator<<(std::ostream& os, const ::matrix<Rep>& v)
{
for (auto i = 0U; i < v.rows(); ++i) {
os << "|";
@@ -61,19 +67,13 @@ namespace {
using namespace units::isq;
using namespace units::isq::si::length_references;
using namespace units::isq::si::force_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>;
using namespace units::isq::si::time_references;
void vector_of_quantity_add()
{
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::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";
}
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()
{
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";
// TODO Uncomment when bug in the LA is fixed
// std::cout << "v / (2 * s) = " << v / (2 * s) << "\n";
// std::cout << "v / 2 = " << v / 2 << "\n";
std::cout << "v / (2 * s) = " << v / (2 * s) << "\n";
std::cout << "v / 2 = " << v / 2 << "\n";
}
void vector_of_quantity_tests()
{
vector_of_quantity_add();
vector_of_quantity_multiply_same();
vector_of_quantity_multiply_different();
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 + 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";
}
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";
std::cout << "v[mm] =\n" << matrix<si::length<si::millimetre>>(v) << "\n";
}
void matrix_of_quantity_divide_by_scalar()
@@ -192,16 +130,13 @@ void matrix_of_quantity_divide_by_scalar()
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 =\n" << v / 2 << "\n";
std::cout << "v / (2 * s) =\n" << v / (2 * s) << "\n";
std::cout << "v / 2 =\n" << v / 2 << "\n";
}
void matrix_of_quantity_tests()
{
matrix_of_quantity_add();
matrix_of_quantity_multiply_same();
matrix_of_quantity_multiply_different();
matrix_of_quantity_divide_by_scalar();
}
@@ -215,7 +150,7 @@ void quantity_of_vector_add()
{
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<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";
}
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()
{
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";
// TODO Uncomment when bug in the LA is fixed
// std::cout << "v / 2 * s = " << v / 2 * s << "\n";
// std::cout << "v / 2 = " << v / 2 << "\n";
std::cout << "v / (2 * s) = " << v / (2 * s) << "\n";
std::cout << "v / 2 = " << v / 2 << "\n";
}
void quantity_of_vector_tests()
{
quantity_of_vector_add();
quantity_of_vector_multiply_same();
quantity_of_vector_multiply_different();
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 + 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";
}
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()
{
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";
// TODO Uncomment when bug in the LA is fixed
// std::cout << "v / (2 * s) =\n" << v / (2 * s) << "\n";
// std::cout << "v / 2 =\n" << v / 2 << "\n";
std::cout << "v / (2 * s) =\n" << v / (2 * s) << "\n";
std::cout << "v / 2 =\n" << v / 2 << "\n";
}
void quantity_of_matrix_tests()
{
quantity_of_matrix_add();
quantity_of_matrix_multiply_same();
quantity_of_matrix_multiply_different();
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)
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")
include(AddUnitsModule)

View File

@@ -401,8 +401,11 @@ concept castable_number_ = // exposition only
template<typename T>
concept scalable_ = // exposition only
castable_number_<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>>);
castable_number_<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>
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> ||
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>
requires requires { 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.
*
* Satisfied by all wrapper types that satisfy `Quantity<typename T::value_type>`
* recursively (i.e. `std::optional<si::length<si::metre>>`).
* Satisfied by all wrapper types that satisfy `Quantity<typename T::value_type>` or
* `Quantity<typename T::element_type>` recursively
* (i.e. `std::optional<si::length<si::metre>>`).
*/
template<typename T>
concept wrapped_quantity_ = // exposition only

View File

@@ -44,6 +44,10 @@ template<typename T>
requires requires { 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
*

View File

@@ -83,6 +83,16 @@ struct cast_traits<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
/**