@@ -84,24 +84,6 @@ def get_transform(self):
8484 return IdentityTransform ()
8585
8686
87- def _mask_non_positives (a ):
88- """
89- Return a Numpy array where all non-positive values are
90- replaced with NaNs. If there are no non-positive values, the
91- original array is returned.
92- """
93- mask = a <= 0.0
94- if mask .any ():
95- return np .where (mask , np .nan , a )
96- return a
97-
98-
99- def _clip_non_positives (a ):
100- a = np .array (a , float )
101- a [a <= 0.0 ] = 1e-300
102- return a
103-
104-
10587class LogTransformBase (Transform ):
10688 input_dims = 1
10789 output_dims = 1
@@ -111,31 +93,35 @@ class LogTransformBase(Transform):
11193 def __init__ (self , nonpos ):
11294 Transform .__init__ (self )
11395 if nonpos == 'mask' :
114- self ._handle_nonpos = _mask_non_positives
96+ self ._fill_value = np . nan
11597 else :
116- self ._handle_nonpos = _clip_non_positives
117-
118-
119- class Log10Transform (LogTransformBase ):
120- base = 10.0
98+ self ._fill_value = 1e-300
12199
122100 def transform_non_affine (self , a ):
123- a = self ._handle_nonpos (a * 10.0 )
124- return np .log10 (a )
125-
126- def inverted (self ):
127- return InvertedLog10Transform ()
101+ with np .errstate (invalid = "ignore" ):
102+ a = np .where (a <= 0 , self ._fill_value , a )
103+ return np .divide (np .log (a , out = a ), np .log (self .base ), out = a )
128104
129105
130- class InvertedLog10Transform (Transform ):
106+ class InvertedLogTransformBase (Transform ):
131107 input_dims = 1
132108 output_dims = 1
133109 is_separable = True
134110 has_inverse = True
135- base = 10.0
136111
137112 def transform_non_affine (self , a ):
138- return ma .power (10.0 , a ) / 10.0
113+ return ma .power (self .base , a )
114+
115+
116+ class Log10Transform (LogTransformBase ):
117+ base = 10.0
118+
119+ def inverted (self ):
120+ return InvertedLog10Transform ()
121+
122+
123+ class InvertedLog10Transform (InvertedLogTransformBase ):
124+ base = 10.0
139125
140126 def inverted (self ):
141127 return Log10Transform ()
@@ -144,88 +130,45 @@ def inverted(self):
144130class Log2Transform (LogTransformBase ):
145131 base = 2.0
146132
147- def transform_non_affine (self , a ):
148- a = self ._handle_nonpos (a * 2.0 )
149- return np .log2 (a )
150-
151133 def inverted (self ):
152134 return InvertedLog2Transform ()
153135
154136
155- class InvertedLog2Transform (Transform ):
156- input_dims = 1
157- output_dims = 1
158- is_separable = True
159- has_inverse = True
137+ class InvertedLog2Transform (InvertedLogTransformBase ):
160138 base = 2.0
161139
162- def transform_non_affine (self , a ):
163- return ma .power (2.0 , a ) / 2.0
164-
165140 def inverted (self ):
166141 return Log2Transform ()
167142
168143
169144class NaturalLogTransform (LogTransformBase ):
170145 base = np .e
171146
172- def transform_non_affine (self , a ):
173- a = self ._handle_nonpos (a * np .e )
174- return np .log (a )
175-
176147 def inverted (self ):
177148 return InvertedNaturalLogTransform ()
178149
179150
180- class InvertedNaturalLogTransform (Transform ):
181- input_dims = 1
182- output_dims = 1
183- is_separable = True
184- has_inverse = True
151+ class InvertedNaturalLogTransform (InvertedLogTransformBase ):
185152 base = np .e
186153
187- def transform_non_affine (self , a ):
188- return ma .power (np .e , a ) / np .e
189-
190154 def inverted (self ):
191155 return NaturalLogTransform ()
192156
193157
194- class LogTransform (Transform ):
195- input_dims = 1
196- output_dims = 1
197- is_separable = True
198- has_inverse = True
199-
158+ class LogTransform (LogTransformBase ):
200159 def __init__ (self , base , nonpos ):
201- Transform .__init__ (self )
160+ LogTransformBase .__init__ (self , nonpos )
202161 self .base = base
203- if nonpos == 'mask' :
204- self ._handle_nonpos = _mask_non_positives
205- else :
206- self ._handle_nonpos = _clip_non_positives
207-
208- def transform_non_affine (self , a ):
209- a = self ._handle_nonpos (a * self .base )
210- return np .log (a ) / np .log (self .base )
211162
212163 def inverted (self ):
213164 return InvertedLogTransform (self .base )
214165
215166
216- class InvertedLogTransform (Transform ):
217- input_dims = 1
218- output_dims = 1
219- is_separable = True
220- has_inverse = True
221-
167+ class InvertedLogTransform (InvertedLogTransformBase ):
222168 def __init__ (self , base ):
223- Transform .__init__ (self )
169+ InvertedLogTransformBase .__init__ (self )
224170 self .base = base
225171
226- def transform_non_affine (self , a ):
227- return ma .power (self .base , a ) / self .base
228-
229172 def inverted (self ):
230173 return LogTransform (self .base )
231174
@@ -474,25 +417,6 @@ def get_transform(self):
474417 return self ._transform
475418
476419
477- def _mask_non_logit (a ):
478- """
479- Return a Numpy array where all values outside ]0, 1[ are
480- replaced with NaNs. If all values are inside ]0, 1[, the original
481- array is returned.
482- """
483- mask = (a <= 0.0 ) | (a >= 1.0 )
484- if mask .any ():
485- return np .where (mask , np .nan , a )
486- return a
487-
488-
489- def _clip_non_logit (a ):
490- a = np .array (a , float )
491- a [a <= 0.0 ] = 1e-300
492- a [a >= 1.0 ] = 1 - 1e-300
493- return a
494-
495-
496420class LogitTransform (Transform ):
497421 input_dims = 1
498422 output_dims = 1
@@ -502,15 +426,17 @@ class LogitTransform(Transform):
502426 def __init__ (self , nonpos ):
503427 Transform .__init__ (self )
504428 if nonpos == 'mask' :
505- self ._handle_nonpos = _mask_non_logit
429+ self ._fill_value = np . nan
506430 else :
507- self ._handle_nonpos = _clip_non_logit
431+ self ._fill_value = 1e-300
508432 self ._nonpos = nonpos
509433
510434 def transform_non_affine (self , a ):
511435 """logit transform (base 10), masked or clipped"""
512- a = self ._handle_nonpos (a )
513- return np .log10 (1.0 * a / (1.0 - a ))
436+ with np .errstate (invalid = "ignore" ):
437+ a = np .select (
438+ [a <= 0 , a >= 1 ], [self ._fill_value , 1 - self ._fill_value ], a )
439+ return np .log10 (a / (1 - a ))
514440
515441 def inverted (self ):
516442 return LogisticTransform (self ._nonpos )
0 commit comments