-
Notifications
You must be signed in to change notification settings - Fork 87
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Division of vector quantities? #409
Comments
If it's not mathematically defined in the first place, there's nothing we can do. ISO 80000-6 actually has many quantities that are a coefficient of two vector quantities: inline constexpr auto permittivity = defn<"𝜀", "𝘿 = 𝜀𝙀", electric_flux_density("𝘿"), electric_field_strength("𝙀")>();
inline constexpr auto electric_susceptibility = defn<"𝜒", "𝙋 = 𝜀₀𝜒𝙀", electric_polarization("𝙋"), electric_constant("𝜀₀"), electric_field_strength("𝙀")>();
inline constexpr auto permeability = defn<"𝜇", "𝘽 = 𝜇𝙃", magnetic_flux_density("𝘽"), magnetic_field_strength("𝙃")>();
inline constexpr auto magnetic_susceptibility = defn<"𝜅", "𝙈 = 𝜅𝙃", magnetization("𝙈"), magnetic_field_strength("𝙃")>();
inline constexpr auto conductivity = defn<"𝜎", "𝙅 = 𝜎𝙀", electric_current_density("𝙅"), electric_field_strength("𝙀")>(); |
Well, I think that an LA vector is not the only way to model a vector quantity, and maybe not even a good choice at all. I can imagine a type like Maybe we should provide such a type in the library? |
Although I haven't gotten far using it, at some point I made something like that: template<class Id, units::Dimension D> struct linear_dimension : units::kind<linear_dimension<Id, D>, D> { };
template<class Id, units::Dimension D> struct coordinate
: units::point_kind<coordinate<Id, D>, linear_dimension<Id, D>> { };
// Cartesian coordinate systems
struct x;
struct y;
struct z;
export template<class D, class U, class R> using x_dimension = units::quantity_kind<linear_dimension<x, D>, U, R>;
export template<class D, class U, class R> using y_dimension = units::quantity_kind<linear_dimension<y, D>, U, R>;
export template<class D, class U, class R> using z_dimension = units::quantity_kind<linear_dimension<z, D>, U, R>;
export template<class D, class U, class R> using x_coordinate = units::quantity_point_kind<coordinate<x, D>, U, R>;
export template<class D, class U, class R> using y_coordinate = units::quantity_point_kind<coordinate<y, D>, U, R>;
export template<class D, class U, class R> using z_coordinate = units::quantity_point_kind<coordinate<z, D>, U, R>;
export template<units::Dimension D, units::UnitOf<D> U, units::Representation R> struct cartesian_size3d {
using x_type = x_dimension<D, U, R>;
using y_type = y_dimension<D, U, R>;
using z_type = z_dimension<D, U, R>;
using quantity_type = units::quantity<D, U, R>;
using dimension = D;
using unit = U;
using rep = R;
x_type x;
y_type y;
z_type z;
template<class D2, class U2, class R2>
requires std::convertible_to<x_type, x_dimension<D2, U2, R2>>
[[nodiscard]] constexpr explicit(false) operator cartesian_size3d<D2, U2, R2>() const { return {x, y, z}; }
template<class D2, class U2, class R2> [[nodiscard]] constexpr bool operator==(const cartesian_size3d<D2, U2, R2>& r)
const requires std::equality_comparable_with<x_type, x_dimension<D2, U2, R2>> {
return x == r.x and y == r.y and z == r.z;
}
// clang-format off
constexpr cartesian_size3d& operator+=(const x_type& r) requires requires { x += r; } { x += r; return *this; }
constexpr cartesian_size3d& operator+=(const y_type& r) requires requires { y += r; } { y += r; return *this; }
constexpr cartesian_size3d& operator+=(const z_type& r) requires requires { z += r; } { z += r; return *this; }
constexpr cartesian_size3d& operator-=(const x_type& r) requires requires { x -= r; } { x -= r; return *this; }
constexpr cartesian_size3d& operator-=(const y_type& r) requires requires { y -= r; } { y -= r; return *this; }
constexpr cartesian_size3d& operator-=(const z_type& r) requires requires { z -= r; } { z -= r; return *this; }
constexpr cartesian_size3d& operator%=(const auto& r) requires requires { x %= r; } { x %= r; return *this; }
constexpr cartesian_size3d& operator%=(const auto& r) requires requires { y %= r; } { y %= r; return *this; }
constexpr cartesian_size3d& operator%=(const auto& r) requires requires { z %= r; } { z %= r; return *this; }
// clang-format on
template<class D2, class U2, class R2> constexpr cartesian_size3d&
operator%=(const cartesian_size3d<D2, U2, R2>& r) requires(requires { x %= r.x, y %= r.y, z %= r.z; }) {
x %= r.x;
y %= r.y;
z %= r.z;
return *this;
}
constexpr cartesian_size3d& operator/=(const auto& r) requires(requires { x /= r, y /= r, z /= r; }) {
x /= r;
y /= r;
z /= r;
return *this;
}
constexpr cartesian_size3d& operator*=(const auto& r) requires(requires { x *= r, y *= r, z *= r; }) {
x *= r;
y *= r;
z *= r;
return *this;
}
template<class D2, class U2, class R2> [[nodiscard]] friend constexpr specialization_of<cartesian_size3d> auto
operator+(const x_dimension<D2, U2, R2>& l, const cartesian_size3d& r) requires(requires { l + r.x; }) {
return jegp::cartesian_size3d{l + r.x, r.y, r.z};
}
}; Even for the single use case of Cartesian coordinate system, it takes effort to specify. |
Is there any other concept than the linear algebra concept of vectors? If so, there may be a need to clarify the concept of a "vector quantity", as I do not know anything else than linear algebra. With that, the following is simply not true:
Instead, the general division between two vectors is mathematically undefined. However, the expression However, In the case 𝘿 = 𝜀𝙀, 𝜀 may be a tensor, and things can become much more complicated. Still, an experimentalist may determine 𝜀 using a hand full of measurements of 𝘿 and 𝙀. They should be able to express the relevant computation using mp-units, which may involve both vectors of 𝙀 represented using an LA vector type, as well as scalar projections represented using a scalar representation (and either of them can additionally be complex, if we talk about AC-characteristics). My gut feeling is thus that, maybe it would be best to simply leave the scalar/vector characteristic to the representation type. |
That makes sense. One argument raised by @mpusz is that |
As I stated in #409 (comment) I think that we could introduce a physical quantities |
Acceleration is a change of velocity over time (
a = V / t
). Acceleration and velocity are defined as vector quantities, whereas time is scalar.If I want to calculate
t = V / a
, it is impossible if representation types ofa
andV
are linear algebra vectors as it is impossible to divide two vectors. Additionally, the characteristics of a derived quantity of velocity divided by acceleration is vector as well so it will not allow assigning to a scalar time.This is a simple and common case but also so complicated now after #405. How to handle that?
The text was updated successfully, but these errors were encountered: