1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
|
"""
pint.converters
~~~~~~~~~~~~~~~
Functions and classes related to unit conversions.
:copyright: 2016 by Pint Authors, see AUTHORS for more details.
:license: BSD, see LICENSE for more details.
"""
from .compat import HAS_NUMPY, exp, log # noqa: F401
class Converter:
"""Base class for value converters."""
@property
def is_multiplicative(self):
return True
@property
def is_logarithmic(self):
return False
def to_reference(self, value, inplace=False):
return value
def from_reference(self, value, inplace=False):
return value
class ScaleConverter(Converter):
"""A linear transformation."""
def __init__(self, scale):
self.scale = scale
def to_reference(self, value, inplace=False):
if inplace:
value *= self.scale
else:
value = value * self.scale
return value
def from_reference(self, value, inplace=False):
if inplace:
value /= self.scale
else:
value = value / self.scale
return value
class OffsetConverter(Converter):
"""An affine transformation."""
def __init__(self, scale, offset):
self.scale = scale
self.offset = offset
@property
def is_multiplicative(self):
return self.offset == 0
def to_reference(self, value, inplace=False):
if inplace:
value *= self.scale
value += self.offset
else:
value = value * self.scale + self.offset
return value
def from_reference(self, value, inplace=False):
if inplace:
value -= self.offset
value /= self.scale
else:
value = (value - self.offset) / self.scale
return value
class LogarithmicConverter(Converter):
"""Converts between linear units and logarithmic units, such as dB, octave, neper or pH.
Q_log = logfactor * log( Q_lin / scale ) / log(log_base)
Parameters
----------
scale : float
unit of reference at denominator for logarithmic unit conversion
logbase : float
base of logarithm used in the logarithmic unit conversion
logfactor : float
factor multiplied to logarithm for unit conversion
inplace : bool
controls if computation is done in place
"""
def __init__(self, scale, logbase, logfactor):
"""
Parameters
----------
scale : float
unit of reference at denominator inside logarithm for unit conversion
logbase: float
base of logarithm used in unit conversion
logfactor: float
factor multiplied to logarithm for unit conversion
"""
self.scale = scale
self.logbase = logbase
self.logfactor = logfactor
@property
def is_multiplicative(self):
return False
@property
def is_logarithmic(self):
return True
def from_reference(self, value, inplace=False):
"""Converts value from the reference unit to the logarithmic unit
dBm <------ mW
y dBm = 10 log10( x / 1mW )
"""
if inplace:
value /= self.scale
if HAS_NUMPY:
log(value, value)
else:
value = log(value)
value *= self.logfactor / log(self.logbase)
else:
value = self.logfactor * log(value / self.scale) / log(self.logbase)
return value
def to_reference(self, value, inplace=False):
"""Converts value to the reference unit from the logarithmic unit
dBm ------> mW
y dBm = 10 log10( x / 1mW )
"""
if inplace:
value /= self.logfactor
value *= log(self.logbase)
if HAS_NUMPY:
exp(value, value)
else:
value = exp(value)
value *= self.scale
else:
value = self.scale * exp(log(self.logbase) * (value / self.logfactor))
return value
|