Package mvpa :: Package misc :: Module transformers
[hide private]
[frames] | no frames]

Source Code for Module mvpa.misc.transformers

  1  #emacs: -*- mode: python-mode; py-indent-offset: 4; indent-tabs-mode: nil -*- 
  2  #ex: set sts=4 ts=4 sw=4 et: 
  3  ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ## 
  4  # 
  5  #   See COPYING file distributed along with the PyMVPA package for the 
  6  #   copyright and license terms. 
  7  # 
  8  ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ## 
  9  """Simply functors that transform something.""" 
 10   
 11  __docformat__ = 'restructuredtext' 
 12   
 13   
 14  import numpy as N 
 15   
 16   
17 -def Absolute(x):
18 """Returns the elementwise absolute of any argument.""" 19 return N.absolute(x)
20 21
22 -def OneMinus(x):
23 """Returns elementwise '1 - x' of any argument.""" 24 return 1 - x
25 26
27 -def Identity(x):
28 """Return whatever it was called with.""" 29 return x
30 31
32 -def FirstAxisMean(x):
33 """Mean computed along the first axis.""" 34 return N.mean(x, axis=0)
35 36
37 -def SecondAxisMean(x):
38 """Mean across 2nd axis 39 40 Use cases: 41 - to combine multiple sensitivities to get sense about 42 mean sensitivity across splits 43 """ 44 return N.mean(x, axis=1)
45 46
47 -def SecondAxisSumOfAbs(x):
48 """Sum of absolute values along the 2nd axis 49 50 Use cases: 51 - to combine multiple sensitivities to get sense about 52 what features are most influential 53 """ 54 return N.abs(x).sum(axis=1)
55 56
57 -def SecondAxisMaxOfAbs(x):
58 """Max of absolute values along the 2nd axis 59 """ 60 return N.abs(x).max(axis=1)
61 62
63 -def GrandMean(x):
64 """Just what the name suggests.""" 65 return N.mean(x)
66 67
68 -def L2Normed(x, norm=1.0, reverse=False):
69 """Norm the values so that regular vector norm becomes `norm` 70 71 More verbose: Norm that the sum of the squared elements of the 72 returned vector becomes `norm`. 73 """ 74 xnorm = N.linalg.norm(x) 75 return x * (norm/xnorm)
76
77 -def L1Normed(x, norm=1.0, reverse=False):
78 """Norm the values so that L_1 norm (sum|x|) becomes `norm`""" 79 xnorm = N.sum(N.abs(x)) 80 return x * (norm/xnorm)
81 82
83 -def RankOrder(x, reverse=False):
84 """Rank-order by value. Highest gets 0""" 85 86 # XXX was Yarik on drugs? please simplify this beast 87 nelements = len(x) 88 indexes = N.arange(nelements) 89 t_indexes = indexes 90 if not reverse: 91 t_indexes = indexes[::-1] 92 tosort = zip(x, indexes) 93 tosort.sort() 94 ztosort = zip(tosort, t_indexes) 95 rankorder = N.empty(nelements, dtype=int) 96 rankorder[ [x[0][1] for x in ztosort] ] = \ 97 [x[1] for x in ztosort] 98 return rankorder
99 100
101 -def ReverseRankOrder(x):
102 """Convinience functor""" 103 return RankOrder(x, reverse=True)
104 105
106 -class OverAxis(object):
107 """Helper to apply transformer over specific axis 108 """ 109
110 - def __init__(self, transformer, axis=None):
111 """Initialize transformer wrapper with an axis. 112 113 :Parameters: 114 transformer 115 A callable to be used 116 axis : None or int 117 If None -- apply transformer across all the data. If some 118 int -- over that axis 119 """ 120 self.transformer = transformer 121 # sanity check 122 if not (axis is None or isinstance(axis, int)): 123 raise ValueError, "axis must be specified by integer" 124 self.axis = axis
125 126
127 - def __call__(self, x, *args, **kwargs):
128 transformer = self.transformer 129 axis = self.axis 130 if axis is None: 131 return transformer(x, *args, **kwargs) 132 133 x = N.asanyarray(x) 134 shape = x.shape 135 if axis >= len(shape): 136 raise ValueError, "Axis given in constructor %d is higher " \ 137 "than dimensionality of the data of shape %s" % (axis, shape) 138 139 # WRONG! ;-) 140 #for ind in xrange(shape[axis]): 141 # results.append(transformer(x.take([ind], axis=axis), 142 # *args, **kwargs)) 143 144 # TODO: more elegant/speedy solution? 145 shape_sweep = shape[:axis] + shape[axis+1:] 146 shrinker = None 147 """Either transformer reduces the dimensionality of the data""" 148 #results = N.empty(shape_out, dtype=x.dtype) 149 for index_sweep in N.ndindex(shape_sweep): 150 if axis > 0: 151 index = index_sweep[:axis] 152 else: 153 index = () 154 index = index + (slice(None),) + index_sweep[axis:] 155 x_sel = x[index] 156 x_t = transformer(x_sel, *args, **kwargs) 157 if shrinker is None: 158 if N.isscalar(x_t) or x_t.shape == shape_sweep: 159 results = N.empty(shape_sweep, dtype=x.dtype) 160 shrinker = True 161 elif x_t.shape == x_sel.shape: 162 results = N.empty(x.shape, dtype=x.dtype) 163 shrinker = False 164 else: 165 raise RuntimeError, 'Not handled by OverAxis kind of transformer' 166 167 if shrinker: 168 results[index_sweep] = x_t 169 else: 170 results[index] = x_t 171 172 return results
173