1 /++
2 Parameters conversions
3 +/
4 /**
5 Authors: [Ilya Yaroshenko](http://9il.github.io)
6 
7 Copyright: © 2014-2015 [Ilya Yaroshenko](http://9il.github.io)
8 
9 License: MIT
10 */
11 module atmosphere.params;
12 
13 import core.stdc.tgmath;
14 
15 import std.traits;
16 import std.typecons;
17 
18 //pure
19 @safe nothrow @nogc:
20 
21 /++
22 <img style="width: 600px;" src="images/GIGChiPsi.png">
23 +/
24 struct GIGChiPsi(T)
25 	if(isFloatingPoint!T)
26 {
27 	///
28 	T chi;
29 	///
30 	T psi;
31 
32 const @property:
33 	/// `sqrt(chi / psi)`
34 	T eta()   { return sqrt(chi / psi); }
35 	/// `sqrt(chi * psi)`
36 	T omega() { return sqrt(chi * psi); }
37 
38 	/// `cast` operator overloading 
39 	R opCast(R : GIGChiPsi!F, F)()      { return R(chi, psi); }
40 	/// ditto
41 	R opCast(R : GIGEtaOmega!F, F)()    { return R(eta, omega); }
42 }
43 
44 ///
45 unittest 
46 {
47 	double _chi  = 3;
48 	double _psi  = 4;
49 
50 	auto params  = GIGChiPsi!double(_chi, _psi);
51 
52 	auto params1 = cast(GIGChiPsi    !real) params;
53 	auto params2 = cast(GIGEtaOmega  !real) params;
54 
55 	double chi   = params.chi;
56 	double psi   = params.psi;
57 
58 	double eta   = params.eta;
59 	double omega = params.omega;
60 }
61 
62 
63 /++
64 <img style="width: 600px;" src="images/GIGEtaOmega.png">
65 +/
66 struct GIGEtaOmega(T)
67 	if(isFloatingPoint!T)
68 {
69 	///
70 	T eta;
71 	///
72 	T omega;
73 
74 const @property:
75 	/// `omega * eta`
76 	T chi()   { return omega * eta; }
77 	/// `omega / eta`
78 	T psi()   { return omega / eta; }
79 
80 	/// `cast` operator overloading 
81 	R opCast(R : GIGChiPsi!F, F)()      { return R(chi, psi); }
82 	/// ditto
83 	R opCast(R : GIGEtaOmega!F, F)()    { return R(eta, omega); }
84 }
85 
86 ///
87 unittest 
88 {
89 	double _eta  = 3;
90 	double _omega= 4;
91 
92 	auto params  = GIGEtaOmega!double(_eta, _omega);
93 
94 	auto params1 = cast(GIGChiPsi    !real) params;
95 	auto params2 = cast(GIGEtaOmega  !real) params;
96 
97 	double chi   = params.chi;
98 	double psi   = params.psi;
99 
100 	double eta   = params.eta;
101 	double omega = params.omega;
102 }
103 
104 
105 /++
106 <img style="width: 600px;" src="images/GHypAlphaDelta.png">
107 <img style="width: 150px;" src="images/GHypYx.png">
108 +/
109 struct GHypAlphaDelta(T)
110 	if(isFloatingPoint!T)
111 {
112 	///
113 	T alpha;
114 	///
115 	T beta;
116 	///
117 	T delta;
118 
119 const @property:
120 	/// `delta^^2`
121 	T chi()   { return delta^^2; }
122 	/// `alpha^^2 - beta^^2`
123 	T psi()   { return alpha^^2 - beta^^2; }
124 	/// `sqrt(chi / psi)`
125 	T eta()   { return sqrt(chi / psi); }
126 	/// `sqrt(chi * psi)`
127 	T omega() { return sqrt(chi * psi); }
128 
129 	/// `cast` operator overloading 
130 	R opCast(R : GHypAlphaDelta!F, F)() { return R(alpha, beta, delta); }
131 	/// ditto 
132 	R opCast(R : GHypChiPsi!F, F)()     { return R(beta, chi, psi); }
133 	/// ditto
134 	R opCast(R : GHypEtaOmega!F, F)()   { return R(beta, eta, omega); }
135 	/// ditto
136 	R opCast(R : GIGChiPsi!F, F)()      { return R(chi, psi); }
137 	/// ditto
138 	R opCast(R : GIGEtaOmega!F, F)()    { return R(eta, omega); }
139 }
140 
141 ///
142 unittest 
143 {
144 	double beta  = 2;
145 	double _alpha= 3;
146 	double _delta= 4;
147 
148 	auto params  = GHypAlphaDelta!double(_alpha, beta, _delta);
149 
150 	auto params0 = cast(GHypAlphaDelta!real) params;
151 	auto params1 = cast(GHypChiPsi    !real) params;
152 	auto params2 = cast(GHypEtaOmega  !real) params;
153 	auto params3 = cast(GIGChiPsi     !real) params;
154 	auto params4 = cast(GIGEtaOmega   !real) params;
155 
156 	double alpha = params.alpha;
157 	double delta = params.delta;
158 
159 	double chi   = params.chi;
160 	double psi   = params.psi;
161 
162 	double eta   = params.eta;
163 	double omega = params.omega;
164 }
165 
166 
167 /++
168 <img style="width: 400px;" src="images/GHypNVMM.png">
169 +/
170 struct GHypChiPsi(T)
171 	if(isFloatingPoint!T)
172 {
173 	///
174 	T beta; 
175 	///
176 	T chi;
177 	///
178 	T psi;
179 
180 const @property:
181 	/// `sqrt(chi / psi)`
182 	T eta()   { return sqrt(chi / psi); }
183 	/// `sqrt(chi * psi)`
184 	T omega() { return sqrt(chi * psi); }
185 	/// `sqrt(chi)`
186 	T delta() { return sqrt(chi); }
187 	/// `sqrt(psi + beta^^2)`
188 	T alpha() { return sqrt(psi + beta^^2); }
189 
190 	/// `cast` operator overloading 
191 	R opCast(R : GHypAlphaDelta!F, F)() { return R(alpha, beta, delta); }
192 	/// ditto 
193 	R opCast(R : GHypChiPsi!F, F)()     { return R(beta, chi, psi); }
194 	/// ditto
195 	R opCast(R : GHypEtaOmega!F, F)()   { return R(beta, eta, omega); }
196 	/// ditto
197 	R opCast(R : GIGChiPsi!F, F)()      { return R(chi, psi); }
198 	/// ditto
199 	R opCast(R : GIGEtaOmega!F, F)()    { return R(eta, omega); }
200 }
201 
202 ///
203 unittest 
204 {
205 	double beta  = 2;
206 	double _chi  = 3;
207 	double _psi  = 4;
208 
209 	auto params  = GHypChiPsi!double(beta, _chi, _psi);
210 
211 	auto params0 = cast(GHypAlphaDelta!real) params;
212 	auto params1 = cast(GHypChiPsi    !real) params;
213 	auto params2 = cast(GHypEtaOmega  !real) params;
214 	auto params3 = cast(GIGChiPsi     !real) params;
215 	auto params4 = cast(GIGEtaOmega   !real) params;
216 
217 	double alpha = params.alpha;
218 	double delta = params.delta;
219 
220 	double chi   = params.chi;
221 	double psi   = params.psi;
222 
223 	double eta   = params.eta;
224 	double omega = params.omega;
225 }
226 
227 
228 /// `beta, eta, omega` generalized hyperbolic distribution parameters
229 struct GHypEtaOmega(T)
230 	if(isFloatingPoint!T)
231 {
232 	///
233 	T beta;
234 	///
235 	T eta;
236 	///
237 	T omega;
238 
239 const @property:
240 	/// `omega * eta`
241 	T chi()   { return omega * eta; }
242 	/// `omega / eta`
243 	T psi()   { return omega / eta; }
244 	/// `sqrt(chi)`
245 	T delta() { return sqrt(chi); }
246 	/// `sqrt(psi + beta^^2)`
247 	T alpha() { return sqrt(psi + beta^^2); }
248 
249 	/// `cast` operator overloading 
250 	R opCast(R : GHypAlphaDelta!F, F)() { return R(alpha, beta, delta); }
251 	/// ditto 
252 	R opCast(R : GHypChiPsi!F, F)()     { return R(beta, chi, psi); }
253 	/// ditto
254 	R opCast(R : GHypEtaOmega!F, F)()   { return R(beta, eta, omega); }
255 	/// ditto
256 	R opCast(R : GIGChiPsi!F, F)()      { return R(chi, psi); }
257 	/// ditto
258 	R opCast(R : GIGEtaOmega!F, F)()    { return R(eta, omega); }
259 }
260 
261 ///
262 unittest 
263 {
264 	double beta  = 2;
265 	double _eta  = 3;
266 	double _omega= 4;
267 
268 	auto params  = GHypEtaOmega!double(beta, _eta, _omega);
269 
270 	auto params0 = cast(GHypAlphaDelta!real) params;
271 	auto params1 = cast(GHypChiPsi    !real) params;
272 	auto params2 = cast(GHypEtaOmega  !real) params;
273 	auto params3 = cast(GIGChiPsi     !real) params;
274 	auto params4 = cast(GIGEtaOmega   !real) params;
275 
276 	double alpha = params.alpha;
277 	double delta = params.delta;
278 
279 	double chi   = params.chi;
280 	double psi   = params.psi;
281 
282 	double eta   = params.eta;
283 	double omega = params.omega;
284 }