class Truncate(LibFcn): name = prefix + "truncate" sig = Sigs([Sig([{"x": P.Array(P.Array(P.Double()))}, {"keep": P.Int()}], P.Array(P.Array(P.Double()))), Sig([{"x": P.Map(P.Map(P.Double()))}, {"keep": P.Array(P.String())}], P.Map(P.Map(P.Double())))]) errcodeBase = 24120 def __call__(self, state, scope, pos, paramTypes, x, keep): if keep < 0: keep = 0 if isinstance(x, (list, tuple)) and all(isinstance(xi, (list, tuple)) for xi in x): rows = len(x) if rows < 1: raise PFARuntimeException("too few rows/cols", self.errcodeBase + 0, self.name, pos) cols = len(x[0]) if cols < 1: raise PFARuntimeException("too few rows/cols", self.errcodeBase + 0, self.name, pos) if raggedArray(x): raise PFARuntimeException("ragged columns", self.errcodeBase + 1, self.name, pos) return x[:keep] elif isinstance(x, dict) and all(isinstance(x[i], dict) for i in x.keys()): rows = rowKeys(x) cols = colKeys(x) if len(rows) < 1 or len(cols) < 1: raise PFARuntimeException("too few rows/cols", self.errcodeBase + 0, self.name, pos) return dict((k, x[k]) for k in rows if k in keep)
class Symmetric(LibFcn): name = prefix + "symmetric" sig = Sigs([Sig([{"x": P.Array(P.Array(P.Double()))}, {"tol": P.Double()}], P.Boolean()), Sig([{"x": P.Map(P.Map(P.Double()))}, {"tol": P.Double()}], P.Boolean())]) errcodeBase = 24100 @staticmethod def same(x, y, tol): if math.isinf(x) and math.isinf(y) and ((x > 0.0 and y > 0.0) or (x < 0.0 and y < 0.0)): return True elif math.isnan(x) and math.isnan(y): return True elif not math.isinf(x) and not math.isnan(x) and not math.isinf(y) and not math.isnan(y): return abs(x - y) < tol else: return False def __call__(self, state, scope, pos, paramTypes, x, tol): if isinstance(x, (list, tuple)) and all(isinstance(xi, (list, tuple)) for xi in x): rows = len(x) if rows < 1: raise PFARuntimeException("too few rows/cols", self.errcodeBase + 0, self.name, pos) cols = len(x[0]) if cols < 1: raise PFARuntimeException("too few rows/cols", self.errcodeBase + 0, self.name, pos) if raggedArray(x): raise PFARuntimeException("ragged columns", self.errcodeBase + 1, self.name, pos) if rows != cols: raise PFARuntimeException("non-square matrix", self.errcodeBase + 2, self.name, pos) return all(all(self.same(x[i][j], x[j][i], tol) for j in range(cols)) for i in range(rows)) elif isinstance(x, dict) and all(isinstance(x[i], dict) for i in x.keys()): keys = list(rowKeys(x).union(colKeys(x))) if len(keys) < 1 or all(len(row) == 0 for row in x.values()): raise PFARuntimeException("too few rows/cols", self.errcodeBase + 0, self.name, pos) return all(all(self.same(x.get(i, {}).get(j, 0.0), x.get(j, {}).get(i, 0.0), tol) for j in keys) for i in keys)
class Bernoulli(LibFcn): name = prefix + "bernoulli" sig = Sigs([ Sig([{ "datum": P.Array(P.String()) }, { "classModel": P.Map(P.Double()) }], P.Double()), Sig([{ "datum": P.Array(P.String()) }, { "classModel": P.WildRecord("C", {"values": P.Map(P.Double())}) }], P.Double()) ]) errcodeBase = 10020 def __call__(self, state, scope, pos, paramTypes, datum, classModel): if paramTypes[1]["type"] == "record": classModel = classModel["values"] ll = 0.0 for v in list(classModel.values()): if (v <= 0.0) or (v >= 1.0): raise PFARuntimeException( "probability in classModel cannot be less than 0 or greater than 1", self.errcodeBase + 0, self.name, pos) ll += math.log(1.0 - v) for item in datum: p = classModel.get(item, None) if p is not None: ll += math.log(p) - math.log(1.0 - p) return ll
class Det(LibFcn): name = prefix + "det" sig = Sigs([Sig([{"x": P.Array(P.Array(P.Double()))}], P.Double()), Sig([{"x": P.Map(P.Map(P.Double()))}], P.Double())]) errcodeBase = 24090 def __call__(self, state, scope, pos, paramTypes, x): if isinstance(x, (list, tuple)) and all(isinstance(xi, (list, tuple)) for xi in x): rows = len(x) if rows < 1: raise PFARuntimeException("too few rows/cols", self.errcodeBase + 0, self.name, pos) cols = len(x[0]) if cols < 1: raise PFARuntimeException("too few rows/cols", self.errcodeBase + 0, self.name, pos) if raggedArray(x): raise PFARuntimeException("ragged columns", self.errcodeBase + 1, self.name, pos) if rows != cols: raise PFARuntimeException("non-square matrix", self.errcodeBase + 2, self.name, pos) if any(any(math.isnan(z) or math.isinf(z) for z in row) for row in x): return float("nan") else: return float(np().linalg.det(arraysToMatrix(x))) elif isinstance(x, dict) and all(isinstance(x[i], dict) for i in x.keys()): keys = list(rowKeys(x).union(colKeys(x))) if len(keys) < 1 or all(len(row) == 0 for row in x.values()): raise PFARuntimeException("too few rows/cols", self.errcodeBase + 0, self.name, pos) if any(any(math.isnan(z) or math.isinf(z) for z in row.values()) for row in x.values()): return float("nan") else: return float(np().linalg.det(mapsToMatrix(x, keys, keys)))
class AbsDiff(LibFcn): name = prefix + "absDiff" sig = Sig([{"x": P.Double()}, {"y": P.Double()}], P.Double()) errcodeBase = 28010 def __call__(self, state, scope, pos, paramTypes, x, y): return abs(x - y)
class Divide(LibFcn): name = "/" sig = Sig([{"x": P.Double()}, {"y": P.Double()}], P.Double()) errcodeBase = 18030 def __call__(self, state, scope, pos, paramTypes, x, y): return div(x, y)
class KSTwoSample(LibFcn): name = prefix + "kolmogorov" sig = Sig([{ "x": P.Array(P.Double()) }, { "y": P.Array(P.Double()) }], P.Double()) errcodeBase = 38000 def __call__(self, state, scope, pos, paramTypes, x, y): x = sorted([xi for xi in x if not math.isnan(xi)]) y = sorted([yi for yi in y if not math.isnan(yi)]) n1, n2 = len(x), len(y) if (x == y): return 1.0 elif ((len(x) == 0) or (len(y) == 0)): return 0.0 else: j1 = j2 = 0 fn1 = fn2 = d = 0.0 while ((j1 < n1) and (j2 < n2)): d1 = x[j1] d2 = y[j2] if d1 <= d2: j1 += 1 fn1 = float(j1) / n1 if d2 <= d1: j2 += 1 fn2 = float(j2) / n2 dt = abs(fn2 - fn1) if dt > d: d = dt en = math.sqrt((n1 * n2) / float(n1 + n2)) stat = (en + 0.12 + 0.11 / en) * d return 1.0 - kolomogorov_cdf(stat)
class Euclidean(MetricWithMissingValues): name = prefix + "euclidean" sig = Sigs([ Sig([{ "similarity": P.Fcn([P.Wildcard("A"), P.Wildcard("B")], P.Double()) }, { "x": P.Array(P.Union([P.Null(), P.Wildcard("A")])) }, { "y": P.Array(P.Union([P.Null(), P.Wildcard("B")])) }], P.Double()), Sig([{ "similarity": P.Fcn([P.Wildcard("A"), P.Wildcard("B")], P.Double()) }, { "x": P.Array(P.Union([P.Null(), P.Wildcard("A")])) }, { "y": P.Array(P.Union([P.Null(), P.Wildcard("B")])) }, { "missingWeight": P.Array(P.Double()) }], P.Double()) ]) errcodeBase = 28030 def increment(self, tally, x): return tally + x**2 def finalize(self, x): return math.sqrt(x)
class Linear(LibFcn): name = prefix + "linear" sig = Sig([{"x": P.Array(P.Double())}, {"y": P.Array(P.Double())}], P.Double()) errcodeBase = 23000 def __call__(self, state, scope, pos, paramTypes, x, y): return dot(x, y, self.errcodeBase + 0, self.name, pos)
class Gaussian(LibFcn): name = prefix + "gaussian" sig = Sig([{"mu": P.Double()}, {"sigma": P.Double()}], P.Double()) errcodeBase = 34120 def __call__(self, state, scope, pos, paramTypes, mu, sigma): return state.rand.gauss(mu, sigma)
class SoftMax(LibFcn): name = prefix + "softmax" sig = Sigs([ Sig([{ "x": P.Array(P.Double()) }], P.Array(P.Double())), Sig([{ "x": P.Map(P.Double()) }], P.Map(P.Double())) ]) errcodeBase = 25000 def __call__(self, state, scope, pos, paramTypes, x): if len(x) == 0: raise PFARuntimeException("empty input", self.errcodeBase + 0, self.name, pos) if paramTypes[0]["type"] == "map": xx = x.copy() tmp = map(abs, xx.values()) if xx.values()[tmp.index(max(tmp))] >= 0: m = max(xx.values()) else: m = min(xx.values()) denom = sum([math.exp(v - m) for v in x.values()]) for key in x.keys(): xx[key] = float(math.exp(xx[key] - m) / denom) return xx else: tmp = map(abs, x) if x[tmp.index(max(tmp))] >= 0: m = max(x) else: m = min(x) denom = sum([math.exp(v - m) for v in x]) return [float(math.exp(val - m) / denom) for val in x]
class Mahalanobis(LibFcn): name = prefix + "mahalanobis" sig = Sigs([Sig([{"observation": P.Array(P.Double())}, {"prediction": P.Array(P.Double())}, {"covariance": P.Array(P.Array(P.Double()))}], P.Double(), Lifespan(None, PFAVersion(0, 7, 2), PFAVersion(0, 9, 0), "use test.mahalanobis instead")), Sig([{"observation": P.Map(P.Double())}, {"prediction": P.Map(P.Double())}, {"covariance": P.Map(P.Map(P.Double()))}], P.Double(), Lifespan(None, PFAVersion(0, 7, 2), PFAVersion(0, 9, 0), "use test.mahalanobis instead"))]) errcodeBase = 31040 def __call__(self, state, scope, pos, paramTypes, observation, prediction, covariance): if isinstance(observation, (tuple, list)): if (len(observation) < 1): raise PFARuntimeException("too few rows/cols", self.errcodeBase + 0, self.name, pos) if (len(observation) != len(prediction)): raise PFARuntimeException("misaligned prediction", self.errcodeBase + 1, self.name, pos) if (not all(len(i)==len(covariance[0]) for i in covariance)) and (len(covariance) != len(covariance[0])): raise PFARuntimeException("misaligned covariance", self.errcodeBase + 2, self.name, pos) x = np().array([(o - p) for o, p in zip(observation, prediction)]) C = np().array(covariance) else: if (len(observation) < 1): raise PFARuntimeException("too few rows/cols", self.errcodeBase + 0, self.name, pos) if (len(observation) != len(prediction)): raise PFARuntimeException("misaligned prediction", self.errcodeBase + 1, self.name, pos) # use observation keys throughout keys = list(observation.keys()) try: x = np().array([observation[key] - prediction[key] for key in keys]) except: raise PFARuntimeException("misaligned prediction", self.errcodeBase + 1, self.name, pos) C = np().empty((len(keys), len(keys))) try: for i,k1 in enumerate(keys): for j,k2 in enumerate(keys): C[i,j] = float(covariance[k1][k2]) except: raise PFARuntimeException("misaligned covariance", self.errcodeBase + 2, self.name, pos) return float(np().sqrt(np().linalg.solve(C, x).T.dot(x)))
class ErrorOnNonNum(LibFcn): name = prefix + "errorOnNonNum" sig = Sigs([ Sig([{ "x": P.Float() }], P.Float()), Sig([{ "x": P.Double() }], P.Double()) ]) errcodeBase = 21050 def __call__(self, state, scope, pos, paramTypes, x): if math.isnan(x): raise PFARuntimeException("encountered nan", self.errcodeBase + 0, self.name, pos) elif math.isinf(x): if x > 0.0: raise PFARuntimeException("encountered +inf", self.errcodeBase + 1, self.name, pos) else: raise PFARuntimeException("encountered -inf", self.errcodeBase + 2, self.name, pos) else: return x
class Transpose(LibFcn): name = prefix + "transpose" sig = Sigs([Sig([{"x": P.Array(P.Array(P.Double()))}], P.Array(P.Array(P.Double()))), Sig([{"x": P.Map(P.Map(P.Double()))}], P.Map(P.Map(P.Double())))]) errcodeBase = 24060 def __call__(self, state, scope, pos, paramTypes, x): if isinstance(x, (list, tuple)) and all(isinstance(xi, (list, tuple)) for xi in x): rows = len(x) if rows < 1: raise PFARuntimeException("too few rows/cols", self.errcodeBase + 0, self.name, pos) cols = len(x[0]) if cols < 1: raise PFARuntimeException("too few rows/cols", self.errcodeBase + 0, self.name, pos) if raggedArray(x): raise PFARuntimeException("ragged columns", self.errcodeBase + 1, self.name, pos) return [[x[r][c] for r in range(rows)] for c in range(cols)] elif isinstance(x, dict) and all(isinstance(x[i], dict) for i in x.keys()): rows = rowKeys(x) cols = colKeys(x) if len(rows) < 1 or len(cols) < 1: raise PFARuntimeException("too few rows/cols", self.errcodeBase + 0, self.name, pos) if raggedMap(x): raise PFARuntimeException("ragged columns", self.errcodeBase + 1, self.name, pos) return dict((c, dict((r, x[r][c]) for r in rows)) for c in cols)
class Chi2Prob(LibFcn): name = prefix + "chi2Prob" sig = Sig([{ "state": P.WildRecord("A", { "chi2": P.Double(), "dof": P.Int() }) }], P.Double()) errcodeBase = 38060 def __call__(self, state, scope, pos, paramTypes, state_): chi2 = state_["chi2"] dof = state_["dof"] if dof < 0: raise PFARuntimeException("invalid parameterization", self.errcodeBase + 0, self.name, pos) elif dof == 0: if chi2 > 0: return 1.0 else: return 0.0 elif math.isnan(chi2): return float("nan") elif math.isinf(chi2): if chi2 > 0: return 1.0 else: return 0.0 else: return float( Chi2Distribution(dof, self.errcodeBase + 0, self.name, pos).CDF(chi2))
class UpdateHoltWintersPeriodic(LibFcn): name = prefix + "updateHoltWintersPeriodic" sig = Sig([{"x": P.Double()}, {"alpha": P.Double()}, {"beta": P.Double()}, {"gamma": P.Double()}, {"state": P.WildRecord("A", {"level": P.Double(), "trend": P.Double(), "cycle": P.Array(P.Double()), "multiplicative": P.Boolean()})}], P.Wildcard("A")) errcodeBase = 14050 def __call__(self, state, scope, pos, paramTypes, x, alpha, beta, gamma, theState): if alpha < 0.0 or alpha > 1.0: raise PFARuntimeException("alpha out of range", self.errcodeBase + 0, self.name, pos) if beta < 0.0 or beta > 1.0: raise PFARuntimeException("beta out of range", self.errcodeBase + 1, self.name, pos) if gamma < 0.0 or gamma > 1.0: raise PFARuntimeException("gamma out of range", self.errcodeBase + 2, self.name, pos) level_prev = theState["level"] trend_prev = theState["trend"] cycle_unrotated = theState["cycle"] if len(cycle_unrotated) == 0: raise PFARuntimeException("empty cycle", self.errcodeBase + 3, self.name, pos) cycle_rotated = cycle_unrotated[1:] + [cycle_unrotated[0]] cycle_prev = cycle_rotated[0] if theState["multiplicative"]: level = div(alpha * x, cycle_prev) + (1.0 - alpha) * (level_prev + trend_prev) trend = beta * (level - level_prev) + (1.0 - beta) * trend_prev cycle = div(gamma * x, level) + (1.0 - gamma) * cycle_prev else: level = alpha * (x - cycle_prev) + (1.0 - alpha) * (level_prev + trend_prev) trend = beta * (level - level_prev) + (1.0 - beta) * trend_prev cycle = gamma * (x - level) + (1.0 - gamma) * cycle_prev return dict(theState, level=level, trend=trend, cycle=([cycle] + cycle_rotated[1:]))
class Update(UpdateMeanVariance): name = prefix + "update" sig = Sig([{"x": P.Double()}, {"w": P.Double()}, {"state": P.WildRecord("A", {"count": P.Double()})}], P.Wildcard("A")) errcodeBase = 14000 def _getRecord(self, paramType): if isinstance(paramType, AvroUnion): for t in paramType.types: if not isinstance(t, AvroNull): return t else: return paramType def __call__(self, state, scope, pos, paramTypes, x, w, theState, level): originalCount = theState["count"] count = originalCount + w if level == 0: return dict(theState, count=count) else: mean = theState["mean"] delta = x - mean shift = div(delta * w, count) mean += shift if level == 1: return dict(theState, count=count, mean=mean) else: varianceTimesCount = theState["variance"] * originalCount varianceTimesCount += originalCount * delta * shift return dict(theState, count=count, mean=mean, variance=div(varianceTimesCount, count))
class UpdateEWMA(LibFcn): name = prefix + "updateEWMA" sig = Sig([{"x": P.Double()}, {"alpha": P.Double()}, {"state": P.WildRecord("A", {"mean": P.Double()})}], P.Wildcard("A")) errcodeBase = 14030 def _getRecord(self, paramType): if isinstance(paramType, AvroUnion): for t in paramType.types: if not isinstance(t, AvroNull): return t else: return paramType def genpy(self, paramTypes, args, pos): hasVariance = False for x in self._getRecord(paramTypes[2]).fields: if x.name == "variance": if not x.avroType.accepts(AvroDouble()): raise PFASemanticException(self.name + " is being given a state record type in which the \"variance\" field is not a double: " + str(x.avroType), None) hasVariance = True return "self.f[{0}]({1}, {2})".format(repr(self.name), ", ".join(["state", "scope", repr(pos), repr(paramTypes)] + args), hasVariance) def __call__(self, state, scope, pos, paramTypes, x, alpha, theState, hasVariance): if alpha < 0.0 or alpha > 1.0: raise PFARuntimeException("alpha out of range", self.errcodeBase + 0, self.name, pos) mean = theState["mean"] diff = x - mean incr = alpha * diff if hasVariance: variance = theState["variance"] return dict(theState, mean=(mean + incr), variance=((1.0 - alpha) * (variance + diff * incr))) else: return dict(theState, mean=(mean + incr))
class Bin(LibFcn): name = prefix + "bin" sig = Sigs([Sig([{"x": P.Double()}, {"numbins": P.Int()}, {"low": P.Double()}, {"high": P.Double()}], P.Int()), Sig([{"x": P.Double()}, {"origin": P.Double()}, {"width": P.Double()}], P.Int())]) errcodeBase = 22000 def __call__(self, state, scope, pos, paramTypes, x, *args): if len(args) == 3: numbins, low, high = args if low >= high or math.isnan(low) or math.isnan(high): raise PFARuntimeException("bad histogram range", self.errcodeBase + 0, self.name, pos) if numbins < 1: raise PFARuntimeException("bad histogram scale", self.errcodeBase + 1, self.name, pos) if math.isnan(x) or x < low or x >= high: raise PFARuntimeException("x out of range", self.errcodeBase + 2, self.name, pos) out = int(math.floor(numbins * div((x - low), (high - low)))) if out < 0 or out >= numbins: raise PFARuntimeException("x out of range", self.errcodeBase + 2, self.name, pos) return out else: origin, width = args if math.isnan(origin) or math.isinf(origin): raise PFARuntimeException("bad histogram range", self.errcodeBase + 0, self.name, pos) if width <= 0.0 or math.isnan(width): raise PFARuntimeException("bad histogram scale", self.errcodeBase + 1, self.name, pos) if math.isnan(x) or math.isinf(x): raise PFARuntimeException("x out of range", self.errcodeBase + 2, self.name, pos) else: return int(math.floor(div((x - origin), width)))
class UpdateHoltWinters(LibFcn): name = prefix + "updateHoltWinters" sig = Sig( [{ "x": P.Double() }, { "alpha": P.Double() }, { "beta": P.Double() }, { "state": P.WildRecord("A", { "level": P.Double(), "trend": P.Double() }) }], P.Wildcard("A")) errcodeBase = 14040 def __call__(self, state, scope, pos, paramTypes, x, alpha, beta, theState): if alpha < 0.0 or alpha > 1.0: raise PFARuntimeException("alpha out of range", self.errcodeBase + 0, self.name, pos) if beta < 0.0 or beta > 1.0: raise PFARuntimeException("beta out of range", self.errcodeBase + 1, self.name, pos) level_prev = theState["level"] trend_prev = theState["trend"] level = alpha * x + (1.0 - alpha) * (level_prev + trend_prev) trend = beta * (level - level_prev) + (1.0 - beta) * trend_prev return dict(theState, level=level, trend=trend)
class Trace(LibFcn): name = prefix + "trace" sig = Sigs([ Sig([{ "x": P.Array(P.Array(P.Double())) }], P.Double()), Sig([{ "x": P.Map(P.Map(P.Double())) }], P.Double()) ]) errcodeBase = 24080 def __call__(self, state, scope, pos, paramTypes, x): if isinstance(x, (list, tuple)) and all( isinstance(xi, (list, tuple)) for xi in x): rows = len(x) if rows == 0: return 0.0 else: cols = len(x[0]) if raggedArray(x): raise PFARuntimeException("ragged columns", self.errcodeBase + 0, self.name, pos) return sum(x[i][i] for i in xrange(min(rows, cols))) elif isinstance(x, dict) and all( isinstance(x[i], dict) for i in x.keys()): keys = rowKeys(x).intersection(colKeys(x)) return sum(x[i][i] for i in keys)
class Taxicab(MetricWithMissingValues): name = prefix + "taxicab" sig = Sigs([ Sig([{ "similarity": P.Fcn([P.Wildcard("A"), P.Wildcard("B")], P.Double()) }, { "x": P.Array(P.Union([P.Null(), P.Wildcard("A")])) }, { "y": P.Array(P.Union([P.Null(), P.Wildcard("B")])) }], P.Double()), Sig([{ "similarity": P.Fcn([P.Wildcard("A"), P.Wildcard("B")], P.Double()) }, { "x": P.Array(P.Union([P.Null(), P.Wildcard("A")])) }, { "y": P.Array(P.Union([P.Null(), P.Wildcard("B")])) }, { "missingWeight": P.Array(P.Double()) }], P.Double()) ]) errcodeBase = 28060 def increment(self, tally, x): return tally + x def finalize(self, x): return x
class Forecast1HoltWinters(LibFcn): name = prefix + "forecast1HoltWinters" sig = Sig( [{ "state": P.WildRecord("A", { "level": P.Double(), "trend": P.Double() }) }], P.Double()) errcodeBase = 14060 def genpy(self, paramTypes, args, pos): hasCycle = False hasMultiplicative = False for x in paramTypes[0].fields: if x.name == "cycle": if not x.avroType.accepts(AvroArray(AvroDouble())): raise PFASemanticException( self.name + " is being given a state record type in which the \"cycle\" field is not an array of double: " + str(x.avroType), None) hasCycle = True elif x.name == "multiplicative": if not x.avroType.accepts(AvroBoolean()): raise PFASemanticException( self.name + " is being given a state record type in which the \"multiplicative\" field is not a boolean: " + str(x.avroType), None) hasMultiplicative = True if hasCycle ^ hasMultiplicative: raise PFASemanticException( self.name + " is being given a state record type with a \"cycle\" but no \"multiplicative\" or vice-versa", None) return "self.f[{0}]({1}, {2})".format( repr(self.name), ", ".join( ["state", "scope", repr(pos), repr(paramTypes)] + args), hasCycle) def __call__(self, state, scope, pos, paramTypes, theState, hasPeriodic): level = theState["level"] trend = theState["trend"] if not hasPeriodic: return level + trend else: cycle = theState["cycle"] L = len(cycle) if L == 0: raise PFARuntimeException("empty cycle", self.errcodeBase + 0, self.name, pos) if theState["multiplicative"]: return (level + trend) * cycle[1 % L] else: return level + trend + cycle[1 % L]
class GeoMean(LibFcn): name = prefix + "geomean" sig = Sig([{"a": P.Array(P.Double())}], P.Double()) errcodeBase = 15440 def __call__(self, state, scope, pos, paramTypes, a): if len(a) == 0: return float("nan") else: return reduce(lambda a, b: a * b, a, 1.0)**(1.0/len(a))
class Score(LibFcn): name = prefix + "score" sig = Sig([{ "datum": P.Array(P.Double()) }, { "model": P.WildRecord( "L", { "const": P.Double(), "posClass": P.Array( P.WildRecord("M", { "supVec": P.Array(P.Double()), "coeff": P.Double() })), "negClass": P.Array( P.WildRecord("N", { "supVec": P.Array(P.Double()), "coeff": P.Double() })) }) }, { "kernel": P.Fcn([P.Array(P.Double()), P.Array(P.Double())], P.Double()) }], P.Double()) errcodeBase = 12000 def __call__(self, state, scope, pos, paramTypes, datum, model, kernel): const = model["const"] negClass = model["negClass"] posClass = model["posClass"] if len(negClass) == 0 and len(posClass) == 0: raise PFARuntimeException("no support vectors", self.errcodeBase + 0, self.name, pos) negClassScore = 0.0 for sv in negClass: supVec = sv["supVec"] if len(supVec) != len(datum): raise PFARuntimeException( "support vectors must have same length as datum", self.errcodeBase + 1, self.name, pos) coeff = sv["coeff"] negClassScore += callfcn(state, scope, kernel, [supVec, datum]) * coeff posClassScore = 0.0 for sv in posClass: supVec = sv["supVec"] if len(supVec) != len(datum): raise PFARuntimeException( "support vectors must have same length as datum", self.errcodeBase + 1, self.name, pos) coeff = sv["coeff"] posClassScore += callfcn(state, scope, kernel, [supVec, datum]) * coeff return negClassScore + posClassScore + const
class Sigmoid(LibFcn): name = prefix + "sigmoid" sig = Sig([{"x": P.Array(P.Double())}, {"y": P.Array(P.Double())}, {"gamma": P.Double()}, {"intercept": P.Double()}], P.Double()) errcodeBase = 23030 def __call__(self, state, scope, pos, paramTypes, x, y, gamma, intercept): return math.tanh(gamma * dot(x, y, self.errcodeBase + 0, self.name, pos) + intercept)
class TanH(LibFcn): name = prefix + "tanh" sig = Sig([{"x": P.Double()}], P.Double()) errcodeBase = 27260 def genpy(self, paramTypes, args, pos): return "math.tanh({0})".format(*args) def __call__(self, state, scope, pos, paramTypes, x): return math.tanh(x)
class ACos(LibFcn): name = prefix + "acos" sig = Sig([{"x": P.Double()}], P.Double()) errcodeBase = 27030 def __call__(self, state, scope, pos, paramTypes, x): try: return math.acos(x) except ValueError: return float("nan")
class RandomDouble(LibFcn): name = prefix + "double" sig = Sig([{"low": P.Double()}, {"high": P.Double()}], P.Double()) errcodeBase = 34030 def __call__(self, state, scope, pos, paramTypes, low, high): if high <= low: raise PFARuntimeException("high must be greater than low", self.errcodeBase + 0, self.name, pos) return state.rand.uniform(low, high)
class Tan(LibFcn): name = prefix + "tan" sig = Sig([{"x": P.Double()}], P.Double()) errcodeBase = 27250 def __call__(self, state, scope, pos, paramTypes, x): if math.isinf(x) or math.isnan(x): return float("nan") else: return math.tan(x)