about summary refs log tree commit diff stats
path: root/translate_subx_emulated
blob: 0eab2c3278713885071dfa79fd16e71bea9ef6cb (plain) (blame)
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
#!/bin/sh
# Translate SubX by running the self-hosted translator in emulated mode on
# Linux or BSD or Mac.
#
# Possible knobs:
#   Whether to run a phase natively or in emulated mode.
#     Just always emulate for now since we debug on non-Linux.
#   Whether to stop after a phase.
#     Just always run all phases, but print out phases so it's clear where an
#     error happens.
#   Whether to trace a phase. Whether to always trace or rerun with tracing
#   enabled after an error.
#     Leave tracing to other scripts. We save intermediate files so it's easy
#     to rerun a single phase afterwards.
#   Whether to run a phase with debug information. (Need to juggle multiple
#   sets of debug files.)
#     Again, that's for subsequent scripts.

set -e

./build

echo "  braces"
cat $*          |./bootstrap_bin run apps/braces   > a.braces

echo "  calls"
cat a.braces    |./bootstrap_bin run apps/calls    > a.calls

echo "  sigils"
cat a.calls     |./bootstrap_bin run apps/sigils   > a.sigils

echo "  tests"
cat a.sigils    |./bootstrap_bin run apps/tests    > a.tests

echo "  dquotes"
cat a.tests     |./bootstrap_bin run apps/dquotes  > a.dquotes

echo "  assort"
cat a.dquotes   |./bootstrap_bin run apps/assort   > a.assort

echo "  pack"
cat a.assort    |./bootstrap_bin run apps/pack     > a.pack

echo "  survey"
cat a.pack      |./bootstrap_bin run apps/survey   > a.survey

echo "  hex"
cat a.survey    |./bootstrap_bin run apps/hex      > a.elf

chmod +x a.elf
0; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } .highlight .hll { background-color: #ffffcc } .highlight .c { color: #888888 } /* Comment */ .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ .highlight .k { color: #008800; font-weight: bold } /* Keyword */ .highlight .ch { color: #888888 } /* Comment.Hashbang */ .highlight .cm { color: #888888 } /* Comment.Multiline */ .highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */ .highlight .cpf { color: #888888 } /* Comment.PreprocFile */ .highlight .c1 { color: #888888 } /* Comment.Single */ .highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */ .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */ .highlight .gr { color: #aa0000 } /* Generic.Error */ .highlight .gh { color: #333333 } /* Generic.Heading */ .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ .highlight .go { color: #888888 } /* Generic.Output */ .highlight .gp { color: #555555 } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #666666 } /* Generic.Subheading */ .highlight .gt { color: #aa0000 } /* Generic.Traceback */ .highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008800 } /* Keyword.Pseudo */ .highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
#
#
#            Nim's Runtime Library
#        (c) Copyright 2015 Nim contributors
#
#    See the file "copying.txt", included in this
#    distribution, for details about the copyright.
#

## Statistical analysis framework for performing
## basic statistical analysis of data.
## The data is analysed in a single pass, when it
## is pushed to a `RunningStat` or `RunningRegress` object.
##
## `RunningStat` calculates for a single data set
## - n (data count)
## - min (smallest value)
## - max (largest value)
## - sum
## - mean
## - variance
## - varianceS (sample variance)
## - standardDeviation
## - standardDeviationS (sample standard deviation)
## - skewness (the third statistical moment)
## - kurtosis (the fourth statistical moment)
##
## `RunningRegress` calculates for two sets of data
## - n (data count)
## - slope
## - intercept
## - correlation
##
## Procs are provided to calculate statistics on `openArray`s.
##
## However, if more than a single statistical calculation is required, it is more
## efficient to push the data once to a `RunningStat` object and then
## call the numerous statistical procs for the `RunningStat` object:

runnableExamples:
  from std/math import almostEqual

  template `~=`(a, b: float): bool = almostEqual(a, b)

  var statistics: RunningStat  # must be var
  statistics.push(@[1.0, 2.0, 1.0, 4.0, 1.0, 4.0, 1.0, 2.0])
  doAssert statistics.n == 8
  doAssert statistics.mean() ~= 2.0
  doAssert statistics.variance() ~= 1.5
  doAssert statistics.varianceS() ~= 1.714285714285715
  doAssert statistics.skewness() ~= 0.8164965809277261
  doAssert statistics.skewnessS() ~= 1.018350154434631
  doAssert statistics.kurtosis() ~= -1.0
  doAssert statistics.kurtosisS() ~= -0.7000000000000008

from math import FloatClass, sqrt, pow, round

when defined(nimPreviewSlimSystem):
  import std/[assertions, formatfloat]

{.push debugger: off.} # the user does not want to trace a part
                       # of the standard library!
{.push checks: off, line_dir: off, stack_trace: off.}

type
  RunningStat* = object           ## An accumulator for statistical data.
    n*: int                       ## amount of pushed data
    min*, max*, sum*: float       ## self-explaining
    mom1, mom2, mom3, mom4: float ## statistical moments, mom1 is mean

  RunningRegress* = object ## An accumulator for regression calculations.
    n*: int                ## amount of pushed data
    x_stats*: RunningStat  ## stats for the first set of data
    y_stats*: RunningStat  ## stats for the second set of data
    s_xy: float            ## accumulated data for combined xy

# ----------- RunningStat --------------------------

proc clear*(s: var RunningStat) =
  ## Resets `s`.
  s.n = 0
  s.min = 0.0
  s.max = 0.0
  s.sum = 0.0
  s.mom1 = 0.0
  s.mom2 = 0.0
  s.mom3 = 0.0
  s.mom4 = 0.0

proc push*(s: var RunningStat, x: float) =
  ## Pushes a value `x` for processing.
  if s.n == 0:
    s.min = x
    s.max = x
  else:
    if s.min > x: s.min = x
    if s.max < x: s.max = x
  inc(s.n)
  # See Knuth TAOCP vol 2, 3rd edition, page 232
  s.sum += x
  let n = toFloat(s.n)
  let delta = x - s.mom1
  let delta_n = delta / toFloat(s.n)
  let delta_n2 = delta_n * delta_n
  let term1 = delta * delta_n * toFloat(s.n - 1)
  s.mom4 += term1 * delta_n2 * (n*n - 3*n + 3) +
              6*delta_n2*s.mom2 - 4*delta_n*s.mom3
  s.mom3 += term1 * delta_n * (n - 2) - 3*delta_n*s.mom2
  s.mom2 += term1
  s.mom1 += delta_n

proc push*(s: var RunningStat, x: int) =
  ## Pushes a value `x` for processing.
  ##
  ## `x` is simply converted to `float`
  ## and the other push operation is called.
  s.push(toFloat(x))

proc push*(s: var RunningStat, x: openArray[float|int]) =
  ## Pushes all values of `x` for processing.
  ##
  ## Int values of `x` are simply converted to `float` and
  ## the other push operation is called.
  for val in x:
    s.push(val)

proc mean*(s: RunningStat): float =
  ## Computes the current mean of `s`.
  result = s.mom1

proc variance*(s: RunningStat): float =
  ## Computes the current population variance of `s`.
  result = s.mom2 / toFloat(s.n)

proc varianceS*(s: RunningStat): float =
  ## Computes the current sample variance of `s`.
  if s.n > 1: result = s.mom2 / toFloat(s.n - 1)

proc standardDeviation*(s: RunningStat): float =
  ## Computes the current population standard deviation of `s`.
  result = sqrt(variance(s))

proc standardDeviationS*(s: RunningStat): float =
  ## Computes the current sample standard deviation of `s`.
  result = sqrt(varianceS(s))

proc skewness*(s: RunningStat): float =
  ## Computes the current population skewness of `s`.
  result = sqrt(toFloat(s.n)) * s.mom3 / pow(s.mom2, 1.5)

proc skewnessS*(s: RunningStat): float =
  ## Computes the current sample skewness of `s`.
  let s2 = skewness(s)
  result = sqrt(toFloat(s.n*(s.n-1)))*s2 / toFloat(s.n-2)

proc kurtosis*(s: RunningStat): float =
  ## Computes the current population kurtosis of `s`.
  result = toFloat(s.n) * s.mom4 / (s.mom2 * s.mom2) - 3.0

proc kurtosisS*(s: RunningStat): float =
  ## Computes the current sample kurtosis of `s`.
  result = toFloat(s.n-1) / toFloat((s.n-2)*(s.n-3)) *
              (toFloat(s.n+1)*kurtosis(s) + 6)

proc `+`*(a, b: RunningStat): RunningStat =
  ## Combines two `RunningStat`s.
  ##
  ## Useful when performing parallel analysis of data series
  ## and needing to re-combine parallel result sets.
  result.clear()
  result.n = a.n + b.n

  let delta = b.mom1 - a.mom1
  let delta2 = delta*delta
  let delta3 = delta*delta2
  let delta4 = delta2*delta2
  let n = toFloat(result.n)

  result.mom1 = (a.n.float*a.mom1 + b.n.float*b.mom1) / n
  result.mom2 = a.mom2 + b.mom2 + delta2 * a.n.float * b.n.float / n
  result.mom3 = a.mom3 + b.mom3 +
                delta3 * a.n.float * b.n.float * (a.n.float - b.n.float)/(n*n);
  result.mom3 += 3.0*delta * (a.n.float*b.mom2 - b.n.float*a.mom2) / n
  result.mom4 = a.mom4 + b.mom4 +
            delta4*a.n.float*b.n.float * toFloat(a.n*a.n - a.n*b.n + b.n*b.n) /
                (n*n*n)
  result.mom4 += 6.0*delta2 * (a.n.float*a.n.float*b.mom2 + b.n.float*b.n.float*a.mom2) /
                (n*n) +
                4.0*delta*(a.n.float*b.mom3 - b.n.float*a.mom3) / n
  result.max = max(a.max, b.max)
  result.min = min(a.min, b.min)

proc `+=`*(a: var RunningStat, b: RunningStat) {.inline.} =
  ## Adds the `RunningStat` `b` to `a`.
  a = a + b

proc `$`*(a: RunningStat): string =
  ## Produces a string representation of the `RunningStat`. The exact
  ## format is currently unspecified and subject to change. Currently
  ## it contains:
  ##
  ## - the number of probes
  ## - min, max values
  ## - sum, mean and standard deviation.
  result = "RunningStat(\n"
  result.add "  number of probes: " & $a.n & "\n"
  result.add "  max: " & $a.max & "\n"
  result.add "  min: " & $a.min & "\n"
  result.add "  sum: " & $a.sum & "\n"
  result.add "  mean: " & $a.mean & "\n"
  result.add "  std deviation: " & $a.standardDeviation & "\n"
  result.add ")"

# ---------------------- standalone array/seq stats ---------------------

proc mean*[T](x: openArray[T]): float =
  ## Computes the mean of `x`.
  var rs: RunningStat
  rs.push(x)
  result = rs.mean()

proc variance*[T](x: openArray[T]): float =
  ## Computes the population variance of `x`.
  var rs: RunningStat
  rs.push(x)
  result = rs.variance()

proc varianceS*[T](x: openArray[T]): float =
  ## Computes the sample variance of `x`.
  var rs: RunningStat
  rs.push(x)
  result = rs.varianceS()

proc standardDeviation*[T](x: openArray[T]): float =
  ## Computes the population standard deviation of `x`.
  var rs: RunningStat
  rs.push(x)
  result = rs.standardDeviation()

proc standardDeviationS*[T](x: openArray[T]): float =
  ## Computes the sample standard deviation of `x`.
  var rs: RunningStat
  rs.push(x)
  result = rs.standardDeviationS()

proc skewness*[T](x: openArray[T]): float =
  ## Computes the population skewness of `x`.
  var rs: RunningStat
  rs.push(x)
  result = rs.skewness()

proc skewnessS*[T](x: openArray[T]): float =
  ## Computes the sample skewness of `x`.
  var rs: RunningStat
  rs.push(x)
  result = rs.skewnessS()

proc kurtosis*[T](x: openArray[T]): float =
  ## Computes the population kurtosis of `x`.
  var rs: RunningStat
  rs.push(x)
  result = rs.kurtosis()

proc kurtosisS*[T](x: openArray[T]): float =
  ## Computes the sample kurtosis of `x`.
  var rs: RunningStat
  rs.push(x)
  result = rs.kurtosisS()

# ---------------------- Running Regression -----------------------------

proc clear*(r: var RunningRegress) =
  ## Resets `r`.
  r.x_stats.clear()
  r.y_stats.clear()
  r.s_xy = 0.0
  r.n = 0

proc push*(r: var RunningRegress, x, y: float) =
  ## Pushes two values `x` and `y` for processing.
  r.s_xy += (r.x_stats.mean() - x)*(r.y_stats.mean() - y) *
                toFloat(r.n) / toFloat(r.n + 1)
  r.x_stats.push(x)
  r.y_stats.push(y)
  inc(r.n)

proc push*(r: var RunningRegress, x, y: int) {.inline.} =
  ## Pushes two values `x` and `y` for processing.
  ##
  ## `x` and `y` are converted to `float`
  ## and the other push operation is called.
  r.push(toFloat(x), toFloat(y))

proc push*(r: var RunningRegress, x, y: openArray[float|int]) =
  ## Pushes two sets of values `x` and `y` for processing.
  assert(x.len == y.len)
  for i in 0..<x.len:
    r.push(x[i], y[i])

proc slope*(r: RunningRegress): float =
  ## Computes the current slope of `r`.
  let s_xx = r.x_stats.varianceS()*toFloat(r.n - 1)
  result = r.s_xy / s_xx

proc intercept*(r: RunningRegress): float =
  ## Computes the current intercept of `r`.
  result = r.y_stats.mean() - r.slope()*r.x_stats.mean()

proc correlation*(r: RunningRegress): float =
  ## Computes the current correlation of the two data
  ## sets pushed into `r`.
  let t = r.x_stats.standardDeviation() * r.y_stats.standardDeviation()
  result = r.s_xy / (toFloat(r.n) * t)

proc `+`*(a, b: RunningRegress): RunningRegress =
  ## Combines two `RunningRegress` objects.
  ##
  ## Useful when performing parallel analysis of data series
  ## and needing to re-combine parallel result sets
  result.clear()
  result.x_stats = a.x_stats + b.x_stats
  result.y_stats = a.y_stats + b.y_stats
  result.n = a.n + b.n

  let delta_x = b.x_stats.mean() - a.x_stats.mean()
  let delta_y = b.y_stats.mean() - a.y_stats.mean()
  result.s_xy = a.s_xy + b.s_xy +
      toFloat(a.n*b.n)*delta_x*delta_y/toFloat(result.n)

proc `+=`*(a: var RunningRegress, b: RunningRegress) =
  ## Adds the `RunningRegress` `b` to `a`.
  a = a + b

{.pop.}
{.pop.}