🛰️航天仿真算法库 SpaceAST 0.0.1
载入中...
搜索中...
未找到
UnitRep.hpp
浏览该文件的文档.
1
20
21#pragma once
22
23#include "AstGlobal.h"
24#include "AstUtil/StringView.hpp"
25#include "Dimension.hpp"
26#include <memory>
27#include <vector>
28#include <cmath>
29
30AST_NAMESPACE_BEGIN
31
37class UnitRep;
38
39enum class EUnitKind: uint8_t{
40 eScale,
41 eAffine,
42 eLogarithmic
43};
44
45
46using UnitRepHandle = std::shared_ptr<UnitRep>;
47using UnitRepPair = std::pair<UnitRepHandle, int>;
48using SubUnitList = std::vector<UnitRepPair>;
49using UnitRepHandleConst = std::shared_ptr<const UnitRep>;
50using UnitRepPairConst = std::pair<UnitRepHandleConst, int>;
51using SubUnitListConst = std::vector<UnitRepPairConst>;
52
53
56class UnitRep{
57public:
58 UnitRep(EUnitKind kind, StringView name, Dimension dimension, const SubUnitListConst& subunits)
59 : kind_{kind}
60 , name_{std::string(name)}
61 , dimension_{dimension}
62 , subUnits_{subunits}
63 {}
64 UnitRep(EUnitKind kind, StringView name, Dimension dimension)
65 : kind_{kind}
66 , name_{std::string(name)}
67 , dimension_{dimension}
68 , subUnits_{}
69 {}
70 EUnitKind kind_;
71 std::string name_;
74
75 bool operator==(const UnitRep& other) const;
76public:
77 virtual ~UnitRep() = default;
78 virtual double toSI(double value) const = 0;
79 virtual double fromSI(double value) const = 0;
81 virtual UnitRepHandle clone() const = 0;
82public:
83 EUnitKind kind() const { return kind_; }
84 double scale() const;
85 bool valid() const;
86};
87
88
90class ScaleUnitRep final: public UnitRep
91{
92public:
93 using UnitRep::UnitRep;
94 ScaleUnitRep(StringView name, Dimension dimension, double scale)
95 : UnitRep(EUnitKind::eScale, name, dimension)
96 , scale_{scale}
97 {}
98 ScaleUnitRep(StringView name, Dimension dimension, const SubUnitListConst& subunits, double scale)
99 : UnitRep(EUnitKind::eScale, name, dimension, subunits)
100 , scale_{scale}
101 {}
102public:
103 double toSI(double value) const override { return value * scale_;}
104 double fromSI(double value) const override { return value / scale_;}
105 double scale_{1.0};
106 double notused_{0.0};
107public:
108 UnitRepHandle clone() const override { return std::make_shared<ScaleUnitRep>(*this); }
109};
110
111
113class AffineUnitRep : public UnitRep {
114public:
115 using UnitRep::UnitRep;
116 AffineUnitRep(StringView name, Dimension dimension, double scale, double offset)
117 : UnitRep(EUnitKind::eAffine, name, dimension)
118 , scale_{scale}
119 , offset_{offset}
120 {}
121public:
122 double toSI(double value) const override { return value * scale_ + offset_;}
123 double fromSI(double value) const override { return (value - offset_) / scale_;}
124 double scale_{1.0};
125 double offset_{0.0};
126public:
127 UnitRepHandle clone() const override { return std::make_shared<AffineUnitRep>(*this); }
128};
129
130
132// @todo 未校验 reference/factor 参数:reference<=0 或 factor<=0 会使 toSI/fromSI 输出异常,应加校验并返回错误。
134public:
135 using UnitRep::UnitRep;
136 LogarithmicUnitRep(StringView name, Dimension dimension, double reference, double factor)
137 : UnitRep(EUnitKind::eLogarithmic, name, dimension)
138 , reference_{reference}
139 , factor_{factor}
140 {}
141public:
142 double toSI(double value) const override { return reference_ * std::pow(10.0, value / factor_);}
143 double fromSI(double value) const override { return std::log10(value / reference_) * factor_;}
144 double reference_{1.0};
145 double factor_{1.0};
146public:
147 UnitRepHandle clone() const override { return std::make_shared<LogarithmicUnitRep>(*this); }
148};
149
150
151inline bool UnitRep::operator==(const UnitRep &rep) const
152{
153 /*
154 单位表示是否相等:比较量纲 + 单位类型 + 两个double成员变量是否相等
155 前置条件:必须保证各个单位表示类型的内存大小一致,两个double成员变量的偏移量一致
156 该前置条件通过编译期检查(static_assert)来保证
157 */
158 auto self = static_cast<const ScaleUnitRep*>(this);
159 auto other = static_cast<const ScaleUnitRep*>(&rep);
160 return dimension_ == other->dimension_ && kind_ == other->kind_ && self->scale_ == other->scale_ && self->notused_ == other->notused_;
161}
162
163inline double UnitRep::scale() const
164{
165 if(kind_ == EUnitKind::eScale){
166 return static_cast<const ScaleUnitRep*>(this)->scale_;
167 }
168 else if(kind_ == EUnitKind::eAffine){
169 return static_cast<const AffineUnitRep*>(this)->scale_;
170 }
171 // @todo 这里需要考虑返回 0 还是 nan 更合适?
172 return 0.0;
173}
174
175inline bool UnitRep::valid() const
176{
177 if(kind_ == EUnitKind::eScale){
178 return static_cast<const ScaleUnitRep*>(this)->scale_ != 0.0;
179 }
180 else if(kind_ == EUnitKind::eAffine){
181 return static_cast<const AffineUnitRep*>(this)->scale_ != 0.0;
182 }
183 else // if(kind_ == EUnitKind::Logarithmic){
184 {
185 return true;
186 }
187 // return false;
188}
189
192AST_NAMESPACE_END
仿射型单位表示: SI = v * scale + offset
定义 UnitRep.hpp:113
UnitRepHandle clone() const override
深拷贝单位表示(独立副本)
定义 UnitRep.hpp:127
量纲
定义 Dimension.hpp:362
对数型单位表示: SI = reference * 10^(v / factor)
定义 UnitRep.hpp:133
UnitRepHandle clone() const override
深拷贝单位表示(独立副本)
定义 UnitRep.hpp:147
乘法型单位表示: SI = v * scale
定义 UnitRep.hpp:91
UnitRepHandle clone() const override
深拷贝单位表示(独立副本)
定义 UnitRep.hpp:108
单位表示
定义 UnitRep.hpp:56
SubUnitListConst subUnits_
子单位列表
定义 UnitRep.hpp:73
std::string name_
名称
定义 UnitRep.hpp:71
virtual UnitRepHandle clone() const =0
深拷贝单位表示(独立副本)
EUnitKind kind_
单位表示类型
定义 UnitRep.hpp:70
Dimension dimension_
量纲
定义 UnitRep.hpp:72
std::pair< UnitRepHandle, int > UnitRepPair
单位表示子项
定义 UnitRep.hpp:47
std::vector< UnitRepPair > SubUnitList
单位表示子项列表
定义 UnitRep.hpp:48
std::shared_ptr< const UnitRep > UnitRepHandleConst
单位表示句柄(常量)
定义 UnitRep.hpp:49
std::pair< UnitRepHandleConst, int > UnitRepPairConst
单位表示子项(常量)
定义 UnitRep.hpp:50
std::shared_ptr< UnitRep > UnitRepHandle
单位表示句柄
定义 UnitRep.hpp:46
std::vector< UnitRepPairConst > SubUnitListConst
单位表示子项列表(常量)
定义 UnitRep.hpp:51