{"version":3,"sources":["jsdelivr-header.js","/npm/src/activation/relu.ts","/npm/src/activation/sigmoid.ts","/npm/src/activation/tanh.ts","/npm/src/activation/leaky-relu.ts","/npm/src/cross-validate.ts","/npm/src/utilities/kernel.ts","/npm/src/estimator/mean-squared-error.ts","/npm/src/layer/base-layer.ts","/npm/src/utilities/zeros.ts","/npm/src/utilities/zeros-2d.ts","/npm/src/utilities/zeros-3d.ts","/npm/src/layer/activation.ts","/npm/src/layer/filter.ts","/npm/src/layer/internal.ts","/npm/src/layer/modifier.ts","/npm/src/layer/operator.ts","/npm/src/layer/target.ts","/npm/src/layer/types.ts","/npm/src/lookup.ts","/npm/src/praxis/base-praxis.ts","/npm/src/praxis/arthur-deviation-biases.ts","/npm/src/praxis/arthur-deviation-weights.ts","/npm/src/praxis/momentum-root-mean-squared-propagation.ts","/npm/src/utilities/traverse-layers-from.ts","/npm/src/utilities/flatten-layers.ts","/npm/src/utilities/layer-size.ts","/npm/src/layer/add.ts","/npm/src/utilities/random-weight.ts","/npm/src/utilities/random.ts","/npm/src/utilities/randos.ts","/npm/src/layer/random.ts","/npm/src/layer/multiply.ts","/npm/src/layer/sigmoid.ts","/npm/src/utilities/layer-setup.ts","/npm/src/utilities/values.ts","/npm/src/layer/convolution.ts","/npm/src/layer/dropout.ts","/npm/src/layer/fully-connected.ts","/npm/src/layer/negative.ts","/npm/src/layer/multiply-element.ts","/npm/src/utilities/ones.ts","/npm/src/layer/ones.ts","/npm/src/layer/tanh.ts","/npm/src/layer/zeros.ts","/npm/src/layer/input.ts","/npm/src/layer/leaky-relu.ts","/npm/src/layer/pool.ts","/npm/src/layer/recurrent-input.ts","/npm/src/layer/recurrent-zeros.ts","/npm/src/layer/relu.ts","/npm/src/layer/regression.ts","/npm/src/layer/soft-max.ts","/npm/src/layer/svm.ts","/npm/src/layer/transpose.ts","/npm/src/layer/index.ts","/npm/src/layer/arthur-feed-forward.ts","/npm/src/layer/feed-forward.ts","/npm/src/layer/gru.ts","/npm/src/layer/lstm-cell.ts","/npm/src/layer/output.ts","/npm/src/layer/rnn-cell.ts","/npm/src/utilities/layer-from-json.ts","/npm/src/utilities/lookup-table.ts","/npm/brain.js@2.0.0-beta.15/node_modules/thaw.js/browser.js","/npm/src/feed-forward.ts","/npm/src/utilities/cast.ts","/npm/src/utilities/max.ts","/npm/src/utilities/mse.ts","/npm/src/neural-network.ts","/npm/src/neural-network-gpu.ts","/npm/src/layer/recurrent-connection.ts","/npm/src/recurrent.ts","/npm/src/recurrent/matrix/index.ts","/npm/src/recurrent/matrix/random-matrix.ts","/npm/src/utilities/data-formatter.ts","/npm/src/recurrent/matrix/add.ts","/npm/src/recurrent/matrix/add-b.ts","/npm/src/recurrent/matrix/all-ones.ts","/npm/src/recurrent/matrix/clone-negative.ts","/npm/src/recurrent/matrix/multiply.ts","/npm/src/recurrent/matrix/multiply-b.ts","/npm/src/recurrent/matrix/multiply-element.ts","/npm/src/recurrent/matrix/multiply-element-b.ts","/npm/src/recurrent/matrix/relu.ts","/npm/src/recurrent/matrix/relu-b.ts","/npm/src/recurrent/matrix/row-pluck.ts","/npm/src/recurrent/matrix/row-pluck-b.ts","/npm/src/recurrent/matrix/sigmoid.ts","/npm/src/recurrent/matrix/sigmoid-b.ts","/npm/src/recurrent/matrix/softmax.ts","/npm/src/recurrent/matrix/tanh.ts","/npm/src/recurrent/matrix/tanh-b.ts","/npm/src/recurrent/matrix/equation.ts","/npm/src/recurrent/matrix/max-i.ts","/npm/src/recurrent/matrix/sample-i.ts","/npm/src/recurrent/rnn.ts","/npm/src/recurrent/matrix/copy.ts","/npm/src/recurrent/gru.ts","/npm/src/utilities/array-lookup-table.ts","/npm/src/recurrent/rnn-time-step.ts","/npm/src/recurrent/gru-time-step.ts","/npm/src/recurrent/lstm.ts","/npm/src/recurrent/lstm-time-step.ts","/npm/src/utilities/to-svg.ts","/npm/src/index.ts","/npm/src/utilities/range.ts","/npm/src/utilities/to-array.ts","/npm/src/likely.ts"],"names":[],"mappings":"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","file":"/npm/brain.js@2.0.0-beta.15/dist/browser.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.37.0.\n * Original file: /npm/brain.js@2.0.0-beta.15/dist/browser.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","/**\n * Relu Activation, aka Rectified Linear Unit Activation\n * @description https://en.wikipedia.org/wiki/Rectifier_(neural_networks)\n */\nexport function activate(weight: number): number {\n  return Math.max(0, weight);\n}\n\n/**\n * Relu derivative\n */\nexport function measure(weight: number, delta: number): number {\n  if (weight <= 0) {\n    return 0;\n  }\n  return delta;\n}\n","/**\n * sigmoid activation\n */\nexport function activate(value: number): number {\n  return 1 / (1 + Math.exp(-value));\n}\n\n/**\n * sigmoid derivative\n */\nexport function measure(weight: number, error: number): number {\n  return weight * (1 - weight) * error;\n}\n","/**\n * Hyperbolic tan\n */\nexport function activate(weight: number): number {\n  return Math.tanh(weight);\n}\n\n/**\n * @description grad for z = tanh(x) is (1 - z^2)\n */\nexport function measure(weight: number, error: number): number {\n  return (1 - weight * weight) * error;\n}\n","/**\n * Leaky Relu Activation, aka Leaky Rectified Linear Unit Activation\n * @description https://en.wikipedia.org/wiki/Rectifier_(neural_networks)\n */\nexport function activate(weight: number): number {\n  return weight > 0 ? weight : 0.01 * weight;\n}\n\n/**\n * Leaky Relu derivative\n */\nexport function measure(weight: number, error: number): number {\n  return weight > 0 ? error : 0.01 * error;\n}\n","import {\n  INeuralNetworkBinaryTestResult,\n  INeuralNetworkState,\n  INeuralNetworkTestResult,\n} from './neural-network-types';\n\nexport type InitClassifier<\n  TrainOptsType,\n  JsonType,\n  DatumType\n> = () => IClassifier<TrainOptsType, JsonType, DatumType>;\n\nexport interface IClassifier<TrainOptsType, JsonType, DatumType> {\n  trainOpts: TrainOptsType;\n  toJSON: () => JsonType;\n  fromJSON: (json: JsonType) => this;\n  train: (\n    data: DatumType[],\n    options?: Partial<TrainOptsType>\n  ) => INeuralNetworkState;\n  test: (\n    data: DatumType[]\n  ) => INeuralNetworkTestResult | INeuralNetworkBinaryTestResult;\n  initialize: () => void;\n}\n\nexport type ICrossValidateJSON<JsonType> =\n  | ICrossValidateStats<JsonType>\n  | ICrossValidateBinaryStats<JsonType>;\n\nexport interface ICrossValidateStatsAverages {\n  trainTime: number;\n  testTime: number;\n  iterations: number;\n  error: number;\n}\n\nexport interface ICrossValidateStats<JsonType> {\n  avgs: ICrossValidateStatsAverages;\n  stats: ICrossValidateStatsResultStats;\n  sets: Array<ICrossValidationTestPartitionResults<JsonType>>;\n}\n\nexport interface ICrossValidateBinaryStats<NetworkType> {\n  avgs: ICrossValidateStatsAverages;\n  stats: ICrossValidateStatsResultBinaryStats;\n  sets: Array<ICrossValidationTestPartitionBinaryResults<NetworkType>>;\n}\n\nexport interface ICrossValidateStatsResultStats {\n  total: number;\n  testSize: number;\n  trainSize: number;\n}\n\nexport interface ICrossValidateStatsResultBinaryStats\n  extends ICrossValidateStatsResultStats {\n  total: number;\n  truePos: number;\n  trueNeg: number;\n  falsePos: number;\n  falseNeg: number;\n  precision: number;\n  recall: number;\n  accuracy: number;\n}\n\nexport interface ICrossValidationTestPartitionResults<JsonType>\n  extends INeuralNetworkTestResult {\n  trainTime: number;\n  testTime: number;\n  iterations: number;\n  network: JsonType;\n  total: number;\n}\n\nexport type ICrossValidationTestPartitionBinaryResults<\n  JsonType\n> = INeuralNetworkBinaryTestResult &\n  ICrossValidationTestPartitionResults<JsonType>;\n\nexport default class CrossValidate<\n  InitClassifierType extends InitClassifier<\n    ReturnType<InitClassifierType>['trainOpts'],\n    ReturnType<ReturnType<InitClassifierType>['toJSON']>,\n    Parameters<ReturnType<InitClassifierType>['train']>[0][0]\n  >\n> {\n  initClassifier: InitClassifierType;\n  json: ICrossValidateJSON<\n    ReturnType<ReturnType<InitClassifierType>['toJSON']>\n  > = {\n    avgs: {\n      error: 0,\n      iterations: 0,\n      testTime: 0,\n      trainTime: 0,\n    },\n    stats: {\n      total: 0,\n      testSize: 0,\n      trainSize: 0,\n    },\n    sets: [],\n  };\n\n  constructor(initClassifier: InitClassifierType) {\n    this.initClassifier = initClassifier;\n  }\n\n  testPartition(\n    trainOpts: Parameters<ReturnType<InitClassifierType>['train']>[1],\n    trainSet: Parameters<ReturnType<InitClassifierType>['train']>[0],\n    testSet: Parameters<ReturnType<InitClassifierType>['train']>[0]\n  ):\n    | ICrossValidationTestPartitionResults<\n        ReturnType<ReturnType<InitClassifierType>['toJSON']>\n      >\n    | ICrossValidationTestPartitionBinaryResults<\n        ReturnType<ReturnType<InitClassifierType>['toJSON']>\n      > {\n    const classifier = this.initClassifier();\n    const beginTrain = Date.now();\n    const trainingStats = classifier.train(trainSet, trainOpts);\n    const beginTest = Date.now();\n    const testStats:\n      | INeuralNetworkTestResult\n      | INeuralNetworkBinaryTestResult = classifier.test(testSet);\n    const endTest = Date.now();\n    return {\n      ...testStats,\n      trainTime: beginTest - beginTrain,\n      testTime: endTest - beginTest,\n      iterations: trainingStats.iterations,\n      error: trainingStats.error,\n      total: testStats.total,\n      network: (classifier as {\n        toJSON: () => ReturnType<ReturnType<InitClassifierType>['toJSON']>;\n      }).toJSON(),\n    };\n  }\n\n  /**\n   * Randomize array element order in-place.\n   * Using Durstenfeld shuffle algorithm.\n   * source: http://stackoverflow.com/a/12646864/1324039\n   */\n  shuffleArray<K>(array: K[]): K[] {\n    for (let i = array.length - 1; i > 0; i--) {\n      const j = Math.floor(Math.random() * (i + 1));\n      const temp = array[i];\n      array[i] = array[j];\n      array[j] = temp;\n    }\n    return array;\n  }\n\n  static isBinaryStats = (\n    stats: ICrossValidateStatsResultStats | ICrossValidateStatsResultBinaryStats\n  ): stats is ICrossValidateStatsResultBinaryStats => {\n    return (\n      (stats as ICrossValidateStatsResultBinaryStats).accuracy !== undefined\n    );\n  };\n\n  static isBinaryResults = <JsonType>(\n    stats: ICrossValidateStats<JsonType> | ICrossValidateBinaryStats<JsonType>\n  ): stats is ICrossValidateBinaryStats<JsonType> =>\n    (stats as ICrossValidateBinaryStats<JsonType>).stats.accuracy !== undefined;\n\n  static isBinaryPartitionResults = <JsonType>(\n    stats:\n      | ICrossValidationTestPartitionResults<JsonType>\n      | ICrossValidationTestPartitionBinaryResults<JsonType>\n  ): stats is ICrossValidationTestPartitionBinaryResults<JsonType> =>\n    (stats as ICrossValidationTestPartitionBinaryResults<JsonType>).accuracy !==\n    undefined;\n\n  train(\n    data: Array<Parameters<ReturnType<InitClassifierType>['train']>[0][0]>,\n    trainOpts: Partial<\n      Parameters<ReturnType<InitClassifierType>['train']>[1]\n    > = {},\n    k = 4\n  ): ICrossValidateStats<ReturnType<InitClassifierType>['toJSON']> {\n    if (data.length < k) {\n      throw new Error(\n        `Training set size is too small for ${data.length} k folds of ${k}`\n      );\n    }\n    this.shuffleArray<unknown>(data);\n    const size = data.length / k;\n\n    const avgs: ICrossValidateStatsAverages = {\n      trainTime: 0,\n      testTime: 0,\n      iterations: 0,\n      error: 0,\n    };\n\n    const stats:\n      | ICrossValidateStatsResultStats\n      | ICrossValidateStatsResultBinaryStats = {\n      total: 0,\n      testSize: 0,\n      trainSize: 0,\n    };\n\n    const binaryStats: ICrossValidateStatsResultBinaryStats = {\n      total: 0,\n      testSize: 0,\n      trainSize: 0,\n      truePos: 0,\n      trueNeg: 0,\n      falsePos: 0,\n      falseNeg: 0,\n      precision: 0,\n      recall: 0,\n      accuracy: 0,\n    };\n\n    const results = [];\n    let isBinary = null;\n\n    for (let i = 0; i < k; i++) {\n      const dclone = data.slice(0);\n      const testSet = dclone.splice(i * size, size);\n      const trainSet = dclone;\n      const result = this.testPartition(trainOpts, trainSet, testSet);\n\n      if (isBinary === null) {\n        isBinary =\n          result.hasOwnProperty('falseNeg') &&\n          result.hasOwnProperty('falsePos') &&\n          result.hasOwnProperty('trueNeg') &&\n          result.hasOwnProperty('truePos');\n        if (isBinary) {\n          Object.assign(stats, binaryStats);\n        }\n      }\n\n      avgs.iterations += result.iterations;\n      avgs.testTime += result.testTime;\n      avgs.trainTime += result.trainTime;\n      avgs.error += result.error;\n      stats.total += result.total;\n      if (\n        CrossValidate.isBinaryStats(stats) &&\n        CrossValidate.isBinaryPartitionResults(result)\n      ) {\n        stats.accuracy += result.accuracy;\n        stats.falseNeg += result.falseNeg;\n        stats.falsePos += result.falsePos;\n        stats.precision += result.precision;\n        stats.recall += result.recall;\n        stats.trueNeg += result.trueNeg;\n        stats.truePos += result.truePos;\n      }\n\n      results.push(result);\n    }\n    avgs.error /= k;\n    avgs.iterations /= k;\n    avgs.testTime /= k;\n    avgs.trainTime /= k;\n\n    if (CrossValidate.isBinaryStats(stats)) {\n      stats.precision = stats.truePos / (stats.truePos + stats.falsePos);\n      stats.recall = stats.truePos / (stats.truePos + stats.falseNeg);\n      stats.accuracy = (stats.trueNeg + stats.truePos) / stats.total;\n    }\n\n    stats.testSize = size;\n    stats.trainSize = data.length - size;\n\n    this.json = {\n      avgs: avgs,\n      stats: stats,\n      sets: results,\n    };\n    return this.json;\n  }\n\n  toNeuralNetwork(): ReturnType<InitClassifierType> {\n    return this.fromJSON(this.json);\n  }\n\n  toJSON(): ICrossValidateJSON<\n    ReturnType<ReturnType<InitClassifierType>['toJSON']>\n  > | null {\n    return this.json;\n  }\n\n  fromJSON(\n    crossValidateJson: ICrossValidateJSON<\n      ReturnType<ReturnType<InitClassifierType>['toJSON']>\n    >\n  ): ReturnType<InitClassifierType> {\n    const winningJSON:\n      | ICrossValidationTestPartitionResults<\n          ReturnType<ReturnType<InitClassifierType>['toJSON']>\n        >\n      | ICrossValidationTestPartitionBinaryResults<\n          ReturnType<ReturnType<InitClassifierType>['toJSON']>\n        > = (crossValidateJson as ICrossValidateStats<\n      ReturnType<ReturnType<InitClassifierType>['toJSON']>\n    >).sets.reduce((prev, cur) => (prev.error < cur.error ? prev : cur));\n    return (this.initClassifier() as ReturnType<InitClassifierType>).fromJSON(\n      winningJSON.network\n    );\n  }\n}\n","import {\n  GPU,\n  IConstantsThis,\n  IGPUKernelSettings,\n  IKernelMapRunShortcut,\n  IKernelRunShortcut,\n  Input,\n  ISubKernelObject,\n  KernelFunction,\n  KernelOutput,\n  OutputDimensions,\n  Texture,\n  ThreadFunction,\n  ThreadKernelVariable,\n} from 'gpu.js';\n\nlet gpuInstance: GPU | null = null;\n\n/**\n * Sets up the gpu.js instance\n */\nexport function setup(value: GPU): void {\n  gpuInstance = value;\n}\n\n/**\n * Destroys any existing gpu.js instance\n */\nexport function teardown(): void {\n  if (gpuInstance !== null) {\n    gpuInstance.destroy().catch(console.log);\n  }\n  gpuInstance = null;\n}\n\nexport function makeKernel<\n  ArgTypes extends ThreadKernelVariable[] = ThreadKernelVariable[],\n  ConstantsTypes extends IConstantsThis = IConstantsThis\n>(\n  fn: KernelFunction<ArgTypes, ConstantsTypes>,\n  settings: IGPUKernelSettings\n): IKernelRunShortcut {\n  let _gpuInstance: GPU = gpuInstance as GPU;\n  if (_gpuInstance === null) {\n    _gpuInstance = new GPU({ mode: 'gpu' });\n    setup(_gpuInstance);\n  }\n\n  return _gpuInstance\n    .createKernel<ArgTypes, ConstantsTypes>(fn, settings)\n    .setPipeline(true);\n}\n\nexport function makeKernelMap<\n  ArgTypes extends ThreadKernelVariable[],\n  ConstantsTypes extends IConstantsThis\n>(\n  map: ISubKernelObject,\n  fn: ThreadFunction<ArgTypes, ConstantsTypes>,\n  settings: IGPUKernelSettings\n): IKernelMapRunShortcut<ISubKernelObject> {\n  let _gpuInstance: GPU = gpuInstance as GPU;\n  if (_gpuInstance === null) {\n    _gpuInstance = new GPU({ mode: 'gpu' });\n    setup(_gpuInstance);\n  }\n\n  return _gpuInstance\n    .createKernelMap<ArgTypes, ConstantsTypes>(map, fn, settings)\n    .setPipeline(true);\n}\n\n/**\n * Compiles a function into a gpu.js dev mode kernel\n */\n// export function makeDevKernel(\n//   fn: ThreadFunction,\n//   settings: makeKernelSettings\n// ): IKernelRunShortcut {\n//   if ('map' in settings) {\n//     throw new Error('map kernels are not supported by dev kernels');\n//   }\n//   const gpu = new GPU({ mode: 'dev' });\n//   return gpu.createKernel(fn, settings);\n// }\n\nexport function kernelInput(value: number[], size: OutputDimensions): Input {\n  return new Input(value, size);\n}\n\n/**\n * Deletes a gpu.js texture and frees VRAM\n */\nexport function release(possibleTexture: KernelOutput | Input): void {\n  if (possibleTexture instanceof Texture) {\n    possibleTexture.delete();\n  }\n}\n\n/**\n * Cleans ie sets all elements to 0 of a Texture or a js array\n */\nexport function clear(value: KernelOutput): void {\n  if (value instanceof Texture) {\n    value.clear();\n    return;\n  }\n\n  // array\n  if (Array.isArray(value)) {\n    if (typeof value[0] === 'number') {\n      (value as number[]).fill(0);\n    } else if (typeof value[0][0] === 'number') {\n      for (let x = 0; x < value.length; x++) {\n        (value[x] as number[]).fill(0);\n      }\n      return;\n    } else if (typeof value[0][0][0] === 'number') {\n      // cube\n      for (let y = 0; y < value.length; y++) {\n        const row: number[][] = value[y] as number[][];\n        for (let x = 0; x < row.length; x++) {\n          row[x].fill(0);\n        }\n      }\n      return;\n    }\n  }\n\n  if (value instanceof Float32Array) {\n    value.fill(0);\n    return;\n  }\n\n  throw new Error('unhandled value');\n}\n\n/**\n * Clones a value\n */\nexport function clone(value: KernelOutput): KernelOutput {\n  if (value instanceof Texture) {\n    return value.clone();\n  }\n  if (value instanceof Float32Array) {\n    return value.slice(0);\n  }\n  if (Array.isArray(value)) {\n    if (typeof value[0] === 'number') {\n      return value.slice(0);\n    } else if (typeof value[0][0] === 'number') {\n      const matrix = new Array(value.length);\n      for (let x = 0; x < value.length; x++) {\n        matrix[x] = (value[x] as Float32Array).slice(0);\n      }\n      return matrix;\n    } else if (typeof value[0][0][0] === 'number') {\n      const cube = new Array(value.length);\n      for (let y = 0; y < value.length; y++) {\n        const row = value[y] as number[][];\n        const matrix = new Array(row.length);\n        for (let x = 0; x < row.length; x++) {\n          matrix[x] = row[x].slice(0);\n        }\n      }\n      return cube;\n    }\n  }\n  throw new Error('unhandled value');\n}\n","import { IKernelRunShortcut, IKernelFunctionThis } from 'gpu.js';\nimport { makeKernel } from '../utilities/kernel';\n\ninterface mse2dThis extends IKernelFunctionThis {\n  constants: { height: number; width: number; length: number };\n}\n\n/**\n * 2D Mean Squared Error\n */\nexport function mse2d(\n  this: mse2dThis,\n  errors: Array<[number, number]>\n): number {\n  let sum = 0;\n  for (let y = 0; y < this.constants.height; y++) {\n    for (let x = 0; x < this.constants.width; x++) {\n      sum += errors[y][x] ** 2;\n    }\n  }\n  return sum / this.constants.length;\n}\n\nexport class MeanSquaredError {\n  /** Calculate the mean squared error given an array of errors */\n  calculate: IKernelRunShortcut;\n  /** Returns the sum of absolute values of previuous error and previous layer errors */\n  addAbsolute: IKernelRunShortcut;\n  /** Adds two erros */\n  add: IKernelRunShortcut;\n  /** Returns the ratio of sum of errors and length (ie the average) */\n  divide: IKernelRunShortcut;\n\n  constructor({ width, height }: { width: number; height: number }) {\n    this.calculate = makeKernel(mse2d, {\n      output: [1],\n      constants: {\n        width,\n        height,\n        length: width * height,\n      },\n      immutable: true,\n    });\n\n    this.addAbsolute = makeKernel(\n      function (prevError: number[], prevLayerErrors: number[][]) {\n        return prevError[0] + Math.abs(prevLayerErrors[0][0]);\n      },\n      {\n        output: [1],\n        immutable: true,\n      }\n    );\n\n    this.add = makeKernel(\n      function (value1: number[], value2: number[]) {\n        return value1[0] + value2[0];\n      },\n      {\n        output: [1],\n        immutable: true,\n      }\n    );\n\n    this.divide = makeKernel(\n      function (length: number, mseSum: number[]) {\n        const value = mseSum[0];\n        if (value > 0) {\n          return value / length;\n        }\n        return 0;\n      },\n      {\n        output: [1],\n        immutable: true,\n      }\n    );\n  }\n}\n","import {\n  IKernelRunShortcut,\n  Input,\n  Kernel,\n  KernelOutput,\n  Texture,\n  TextureArrayOutput,\n} from 'gpu.js';\nimport { IPraxis, IPraxisSettings } from '../praxis/base-praxis';\nimport { clear } from '../utilities/kernel';\n\nexport interface ILayerJSON {\n  width?: number;\n  height?: number;\n  depth?: number;\n  weights?: number[] | number[][] | number[][][] | null;\n  type: string;\n  inputLayerIndex?: number;\n  inputLayer1Index?: number;\n  inputLayer2Index?: number;\n  praxisOpts?: Partial<IPraxisSettings> | null;\n}\n\nexport interface ILayer {\n  width: number;\n  height: number;\n  depth: number;\n  weights: KernelOutput | Input;\n  deltas: KernelOutput;\n  praxis: IPraxis | null;\n  errors?: KernelOutput | null;\n  setupKernels: (training?: boolean) => void;\n  predictKernel: IKernelRunShortcut | null;\n  compareKernel: IKernelRunShortcut | null;\n  settings: Partial<ILayerSettings>;\n  reuseKernels: (layer: ILayer) => void;\n  predict: (inputs?: KernelOutput) => void;\n  compare: (targetValues?: KernelOutput) => void;\n  learn: ((learningRate?: number) => void) | ((learningRate: number) => void);\n  toJSON: () => Partial<ILayerJSON>;\n  inputLayer?: ILayer;\n  inputLayer1?: ILayer;\n  inputLayer2?: ILayer;\n  index?: number;\n  id?: string;\n}\n\nexport interface ILayerSettings {\n  width?: number | null;\n  height?: number | null;\n  depth?: number | null;\n  weights?: KernelOutput | null;\n  deltas?: KernelOutput | null;\n  id?: string;\n  praxis?: IPraxis | null;\n  praxisOpts?: Partial<IPraxisSettings> | null;\n  initPraxis?:\n    | ((layerTemplate: ILayer, settings?: IPraxisSettings) => IPraxis)\n    | null;\n  cleanupDeltas?: boolean;\n}\n\nexport const baseLayerDefaultSettings: ILayerSettings = {\n  width: 1,\n  height: 1,\n  depth: null,\n  weights: null,\n  deltas: null,\n  praxis: null,\n  praxisOpts: null,\n  cleanupDeltas: true,\n};\n\nexport type BaseLayerType = new (settings?: Partial<ILayerSettings>) => ILayer;\n\nexport class BaseLayer implements ILayer {\n  praxis: IPraxis | null = null;\n  predictKernel: IKernelRunShortcut | null = null;\n  compareKernel: IKernelRunShortcut | null = null;\n  settings: Partial<ILayerSettings>;\n\n  get width(): number {\n    return this.settings.width ?? 0;\n  }\n\n  get height(): number {\n    return this.settings.height ?? 0;\n  }\n\n  get depth(): number {\n    return this.settings.depth ?? 0;\n  }\n\n  get weights(): KernelOutput | Input {\n    return this.settings.weights as KernelOutput;\n  }\n\n  set weights(weights: KernelOutput | Input) {\n    this.settings.weights = weights as KernelOutput;\n    if (this.settings.cleanupDeltas && this.deltas) {\n      clear(this.deltas);\n    }\n  }\n\n  get deltas(): KernelOutput {\n    return this.settings.deltas as KernelOutput;\n  }\n\n  set deltas(deltas: KernelOutput) {\n    this.settings.deltas = deltas;\n  }\n\n  get id(): string {\n    return this.settings.id ?? '';\n  }\n\n  set id(title: string) {\n    this.settings.id = title;\n  }\n\n  constructor(settings?: Partial<ILayerSettings>) {\n    if (settings) {\n      this.settings = { ...baseLayerDefaultSettings, ...settings };\n    } else {\n      this.settings = { ...baseLayerDefaultSettings };\n    }\n    this.setupPraxis();\n  }\n\n  setupPraxis(): void {\n    const { initPraxis, praxis, praxisOpts } = this.settings;\n    if (!this.praxis) {\n      if (initPraxis) {\n        if (praxisOpts) {\n          this.praxis = initPraxis(this, praxisOpts);\n        } else {\n          this.praxis = initPraxis(this);\n        }\n      } else if (praxis) {\n        this.praxis = praxis;\n      }\n    }\n  }\n\n  /*\n  get weights() {\n    return this._weights;\n  }\n\n  set weights(value) {\n    if (value) {\n      if (value.dimensions) {\n        if (value.dimensions[0] !== this.width) {\n          throw new Error(`${this.constructor.name}.weights being set with improper value width`);\n        }\n        if (value.dimensions[1] !== this.height) {\n          throw new Error(`${this.constructor.name}.weights being set with improper value height`);\n        }\n      } else {\n        if (value[0].length !== this.width) {\n          throw new Error(`${this.constructor.name}.weights being set with improper value width`);\n        }\n        if (value.length !== this.height) {\n          throw new Error(`${this.constructor.name}.weights being set with improper value height`);\n        }\n      }\n    }\n    this._weights = value;\n  }\n\n  get deltas() {\n    return this._deltas;\n  }\n\n  set deltas(value) {\n    if (value) {\n      if (value.dimensions) {\n        if (value.dimensions[0] !== this.width) {\n          throw new Error(`${this.constructor.name}.deltas being set with improper value width`);\n        }\n        if (value.dimensions[1] !== this.height) {\n          throw new Error(`${this.constructor.name}.deltas being set with improper value height`);\n        }\n      } else {\n        if (value[0].length !== this.width) {\n          throw new Error(`${this.constructor.name}.deltas being set with improper value width`);\n        }\n        if (value.length !== this.height) {\n          throw new Error(`${this.constructor.name}.deltas being set with improper value height`);\n        }\n      }\n    }\n    this._deltas = value;\n  } */\n\n  validate(): void {\n    if (Number.isNaN(this.height)) {\n      throw new Error(`${this.constructor.name} layer height is not a number`);\n    }\n    if (Number.isNaN(this.width)) {\n      throw new Error(`${this.constructor.name} layer width is not a number`);\n    }\n    if (this.height < 1) {\n      throw new Error(`${this.constructor.name} layer height is less than 1`);\n    }\n    if (this.width < 1) {\n      throw new Error(`${this.constructor.name} layer width is less than 1`);\n    }\n  }\n\n  setupKernels(isTraining?: boolean): void {}\n\n  reuseKernels(layer: ILayer): void {\n    if (layer.width !== this.width) {\n      throw new Error(\n        `${this.constructor.name} kernel width mismatch ${layer.width} is not ${this.width}`\n      );\n    }\n    if (layer.height !== this.height) {\n      throw new Error(\n        `${this.constructor.name} kernel width mismatch ${layer.height} is not ${this.height}`\n      );\n    }\n    if (layer.hasOwnProperty('predictKernel') && layer.predictKernel !== null) {\n      if (!(layer.predictKernel as Kernel).immutable) {\n        throw new Error(\n          `${layer.constructor.name}.predictKernel is not reusable, set kernel.immutable = true`\n        );\n      }\n      this.predictKernel = layer.predictKernel;\n    }\n    if (layer.hasOwnProperty('compareKernel') && layer.compareKernel !== null) {\n      if (!(layer.compareKernel as Kernel).immutable) {\n        throw new Error(\n          `${layer.constructor.name}.compareKernel is not reusable, set kernel.immutable = true`\n        );\n      }\n      this.compareKernel = layer.compareKernel;\n    }\n    this.praxis = layer.praxis;\n  }\n\n  predict(inputs?: KernelOutput): void {}\n\n  compare(targetValues?: KernelOutput): void {}\n\n  learn(learningRate?: number): void {}\n\n  toArray(): TextureArrayOutput {\n    return Array.isArray(this.weights)\n      ? this.weights\n      : (this.weights as Texture).toArray();\n  }\n\n  toJSON(): Partial<ILayerJSON> {\n    return BaseLayer.toJSON(this);\n  }\n\n  static toJSON(layer: ILayer): Partial<ILayerJSON> {\n    const { weights } = layer;\n    return {\n      width: layer.width,\n      height: layer.height,\n      depth: layer.depth,\n      weights: toUntypedArray(\n        (weights && weights instanceof Texture\n          ? weights.toArray()\n          : weights) as\n          | Float32Array\n          | Float32Array[]\n          | Float32Array[][]\n          | number[]\n          | number[][]\n          | number[][][]\n          | null\n      ),\n      type: layer.constructor.name,\n      praxisOpts: layer.praxis ? layer.praxis.toJSON() : null,\n    };\n  }\n}\n\nfunction toUntypedArray(\n  weights:\n    | Float32Array\n    | Float32Array[]\n    | Float32Array[][]\n    | number[]\n    | number[][]\n    | number[][][]\n    | null\n): number[][][] | number[][] | number[] | null {\n  if (weights === null) return null;\n  if (Array.isArray(weights)) {\n    if (typeof weights[0] === 'number') {\n      return weights as number[];\n    } else if (Array.isArray(weights[0]) && typeof weights[0][0] === 'number') {\n      return weights as number[][];\n    } else if (\n      Array.isArray(weights[0][0]) &&\n      typeof weights[0][0][0] === 'number'\n    ) {\n      return weights as number[][][];\n    } else if (weights[0] instanceof Float32Array) {\n      const matrix = weights as Float32Array[];\n      return matrix.map((row: Float32Array) => {\n        return Array.from(row);\n      });\n    } else if (weights[0][0] instanceof Float32Array) {\n      const cube = weights as Float32Array[][];\n      return cube.map((matrix: Float32Array[]): number[][] => {\n        return matrix.map((row: Float32Array): number[] => {\n          return Array.from(row);\n        });\n      });\n    }\n  } else if (weights) {\n    return Array.from(weights);\n  }\n  throw new Error('unexpected value');\n}\n","/**\n * Returns an array of zeros\n */\nexport function zeros(size: number): Float32Array {\n  return new Float32Array(size);\n}\n","import { zeros } from './zeros';\n\n/**\n * Returns a 2D tensor(matrix) of zeros\n */\nexport function zeros2D(width: number, height: number): Float32Array[] {\n  const result: Float32Array[] = new Array(height);\n  for (let y = 0; y < height; y++) {\n    result[y] = zeros(width);\n  }\n  return result;\n}\n","import { zeros2D } from './zeros-2d';\n\n/**\n * Returns a 3D tensor of arrays\n */\nexport function zeros3D(\n  width: number,\n  height: number,\n  depth: number\n): Float32Array[][] {\n  const result: Float32Array[][] = new Array(depth);\n  for (let z = 0; z < depth; z++) {\n    result[z] = zeros2D(width, height);\n  }\n  return result;\n}\n","import { BaseLayer, ILayerSettings, ILayer } from './base-layer';\nimport { zeros2D } from '../utilities/zeros-2d';\nimport { zeros3D } from '../utilities/zeros-3d';\n\nexport type ActivationType = new (\n  inputLayer: ILayer,\n  settings: Partial<ILayerSettings>\n) => ILayer;\n\nexport class Activation extends BaseLayer {\n  inputLayer: ILayer;\n\n  get width(): number {\n    return this.inputLayer.width;\n  }\n\n  get height(): number {\n    return this.inputLayer.height;\n  }\n\n  get depth(): number {\n    return this.inputLayer.depth;\n  }\n\n  constructor(inputLayer: ILayer, settings?: Partial<ILayerSettings>) {\n    super(settings);\n    this.inputLayer = inputLayer;\n    const { width, height, depth } = this;\n    this.predictKernel = null;\n    this.compareKernel = null;\n    this.validate();\n    if (depth > 0) {\n      this.weights = zeros3D(width, height, depth);\n      this.deltas = zeros3D(width, height, depth);\n    } else if (height > 0) {\n      this.weights = zeros2D(width, height);\n      this.deltas = zeros2D(width, height);\n    }\n    this.setupPraxis();\n  }\n}\n","import { KernelOutput } from 'gpu.js';\nimport { BaseLayer, ILayer, ILayerSettings } from './base-layer';\n\nexport interface IFilterSettings extends ILayerSettings {\n  filterCount: number;\n  filterWidth: number;\n  filterHeight: number;\n  filters?: KernelOutput;\n  filterDeltas?: KernelOutput;\n}\n\nexport type FilterType = new (\n  settings: Partial<IFilterSettings>,\n  inputLayer: ILayer\n) => ILayer;\n\nexport class Filter extends BaseLayer {\n  get width(): number {\n    return this.inputLayer.width;\n  }\n\n  get height(): number {\n    return this.inputLayer.height;\n  }\n\n  get depth(): number {\n    return this.inputLayer.depth;\n  }\n\n  get filterCount(): number {\n    return this.settings.filterCount as number;\n  }\n\n  get filterWidth(): number {\n    return this.settings.filterWidth as number;\n  }\n\n  get filterHeight(): number {\n    return this.settings.filterHeight as number;\n  }\n\n  get filters(): KernelOutput {\n    return this.settings.filters;\n  }\n\n  set filters(filters: KernelOutput) {\n    this.settings.filters = filters;\n  }\n\n  get filterDeltas(): KernelOutput {\n    return this.settings.filterDeltas;\n  }\n\n  set filterDeltas(filterDeltas: KernelOutput) {\n    this.settings.filterDeltas = filterDeltas;\n  }\n\n  settings: Partial<IFilterSettings>;\n  inputLayer: ILayer;\n  constructor(settings: Partial<IFilterSettings>, inputLayer: ILayer) {\n    super();\n    this.settings = settings;\n    this.inputLayer = inputLayer;\n  }\n}\n","import { BaseLayer, ILayer, ILayerJSON, ILayerSettings } from './base-layer';\nimport { IKernelRunShortcut, Input, KernelOutput } from 'gpu.js';\nimport { IPraxis } from '../praxis/base-praxis';\n\nexport type InternalType = new (settings: Partial<ILayerSettings>) => ILayer;\n\nexport abstract class Internal implements ILayer {\n  abstract settings: ILayerSettings;\n  abstract predict(inputs?: KernelOutput): void;\n  abstract compare(targetValues?: KernelOutput): void;\n  abstract learn(learningRate?: number): void;\n  abstract setupKernels(training?: boolean): void;\n  predictKernel: IKernelRunShortcut | null = null;\n  compareKernel: IKernelRunShortcut | null = null;\n  praxis: IPraxis | null = null;\n\n  get width(): number {\n    return this.settings.width as number;\n  }\n\n  get height(): number {\n    return this.settings.height as number;\n  }\n\n  get depth(): number {\n    return this.settings.depth as number;\n  }\n\n  get weights(): KernelOutput | Input {\n    return this.settings.weights as KernelOutput;\n  }\n\n  set weights(weights: KernelOutput | Input) {\n    this.settings.weights = weights as KernelOutput;\n  }\n\n  get deltas(): KernelOutput {\n    return this.settings.deltas as KernelOutput;\n  }\n\n  set deltas(deltas: KernelOutput) {\n    this.settings.deltas = deltas;\n  }\n\n  toJSON(): Partial<ILayerJSON> {\n    return BaseLayer.toJSON(this);\n  }\n\n  abstract reuseKernels(layer: ILayer): void;\n}\n","import { BaseLayer, ILayer, ILayerSettings } from './base-layer';\n\nexport type ModifierType = new (\n  inputLayer: ILayer,\n  settings?: Partial<ILayerSettings>\n) => ILayer;\n\nexport class Modifier extends BaseLayer {\n  inputLayer: ILayer;\n  constructor(inputLayer: ILayer, settings?: Partial<ILayerSettings>) {\n    super({\n      ...settings,\n      width: inputLayer.width,\n      height: inputLayer.height,\n      depth: inputLayer.depth,\n    });\n    this.inputLayer = inputLayer;\n  }\n\n  validate(): void {\n    super.validate();\n\n    if (this.width !== this.inputLayer.width) {\n      throw new Error(\n        `width of ${this.width} does not match inputLayer.width of ${this.inputLayer.width}`\n      );\n    }\n\n    if (this.height !== this.inputLayer.height) {\n      throw new Error(\n        `height of ${this.height} does not match inputLayer.height of ${this.inputLayer.height}`\n      );\n    }\n\n    if (this.depth !== (this.inputLayer.depth ?? 0)) {\n      throw new Error(\n        `depth of ${this.depth} does not match inputLayer.depth of ${this.inputLayer.depth}`\n      );\n    }\n  }\n}\n","import { BaseLayer, ILayerSettings, ILayer } from './base-layer';\nimport { zeros2D } from '../utilities/zeros-2d';\n\nexport type OperatorType = new (\n  inputLayer1: ILayer,\n  inputLayer2: ILayer,\n  settings?: Partial<ILayerSettings>\n) => ILayer;\n\nexport abstract class Operator extends BaseLayer {\n  inputLayer1: ILayer;\n  inputLayer2: ILayer;\n  constructor(\n    inputLayer1: ILayer,\n    inputLayer2: ILayer,\n    settings?: Partial<ILayerSettings>\n  ) {\n    super(settings);\n    this.inputLayer1 = inputLayer1;\n    this.inputLayer2 = inputLayer2;\n    this.validate();\n    this.weights = zeros2D(this.width, this.height);\n    this.deltas = zeros2D(this.width, this.height);\n    this.setupPraxis();\n  }\n}\n","import { IKernelFunctionThis, IKernelRunShortcut, KernelOutput } from 'gpu.js';\n\nimport { makeKernel, release, clone } from '../utilities/kernel';\nimport { zeros } from '../utilities/zeros';\nimport { zeros2D } from '../utilities/zeros-2d';\nimport { BaseLayer, ILayer, ILayerSettings } from './base-layer';\n\nexport function compare1D(\n  this: IKernelFunctionThis,\n  weights: number[][],\n  targetValues: number[]\n): number {\n  return weights[this.thread.y][this.thread.x] - targetValues[this.thread.x];\n}\n\nexport function compare2D(\n  this: IKernelFunctionThis,\n  weights: number[][],\n  targetValues: number[][]\n): number {\n  return (\n    weights[this.thread.y][this.thread.x] -\n    targetValues[this.thread.y][this.thread.x]\n  );\n}\n\nexport type TargetType = new (\n  settings: Partial<ILayerSettings>,\n  inputLayer: ILayer\n) => ILayer;\n\nexport class Target extends BaseLayer {\n  errors: KernelOutput;\n  inputLayer: ILayer;\n  constructor(settings: Partial<ILayerSettings>, inputLayer: ILayer) {\n    super(settings);\n    this.inputLayer = inputLayer;\n    this.validate();\n    if (this.depth) {\n      throw new Error('Target layer not implemented for depth');\n    } else if (this.height) {\n      this.weights = zeros2D(this.width, this.height);\n      this.deltas = zeros2D(this.width, this.height);\n      this.errors = zeros2D(this.width, this.height);\n    } else {\n      this.weights = zeros(this.width);\n      this.deltas = zeros(this.width);\n      this.errors = zeros(this.width);\n    }\n  }\n\n  setupKernels(): void {\n    if (this.width === 1) {\n      this.compareKernel = makeKernel(compare1D, {\n        output: [this.width, this.height],\n        immutable: true,\n      });\n    } else {\n      this.compareKernel = makeKernel(compare2D, {\n        output: [this.width, this.height],\n        immutable: true,\n      });\n    }\n  }\n\n  predict(): void {\n    // TODO: should we clone here?\n    // NOTE: this looks like it shouldn't be, but the weights are immutable, and this is where they are reused.\n    release(this.weights);\n    this.weights = clone(this.inputLayer.weights as KernelOutput);\n  }\n\n  compare(targetValues: KernelOutput): void {\n    // this is where weights attach to deltas\n    // deltas will be zero on learn, so save it in error for comparing to mse later\n    release(this.deltas);\n    release(this.errors);\n    release(this.inputLayer.deltas);\n    this.deltas = (this.compareKernel as IKernelRunShortcut)(\n      this.weights,\n      targetValues\n    );\n    this.inputLayer.deltas = clone(this.deltas);\n    this.errors = clone(this.deltas);\n  }\n\n  setupPraxis(): void {}\n}\n\nexport function target(settings: ILayerSettings, inputLayer: ILayer): Target {\n  return new Target(settings, inputLayer);\n}\n","import { release } from '../utilities/kernel';\nimport { BaseLayer, ILayer, ILayerSettings } from './base-layer';\nexport { Activation } from './activation';\nexport { Filter } from './filter';\nexport { Internal } from './internal';\nexport { Modifier } from './modifier';\nexport { Operator } from './operator';\nexport { Target } from './target';\n\n// eslint-disable-next-line @typescript-eslint/no-extraneous-class\nexport class InternalModel {}\n\nexport type EntryPointType = new (settings: Partial<ILayerSettings>) => ILayer;\n// eslint-disable-next-line @typescript-eslint/no-extraneous-class\nexport class EntryPoint extends BaseLayer {}\n\n// eslint-disable-next-line @typescript-eslint/no-extraneous-class\nexport class Model extends BaseLayer {\n  learn(learningRate?: number): void {\n    // TODO: do we need to release here?\n    const { weights: oldWeights } = this;\n    if (!this.praxis) throw new Error('this.praxis not defined');\n    this.weights = this.praxis.run(this, learningRate as number);\n    release(oldWeights);\n  }\n}\n","import { KernelOutput } from 'gpu.js';\n\nexport interface INumberHash {\n  [character: string]: number;\n}\n\nexport interface INumberArray {\n  length: number;\n  buffer?: ArrayBuffer;\n  [index: number]: number;\n}\n\nexport type InputOutputValue = INumberArray | Partial<INumberHash>;\n\nexport interface ITrainingDatum {\n  input: InputOutputValue | InputOutputValue[] | KernelOutput;\n  output: InputOutputValue | InputOutputValue[] | KernelOutput;\n}\n\nexport type FormattableData =\n  | number\n  | ITrainingDatum\n  | InputOutputValue\n  | InputOutputValue[];\n\n/* Functions for turning sparse hashes into arrays and vice versa */\nexport const lookup = {\n  /**\n   * Performs `[{a: 1}, {b: 6, c: 7}] -> {a: 0, b: 1, c: 2}`\n   * @param {Object} hashes\n   * @returns {Object}\n   */\n  toTable(hashes: INumberHash[]): INumberHash {\n    const hash = hashes.reduce((memo, hash) => {\n      return Object.assign(memo, hash);\n    }, {});\n\n    return lookup.toHash(hash);\n  },\n\n  /**\n   * Performs `[{a: 1}, {b: 6, c: 7}] -> {a: 0, b: 1, c: 2}`\n   */\n  toTable2D(objects2D: INumberHash[][]): INumberHash {\n    const table: INumberHash = {};\n    let valueIndex = 0;\n    for (let i = 0; i < objects2D.length; i++) {\n      const objects = objects2D[i];\n      for (let j = 0; j < objects.length; j++) {\n        const object = objects[j];\n        for (const p in object) {\n          if (object.hasOwnProperty(p) && !table.hasOwnProperty(p)) {\n            table[p] = valueIndex++;\n          }\n        }\n      }\n    }\n    return table;\n  },\n\n  toInputTable2D(\n    data: Array<{ input: Array<{ [key: string]: number }> }>\n  ): INumberHash {\n    const table: INumberHash = {};\n    let tableIndex = 0;\n    for (let dataIndex = 0; dataIndex < data.length; dataIndex++) {\n      const input = data[dataIndex].input;\n      for (let i = 0; i < input.length; i++) {\n        const object = input[i];\n        for (const p in object) {\n          if (!object.hasOwnProperty(p)) continue;\n          if (!table.hasOwnProperty(p)) {\n            table[p] = tableIndex++;\n          }\n        }\n      }\n    }\n    return table;\n  },\n\n  toOutputTable2D(\n    data: Array<{ output: Array<{ [key: string]: number }> }>\n  ): INumberHash {\n    const table: INumberHash = {};\n    let tableIndex = 0;\n    for (let dataIndex = 0; dataIndex < data.length; dataIndex++) {\n      const output = data[dataIndex].output;\n      for (let i = 0; i < output.length; i++) {\n        const object = output[i];\n        for (const p in object) {\n          if (!object.hasOwnProperty(p)) continue;\n          if (!table.hasOwnProperty(p)) {\n            table[p] = tableIndex++;\n          }\n        }\n      }\n    }\n    return table;\n  },\n\n  /**\n   * performs `{a: 6, b: 7} -> {a: 0, b: 1}`\n   */\n  toHash(hash: INumberHash): INumberHash {\n    const lookup: INumberHash = {};\n    let index = 0;\n    const keys = Object.keys(hash);\n    for (let i = 0; i < keys.length; i++) {\n      lookup[keys[i]] = index++;\n    }\n    return lookup;\n  },\n\n  /**\n   * performs `{a: 0, b: 1}, {a: 6} -> [6, 0]`\n   */\n  toArray(\n    lookup: INumberHash,\n    object: INumberHash,\n    arrayLength: number\n  ): Float32Array {\n    const result = new Float32Array(arrayLength);\n    for (const p in lookup) {\n      if (!lookup.hasOwnProperty(p)) continue;\n      result[lookup[p]] = object.hasOwnProperty(p) ? object[p] : 0;\n    }\n    return result;\n  },\n\n  toArrayShort(lookup: INumberHash, object: INumberHash): Float32Array {\n    const result = [];\n    for (const p in lookup) {\n      if (!lookup.hasOwnProperty(p)) continue;\n      if (!object.hasOwnProperty(p)) break;\n      result[lookup[p]] = object[p];\n    }\n    return Float32Array.from(result);\n  },\n\n  toArrays(\n    lookup: INumberHash,\n    objects: INumberHash[],\n    arrayLength: number\n  ): Float32Array[] {\n    const result = [];\n    for (let i = 0; i < objects.length; i++) {\n      result.push(this.toArray(lookup, objects[i], arrayLength));\n    }\n    return result;\n  },\n\n  /**\n   * performs `{a: 0, b: 1}, [6, 7] -> {a: 6, b: 7}`\n   * @param {Object} lookup\n   * @param {Array} array\n   * @returns {Object}\n   */\n  toObject(lookup: INumberHash, array: number[] | Float32Array): INumberHash {\n    const object: INumberHash = {};\n    for (const p in lookup) {\n      if (!lookup.hasOwnProperty(p)) continue;\n      object[p] = array[lookup[p]];\n    }\n    return object;\n  },\n\n  toObjectPartial(\n    lookup: INumberHash,\n    array: number[] | Float32Array,\n    offset = 0,\n    limit = 0\n  ): INumberHash {\n    const object: INumberHash = {};\n    let i = 0;\n    for (const p in lookup) {\n      if (!lookup.hasOwnProperty(p)) continue;\n      if (offset > 0) {\n        if (i++ < offset) continue;\n      }\n      if (limit > 0) {\n        if (i++ >= limit) continue;\n      }\n      object[p] = array[lookup[p] - offset];\n    }\n    return object;\n  },\n\n  dataShape(data: FormattableData[] | FormattableData): string[] {\n    const shape = [];\n    let lastData;\n    if (data.hasOwnProperty('input')) {\n      shape.push('datum');\n      lastData = (data as ITrainingDatum).input;\n    } else if (Array.isArray(data)) {\n      if (\n        (data as ITrainingDatum[])[0] &&\n        (data as ITrainingDatum[])[0].input\n      ) {\n        shape.push('array', 'datum');\n        lastData = (data as ITrainingDatum[])[0].input;\n      } else if (Array.isArray(data[0])) {\n        shape.push('array');\n        lastData = data[0];\n      } else {\n        lastData = data as\n          | InputOutputValue\n          | InputOutputValue[]\n          | InputOutputValue[][];\n      }\n    } else {\n      lastData = data as\n        | InputOutputValue\n        | InputOutputValue[]\n        | InputOutputValue[][];\n    }\n\n    let p;\n    while (lastData) {\n      p = Object.keys(lastData)[0];\n      if (\n        Array.isArray(lastData) ||\n        typeof (lastData as Float32Array).buffer === 'object'\n      ) {\n        shape.push('array');\n        const possibleNumber:\n          | number\n          | INumberArray = (lastData as INumberArray[])[parseInt(p)];\n        if (typeof possibleNumber === 'number') {\n          shape.push('number');\n          break;\n        } else {\n          lastData = possibleNumber;\n        }\n      } else if (\n        typeof lastData === 'object' &&\n        typeof (lastData as Float32Array).buffer !== 'object'\n      ) {\n        shape.push('object');\n        const possibleNumber: number | INumberHash = (lastData as INumberHash)[\n          p\n        ];\n        if (typeof possibleNumber === 'number') {\n          shape.push('number');\n          break;\n        } else {\n          lastData = possibleNumber;\n        }\n      } else {\n        throw new Error('unhandled signature');\n      }\n    }\n    return shape;\n  },\n\n  addKeys(value: number[] | INumberHash, table: INumberHash): INumberHash {\n    if (Array.isArray(value)) return table;\n    let i = Object.keys(table).length;\n    for (const p in value) {\n      if (!value.hasOwnProperty(p)) continue;\n      if (table.hasOwnProperty(p)) continue;\n      table[p] = i++;\n    }\n    return table;\n  },\n};\n","import { ILayer } from '../layer';\nimport { IKernelRunShortcut, KernelOutput } from 'gpu.js';\n\nexport interface ILayerTemplate {\n  width: number;\n  height: number;\n  depth: number;\n}\n\nexport interface IPraxisJSON {\n  width: number;\n  height: number;\n  depth: number;\n}\n\nexport interface IPraxisSettings {\n  width?: number;\n  height?: number;\n  depth?: number;\n  kernel?: IKernelRunShortcut | null;\n}\n\nexport interface IPraxis {\n  layerTemplate: ILayerTemplate | null;\n  kernel: IKernelRunShortcut | null;\n  settings: Partial<IPraxisSettings>;\n  setupKernels: () => void;\n  width: number;\n  height: number;\n  depth: number;\n  run:\n    | ((layer: ILayer, learningRate: number) => KernelOutput)\n    | ((layer: ILayer, learningRate?: number) => KernelOutput);\n  toJSON: () => Partial<IPraxisSettings>;\n}\n\nexport abstract class BasePraxis implements IPraxis {\n  layerTemplate: ILayerTemplate;\n  kernel: IKernelRunShortcut | null;\n  settings: Partial<IPraxisSettings>;\n\n  get width(): number {\n    return this.layerTemplate.width;\n  }\n\n  get height(): number {\n    return this.layerTemplate.height;\n  }\n\n  get depth(): number {\n    return this.layerTemplate.depth;\n  }\n\n  constructor(\n    layerTemplate: ILayerTemplate,\n    settings: Partial<IPraxisSettings> = {}\n  ) {\n    this.layerTemplate = layerTemplate;\n    this.settings = { ...settings };\n    this.kernel = null;\n  }\n\n  setupKernels(): void {}\n\n  reuseKernels(praxis: IPraxis): void {\n    if (praxis.width !== this.width) {\n      throw new Error(\n        `${this.constructor.name} kernel width mismatch ${praxis.width} is not ${this.width}`\n      );\n    }\n    if (praxis.height !== this.height) {\n      throw new Error(\n        `${this.constructor.name} kernel width mismatch ${praxis.height} is not ${this.height}`\n      );\n    }\n    if (praxis.hasOwnProperty('kernel')) {\n      this.kernel = praxis.kernel;\n    }\n  }\n\n  abstract run(layer: ILayer, learningRate?: number): KernelOutput;\n\n  toJSON(): Partial<IPraxisSettings> {\n    return { ...this.settings };\n  }\n}\n","import { makeKernel } from '../utilities/kernel';\nimport { BasePraxis, IPraxisSettings } from './base-praxis';\nimport { ILayer } from '../layer/base-layer';\nimport { IKernelFunctionThis, IKernelRunShortcut, KernelOutput } from 'gpu.js';\n\nexport interface IUpdateThis extends IKernelFunctionThis {\n  constants: {\n    learningRate: number;\n  };\n}\n\nexport function update(\n  this: IUpdateThis,\n  weights: number[][],\n  deltas: number[][]\n): number {\n  return (\n    weights[this.thread.y][this.thread.x] +\n    this.constants.learningRate * deltas[this.thread.y][this.thread.x]\n  );\n}\n\nexport interface IArthurDeviationBiasesSettings extends IPraxisSettings {\n  learningRate?: number;\n}\n\nexport const defaultSettings = {\n  learningRate: 0.3,\n};\n\nexport class ArthurDeviationBiases extends BasePraxis {\n  settings: IArthurDeviationBiasesSettings;\n  kernel: IKernelRunShortcut | null;\n  constructor(layer: ILayer, settings?: IArthurDeviationBiasesSettings) {\n    super(layer);\n    this.settings = { ...defaultSettings, ...settings };\n    this.kernel = null;\n  }\n\n  run(layer: ILayer): KernelOutput {\n    return (this.kernel as IKernelRunShortcut)(layer.weights, layer.deltas);\n  }\n\n  setupKernels(): void {\n    this.kernel = makeKernel(update, {\n      output: [this.width, this.height],\n      constants: {\n        learningRate: this.settings.learningRate,\n      },\n    });\n  }\n}\n\nexport function arthurDeviationBiases(\n  layer: ILayer,\n  settings?: Partial<IArthurDeviationBiasesSettings>\n): ArthurDeviationBiases {\n  return new ArthurDeviationBiases(layer, settings);\n}\n","import { makeKernelMap } from '../utilities/kernel';\nimport { zeros2D } from '../utilities/zeros-2d';\nimport { BasePraxis, IPraxisSettings } from './base-praxis';\nimport { ILayer } from '../layer/base-layer';\nimport {\n  IConstantsThis,\n  IKernelFunctionThis,\n  IKernelMapRunShortcut,\n  ISubKernelObject,\n  ISubKernelsResults,\n  KernelOutput,\n} from 'gpu.js';\n\nexport function updateChange(value: number): number {\n  return value;\n}\n\nexport interface IUpdateConstants extends IConstantsThis {\n  learningRate: number;\n  momentum: number;\n}\n\nexport function update(\n  this: IKernelFunctionThis<IUpdateConstants>,\n  changes: number[][],\n  weights: number[][],\n  incomingWeights: number[][],\n  inputDeltas: number[][]\n): number {\n  const lastChange: number = changes[this.thread.y][this.thread.x];\n  const inputDelta: number = inputDeltas[this.thread.y][0];\n  const weight: number = weights[this.thread.y][this.thread.x];\n  const incoming: number = incomingWeights[this.thread.x][0];\n\n  const change =\n    this.constants.learningRate * inputDelta * incoming +\n    this.constants.momentum * lastChange;\n  updateChange(change);\n  return weight + change;\n}\n\nexport interface IArthurDeviationWeightsSettings extends IPraxisSettings {\n  learningRate?: number;\n  momentum?: number;\n  weightsLayer?: ILayer | null;\n  incomingLayer?: ILayer | null;\n  deltaLayer?: ILayer | null;\n}\n\nexport interface IKernelMapResults extends ISubKernelsResults {\n  changes: KernelOutput;\n}\n\nexport const defaultSettings: IArthurDeviationWeightsSettings = {\n  learningRate: 0.3,\n  momentum: 0.1,\n  weightsLayer: null,\n  incomingLayer: null,\n  deltaLayer: null,\n};\n\nexport class ArthurDeviationWeights extends BasePraxis {\n  changes: KernelOutput;\n  kernelMap: IKernelMapRunShortcut<ISubKernelObject> | null = null;\n  settings: IArthurDeviationWeightsSettings;\n  get learningRate(): number {\n    return this.settings.learningRate as number;\n  }\n\n  get momentum(): number {\n    return this.settings.momentum as number;\n  }\n\n  get weightsLayer(): ILayer {\n    return this.settings.weightsLayer as ILayer;\n  }\n\n  set weightsLayer(layer: ILayer) {\n    this.settings.weightsLayer = layer;\n  }\n\n  get deltaLayer(): ILayer {\n    return this.settings.deltaLayer as ILayer;\n  }\n\n  set deltaLayer(layer: ILayer) {\n    this.settings.deltaLayer = layer;\n  }\n\n  get incomingLayer(): ILayer {\n    return this.settings.incomingLayer as ILayer;\n  }\n\n  set incomingLayer(layer: ILayer) {\n    this.settings.incomingLayer = layer;\n  }\n\n  constructor(layer: ILayer, settings?: IArthurDeviationWeightsSettings) {\n    super(layer);\n    this.settings = { ...defaultSettings, ...settings };\n    this.changes = zeros2D(layer.width, layer.height);\n  }\n\n  run(): KernelOutput {\n    const output = (this.kernelMap as IKernelMapRunShortcut<IKernelMapResults>)(\n      this.changes,\n      this.weightsLayer.weights,\n      this.incomingLayer.weights,\n      this.deltaLayer.deltas\n    );\n    this.changes = output.changes;\n    return output.result;\n  }\n\n  setupKernels(): void {\n    this.kernelMap = makeKernelMap<Parameters<typeof update>, IUpdateConstants>(\n      {\n        changes: updateChange,\n      },\n      update,\n      {\n        output: [this.width, this.height],\n        constants: {\n          learningRate: this.learningRate,\n          momentum: this.momentum,\n        },\n      }\n    );\n  }\n}\n\nexport function arthurDeviationWeights(\n  layer: ILayer,\n  settings?: Partial<IArthurDeviationWeightsSettings>\n): ArthurDeviationWeights {\n  return new ArthurDeviationWeights(layer, settings);\n}\n","import { BasePraxis, ILayerTemplate, IPraxisSettings } from './base-praxis';\n\nimport { makeKernelMap, release } from '../utilities/kernel';\nimport { zeros2D } from '../utilities/zeros-2d';\nimport {\n  IConstantsThis,\n  IKernelFunctionThis,\n  IKernelMapRunShortcut,\n  ISubKernelObject,\n  KernelOutput,\n} from 'gpu.js';\nimport { ILayer } from '../layer';\n\nexport function getMomentum(\n  delta: number,\n  decay: number,\n  previousMomentum: number\n): number {\n  return previousMomentum * decay + (1 - decay) * delta * delta;\n}\n\nexport function clipByValue(value: number, max: number, min: number): number {\n  if (value > max) {\n    return max;\n  }\n  if (value < min) {\n    return min;\n  }\n  return value;\n}\n\ninterface IUpdate extends IConstantsThis {\n  clipValue: number;\n  decayRate: number;\n  smoothEps: number;\n  regularizationStrength: number;\n}\n/**\n * @description Momentum Root Mean Square Propagation Function\n */\nexport function update(\n  this: IKernelFunctionThis<IUpdate>,\n  weights: number[][],\n  deltas: number[][],\n  previousMomenta: number[][]\n): number {\n  const delta = deltas[this.thread.y][this.thread.x];\n  const clippedDelta = clipByValue(\n    delta,\n    this.constants.clipValue,\n    -this.constants.clipValue\n  );\n  const weight = weights[this.thread.y][this.thread.x];\n  const previousMomentum = previousMomenta[this.thread.y][this.thread.x];\n  const momentum = getMomentum(\n    delta,\n    this.constants.decayRate,\n    previousMomentum\n  );\n  return (\n    weight +\n    (-this.constants.learningRate * clippedDelta) /\n      Math.sqrt(momentum + this.constants.smoothEps) -\n    this.constants.regularizationStrength * weight\n  );\n}\n\nexport function isClippedByValue(\n  value: number,\n  max: number,\n  min: number\n): number {\n  if (value > max) {\n    return 1;\n  }\n  if (value < min) {\n    return 1;\n  }\n  return 0;\n}\n\nexport interface IMomentumRootMeanSquaredPropagationSettings\n  extends IPraxisSettings {\n  decayRate?: number;\n  regularizationStrength?: number;\n  learningRate?: number;\n  smoothEps: number;\n  clipValue: number;\n}\n\nexport const defaults: IMomentumRootMeanSquaredPropagationSettings = {\n  decayRate: 0.999,\n  regularizationStrength: 0.000001,\n  learningRate: 0.01,\n  smoothEps: 1e-8,\n  clipValue: 5,\n};\n\nexport class MomentumRootMeanSquaredPropagation extends BasePraxis {\n  momenta: KernelOutput;\n  kernelMap: IKernelMapRunShortcut<ISubKernelObject> | null = null;\n  settings: Partial<IMomentumRootMeanSquaredPropagationSettings>;\n\n  get clipValue(): number {\n    return this.settings.clipValue as number;\n  }\n\n  get decayRate(): number {\n    return this.settings.decayRate as number;\n  }\n\n  get learningRate(): number {\n    return this.settings.learningRate as number;\n  }\n\n  get regularizationStrength(): number {\n    return this.settings.regularizationStrength as number;\n  }\n\n  get smoothEps(): number {\n    return this.settings.smoothEps as number;\n  }\n\n  constructor(\n    layerTemplate: ILayerTemplate,\n    settings: Partial<IMomentumRootMeanSquaredPropagationSettings> = {}\n  ) {\n    super(layerTemplate);\n    this.settings = { ...defaults, ...settings };\n    this.momenta = zeros2D(layerTemplate.width, layerTemplate.height);\n  }\n\n  run(layer: ILayer): KernelOutput {\n    const { momenta, result } = (this.kernelMap as IKernelMapRunShortcut<\n      ISubKernelObject\n    >)(layer.weights, layer.deltas, this.momenta);\n    release(this.momenta);\n    this.momenta = momenta;\n    return result;\n  }\n\n  setupKernels(): void {\n    this.kernelMap = makeKernelMap(\n      {\n        momenta: getMomentum,\n      },\n      update,\n      {\n        output: [this.width, this.height],\n        constants: {\n          clipValue: this.clipValue,\n          decayRate: this.decayRate,\n          learningRate: this.learningRate,\n          regularizationStrength: this.regularizationStrength,\n          smoothEps: this.smoothEps,\n        },\n        functions: [clipByValue],\n        immutable: true,\n      }\n    );\n  }\n}\n\nexport function momentumRootMeanSquaredPropagation(\n  layer: ILayer,\n  settings: Partial<IMomentumRootMeanSquaredPropagationSettings>\n): MomentumRootMeanSquaredPropagation {\n  return new MomentumRootMeanSquaredPropagation(layer, settings);\n}\n\n/**\n * @description Mathematician friendly name of MomentumRootMeanSquaredPropagation class. For those that are not mere mortals\n */\nexport const MRmsProp = MomentumRootMeanSquaredPropagation;\nexport const mRmsProp = momentumRootMeanSquaredPropagation;\n","import { ILayer } from '../layer/base-layer';\n\nexport function traverseLayersFrom(\n  layer: ILayer,\n  cb: (layer: ILayer) => void\n): void {\n  if (layer.hasOwnProperty('inputLayer')) {\n    traverseLayersFrom(\n      (layer as ILayer & { inputLayer: ILayer }).inputLayer,\n      cb\n    );\n  } else {\n    if (layer.hasOwnProperty('inputLayer1')) {\n      traverseLayersFrom(\n        (layer as ILayer & { inputLayer1: ILayer }).inputLayer1,\n        cb\n      );\n    }\n    if (layer.hasOwnProperty('inputLayer2')) {\n      traverseLayersFrom(\n        (layer as ILayer & { inputLayer2: ILayer }).inputLayer2,\n        cb\n      );\n    }\n  }\n  cb(layer);\n}\n","import { ILayer } from '../layer/base-layer';\nimport { traverseLayersFrom } from './traverse-layers-from';\n\nexport function flattenLayers(layers: ILayer[]): ILayer[] {\n  const result = layers.slice(0);\n  for (let i = 0; i < result.length; i++) {\n    let offset = 0;\n    traverseLayersFrom(result[i], (layer: ILayer) => {\n      if (!result.includes(layer)) {\n        result.splice(i + offset, 0, layer);\n        offset++;\n      }\n    });\n  }\n  return result;\n}\n","import { ILayer } from '../layer/base-layer';\n\nexport function checkSameSize(layer1: ILayer, layer2: ILayer): void {\n  if (layer1.width !== layer2.width) {\n    throw new Error(\n      `Layer width mismatch of ${layer1.width} and ${layer2.width}`\n    );\n  }\n\n  if (layer1.height !== layer2.height) {\n    throw new Error(\n      `Layer height mismatch of ${layer1.height} and ${layer2.height}`\n    );\n  }\n}\n","import { makeKernel, release, clone } from '../utilities/kernel';\nimport { checkSameSize } from '../utilities/layer-size';\nimport { Operator } from './operator';\nimport { IKernelFunctionThis, IKernelRunShortcut, Texture } from 'gpu.js';\nimport { ILayerSettings, ILayer } from './base-layer';\n\nexport function predict(\n  this: IKernelFunctionThis,\n  inputWeights1: number[][],\n  inputWeights2: number[][]\n): number {\n  return (\n    inputWeights1[this.thread.y][this.thread.x] +\n    inputWeights2[this.thread.y][this.thread.x]\n  );\n}\n\nexport class Add extends Operator {\n  get width(): number {\n    return this.inputLayer1.width;\n  }\n\n  get height(): number {\n    return this.inputLayer1.height;\n  }\n\n  get depth(): number {\n    return this.inputLayer1.depth;\n  }\n\n  validate(): void {\n    super.validate();\n    checkSameSize(this.inputLayer1, this.inputLayer2);\n  }\n\n  setupKernels(): void {\n    this.predictKernel = makeKernel(predict, {\n      output: [this.width, this.height],\n      immutable: true,\n    });\n  }\n\n  predict(): void {\n    release(this.weights);\n    this.weights = (this.predictKernel as IKernelRunShortcut)(\n      this.inputLayer1.weights,\n      this.inputLayer2.weights\n    ) as Texture;\n  }\n\n  compare(): void {\n    // TODO: Do we need release and clone here?\n    release(this.inputLayer1.deltas);\n    release(this.inputLayer2.deltas);\n    this.inputLayer1.deltas = clone(this.deltas);\n    this.inputLayer2.deltas = clone(this.deltas);\n  }\n}\n\nexport function add(\n  inputLayer1: ILayer,\n  inputLayer2: ILayer,\n  settings?: ILayerSettings\n): Add {\n  return new Add(inputLayer1, inputLayer2, settings);\n}\n","export function randomWeight(): number {\n  return Math.random() * 0.4 - 0.2;\n}\n","/**\n * Returns a random float between given min and max bounds (inclusive)\n * @param min Minimum value of the ranfom float\n * @param max Maximum value of the random float\n */\nexport function randomFloat(min: number, max: number): number {\n  return Math.random() * (max - min) + min;\n}\n\n/**\n * Complicated math. All you need to know is that it returns a random number.\n * More info: https://en.wikipedia.org/wiki/Normal_distribution\n */\nexport function gaussRandom(): number {\n  if (gaussRandom.returnV) {\n    gaussRandom.returnV = false;\n    return gaussRandom.vVal;\n  }\n  const u = 2 * Math.random() - 1;\n  const v = 2 * Math.random() - 1;\n  const r = u * u + v * v;\n  if (r === 0 || r > 1) {\n    return gaussRandom();\n  }\n  const c = Math.sqrt((-2 * Math.log(r)) / r);\n  gaussRandom.vVal = v * c; // cache this\n  gaussRandom.returnV = true;\n  return u * c;\n}\n\n/**\n * Returns a random integer between given min and max bounds\n * @param min Minimum value of the random integer\n * @param max Maximum value of the random integer\n */\nexport function randomInteger(min: number, max: number): number {\n  return Math.floor(Math.random() * (max - min) + min);\n}\n\n/**\n * If you know what this is: https://en.wikipedia.org/wiki/Normal_distribution\n * @param mu\n * @param std\n */\nexport function randomN(mu: number, std: number): number {\n  return mu + gaussRandom() * std;\n}\n\ngaussRandom.returnV = false;\ngaussRandom.vVal = 0;\n","import { randomWeight } from './random-weight';\nimport { randomFloat } from './random';\n\n/**\n * Returns an array of given size, full of randomness\n */\nexport function randos(size: number, std: number | null = null): Float32Array {\n  const array: Float32Array = new Float32Array(size);\n  if (std === null) {\n    for (let i = 0; i < size; i++) {\n      array[i] = randomWeight();\n    }\n  } else {\n    for (let i = 0; i < size; i++) {\n      array[i] = randomFloat(-std, std);\n    }\n  }\n  return array;\n}\n\n/**\n * Returns a 2D matrix of given size, full of randomness\n */\nexport function randos2D(\n  width: number,\n  height: number,\n  std?: number | null\n): Float32Array[] {\n  const result: Float32Array[] = new Array(height);\n  for (let y = 0; y < height; y++) {\n    result[y] = randos(width, std);\n  }\n  return result;\n}\n\n/**\n * Returns a 3D tensor of given size, full of randomness\n */\nexport function randos3D(\n  width: number,\n  height: number,\n  depth: number,\n  std?: number | null\n): Float32Array[][] {\n  const result: Float32Array[][] = new Array(depth);\n  for (let z = 0; z < depth; z++) {\n    result[z] = randos2D(width, height, std);\n  }\n  return result;\n}\n","import { randos2D } from '../utilities/randos';\nimport { zeros2D } from '../utilities/zeros-2d';\nimport { baseLayerDefaultSettings, ILayer, ILayerSettings } from './base-layer';\nimport { Model } from './types';\n\nexport interface IRandomSettings extends ILayerSettings {\n  std?: number | null;\n}\n\nexport const defaults: IRandomSettings = {\n  ...baseLayerDefaultSettings,\n  std: null,\n};\n\nexport class Random extends Model implements ILayer {\n  settings: IRandomSettings;\n  constructor(settings: Partial<IRandomSettings>) {\n    super();\n    this.settings = { ...defaults, ...settings };\n    this.setupPraxis();\n    this.validate();\n\n    if (!this.weights) {\n      this.weights = randos2D(this.width, this.height, settings.std);\n    }\n    if (!this.deltas) {\n      this.deltas = zeros2D(this.width, this.height);\n    }\n  }\n\n  predict(): void {}\n\n  compare(): void {}\n}\n\nexport function random(settings: IRandomSettings): Random {\n  return new Random(settings);\n}\n","import { makeKernel, release } from '../utilities/kernel';\nimport { Operator } from './operator';\nimport {\n  IConstantsThis,\n  IKernelFunctionThis,\n  IKernelRunShortcut,\n  Texture,\n} from 'gpu.js';\nimport { ILayer, ILayerJSON, ILayerSettings } from './base-layer';\n\nexport interface IMultiplyConstants extends IConstantsThis {\n  size: number;\n}\n\nexport function predict(\n  this: IKernelFunctionThis<IMultiplyConstants>,\n  weights1: number[][],\n  weights2: number[][]\n): number {\n  let sum = 0;\n  for (let i = 0; i < this.constants.size; i++) {\n    sum += weights1[this.thread.y][i] * weights2[i][this.thread.x];\n  }\n  return sum;\n}\n\nexport function compareFromX(\n  this: IKernelFunctionThis<IMultiplyConstants>,\n  deltas: number[][],\n  inputDeltas: number[][],\n  inputWeights: number[][]\n): number {\n  let sum = inputDeltas[this.thread.y][this.thread.x];\n  for (let i = 0; i < this.constants.size; i++) {\n    sum += deltas[this.thread.y][i] * inputWeights[this.thread.x][i];\n  }\n  return sum;\n}\n\nexport function compareFromY(\n  this: IKernelFunctionThis<IMultiplyConstants>,\n  deltas: number[][],\n  inputDeltas: number[][],\n  inputWeights: number[][]\n): number {\n  let sum = inputDeltas[this.thread.y][this.thread.x];\n  for (let i = 0; i < this.constants.size; i++) {\n    sum += deltas[i][this.thread.x] * inputWeights[i][this.thread.y];\n  }\n  return sum;\n}\n\nexport class Multiply extends Operator {\n  compareKernel1: IKernelRunShortcut | null = null;\n  compareKernel2: IKernelRunShortcut | null = null;\n\n  get width(): number {\n    return this.inputLayer2.width;\n  }\n\n  set width(width: number) {\n    throw new Error('Cannot set width on Multiply');\n  }\n\n  get height(): number {\n    return this.inputLayer1.height;\n  }\n\n  set height(height: number) {\n    throw new Error('Cannot set height on Multiply');\n  }\n\n  get depth(): number {\n    return this.inputLayer1.depth;\n  }\n\n  set depth(depth: number) {\n    throw new Error('Cannot set depth on Multiply');\n  }\n\n  validate(): void {\n    super.validate();\n    if (this.inputLayer1.width !== this.inputLayer2.height) {\n      throw new Error(\n        `Layer width mismatch of ${this.inputLayer1.width} and ${this.inputLayer2.height}`\n      );\n    }\n  }\n\n  setupKernels(): void {\n    this.predictKernel = makeKernel(predict, {\n      output: [this.width, this.height],\n      constants: {\n        size: this.inputLayer2.height,\n      },\n      immutable: true,\n    });\n    this.compareKernel1 = makeKernel(compareFromX, {\n      output: [this.inputLayer1.width, this.inputLayer1.height],\n      constants: {\n        size: this.inputLayer2.width,\n      },\n      immutable: true,\n    });\n    this.compareKernel2 = makeKernel(compareFromY, {\n      output: [this.inputLayer2.width, this.inputLayer2.height],\n      constants: {\n        size: this.inputLayer1.height,\n      },\n      immutable: true,\n    });\n  }\n\n  reuseKernels(layer: ILayer): void {\n    super.reuseKernels(layer);\n    this.compareKernel1 = (layer as Multiply).compareKernel1;\n    this.compareKernel2 = (layer as Multiply).compareKernel2;\n  }\n\n  predict(): void {\n    release(this.weights);\n    if (!this.predictKernel) throw new Error('this.predictKernel is not set');\n    this.weights = this.predictKernel(\n      this.inputLayer1.weights,\n      this.inputLayer2.weights\n    ) as Texture;\n  }\n\n  compare(): void {\n    if (!this.compareKernel1) throw new Error('this.compareKernel1 not set');\n    if (!this.compareKernel2) throw new Error('this.compareKernel2 not set');\n\n    const inputLayer1Deltas = this.inputLayer1.deltas;\n    const inputLayer2Deltas = this.inputLayer2.deltas;\n\n    const newDeltas1 = this.compareKernel1(\n      this.deltas,\n      this.inputLayer1.deltas,\n      this.inputLayer2.weights\n    );\n    const newDeltas2 = this.compareKernel2(\n      this.deltas,\n      this.inputLayer2.deltas,\n      this.inputLayer1.weights\n    );\n\n    this.inputLayer2.deltas = newDeltas2 as Texture;\n    this.inputLayer1.deltas = newDeltas1 as Texture;\n\n    release(inputLayer1Deltas);\n    release(inputLayer2Deltas);\n  }\n\n  setupPraxis(): void {}\n\n  toJSON(): Partial<ILayerJSON> {\n    return {\n      ...super.toJSON(),\n      width: this.width,\n      height: this.height,\n    };\n  }\n}\n\nexport function multiply(\n  inputLayer1: ILayer,\n  inputLayer2: ILayer,\n  settings?: ILayerSettings\n): Multiply {\n  return new Multiply(inputLayer1, inputLayer2, settings);\n}\n","import { ILayer, ILayerSettings } from './base-layer';\nimport { IKernelFunctionThis, IKernelRunShortcut } from 'gpu.js';\n\nimport { Activation } from './types';\nimport { makeKernel, release } from '../utilities/kernel';\nimport { activate, measure } from '../activation/sigmoid';\n\nexport function predict2D(\n  this: IKernelFunctionThis,\n  inputs: number[][]\n): number {\n  return 1 / (1 + Math.exp(-inputs[this.thread.y][this.thread.x]));\n}\n\nexport function predict3D(\n  this: IKernelFunctionThis,\n  inputs: number[][][]\n): number {\n  return (\n    1 / (1 + Math.exp(-inputs[this.thread.z][this.thread.y][this.thread.x]))\n  );\n}\n\nexport function compare2D(\n  this: IKernelFunctionThis,\n  weights: number[][],\n  deltas: number[][]\n): number {\n  const weight = weights[this.thread.y][this.thread.x];\n  const delta = deltas[this.thread.y][this.thread.x];\n  return weight * (1 - weight) * delta;\n}\n\nexport function compare3D(\n  this: IKernelFunctionThis,\n  weights: number[][][],\n  deltas: number[][][]\n): number {\n  const weight = weights[this.thread.z][this.thread.y][this.thread.x];\n  const delta = deltas[this.thread.z][this.thread.y][this.thread.x];\n  return weight * (1 - weight) * delta;\n}\n\nexport class Sigmoid extends Activation {\n  setupKernels(): void {\n    if (this.depth > 0) {\n      this.predictKernel = makeKernel(predict3D, {\n        output: [this.width, this.height, this.depth],\n        functions: [activate],\n        immutable: true,\n      });\n\n      this.compareKernel = makeKernel(compare3D, {\n        output: [this.width, this.height, this.depth],\n        functions: [measure],\n        immutable: true,\n      });\n    } else {\n      this.predictKernel = makeKernel(predict2D, {\n        output: [this.width, this.height],\n        functions: [activate],\n        immutable: true,\n      });\n\n      this.compareKernel = makeKernel(compare2D, {\n        output: [this.width, this.height],\n        functions: [measure],\n        immutable: true,\n      });\n    }\n  }\n\n  predict(): void {\n    release(this.weights);\n    this.weights = (this.predictKernel as IKernelRunShortcut)(\n      this.inputLayer.weights\n    );\n  }\n\n  compare(): void {\n    release(this.inputLayer.deltas);\n    this.inputLayer.deltas = (this.compareKernel as IKernelRunShortcut)(\n      this.weights,\n      this.deltas\n    );\n  }\n\n  learn(learningRate?: number): void {}\n}\n\nexport function sigmoid(\n  inputLayer: ILayer,\n  settings?: ILayerSettings\n): Sigmoid {\n  return new Sigmoid(inputLayer, settings);\n}\n","import { IConvolutionSettingsBase } from '../layer/convolution';\n\nexport interface IStride {\n  strideX: number;\n  strideY: number;\n}\n\nexport function getStride(\n  settings: IConvolutionSettingsBase,\n  defaults: IConvolutionSettingsBase\n): IStride {\n  if (typeof settings.stride === 'number') {\n    return { strideX: settings.stride, strideY: settings.stride };\n  } else {\n    let strideX: number = defaults.stride as number;\n    let strideY: number = defaults.stride as number;\n    if (typeof settings.strideX === 'number') {\n      strideX = settings.strideX;\n    }\n    if (typeof settings.strideY === 'number') {\n      strideY = settings.strideY;\n    }\n    return { strideX, strideY };\n  }\n}\n\nexport interface IPadding {\n  paddingX: number;\n  paddingY: number;\n}\n\nexport function getPadding(\n  settings: IConvolutionSettingsBase,\n  defaults: IConvolutionSettingsBase\n): IPadding {\n  if (typeof settings.padding === 'number') {\n    return { paddingX: settings.padding, paddingY: settings.padding };\n  } else {\n    let paddingX: number = defaults.padding as number;\n    let paddingY: number = defaults.padding as number;\n    if (typeof settings.paddingX === 'number') {\n      paddingX = settings.paddingX;\n    }\n    if (typeof settings.paddingY === 'number') {\n      paddingY = settings.paddingY;\n    }\n    return { paddingX, paddingY };\n  }\n}\n","/**\n * Returns an array of a given size with each element filled with a single value\n */\nexport function values(size: number, value: number): Float32Array {\n  return new Float32Array(size).fill(value);\n}\n","import { makeKernel, release, clone } from '../utilities/kernel';\nimport { getStride, getPadding } from '../utilities/layer-setup';\nimport { Filter } from './filter';\nimport { randos, randos3D } from '../utilities/randos';\nimport { zeros3D } from '../utilities/zeros-3d';\nimport { values } from '../utilities/values';\nimport {\n  IConstantsThis,\n  IKernelFunctionThis,\n  IKernelRunShortcut,\n  KernelOutput,\n} from 'gpu.js';\nimport { ILayer, ILayerSettings } from './base-layer';\nimport { IPraxis } from '../praxis/base-praxis';\n\nexport interface IConvolutionConstantsBase extends IConstantsThis {\n  paddingX: number;\n  paddingY: number;\n  strideX: number;\n  strideY: number;\n  filterWidth: number;\n  filterHeight: number;\n}\n\nexport interface IPredictConstants extends IConvolutionConstantsBase {\n  inputWidth: number;\n  inputHeight: number;\n}\n\nexport function predict(\n  this: IKernelFunctionThis<IPredictConstants>,\n  inputs: number[][][],\n  filters: number[][][],\n  biases: number[]\n): number {\n  const startFilterX =\n    this.constants.paddingX - this.thread.x * this.constants.strideX;\n  const startInputX =\n    this.thread.x * this.constants.strideX - this.constants.paddingX;\n  const endFilterX = Math.min(\n    this.constants.filterWidth,\n    startFilterX + this.constants.inputWidth\n  );\n\n  const startFilterY =\n    this.constants.paddingY - this.thread.y * this.constants.strideY;\n  const startInputY =\n    this.thread.y * this.constants.strideY - this.constants.paddingY;\n  const endFilterY = Math.min(\n    this.constants.filterHeight,\n    startFilterY + this.constants.inputHeight\n  );\n\n  let sum = 0;\n  for (let z = 0; z < this.constants.inputDepth; z++) {\n    for (\n      let filterY = Math.max(0, startFilterY),\n        inputY = Math.max(0, startInputY);\n      filterY < endFilterY;\n      filterY++, inputY++\n    ) {\n      for (\n        let filterX = Math.max(0, startFilterX),\n          inputX = Math.max(0, startInputX);\n        filterX < endFilterX;\n        filterX++, inputX++\n      ) {\n        sum += filters[z][filterY][filterX] * inputs[z][inputY][inputX];\n      }\n    }\n  }\n  return sum + biases[this.thread.z];\n}\n\nexport interface ICompareFilterDeltasConstants\n  extends IConvolutionConstantsBase {\n  deltaWidth: number;\n  deltaHeight: number;\n  inputWidth: number;\n  inputHeight: number;\n  deltaZ: number;\n}\n\nexport function compareFilterDeltas(\n  this: IKernelFunctionThis<ICompareFilterDeltasConstants>,\n  filterDeltas: number[][][],\n  inputs: number[][][],\n  deltas: number[][][]\n): number {\n  const startDeltaX = Math.max(\n    0,\n    Math.ceil(\n      (this.constants.paddingX - this.thread.x) / this.constants.strideX\n    )\n  );\n  const startInputX =\n    startDeltaX * this.constants.strideX +\n    this.thread.x -\n    this.constants.paddingX;\n  const endDeltaX = Math.min(\n    this.constants.deltaWidth,\n    Math.floor(\n      (this.constants.inputWidth -\n        1 -\n        this.thread.x +\n        this.constants.paddingX) /\n        this.constants.strideX\n    ) + 1\n  );\n\n  const startDeltaY = Math.max(\n    0,\n    Math.ceil(\n      (this.constants.paddingY - this.thread.y) / this.constants.strideY\n    )\n  );\n  const startInputY =\n    startDeltaY * this.constants.strideY +\n    this.thread.y -\n    this.constants.paddingY;\n  const endDeltaY = Math.min(\n    this.constants.deltaHeight,\n    Math.floor(\n      (this.constants.inputHeight -\n        1 -\n        this.thread.y +\n        this.constants.paddingY) /\n        this.constants.strideY\n    ) + 1\n  );\n\n  let sum = filterDeltas[this.thread.z][this.thread.y][this.thread.x];\n  for (\n    let deltaY = startDeltaY, inputY = startInputY;\n    deltaY < endDeltaY;\n    deltaY++, inputY += this.constants.strideY\n  ) {\n    for (\n      let deltaX = startDeltaX, inputX = startInputX;\n      deltaX < endDeltaX;\n      deltaX++, inputX += this.constants.strideX\n    ) {\n      sum +=\n        inputs[this.thread.z][inputY][inputX] *\n        deltas[this.constants.deltaZ][deltaY][deltaX];\n    }\n  }\n  return sum;\n}\n\nexport interface ICompareInputDeltasConstants\n  extends IConvolutionConstantsBase {\n  deltaHeight: number;\n  deltaWidth: number;\n  deltaZ: number;\n}\n\nexport function compareInputDeltas(\n  this: IKernelFunctionThis<ICompareInputDeltasConstants>,\n  inputDeltas: number[][][],\n  filters: number[][][],\n  deltas: number[][][]\n): number {\n  const x = this.thread.x + this.constants.paddingX;\n  const startDeltaX =\n    x < this.constants.filterWidth\n      ? 0\n      : Math.floor(\n          (x - this.constants.filterWidth + this.constants.strideX) /\n            this.constants.strideX\n        );\n  const startFilterX = x - startDeltaX * this.constants.strideX;\n  const endDeltaX = Math.min(\n    startDeltaX + Math.floor(startFilterX / this.constants.strideX) + 1,\n    this.constants.deltaWidth\n  );\n\n  const y = this.thread.y + this.constants.paddingY;\n  const startDeltaY =\n    y < this.constants.filterHeight\n      ? 0\n      : Math.floor(\n          (y - this.constants.filterHeight + this.constants.strideY) /\n            this.constants.strideY\n        );\n  const startFilterY = y - startDeltaY * this.constants.strideY;\n  const endDeltaY = Math.min(\n    startDeltaY + Math.floor(startFilterY / this.constants.strideY) + 1,\n    this.constants.deltaHeight\n  );\n\n  let sum = inputDeltas[this.thread.z][this.thread.y][this.thread.x];\n  let deltaY = startDeltaY;\n  for (\n    let filterY = startFilterY;\n    deltaY < endDeltaY;\n    filterY -= this.constants.strideY, deltaY++\n  ) {\n    let deltaX = startDeltaX;\n    for (\n      let filterX = startFilterX;\n      deltaX < endDeltaX;\n      filterX -= this.constants.strideX, deltaX++\n    ) {\n      sum +=\n        filters[this.thread.z][filterY][filterX] *\n        deltas[this.constants.deltaZ][deltaY][deltaX];\n    }\n  }\n  return sum;\n}\n\nexport interface ICompareBiasesConstants extends IConstantsThis {\n  deltaHeight: number;\n  deltaWdith: number;\n}\n\nexport function compareBiases(\n  this: IKernelFunctionThis<ICompareBiasesConstants>,\n  biasDeltas: number[][][],\n  deltas: number[][][]\n): number {\n  let sum = 0;\n  for (let y = 0; y < this.constants.deltaHeight; y++) {\n    for (let x = 0; x < this.constants.deltaWidth; x++) {\n      sum += deltas[this.thread.z][y][x];\n    }\n  }\n  return biasDeltas[this.thread.z][this.thread.y][this.thread.x] + sum;\n}\n\nexport interface IConvolutionSettingsBase {\n  stride?: number;\n  strideX?: number;\n  strideY?: number;\n  padding?: number;\n  paddingX?: number;\n  paddingY?: number;\n  filterCount?: number;\n  filterWidth?: number;\n  filterHeight?: number;\n}\n\nexport interface IConvolutionSettings\n  extends ILayerSettings,\n    IConvolutionSettingsBase {\n  bias?: number;\n  biases?: KernelOutput;\n  biasDeltas?: KernelOutput;\n  filters?: KernelOutput;\n  filterDeltas?: KernelOutput;\n}\n\nexport const defaults: IConvolutionSettings = {\n  stride: 0,\n  padding: 0,\n  bias: 0.1,\n  filterCount: 1,\n  filterWidth: 0,\n  filterHeight: 0,\n};\n\nexport class Convolution extends Filter {\n  settings: Partial<IConvolutionSettings>;\n\n  get strideX(): number {\n    return this.settings.strideX as number;\n  }\n\n  get strideY(): number {\n    return this.settings.strideY as number;\n  }\n\n  get paddingX(): number {\n    return this.settings.paddingX as number;\n  }\n\n  get paddingY(): number {\n    return this.settings.paddingX as number;\n  }\n\n  get width(): number {\n    return Math.floor(\n      (this.inputLayer.width + this.paddingX * 2 - this.filterWidth) /\n        this.strideX +\n        1\n    );\n  }\n\n  get height(): number {\n    return Math.floor(\n      (this.inputLayer.height + this.paddingY * 2 - this.filterHeight) /\n        this.strideY +\n        1\n    );\n  }\n\n  get bias(): number {\n    return this.settings.bias as number;\n  }\n\n  get depth(): number {\n    return this.filterCount;\n  }\n\n  get biases(): KernelOutput {\n    return this.settings.biases;\n  }\n\n  set biases(biases: KernelOutput) {\n    this.settings.biases = biases;\n  }\n\n  get biasDeltas(): KernelOutput {\n    return this.settings.biasDeltas;\n  }\n\n  set biasDeltas(weights: KernelOutput) {\n    this.settings.biasDeltas = weights;\n  }\n\n  get filters(): KernelOutput {\n    return this.settings.filters;\n  }\n\n  set filters(filters: KernelOutput) {\n    this.settings.filters = filters;\n  }\n\n  get filterDeltas(): KernelOutput {\n    return this.settings.filterDeltas;\n  }\n\n  set filterDeltas(filterDeltas: KernelOutput) {\n    this.settings.filterDeltas = filterDeltas;\n  }\n\n  constructor(settings: IConvolutionSettings, inputLayer: ILayer) {\n    super(settings, inputLayer);\n    this.settings = {\n      ...defaults,\n      ...settings,\n      ...getPadding(settings, defaults),\n      ...getStride(settings, defaults),\n    };\n\n    this.weights =\n      settings.weights ?? randos3D(this.width, this.height, this.depth);\n    this.deltas = zeros3D(this.width, this.height, this.depth);\n\n    this.biases = values(this.depth, this.bias);\n    this.biasDeltas = settings.biasDeltas ?? randos(this.depth);\n\n    this.filters =\n      settings.filters ??\n      randos3D(this.filterWidth, this.filterHeight, this.filterCount);\n    this.filterDeltas = zeros3D(\n      this.filterWidth,\n      this.filterHeight,\n      this.filterCount\n    );\n    this.validate();\n  }\n\n  compareFilterDeltasKernel: IKernelRunShortcut | null = null;\n  compareInputDeltasKernel: IKernelRunShortcut | null = null;\n  compareBiasesKernel: IKernelRunShortcut | null = null;\n  setupKernels(): void {\n    this.predictKernel = makeKernel<\n      Parameters<typeof predict>,\n      IPredictConstants\n    >(predict, {\n      constants: {\n        inputWidth: this.inputLayer.width,\n        inputHeight: this.inputLayer.height,\n        inputDepth: this.inputLayer.depth,\n        strideX: this.strideX,\n        strideY: this.strideY,\n        paddingX: this.paddingX,\n        paddingY: this.paddingY,\n        filterWidth: this.filterWidth,\n        filterHeight: this.filterHeight,\n      },\n      output: [this.width, this.height, this.depth],\n      immutable: true,\n    });\n\n    this.compareFilterDeltasKernel = makeKernel(compareFilterDeltas, {\n      constants: {\n        deltasWidth: this.width,\n        deltasHeight: this.height,\n        deltasDepth: this.depth,\n        inputWidth: this.inputLayer.width,\n        inputHeight: this.inputLayer.height,\n        inputDepth: this.inputLayer.depth,\n        strideX: this.strideX,\n        strideY: this.strideY,\n        paddingX: this.paddingX,\n        paddingY: this.paddingY,\n        filterWidth: this.filterWidth,\n        filterHeight: this.filterHeight,\n      },\n      output: [this.width, this.height, this.depth],\n      immutable: true,\n    });\n\n    this.compareInputDeltasKernel = makeKernel(compareInputDeltas, {\n      constants: {\n        filterCount: this.filterCount,\n      },\n      output: [\n        this.inputLayer.width,\n        this.inputLayer.height,\n        this.inputLayer.depth,\n      ],\n      immutable: true,\n    });\n\n    this.compareBiasesKernel = makeKernel(compareBiases, {\n      output: [1, 1, this.depth],\n      constants: {\n        deltaWidth: this.width,\n        deltaHeight: this.height,\n      },\n      immutable: true,\n    });\n  }\n\n  predict(): void {\n    this.weights = (this.predictKernel as IKernelRunShortcut)(\n      this.inputLayer.weights,\n      this.filters,\n      this.biases\n    );\n  }\n\n  compare(): void {\n    const { filterDeltas, biasDeltas } = this;\n    this.filterDeltas = (this.compareFilterDeltasKernel as IKernelRunShortcut)(\n      filterDeltas,\n      this.inputLayer.weights,\n      this.deltas\n    );\n    release(filterDeltas);\n    this.biasDeltas = (this.compareBiasesKernel as IKernelRunShortcut)(\n      biasDeltas,\n      this.deltas\n    );\n    release(biasDeltas);\n    release(this.deltas);\n    this.deltas = (this.compareInputDeltasKernel as IKernelRunShortcut)(\n      this.filters,\n      this.inputLayer.deltas\n    );\n\n    release(this.inputLayer.deltas);\n    // TODO: do we need to clone here?\n    this.inputLayer.deltas = clone(this.deltas);\n  }\n\n  learn(learningRate: number): void {\n    // TODO: handle filters\n    // TODO: do we need to release here?\n    const { weights: oldWeights } = this;\n    this.weights = (this.praxis as IPraxis).run(this, learningRate);\n    release(oldWeights);\n  }\n}\n\nexport function convolution(\n  settings: IConvolutionSettings,\n  inputLayer: ILayer\n): Convolution {\n  return new Convolution(settings, inputLayer);\n}\n","import { Filter, IFilterSettings } from './filter';\nimport { makeKernel, makeKernelMap, release } from '../utilities/kernel';\nimport {\n  IConstantsThis,\n  IKernelFunctionThis,\n  IKernelMapRunShortcut,\n  IKernelRunShortcut,\n  ISubKernelObject,\n  KernelOutput,\n} from 'gpu.js';\nimport { ILayer, ILayerSettings, baseLayerDefaultSettings } from './base-layer';\n\nexport function setDropout(dropout: number): number {\n  return dropout;\n}\n\nexport interface IDropoutConstants extends IConstantsThis {\n  probability: number;\n}\n\nexport function trainingPredict(\n  this: IKernelFunctionThis<IDropoutConstants>,\n  inputs: number[][]\n): number {\n  if (setDropout(Math.random()) < this.constants.probability) {\n    return 0;\n  }\n  return inputs[this.thread.y][this.thread.x];\n}\n\nexport function predict(\n  this: IKernelFunctionThis<IDropoutConstants>,\n  inputs: number[][]\n): number {\n  return inputs[this.thread.y][this.thread.x] * this.constants.probability;\n}\n\nexport function compare(\n  this: IKernelFunctionThis,\n  dropouts: number[][],\n  deltas: number[][]\n): number {\n  if (dropouts[this.thread.y][this.thread.x] === 0) {\n    return 0;\n  }\n  return deltas[this.thread.y][this.thread.x];\n}\n\nexport interface IDropoutSettings extends ILayerSettings {\n  probability: number;\n}\n\nexport const dropoutDefaults: IDropoutSettings = {\n  ...baseLayerDefaultSettings,\n  probability: 0.5,\n};\n\nexport class Dropout extends Filter {\n  dropouts: KernelOutput | null;\n  predictKernelMap: IKernelMapRunShortcut<ISubKernelObject> | null = null;\n  settings: Partial<IDropoutSettings>;\n  constructor(\n    inputLayer: ILayer,\n    settings?: Partial<IDropoutSettings> & Partial<IFilterSettings>\n  ) {\n    super(settings as Partial<IFilterSettings>, inputLayer);\n    this.settings = { ...dropoutDefaults, ...settings };\n    this.dropouts = null;\n    this.validate();\n  }\n\n  setupKernels(isTraining?: boolean): void {\n    const output = [this.width, this.height];\n\n    if (isTraining) {\n      this.predictKernelMap = makeKernelMap<\n        Parameters<typeof trainingPredict>,\n        IDropoutConstants\n      >({ dropouts: setDropout }, trainingPredict, {\n        output,\n        immutable: true,\n      });\n      this.compareKernel = makeKernel(compare, { output, immutable: true });\n    } else {\n      this.predictKernelMap = makeKernelMap<\n        Parameters<typeof predict>,\n        IDropoutConstants\n      >({}, predict, { output, immutable: true });\n    }\n  }\n\n  predict(): void {\n    release(this.weights);\n    if (this.dropouts) {\n      release(this.dropouts);\n    }\n    const { result, dropouts } = (this\n      .predictKernelMap as IKernelMapRunShortcut<ISubKernelObject>)(\n      this.inputLayer.weights\n    );\n    this.weights = result;\n    this.dropouts = dropouts;\n  }\n\n  compare(): void {\n    release(this.deltas);\n    this.deltas = (this.compareKernel as IKernelRunShortcut)(\n      this.dropouts as KernelOutput,\n      this.inputLayer.deltas\n    );\n  }\n}\n\nexport function dropout(\n  inputLayer: ILayer,\n  settings?: Partial<IDropoutSettings>\n): Dropout {\n  return new Dropout(inputLayer, settings);\n}\n","import {\n  IConstantsThis,\n  IKernelFunctionThis,\n  IKernelRunShortcut,\n  KernelOutput,\n} from 'gpu.js';\nimport { Filter, IFilterSettings } from './filter';\nimport { makeKernel, release } from '../utilities/kernel';\nimport { values } from '../utilities/values';\nimport { randos2D, randos3D } from '../utilities/randos';\nimport { zeros } from '../utilities/zeros';\nimport { zeros2D } from '../utilities/zeros-2d';\nimport { zeros3D } from '../utilities/zeros-3d';\nimport { ILayer } from './base-layer';\n\nexport interface IPredictConstants extends IConstantsThis {\n  inputWidth: number;\n  inputHeight: number;\n}\n\nexport function predict(\n  this: IKernelFunctionThis<IPredictConstants>,\n  inputs: number[][],\n  filters: number[][],\n  biases: number[]\n): number {\n  let output = 0;\n  let i = 0;\n  for (let y = 0; y < this.constants.inputHeight; y++) {\n    for (let x = 0; x < this.constants.inputWidth; x++) {\n      output += inputs[y][x] * filters[this.thread.x][i];\n      i++;\n    }\n  }\n  return output + biases[this.thread.x];\n}\n\nexport function predict3D(\n  this: IKernelFunctionThis<IPredictConstants>,\n  inputs: number[][][],\n  filters: number[][],\n  biases: number[]\n): number {\n  let output = 0;\n  let i = 0;\n  for (let z = 0; z < this.constants.inputDepth; z++) {\n    for (let y = 0; y < this.constants.inputHeight; y++) {\n      for (let x = 0; x < this.constants.inputWidth; x++) {\n        output += inputs[z][y][x] * filters[this.thread.x][i];\n        i++;\n      }\n    }\n  }\n  return output + biases[this.thread.x];\n}\n\nexport interface ICompareInputDeltasConstants extends IConstantsThis {\n  filterCount: number;\n}\n\nexport function compareInputDeltas(\n  this: IKernelFunctionThis<ICompareInputDeltasConstants>,\n  inputDeltas: number[][],\n  deltas: number[][],\n  filters: number[][]\n): number {\n  let sum = 0;\n  const filterX = this.thread.x + this.thread.y * this.output.x;\n  for (let filterY = 0; filterY < this.constants.filterCount; filterY++) {\n    sum += filters[filterY][filterX] * deltas[0][filterY];\n  }\n  return sum + inputDeltas[this.thread.y][this.thread.x];\n}\n\nexport function compareInputDeltas3D(\n  this: IKernelFunctionThis<ICompareInputDeltasConstants>,\n  inputDeltas: number[][][],\n  deltas: number[][],\n  filters: number[][]\n): number {\n  let sum = 0;\n  const filterX = this.thread.x + this.thread.y * this.output.x;\n  for (let filterY = 0; filterY < this.constants.filterCount; filterY++) {\n    sum += filters[filterY][filterX] * deltas[0][filterY];\n  }\n  return sum + inputDeltas[this.thread.z][this.thread.y][this.thread.x];\n}\n\nexport function compareBiases(\n  this: IKernelFunctionThis,\n  biases: number[],\n  deltas: number[][]\n): number {\n  return biases[this.thread.x] + deltas[this.thread.y][this.thread.x];\n}\n\nexport interface ICompareFiltersDeltas extends IConstantsThis {\n  deltaX: number;\n  deltaY: number;\n  inputWidth: number;\n  inputHeight: number;\n}\n\nexport function compareFilterDeltas(\n  this: IKernelFunctionThis<ICompareFiltersDeltas>,\n  filterDeltas: number[][],\n  inputWeights: number[][],\n  deltas: number[][]\n): number {\n  return (\n    filterDeltas[this.thread.y][this.thread.x] +\n    inputWeights[this.thread.y][this.thread.x] *\n      deltas[this.constants.deltaY][this.constants.deltaX]\n  );\n}\n\nexport function compareFilterDeltas3D(\n  this: IKernelFunctionThis<ICompareFiltersDeltas>,\n  filterDeltas: number[][],\n  inputWeights: number[][][],\n  deltas: number[][]\n): number {\n  const inputZ = Math.floor(\n    this.thread.x / (this.constants.inputWidth * this.constants.inputHeight)\n  );\n  const inputY = Math.floor(\n    (this.thread.x -\n      inputZ * this.constants.inputWidth * this.constants.inputHeight) /\n      this.constants.inputWidth\n  );\n  const inputX =\n    this.thread.x -\n    this.constants.inputWidth * (inputY + this.constants.inputHeight * inputZ);\n  return (\n    filterDeltas[this.thread.y][this.thread.x] +\n    inputWeights[inputZ][inputY][inputX] * deltas[0][this.thread.y]\n  );\n}\n\nexport interface IFullyConnectedDefaultSettings\n  extends Partial<IFilterSettings> {\n  bias?: number;\n  biases?: KernelOutput;\n  biasDeltas?: KernelOutput;\n}\n\nexport const defaults: IFullyConnectedDefaultSettings = {\n  bias: 0.1,\n};\n\nexport class FullyConnected extends Filter {\n  get bias(): number {\n    return this.settings.bias as number;\n  }\n\n  get biases(): KernelOutput {\n    return this.settings.biases;\n  }\n\n  set biases(biases: KernelOutput) {\n    this.settings.biases = biases;\n  }\n\n  get biasDeltas(): KernelOutput {\n    return this.settings.biases;\n  }\n\n  set biasDeltas(biasDeltas: KernelOutput) {\n    this.settings.biasDeltas = biasDeltas;\n  }\n\n  settings: Partial<IFullyConnectedDefaultSettings>;\n  compareFilterDeltasKernel: IKernelRunShortcut | null = null;\n  compareInputDeltasKernel: IKernelRunShortcut | null = null;\n  compareBiasesKernel: IKernelRunShortcut | null = null;\n  constructor(\n    settings: Partial<IFullyConnectedDefaultSettings>,\n    inputLayer: ILayer\n  ) {\n    super(settings, inputLayer);\n    this.settings = { ...settings };\n    this.validate();\n\n    const connectionCount =\n      inputLayer.width * inputLayer.height * inputLayer.depth;\n\n    this.biases = values(this.height, this.bias);\n    this.biasDeltas = zeros(this.height);\n\n    this.filters = randos2D(connectionCount, this.height);\n    this.filterDeltas = zeros2D(connectionCount, this.height);\n\n    if (this.depth > 0) {\n      this.weights = randos3D(this.width, this.height, this.depth);\n      this.deltas = zeros3D(this.width, this.height, this.depth);\n    } else if (this.height > 0) {\n      this.weights = randos2D(this.width, this.height);\n      this.deltas = zeros2D(this.width, this.height);\n    }\n  }\n\n  validate(): void {\n    super.validate();\n    if (this.depth > 0) throw new Error('depth not supported');\n  }\n\n  setupKernels(): void {\n    const { inputLayer } = this;\n    const connectionCount =\n      inputLayer.width * inputLayer.height * inputLayer.depth;\n    if (inputLayer.depth > 0) {\n      this.predictKernel = makeKernel(predict3D, {\n        output: [this.width, this.height],\n        constants: {\n          inputHeight: inputLayer.height,\n          inputWidth: inputLayer.width,\n          inputDepth: inputLayer.depth,\n        },\n      });\n\n      this.compareFilterDeltasKernel = makeKernel(compareFilterDeltas3D, {\n        output: [connectionCount, this.height],\n        constants: {\n          inputWidth: inputLayer.width,\n          inputHeight: inputLayer.height,\n        },\n        immutable: true,\n      });\n\n      this.compareInputDeltasKernel = makeKernel(compareInputDeltas3D, {\n        output: [inputLayer.width, inputLayer.height, inputLayer.depth],\n        constants: {\n          filterCount: this.height,\n        },\n        immutable: true,\n      });\n    } else {\n      this.predictKernel = makeKernel(predict, {\n        output: [this.width, this.height],\n        constants: {\n          inputHeight: inputLayer.height,\n          inputWidth: inputLayer.width,\n        },\n      });\n\n      this.compareFilterDeltasKernel = makeKernel(compareFilterDeltas, {\n        output: [connectionCount, this.height],\n        constants: {\n          inputWidth: inputLayer.width,\n        },\n      });\n\n      this.compareInputDeltasKernel = makeKernel(compareInputDeltas, {\n        output: [inputLayer.width, inputLayer.height],\n        constants: {\n          filterCount: this.height,\n        },\n      });\n    }\n\n    this.compareBiasesKernel = makeKernel(compareBiases, {\n      output: [this.width, this.height],\n    });\n  }\n\n  predict(): void {\n    this.weights = (this.predictKernel as IKernelRunShortcut)(\n      this.inputLayer.weights,\n      this.filters,\n      this.biases\n    );\n  }\n\n  compare(): void {\n    const inputLayerDeltas = this.inputLayer.deltas;\n    this.inputLayer.deltas = (this\n      .compareInputDeltasKernel as IKernelRunShortcut)(\n      inputLayerDeltas,\n      this.deltas,\n      this.filters\n    );\n    release(inputLayerDeltas);\n\n    const { biasDeltas, filterDeltas } = this;\n    // TODO: handle biasDeltas learn\n    this.biasDeltas = (this.compareBiasesKernel as IKernelRunShortcut)(\n      this.biases,\n      this.deltas\n    );\n\n    // TODO: handle filterDeltas learn\n    this.filterDeltas = (this.compareFilterDeltasKernel as IKernelRunShortcut)(\n      filterDeltas,\n      this.inputLayer.weights,\n      this.deltas\n    );\n    release(biasDeltas);\n    release(filterDeltas);\n  }\n}\n\nexport function fullyConnected(\n  settings: IFullyConnectedDefaultSettings,\n  inputLayer: ILayer\n): FullyConnected {\n  return new FullyConnected(settings, inputLayer);\n}\n","import { makeKernel } from '../utilities/kernel';\nimport { Modifier } from './types';\nimport { IKernelFunctionThis, IKernelRunShortcut } from 'gpu.js';\nimport { ILayer, ILayerSettings } from './base-layer';\n\nexport function predict(\n  this: IKernelFunctionThis,\n  weights: number[][]\n): number {\n  return -weights[this.thread.y][this.thread.x];\n}\n\nexport class Negative extends Modifier {\n  constructor(inputLayer: ILayer, settings?: ILayerSettings) {\n    super(inputLayer, settings);\n    this.validate();\n  }\n\n  setupKernels(): void {\n    this.predictKernel = makeKernel(predict, {\n      output: [this.width, this.height],\n    });\n  }\n\n  predict(): void {\n    this.weights = (this.predictKernel as IKernelRunShortcut)(\n      this.inputLayer.weights\n    );\n  }\n}\n\nexport function negative(\n  inputLayer: ILayer,\n  settings?: ILayerSettings\n): Negative {\n  return new Negative(inputLayer, settings);\n}\n","import { makeKernel, release } from '../utilities/kernel';\nimport { Operator } from './operator';\nimport { checkSameSize } from '../utilities/layer-size';\nimport { ILayer, ILayerSettings } from './base-layer';\nimport { IKernelFunctionThis, IKernelRunShortcut } from 'gpu.js';\n\nexport function predict(\n  this: IKernelFunctionThis,\n  inputLayerWeights1: number[][],\n  inputLayerWeights2: number[][]\n): number {\n  return (\n    inputLayerWeights1[this.thread.y][this.thread.x] *\n    inputLayerWeights2[this.thread.y][this.thread.x]\n  );\n}\n\nexport function compare(\n  this: IKernelFunctionThis,\n  weights: number[][],\n  deltas: number[][]\n): number {\n  return (\n    weights[this.thread.y][this.thread.x] * deltas[this.thread.y][this.thread.x]\n  );\n}\n\nexport class MultiplyElement extends Operator {\n  get width(): number {\n    return this.inputLayer1.width;\n  }\n\n  get height(): number {\n    return this.inputLayer1.height;\n  }\n\n  get depth(): number {\n    return this.inputLayer1.depth;\n  }\n\n  validate(): void {\n    super.validate();\n    checkSameSize(this.inputLayer1, this.inputLayer2);\n  }\n\n  setupKernels(): void {\n    this.predictKernel = makeKernel(predict, {\n      output: [this.width, this.height],\n      immutable: true,\n    });\n\n    this.compareKernel = makeKernel(compare, {\n      output: [this.width, this.height],\n      immutable: true,\n    });\n  }\n\n  predict(): void {\n    release(this.weights);\n    this.weights = (this.predictKernel as IKernelRunShortcut)(\n      this.inputLayer1.weights,\n      this.inputLayer2.weights\n    );\n  }\n\n  compare(): void {\n    release(this.inputLayer1.deltas);\n    release(this.inputLayer2.deltas);\n    this.inputLayer1.deltas = (this.compareKernel as IKernelRunShortcut)(\n      this.inputLayer2.weights,\n      this.deltas\n    );\n    this.inputLayer2.deltas = (this.compareKernel as IKernelRunShortcut)(\n      this.inputLayer1.weights,\n      this.deltas\n    );\n  }\n}\n\nexport function multiplyElement(\n  inputLayer1: ILayer,\n  inputLayer2: ILayer,\n  settings?: ILayerSettings\n): MultiplyElement {\n  return new MultiplyElement(inputLayer1, inputLayer2, settings);\n}\n","export function ones(size: number): Float32Array {\n  return new Float32Array(size).fill(1);\n}\n\nexport function ones2D(width: number, height: number): Float32Array[] {\n  const result = new Array(height);\n  for (let y = 0; y < height; y++) {\n    result[y] = ones(width);\n  }\n  return result;\n}\n","import { ILayerSettings } from './base-layer';\n\nimport { ones2D } from '../utilities/ones';\nimport { zeros2D } from '../utilities/zeros-2d';\nimport { Model } from './types';\n\nexport class Ones extends Model {\n  constructor(settings: ILayerSettings) {\n    super(settings);\n    this.validate();\n    this.weights = ones2D(this.width, this.height);\n    this.deltas = zeros2D(this.width, this.height);\n  }\n}\n\nexport function ones(settings: ILayerSettings): Ones {\n  return new Ones(settings);\n}\n","import { IKernelFunctionThis, IKernelRunShortcut } from 'gpu.js';\n\nimport { Activation } from './activation';\nimport { activate, measure } from '../activation/tanh';\nimport { release, makeKernel } from '../utilities/kernel';\nimport { ILayer, ILayerSettings } from './base-layer';\n\nexport function predict2D(\n  this: IKernelFunctionThis,\n  inputs: number[][]\n): number {\n  return activate(inputs[this.thread.y][this.thread.x]);\n}\n\nexport function predict3D(\n  this: IKernelFunctionThis,\n  inputs: number[][][]\n): number {\n  return activate(inputs[this.thread.z][this.thread.y][this.thread.x]);\n}\n\nexport function compare2D(\n  this: IKernelFunctionThis,\n  weights: number[][],\n  errors: number[][]\n): number {\n  return measure(\n    weights[this.thread.y][this.thread.x],\n    errors[this.thread.y][this.thread.x]\n  );\n}\n\nexport function compare3D(\n  this: IKernelFunctionThis,\n  weights: number[][][],\n  errors: number[][][]\n): number {\n  return measure(\n    weights[this.thread.z][this.thread.y][this.thread.x],\n    errors[this.thread.z][this.thread.y][this.thread.x]\n  );\n}\n\nexport class Tanh extends Activation {\n  setupKernels(): void {\n    if (this.depth > 0) {\n      this.predictKernel = makeKernel(predict3D, {\n        output: [this.width, this.height, this.depth],\n        functions: [activate],\n        immutable: true,\n      });\n\n      this.compareKernel = makeKernel(compare3D, {\n        output: [this.width, this.height, this.depth],\n        functions: [measure],\n        immutable: true,\n      });\n    } else {\n      this.predictKernel = makeKernel(predict2D, {\n        output: [this.width, this.height],\n        functions: [activate],\n        immutable: true,\n      });\n\n      this.compareKernel = makeKernel(compare2D, {\n        output: [this.width, this.height],\n        functions: [measure],\n        immutable: true,\n      });\n    }\n  }\n\n  predict(): void {\n    release(this.weights);\n    this.weights = (this.predictKernel as IKernelRunShortcut)(\n      this.inputLayer.weights\n    );\n  }\n\n  compare(): void {\n    release(this.inputLayer.deltas);\n    this.inputLayer.deltas = (this.compareKernel as IKernelRunShortcut)(\n      this.weights,\n      this.deltas\n    );\n  }\n}\n\nexport function tanh(inputLayer: ILayer, settings?: ILayerSettings): Tanh {\n  return new Tanh(inputLayer, settings);\n}\n","import { zeros2D } from '../utilities/zeros-2d';\nimport { Model } from './types';\nimport { ILayerSettings } from './base-layer';\n\nexport class Zeros extends Model {\n  constructor(settings: ILayerSettings) {\n    super(settings);\n    this.validate();\n    this.weights = zeros2D(this.width, this.height);\n    this.deltas = zeros2D(this.width, this.height);\n  }\n\n  predict(): void {\n    // throw new Error(`${this.constructor.name}-predict is not yet implemented`)\n  }\n\n  compare(): void {\n    // throw new Error(`${this.constructor.name}-compare is not yet implemented`)\n  }\n\n  // learn(): void {}\n}\n\nexport function zeros(settings: ILayerSettings): Zeros {\n  return new Zeros(settings);\n}\n","import { IKernelFunctionThis, IKernelRunShortcut, KernelOutput } from 'gpu.js';\nimport { EntryPoint } from './types';\nimport { ILayer, ILayerSettings } from './base-layer';\nimport { zeros2D } from '../utilities/zeros-2d';\nimport { makeKernel, release, kernelInput, clone } from '../utilities/kernel';\n\nexport const defaults: ILayerSettings = {\n  weights: null,\n};\n\nexport class Input extends EntryPoint {\n  reshapeInput: IKernelRunShortcut | null = null;\n  constructor(settings: ILayerSettings) {\n    super({ ...defaults, ...settings });\n    this.validate();\n    this.reshapeInput = null;\n    this.deltas = zeros2D(this.width, this.height);\n  }\n\n  setupKernels(): void {\n    if (this.width === 1) {\n      this.predict = this.predict1D;\n      this.reshapeInput = makeKernel(\n        function (this: IKernelFunctionThis, value: number[]) {\n          return value[this.thread.y];\n        },\n        {\n          output: [1, this.height],\n          immutable: true,\n        }\n      );\n    }\n  }\n\n  reuseKernels(layer: ILayer): void {\n    // super.reuseKernels(layer);\n    this.reshapeInput = (layer as Input).reshapeInput;\n  }\n\n  predict(inputs: KernelOutput): void {\n    if (\n      (Array.isArray(inputs) || inputs instanceof Float32Array) &&\n      typeof inputs[0] === 'number' &&\n      inputs.length === this.height * this.width\n    ) {\n      release(this.weights);\n      this.weights = kernelInput(inputs as number[], [this.width, this.height]);\n    } else if (\n      Array.isArray(inputs) &&\n      inputs.length === this.height &&\n      (Array.isArray(inputs[0]) || inputs[0] instanceof Float32Array) &&\n      inputs[0].length === this.width\n    ) {\n      this.weights = clone(inputs);\n    } else {\n      throw new Error('Inputs are not of sized correctly');\n    }\n  }\n\n  predict1D(inputs: KernelOutput): void {\n    if (this.weights) release(this.weights);\n    if (this.reshapeInput) {\n      this.weights = this.reshapeInput(inputs);\n    } else {\n      this.weights = inputs;\n    }\n  }\n\n  compare(): void {\n    // throw new Error(`${this.constructor.name}-compare is not yet implemented`)\n  }\n\n  learn(): void {}\n}\n\nexport function input(settings: ILayerSettings): Input {\n  return new Input(settings);\n}\n","import { Activation } from './types';\nimport { makeKernel, release } from '../utilities/kernel';\nimport { activate, measure } from '../activation/leaky-relu';\nimport { IKernelFunctionThis, IKernelRunShortcut } from 'gpu.js';\nimport { ILayer, ILayerSettings } from './base-layer';\n\nexport function predict2D(\n  this: IKernelFunctionThis,\n  inputs: number[][]\n): number {\n  return activate(inputs[this.thread.y][this.thread.x]);\n}\n\nexport function predict3D(\n  this: IKernelFunctionThis,\n  inputs: number[][][]\n): number {\n  return activate(inputs[this.thread.z][this.thread.y][this.thread.x]);\n}\n\nexport function compare2D(\n  this: IKernelFunctionThis,\n  weights: number[][],\n  deltas: number[][]\n): number {\n  return measure(\n    weights[this.thread.y][this.thread.x],\n    deltas[this.thread.y][this.thread.x]\n  );\n}\n\nexport function compare3D(\n  this: IKernelFunctionThis,\n  weights: number[][][],\n  deltas: number[][][]\n): number {\n  return measure(\n    weights[this.thread.z][this.thread.y][this.thread.x],\n    deltas[this.thread.z][this.thread.y][this.thread.x]\n  );\n}\n\nexport class LeakyRelu extends Activation {\n  setupKernels(): void {\n    const { width, height, depth } = this.inputLayer;\n    if (this.depth > 0) {\n      this.predictKernel = makeKernel(predict3D, {\n        output: [width, height, depth],\n        functions: [activate],\n        immutable: true,\n      });\n\n      this.compareKernel = makeKernel(compare3D, {\n        output: [width, height, depth],\n        functions: [measure],\n        immutable: true,\n      });\n    } else {\n      this.predictKernel = makeKernel(predict2D, {\n        output: [width, height],\n        functions: [activate],\n        immutable: true,\n      });\n\n      this.compareKernel = makeKernel(compare2D, {\n        output: [width, height],\n        functions: [measure],\n        immutable: true,\n      });\n    }\n  }\n\n  predict(): void {\n    release(this.weights);\n    this.weights = (this.predictKernel as IKernelRunShortcut)(\n      this.inputLayer.weights\n    );\n  }\n\n  compare(): void {\n    const { deltas } = this;\n    this.deltas = (this.compareKernel as IKernelRunShortcut)(\n      this.weights,\n      deltas\n    );\n    release(deltas);\n  }\n}\n\nexport function leakyRelu(\n  inputLayer: ILayer,\n  settings: ILayerSettings\n): LeakyRelu {\n  return new LeakyRelu(inputLayer, settings);\n}\n","import { Filter } from './filter';\nimport { makeKernel, makeKernelMap, release } from '../utilities/kernel';\nimport { getPadding, getStride } from '../utilities/layer-setup';\nimport { zeros3D } from '../utilities/zeros-3d';\nimport { randos3D } from '../utilities/randos';\nimport {\n  IConstantsThis,\n  IKernelFunctionThis,\n  IKernelMapRunShortcut,\n  IKernelRunShortcut,\n  ISubKernelObject,\n  KernelOutput,\n} from 'gpu.js';\nimport {\n  IConvolutionSettingsBase,\n  IConvolutionConstantsBase,\n} from './convolution';\nimport { ILayer, ILayerSettings } from './base-layer';\n\nexport function setSwitchY(value: number): number {\n  return value;\n}\n\nexport function setSwitchX(value: number): number {\n  return value;\n}\n\nexport interface IPredictConstants extends IConvolutionConstantsBase {\n  inputWidth: number;\n  inputHeight: number;\n}\n\nexport function predict(\n  this: IKernelFunctionThis<IPredictConstants>,\n  inputs: number[][][]\n): number {\n  const startFilterX =\n    this.constants.paddingX - this.thread.x * this.constants.strideX;\n  const startInputX =\n    this.thread.x * this.constants.strideX - this.constants.paddingX;\n  const endFilterX = Math.min(\n    this.constants.filterWidth,\n    startFilterX + this.constants.inputWidth\n  );\n\n  const startFilterY =\n    this.constants.paddingY - this.thread.y * this.constants.strideY;\n  const startInputY =\n    this.thread.y * this.constants.strideY - this.constants.paddingY;\n  const endFilterY = Math.min(\n    this.constants.filterHeight,\n    startFilterY + this.constants.inputHeight\n  );\n\n  let largestValue = -99999;\n  let largestX = -1;\n  let largestY = -1;\n\n  // convolve centered at this particular location\n  for (\n    let filterY = Math.max(0, startFilterY), inputY = Math.max(0, startInputY);\n    filterY < endFilterY;\n    filterY++, inputY++\n  ) {\n    for (\n      let filterX = Math.max(0, startFilterX),\n        inputX = Math.max(0, startInputX);\n      filterX < endFilterX;\n      filterX++, inputX++\n    ) {\n      if (\n        inputY >= 0 &&\n        inputY < this.constants.inputHeight &&\n        inputX >= 0 &&\n        inputX < this.constants.inputWidth\n      ) {\n        const input = inputs[this.thread.z][inputY][inputX];\n        if (input > largestValue) {\n          largestValue = input;\n          largestY = inputY;\n          largestX = inputX;\n        }\n      }\n    }\n  }\n  setSwitchY(largestY);\n  setSwitchX(largestX);\n  return largestValue;\n}\n\nexport interface ICompareConstants extends IConstantsThis {\n  inputWidth: number;\n  inputHeight: number;\n\n  outputWidth: number;\n  outputHeight: number;\n}\n\nexport function compare(\n  this: IKernelFunctionThis<ICompareConstants>,\n  deltas: number[][],\n  switchY: number[][],\n  switchX: number[][]\n): number {\n  const x = Math.floor(\n    (this.thread.x / this.output.x) * this.constants.outputWidth\n  );\n  const y = Math.floor(\n    (this.thread.y / this.output.y) * this.constants.outputHeight\n  );\n\n  let value = 0;\n\n  for (let deltasY = 0; deltasY < this.constants.inputHeight; deltasY++) {\n    for (let deltasX = 0; deltasX < this.constants.inputWidth; deltasX++) {\n      const switchXValue = switchX[deltasY][deltasX];\n      const switchYValue = switchY[deltasY][deltasX];\n      if (switchXValue === x && switchYValue === y) {\n        value += deltas[deltasY][deltasX];\n      }\n    }\n  }\n\n  return value;\n}\n\nexport function compare3D(\n  this: IKernelFunctionThis<ICompareConstants>,\n  deltas: number[][][],\n  switchY: number[][][],\n  switchX: number[][][]\n): number {\n  const x = Math.floor(\n    (this.thread.x / this.output.x) * this.constants.outputWidth\n  );\n  const y = Math.floor(\n    (this.thread.y / this.output.y) * this.constants.outputHeight\n  );\n\n  let value = 0;\n\n  for (let deltasY = 0; deltasY < this.constants.inputHeight; deltasY++) {\n    for (let deltasX = 0; deltasX < this.constants.inputWidth; deltasX++) {\n      const switchXValue = switchX[this.thread.z][deltasY][deltasX];\n      const switchYValue = switchY[this.thread.z][deltasY][deltasX];\n      if (switchXValue === x && switchYValue === y) {\n        value += deltas[this.thread.z][deltasY][deltasX];\n      }\n    }\n  }\n\n  return value;\n}\n\nexport interface IPoolSettings\n  extends ILayerSettings,\n    IConvolutionSettingsBase {\n  switchX?: KernelOutput;\n  switchY?: KernelOutput;\n}\n\nexport const defaults: IPoolSettings = {\n  padding: 0,\n  stride: 0,\n  filterWidth: 0,\n  filterHeight: 0,\n  filterCount: 0,\n};\n\nexport class Pool extends Filter {\n  settings: Partial<IPoolSettings>;\n\n  get strideX(): number {\n    return this.settings.strideX as number;\n  }\n\n  get strideY(): number {\n    return this.settings.strideY as number;\n  }\n\n  get paddingX(): number {\n    return this.settings.paddingX as number;\n  }\n\n  get paddingY(): number {\n    return this.settings.paddingY as number;\n  }\n\n  get width(): number {\n    return Math.floor(\n      (this.inputLayer.width + this.paddingX * 2 - this.filterWidth) /\n        this.strideX +\n        1\n    );\n  }\n\n  get height(): number {\n    return Math.floor(\n      (this.inputLayer.height + this.paddingY * 2 - this.filterHeight) /\n        this.strideY +\n        1\n    );\n  }\n\n  get depth(): number {\n    return this.settings.filterCount as number;\n  }\n\n  get filterCount(): number {\n    // TODO: handle 1 depth?\n    return this.settings.filterCount as number;\n  }\n\n  get switchX(): KernelOutput {\n    return this.settings.switchX;\n  }\n\n  set switchX(switchX: KernelOutput) {\n    this.settings.switchX = switchX;\n  }\n\n  get switchY(): KernelOutput {\n    return this.settings.switchY;\n  }\n\n  set switchY(switchY: KernelOutput) {\n    this.settings.switchY = switchY;\n  }\n\n  predictKernelMap: IKernelMapRunShortcut<ISubKernelObject> | null = null;\n  constructor(settings: IPoolSettings, inputLayer: ILayer) {\n    super(settings, inputLayer);\n    this.settings = {\n      ...settings,\n      ...getStride(settings, defaults),\n      ...getPadding(settings, defaults),\n    };\n\n    this.weights = randos3D(this.width, this.height, this.depth);\n    this.deltas = zeros3D(this.width, this.height, this.depth);\n\n    this.filters = randos3D(\n      this.filterWidth,\n      this.filterHeight,\n      this.filterCount\n    );\n    this.filterDeltas = zeros3D(\n      this.filterWidth,\n      this.filterHeight,\n      this.filterCount\n    );\n    this.validate();\n  }\n\n  setupKernels(): void {\n    this.predictKernelMap = makeKernelMap<\n      Parameters<typeof predict>,\n      IPredictConstants\n    >(\n      {\n        switchX: setSwitchX,\n        switchY: setSwitchY,\n      },\n      predict,\n      {\n        output: [this.width, this.height, this.depth],\n        constants: {\n          inputWidth: this.inputLayer.width,\n          inputHeight: this.inputLayer.height,\n          paddingX: this.paddingX,\n          paddingY: this.paddingY,\n          filterHeight: this.filterHeight,\n          filterWidth: this.filterWidth,\n        },\n      }\n    );\n\n    this.compareKernel = makeKernel(compare, {\n      output: [\n        this.inputLayer.width,\n        this.inputLayer.height,\n        this.inputLayer.depth,\n      ],\n      constants: {\n        inputWidth: this.inputLayer.width,\n        inputHeight: this.inputLayer.height,\n\n        outputWidth: this.width,\n        outputHeight: this.height,\n      },\n    });\n  }\n\n  predict(): void {\n    const { result: weights, switchX, switchY } = (this\n      .predictKernelMap as IKernelMapRunShortcut<ISubKernelObject>)(\n      this.inputLayer.weights\n    );\n    this.switchX = switchX;\n    this.switchY = switchY;\n    this.weights = weights;\n  }\n\n  compare(): void {\n    // debugger;\n    // const depth = this.inputLayer.deltas.length;\n    // const height = this.inputLayer.deltas[0].length;\n    // const width = this.inputLayer.deltas[0][0].length;\n    // const type = typeof this.inputLayer.deltas[0][0][0];\n    const inputLayerDeltas = this.inputLayer.deltas;\n    this.inputLayer.deltas = (this.compareKernel as IKernelRunShortcut)(\n      this.deltas,\n      this.switchX,\n      this.switchY\n    );\n    release(inputLayerDeltas);\n    // debugger;\n    // if (depth !== this.inputLayer.deltas.length) debugger;\n    // if (height !== this.inputLayer.deltas[0].length) debugger;\n    // if (width !== this.inputLayer.deltas[0][0].length) debugger;\n    // if (type !== typeof this.inputLayer.deltas[0][0][0]) debugger;\n  }\n}\n\nexport function pool(settings: IPoolSettings, inputLayer: ILayer): Pool {\n  return new Pool(settings, inputLayer);\n}\n","import { KernelOutput } from 'gpu.js';\nimport { IPraxis } from '../praxis/base-praxis';\nimport { release } from '../utilities/kernel';\nimport { BaseLayer, ILayer } from './base-layer';\nimport { Internal } from './internal';\n\nexport interface IRecurrentInput extends ILayer {\n  setDimensions?: (width: number, height: number) => void;\n}\n\nexport class RecurrentInput extends Internal implements IRecurrentInput {\n  recurrentInput: ILayer;\n  praxis: IPraxis | null = null;\n  predictKernel = null;\n  compareKernel = null;\n  settings = {};\n  constructor(recurrentInput: ILayer) {\n    super();\n    this.recurrentInput = recurrentInput;\n    this.validate();\n  }\n\n  get width(): number {\n    return this.recurrentInput.width;\n  }\n\n  get height(): number {\n    return this.recurrentInput.height;\n  }\n\n  get depth(): number {\n    return this.recurrentInput.depth;\n  }\n\n  get deltas(): KernelOutput {\n    return this.recurrentInput.deltas;\n  }\n\n  set deltas(deltas: KernelOutput) {\n    const recurrentInputDeltas = this.recurrentInput.deltas;\n    this.recurrentInput.deltas = deltas;\n    release(recurrentInputDeltas);\n  }\n\n  get weights(): KernelOutput {\n    return this.recurrentInput.weights as KernelOutput;\n  }\n\n  set weights(weights: KernelOutput) {\n    const recurrentInputWeights = this.recurrentInput.weights;\n    this.recurrentInput.weights = weights;\n    release(recurrentInputWeights);\n  }\n\n  validate(): void {\n    BaseLayer.prototype.validate.call(this);\n    if (this.width !== this.recurrentInput.width) {\n      throw new Error(\n        `${this.constructor.name} layer width ${this.width} and ${this.recurrentInput.constructor.name} width (${this.recurrentInput.width}) are not same`\n      );\n    }\n\n    if (this.height !== this.recurrentInput.height) {\n      throw new Error(\n        `${this.constructor.name} layer height ${this.height} and ${this.recurrentInput.constructor.name} width (${this.recurrentInput.height}) are not same`\n      );\n    }\n  }\n\n  setDimensions(width: number, height: number): void {\n    this.recurrentInput.width = width;\n    this.recurrentInput.height = height;\n  }\n\n  predict(): void {\n    // throw new Error(`${this.constructor.name}-predict is not yet implemented`)\n  }\n\n  compare(): void {\n    // throw new Error(`${this.constructor.name}-compare is not yet implemented`)\n  }\n\n  learn(): void {\n    // throw new Error(`${this.constructor.name}-learn is not yet implemented`)\n  }\n\n  setupKernels(): void {\n    // throw new Error(\n    //   `${this.constructor.name}-setupKernels is not yet implemented`\n    // )\n  }\n\n  reuseKernels(): void {\n    // throw new Error(\n    //   `${this.constructor.name}-reuseKernels is not yet implemented`\n    // )\n  }\n}\n","import { IPraxis } from '../praxis/base-praxis';\nimport { release } from '../utilities/kernel';\nimport { zeros2D } from '../utilities/zeros-2d';\nimport { ILayerSettings } from './base-layer';\nimport { Internal } from './internal';\nimport { IRecurrentInput } from './recurrent-input';\n\nexport class RecurrentZeros extends Internal implements IRecurrentInput {\n  praxis: IPraxis | null = null;\n  settings: Partial<ILayerSettings> = {};\n  predictKernel = null;\n  compareKernel = null;\n\n  constructor(settings?: Partial<ILayerSettings>) {\n    super();\n    if (settings) {\n      this.settings = { ...settings };\n    }\n  }\n\n  setDimensions(width: number, height: number): void {\n    this.praxis = null;\n    this.settings = {\n      ...this.settings,\n      width,\n      height,\n      weights: zeros2D(width, height),\n      deltas: zeros2D(width, height),\n    };\n  }\n\n  setupKernels(): void {\n    // throw new Error(\n    //   `${this.constructor.name}-setupKernels is not yet implemented`\n    // )\n  }\n\n  reuseKernels(): void {\n    // throw new Error(\n    //   `${this.constructor.name}-reuseKernels is not yet implemented`\n    // )\n  }\n\n  predict(): void {\n    // throw new Error(`${this.constructor.name}-predict is not yet implemented`)\n  }\n\n  compare(): void {\n    // throw new Error(`${this.constructor.name}-compare is not yet implemented`)\n  }\n\n  learn(learningRate: number): void {\n    const { weights: oldWeights } = this;\n    this.weights = (this.praxis as IPraxis).run(this, learningRate);\n    // this.deltas = deltas;\n    release(oldWeights);\n  }\n\n  // validate(): void {\n  //   throw new Error(`${this.constructor.name}-validate is not yet implemented`);\n  // }\n\n  // reset(): void {\n  //   throw new Error(`${this.constructor.name}-reset is not yet implemented`);\n  // }\n}\n\nexport function recurrentZeros(): RecurrentZeros {\n  return new RecurrentZeros();\n}\n","import { IKernelFunctionThis, IKernelRunShortcut } from 'gpu.js';\n\nimport { Activation } from './types';\nimport { makeKernel, release } from '../utilities/kernel';\nimport { activate, measure } from '../activation/relu';\nimport { ILayer, ILayerSettings } from './base-layer';\n\nexport function predict2D(\n  this: IKernelFunctionThis,\n  inputs: number[][]\n): number {\n  return activate(inputs[this.thread.y][this.thread.x]);\n}\n\nexport function compare2D(\n  this: IKernelFunctionThis,\n  weights: number[][],\n  deltas: number[][]\n): number {\n  return measure(\n    weights[this.thread.y][this.thread.x],\n    deltas[this.thread.y][this.thread.x]\n  );\n}\n\nexport function predict3D(\n  this: IKernelFunctionThis,\n  inputs: number[][][]\n): number {\n  return activate(inputs[this.thread.z][this.thread.y][this.thread.x]);\n}\n\nexport function compare3D(\n  this: IKernelFunctionThis,\n  weights: number[][][],\n  deltas: number[][][]\n): number {\n  return measure(\n    weights[this.thread.z][this.thread.y][this.thread.x],\n    deltas[this.thread.z][this.thread.y][this.thread.x]\n  );\n}\n\nexport class Relu extends Activation {\n  setupKernels(): void {\n    const { width, height, depth } = this.inputLayer;\n    if (depth > 0) {\n      this.predictKernel = makeKernel(predict3D, {\n        output: [width, height, depth],\n        functions: [activate],\n        immutable: true,\n      });\n\n      this.compareKernel = makeKernel(compare3D, {\n        output: [width, height, depth],\n        functions: [measure],\n        immutable: true,\n      });\n    } else {\n      this.predictKernel = makeKernel(predict2D, {\n        output: [width, height],\n        functions: [activate],\n        immutable: true,\n      });\n\n      this.compareKernel = makeKernel(compare2D, {\n        output: [width, height],\n        functions: [measure],\n        immutable: true,\n      });\n    }\n  }\n\n  predict(): void {\n    release(this.weights);\n    this.weights = (this.predictKernel as IKernelRunShortcut)(\n      this.inputLayer.weights\n    );\n  }\n\n  compare(): void {\n    release(this.inputLayer.deltas);\n    this.inputLayer.deltas = (this.compareKernel as IKernelRunShortcut)(\n      this.weights,\n      this.deltas\n    );\n  }\n}\n\nexport function relu(inputLayer: ILayer, settings?: ILayerSettings): Relu {\n  return new Relu(inputLayer, settings);\n}\n","import { IKernelFunctionThis, KernelOutput } from 'gpu.js';\n\nimport { BaseLayer, ILayer, ILayerSettings } from './base-layer';\nimport { clone, release } from '../utilities/kernel';\n\nexport class Regression extends BaseLayer {\n  inputLayer: ILayer;\n  constructor(settings: ILayerSettings, inputLayer: ILayer) {\n    super(settings);\n    this.inputLayer = inputLayer;\n    this.validate();\n  }\n\n  predict(): void {\n    release(this.weights);\n    this.weights = clone(this.inputLayer.weights as KernelOutput);\n  }\n\n  learn(): void {\n    // throw new Error(`${this.constructor.name}-learn is not yet implemented`)\n  }\n}\n\n// TODO: Connect up\nexport function learn(\n  this: IKernelFunctionThis,\n  inputs: number[],\n  targets: number[]\n): number {\n  return inputs[this.thread.x] - targets[this.thread.x];\n}\n\n// TODO: handle `loss += 0.5*dy*dy;` total and sum in learn\nexport function regression(\n  settings: ILayerSettings,\n  inputLayer: ILayer\n): Regression {\n  return new Regression(settings, inputLayer);\n}\n","import {\n  IConstantsThis,\n  IKernelFunctionThis,\n  IKernelRunShortcut,\n  KernelOutput,\n  Texture,\n} from 'gpu.js';\n\nimport { makeKernel, release, clone } from '../utilities/kernel';\nimport { randos, randos2D, randos3D } from '../utilities/randos';\nimport { zeros } from '../utilities/zeros';\nimport { zeros2D } from '../utilities/zeros-2d';\nimport { zeros3D } from '../utilities/zeros-3d';\nimport { ILayer, ILayerSettings } from './base-layer';\nimport { Modifier } from './modifier';\n\ninterface ISoftMaxConstants extends IConstantsThis {\n  inputWidth: number;\n}\n\nexport function getMaxValue(\n  this: IKernelFunctionThis<ISoftMaxConstants>,\n  inputs: number[]\n): number {\n  let maxInput = -Infinity;\n  for (let x = 0; x < this.constants.inputWidth; x++) {\n    const input = inputs[x];\n    if (input > maxInput) {\n      maxInput = input;\n    }\n  }\n  return maxInput;\n}\n\nexport function getMaxValue2D(\n  this: IKernelFunctionThis<ISoftMaxConstants>,\n  inputs: number[][]\n): number {\n  let maxInput = -Infinity;\n  for (let y = 0; y < this.constants.inputHeight; y++) {\n    for (let x = 0; x < this.constants.inputWidth; x++) {\n      const input = inputs[y][x];\n      if (input > maxInput) {\n        maxInput = input;\n      }\n    }\n  }\n  return maxInput;\n}\n\nexport function getMaxValue3D(\n  this: IKernelFunctionThis<ISoftMaxConstants>,\n  inputs: number[][][]\n): number {\n  let maxInput = -Infinity;\n  for (let z = 0; z < this.constants.inputDepth; z++) {\n    for (let y = 0; y < this.constants.inputHeight; y++) {\n      for (let x = 0; x < this.constants.inputWidth; x++) {\n        const input = inputs[z][y][x];\n        if (input > maxInput) {\n          maxInput = input;\n        }\n      }\n    }\n  }\n  return maxInput;\n}\n\nexport function getSum(\n  this: IKernelFunctionThis<ISoftMaxConstants>,\n  inputs: number[]\n): number {\n  let sum = 0;\n  for (let x = 0; x < this.constants.inputWidth; x++) {\n    sum += inputs[x];\n  }\n  return sum;\n}\n\nexport function getSum2D(\n  this: IKernelFunctionThis<ISoftMaxConstants>,\n  inputs: number[][]\n): number {\n  let sum = 0;\n  for (let y = 0; y < this.constants.inputHeight; y++) {\n    for (let x = 0; x < this.constants.inputWidth; x++) {\n      sum += inputs[y][x];\n    }\n  }\n  return sum;\n}\n\nexport function getSum3D(\n  this: IKernelFunctionThis<ISoftMaxConstants>,\n  inputs: number[][][]\n): number {\n  let sum = 0;\n  for (let z = 0; z < this.constants.inputDepth; z++) {\n    for (let y = 0; y < this.constants.inputHeight; y++) {\n      for (let x = 0; x < this.constants.inputWidth; x++) {\n        sum += inputs[z][y][x];\n      }\n    }\n  }\n  return sum;\n}\n\nexport function getExponentials(\n  this: IKernelFunctionThis,\n  inputs: number[],\n  maxInput: number[]\n): number {\n  return Math.exp(inputs[this.thread.x] - maxInput[0]);\n}\n\nexport function getExponentials2D(\n  this: IKernelFunctionThis,\n  inputs: number[][],\n  maxInput: number[]\n): number {\n  return Math.exp(inputs[this.thread.y][this.thread.x] - maxInput[0]);\n}\n\nexport function getExponentials3D(\n  this: IKernelFunctionThis,\n  inputs: number[][][],\n  maxInput: number[]\n): number {\n  return Math.exp(\n    inputs[this.thread.z][this.thread.y][this.thread.x] - maxInput[0]\n  );\n}\n\nexport function predict(\n  this: IKernelFunctionThis,\n  exponentials: number[],\n  exponentialsSum: number[]\n): number {\n  return exponentials[this.thread.x] / exponentialsSum[0];\n}\n\nexport function predict2D(\n  this: IKernelFunctionThis,\n  exponentials: number[][],\n  exponentialsSum: number[]\n): number {\n  return exponentials[this.thread.y][this.thread.x] / exponentialsSum[0];\n}\n\nexport function predict3D(\n  this: IKernelFunctionThis,\n  exponentials: number[][][],\n  exponentialsSum: number[]\n): number {\n  return (\n    exponentials[this.thread.z][this.thread.y][this.thread.x] /\n    exponentialsSum[0]\n  );\n}\n\nexport function compare(\n  this: IKernelFunctionThis,\n  target: number,\n  exponentials: number[]\n): number {\n  let indicator = 0;\n  if (this.thread.x === target) {\n    indicator = 1;\n  }\n  return -(indicator - exponentials[this.thread.x]);\n}\n\nexport function compare2D(\n  this: IKernelFunctionThis,\n  target: number,\n  exponentials: number[][]\n): number {\n  let indicator = 0;\n  const index = this.thread.x + this.thread.y * this.output.x;\n  if (index === target) {\n    indicator = 1;\n  }\n  return -(indicator - exponentials[this.thread.y][this.thread.x]);\n}\n\nexport function compare3D(\n  this: IKernelFunctionThis,\n  target: number,\n  exponentials: number[][][]\n): number {\n  let indicator = 0;\n  const index =\n    this.thread.x +\n    this.thread.y * this.output.x +\n    this.thread.z * this.output.x * this.output.y;\n  if (index === target) {\n    indicator = 1;\n  }\n  return -(\n    indicator - exponentials[this.thread.z][this.thread.y][this.thread.x]\n  );\n}\n\nexport function loss(): number {\n  return -Math.log(0);\n}\n\n// TODO: handle: `return -Math.log(this.es[y]);` in learn\n\nexport class SoftMax extends Modifier {\n  getExponentialsKernel: IKernelRunShortcut | null;\n  getMaxValueKernel: IKernelRunShortcut | null;\n  getSumKernel: IKernelRunShortcut | null;\n  errors: KernelOutput | null = null;\n  constructor(inputLayer: ILayer, settings?: ILayerSettings) {\n    super(inputLayer, settings);\n    this.getExponentialsKernel = null;\n    this.getMaxValueKernel = null;\n    this.getSumKernel = null;\n    this.validate();\n\n    if (this.depth > 0) {\n      this.weights = randos3D(this.width, this.height, this.depth);\n      this.deltas = zeros3D(this.width, this.height, this.depth);\n    } else if (this.height > 0) {\n      this.weights = randos2D(this.width, this.height);\n      this.deltas = zeros2D(this.width, this.height);\n    } else {\n      this.weights = randos(this.width);\n      this.deltas = zeros(this.width);\n    }\n  }\n\n  setupKernels(): void {\n    const { width, height, depth } = this;\n    if (depth > 0) {\n      this.getExponentialsKernel = makeKernel(getExponentials3D, {\n        output: [width, height, depth],\n      });\n      this.getMaxValueKernel = makeKernel(getMaxValue3D, {\n        output: [1, 1, 1],\n        constants: {\n          inputWidth: width,\n          inputHeight: height,\n          inputDepth: depth,\n        },\n      });\n      this.getSumKernel = makeKernel(getSum3D, {\n        output: [1, 1, 1],\n        constants: {\n          inputWidth: width,\n          inputHeight: height,\n          inputDepth: depth,\n        },\n      });\n      this.predictKernel = makeKernel(predict3D, {\n        output: [width, height, depth],\n      });\n      this.compareKernel = makeKernel(compare3D, {\n        output: [width, height, depth],\n        immutable: true,\n      });\n    } else {\n      this.getExponentialsKernel = makeKernel(getExponentials, {\n        output: [width, height],\n      });\n      this.getMaxValueKernel = makeKernel(getMaxValue2D, {\n        output: [1, 1],\n        constants: {\n          inputWidth: width,\n          inputHeight: height,\n        },\n      });\n      this.getSumKernel = makeKernel(getSum2D, {\n        output: [1, 1],\n        constants: {\n          inputWidth: width,\n          inputHeight: height,\n        },\n      });\n      this.predictKernel = makeKernel(predict2D, {\n        output: [width, height],\n      });\n      this.compareKernel = makeKernel(compare2D, {\n        output: [width, height],\n        immutable: true,\n      });\n    }\n  }\n\n  predict(): void {\n    const maxValue = (this.getMaxValueKernel as IKernelRunShortcut)(\n      this.inputLayer.weights\n    );\n    const exponentials = (this.getExponentialsKernel as IKernelRunShortcut)(\n      this.inputLayer.weights,\n      maxValue\n    );\n    const exponentialsSum = (this.getSumKernel as IKernelRunShortcut)(\n      exponentials\n    );\n    this.weights = (this.predictKernel as IKernelRunShortcut)(\n      exponentials,\n      exponentialsSum\n    );\n  }\n\n  compare(targetValues: KernelOutput): void {\n    const { deltas, errors } = this;\n    this.errors = (this.compareKernel as IKernelRunShortcut)(\n      (targetValues as number[])[0],\n      deltas\n    );\n    this.deltas = clone(this.errors);\n    release(deltas);\n    release(errors as Texture);\n\n    const inputLayerDeltas = this.inputLayer.deltas;\n    this.inputLayer.deltas = clone(this.deltas);\n    release(inputLayerDeltas);\n  }\n}\n\nexport function softMax(\n  inputLayer: ILayer,\n  settings?: ILayerSettings\n): SoftMax {\n  return new SoftMax(inputLayer, settings);\n}\n","import { KernelOutput } from 'gpu.js';\n\nimport { BaseLayer, ILayer, ILayerSettings } from './base-layer';\nimport { clone, release } from '../utilities/kernel';\n\nexport class SVM extends BaseLayer {\n  inputLayer: ILayer;\n  constructor(inputLayer: ILayer, settings: ILayerSettings) {\n    super(settings);\n    this.inputLayer = inputLayer;\n  }\n\n  predict(): void {\n    release(this.weights);\n    this.weights = clone(this.inputLayer.weights as KernelOutput);\n    this.validate();\n  }\n\n  learn(): void {\n    // throw new Error(`${this.constructor.name}-learn is not yet implemented`)\n  }\n}\n\n// function learn(target) {\n//   if (y === i) {\n//     continue;\n//   }\n//   const ydiff = -yscore + x.w[i] + margin;\n//   if (ydiff > 0) {\n//     // violating dimension, apply loss\n//     x.dw[i] += 1;\n//     x.dw[y] -= 1;\n//     loss += ydiff;\n//   }\n// }\n\nexport function svm(inputLayer: ILayer, settings: ILayerSettings): SVM {\n  return new SVM(inputLayer, settings);\n}\n","import { IKernelFunctionThis, IKernelRunShortcut } from 'gpu.js';\nimport { makeKernel } from '../utilities/kernel';\nimport { ILayer } from './base-layer';\nimport { Modifier } from './types';\n\nexport function predict(this: IKernelFunctionThis, value: number[][]): number {\n  return value[this.thread.x][this.thread.y];\n}\n\nconst compare = predict;\n\nexport class Transpose extends Modifier {\n  get width(): number {\n    return this.inputLayer.height;\n  }\n\n  get height(): number {\n    return this.inputLayer.width;\n  }\n\n  constructor(inputLayer: ILayer) {\n    super(inputLayer);\n    this.validate();\n  }\n\n  setupKernels(): void {\n    this.predictKernel = makeKernel(predict, {\n      output: [this.height, this.width],\n    });\n    this.compareKernel = makeKernel(compare, {\n      output: [this.width, this.height],\n    });\n  }\n\n  predict(): void {\n    this.weights = (this.predictKernel as IKernelRunShortcut)(\n      this.inputLayer.weights\n    );\n  }\n\n  compare(): void {\n    this.inputLayer.deltas = (this.compareKernel as IKernelRunShortcut)(\n      this.deltas\n    );\n  }\n}\n\nexport function transpose(inputLayer: ILayer): Transpose {\n  return new Transpose(inputLayer);\n}\n","import {\n  Activation,\n  EntryPoint,\n  Filter,\n  Internal,\n  InternalModel,\n  Model,\n  Modifier,\n  Operator,\n  Target,\n} from './types';\n\nexport { Add, add } from './add';\nexport { arthurFeedForward } from './arthur-feed-forward';\nexport {\n  BaseLayer,\n  ILayer,\n  ILayerSettings,\n  ILayerJSON,\n  baseLayerDefaultSettings,\n} from './base-layer';\nexport { Convolution, convolution } from './convolution';\nexport { Dropout, dropout } from './dropout';\nexport { feedForward } from './feed-forward';\nexport { FullyConnected, fullyConnected } from './fully-connected';\nexport { gru } from './gru';\nexport { Input, input } from './input';\nexport { LeakyRelu, leakyRelu } from './leaky-relu';\nexport { lstmCell } from './lstm-cell';\nexport { Multiply, multiply } from './multiply';\nexport { MultiplyElement, multiplyElement } from './multiply-element';\nexport { Negative, negative } from './negative';\nexport { Ones, ones } from './ones';\nexport { output } from './output';\nexport { Pool, pool } from './pool';\nexport { Random, random } from './random';\nexport { RecurrentInput, IRecurrentInput } from './recurrent-input';\nexport { RecurrentZeros } from './recurrent-zeros';\nexport { rnnCell } from './rnn-cell';\nexport { Regression, regression } from './regression';\nexport { Relu, relu } from './relu';\nexport { Sigmoid, sigmoid } from './sigmoid';\nexport { SoftMax, softMax } from './soft-max';\nexport { SVM, svm } from './svm';\nexport { Tanh, tanh } from './tanh';\nexport { Target, target } from './target';\nexport { Transpose, transpose } from './transpose';\nexport { Zeros, zeros } from './zeros';\n\nexport const layerTypes = {\n  Activation,\n  Internal,\n  InternalModel,\n  EntryPoint,\n  Filter,\n  Model,\n  Modifier,\n  Operator,\n  Target,\n};\n","import {\n  ArthurDeviationWeights,\n  arthurDeviationWeights,\n  IArthurDeviationWeightsSettings,\n} from '../praxis/arthur-deviation-weights';\nimport {\n  arthurDeviationBiases,\n  IArthurDeviationBiasesSettings,\n} from '../praxis/arthur-deviation-biases';\nimport { ILayer } from './base-layer';\nimport { add } from './add';\nimport { IRandomSettings, random } from './random';\nimport { multiply } from './multiply';\nimport { Sigmoid, sigmoid } from './sigmoid';\nimport { IPraxis } from '../praxis/base-praxis';\n\nexport interface IArthurFeedForwardPraxisSettings\n  extends IArthurDeviationBiasesSettings,\n    IArthurDeviationWeightsSettings {}\n\nexport interface IArthurFeedForwardSettings extends IRandomSettings {\n  initPraxis?: (\n    layerTemplate: ILayer,\n    settings?: IArthurFeedForwardPraxisSettings | null\n  ) => IPraxis;\n}\n\nexport function arthurFeedForward(\n  settings: IArthurFeedForwardPraxisSettings,\n  inputLayer: ILayer\n): Sigmoid {\n  const { height } = settings;\n  function initWeightsPraxis(\n    layerTemplate: ILayer,\n    settings?: IArthurDeviationWeightsSettings\n  ): IPraxis {\n    const praxis = arthurDeviationWeights(layerTemplate, settings);\n    praxis.setupKernels();\n    return praxis;\n  }\n  function initBiasesPraxis(\n    layerTemplate: ILayer,\n    settings?: IArthurDeviationBiasesSettings\n  ): IPraxis {\n    const praxis = arthurDeviationBiases(layerTemplate, settings);\n    praxis.setupKernels();\n    return praxis;\n  }\n  const weightsLayer = random({\n    id: 'weights',\n    height,\n    width: inputLayer.height,\n    initPraxis: initWeightsPraxis,\n  });\n\n  const biasesLayer = random({\n    id: 'biases',\n    height,\n    initPraxis: initBiasesPraxis,\n  });\n\n  const multiplyLayer = multiply(weightsLayer, inputLayer);\n  const addLayer = add(multiplyLayer, biasesLayer);\n  const sigmoidLayer = sigmoid(addLayer);\n\n  const weightsPraxis = weightsLayer.praxis as ArthurDeviationWeights;\n  weightsPraxis.weightsLayer = weightsLayer;\n  weightsPraxis.incomingLayer = inputLayer;\n  weightsPraxis.deltaLayer = sigmoidLayer;\n  return sigmoidLayer;\n}\n","import { random } from './random';\nimport { add } from './add';\nimport { multiply } from './multiply';\nimport { sigmoid } from './sigmoid';\nimport { ILayer, ILayerSettings } from './base-layer';\n\nexport function feedForward(settings: ILayerSettings, input: ILayer): ILayer {\n  const { height, praxisOpts = null } = settings;\n  const weights = random({\n    id: 'weights',\n    height,\n    width: input.height,\n    praxisOpts,\n  });\n  const biases = random({ id: 'biases', height, praxisOpts });\n  return sigmoid(\n    add(multiply(weights, input, { praxisOpts }), biases, { praxisOpts }),\n    { praxisOpts }\n  );\n}\n","import { add } from './add';\nimport { negative } from './negative';\nimport { multiply } from './multiply';\nimport { multiplyElement } from './multiply-element';\nimport { ones } from './ones';\nimport { sigmoid } from './sigmoid';\nimport { random } from './random';\nimport { tanh } from './tanh';\nimport { zeros } from './zeros';\nimport { ILayer, ILayerSettings } from './base-layer';\nimport { RecurrentInput } from './recurrent-input';\n\nexport function gru(\n  settings: ILayerSettings,\n  recurrentInput: RecurrentInput,\n  input: ILayer\n): ILayer {\n  const { height } = settings;\n  const updateGateWeights = random({ height, width: input.height });\n  const updateGatePeepholes = random({ width: height, height });\n  const updateGateBias = zeros({ height });\n  const updateGate = sigmoid(\n    add(\n      add(\n        multiply(updateGateWeights, input),\n        multiply(updateGatePeepholes, recurrentInput)\n      ),\n      updateGateBias\n    )\n  );\n\n  const resetGateWeights = random({ height, width: input.height });\n  const resetGatePeepholes = random({ width: height, height });\n  const resetGateBias = zeros({ height });\n  const resetGate = sigmoid(\n    add(\n      add(\n        multiply(resetGateWeights, input),\n        multiply(resetGatePeepholes, recurrentInput)\n      ),\n      resetGateBias\n    )\n  );\n\n  const cellWeights = random({ height, width: input.height });\n  const cellPeepholes = random({ width: height, height });\n  const cellBias = zeros({ height });\n  const cell = tanh(\n    add(\n      add(\n        multiply(cellWeights, input),\n        multiply(cellPeepholes, multiplyElement(resetGate, recurrentInput))\n      ),\n      cellBias\n    )\n  );\n\n  // compute hidden state as gated, saturated cell activations\n  // negate updateGate\n  return add(\n    multiplyElement(\n      add(\n        ones({ width: updateGate.width, height: updateGate.height }),\n        negative(updateGate)\n      ),\n      cell\n    ),\n    multiplyElement(recurrentInput, updateGate)\n  );\n}\n","import { add } from './add';\nimport { multiply } from './multiply';\nimport { multiplyElement } from './multiply-element';\nimport { random } from './random';\nimport { sigmoid } from './sigmoid';\nimport { tanh } from './tanh';\nimport { zeros } from './zeros';\nimport { ILayer, ILayerSettings } from './base-layer';\nimport { IRecurrentInput } from './recurrent-input';\n\nexport function lstmCell(\n  settings: ILayerSettings,\n  input: ILayer,\n  recurrentInput: IRecurrentInput\n): ILayer {\n  const { height } = settings;\n\n  if (typeof height !== 'number') {\n    throw new Error('no settings.height given');\n  }\n  if (recurrentInput.setDimensions) {\n    recurrentInput.setDimensions(1, height);\n  }\n\n  const inputGateWeights = random({\n    width: input.height,\n    height,\n    std: 0.08,\n    id: 'inputGateWeights',\n  });\n  const inputGatePeepholes = random({\n    width: height,\n    height,\n    std: 0.08,\n    id: 'inputGatePeepholes',\n  });\n  const inputGateBias = zeros({ width: 1, height, id: 'inputGateBias' });\n  const inputGate = sigmoid(\n    add(\n      add(\n        multiply(inputGateWeights, input),\n        multiply(inputGatePeepholes, recurrentInput)\n      ),\n      inputGateBias\n    ),\n    { id: 'inputGate' }\n  );\n\n  const forgetGateWeights = random({\n    width: input.height,\n    height,\n    std: 0.08,\n    id: 'forgetGateWeights',\n  });\n  const forgetGatePeepholes = random({\n    width: height,\n    height,\n    std: 0.08,\n    id: 'forgetGatePeepholes',\n  });\n  const forgetGateBias = zeros({ width: 1, height, id: 'forgetGateBias' });\n  const forgetGate = sigmoid(\n    add(\n      add(\n        multiply(forgetGateWeights, input),\n        multiply(forgetGatePeepholes, recurrentInput)\n      ),\n      forgetGateBias\n    ),\n    { id: 'forgetGate' }\n  );\n\n  const outputGateWeights = random({\n    width: input.height,\n    height,\n    std: 0.08,\n    id: 'outputGateWeights',\n  });\n  const outputGatePeepholes = random({\n    width: height,\n    height,\n    std: 0.08,\n    id: 'outputGatePeepholes',\n  });\n  const outputGateBias = zeros({ width: 1, height, id: 'outputGateBias' });\n  const outputGate = sigmoid(\n    add(\n      add(\n        multiply(outputGateWeights, input),\n        multiply(outputGatePeepholes, recurrentInput)\n      ),\n      outputGateBias\n    ),\n    { id: 'outputGate' }\n  );\n\n  const memoryWeights = random({\n    width: input.height,\n    height,\n    std: 0.08,\n    id: 'memoryWeights',\n  });\n  const memoryPeepholes = random({\n    width: height,\n    height,\n    std: 0.08,\n    id: 'memoryPeepholes',\n  });\n  const memoryBias = zeros({ width: 1, height, id: 'memoryBias' });\n  const memory = tanh(\n    add(\n      add(\n        multiply(memoryWeights, input),\n        multiply(memoryPeepholes, recurrentInput)\n      ),\n      memoryBias\n    ),\n    { id: 'memory' }\n  );\n\n  // compute new cell activation\n  const retainCell = multiplyElement(forgetGate, recurrentInput, {\n    id: 'retainCell',\n  }); // what do we keep from cell\n  const writeCell = multiplyElement(inputGate, memory, { id: 'writeCell' }); // what do we write to cell\n  const cell = add(retainCell, writeCell, { id: 'cell' }); // new cell contents\n\n  // compute hidden state as gated, saturated cell activations\n  return multiplyElement(outputGate, tanh(cell), { id: 'activations' });\n}\n","import { add } from './add';\nimport { multiply } from './multiply';\nimport { random } from './random';\nimport { target } from './target';\nimport { ILayer, ILayerSettings } from './base-layer';\n\nexport function output(settings: ILayerSettings, inputLayer: ILayer): ILayer {\n  const { height } = settings;\n  const outputGate = random({\n    height,\n    width: inputLayer.height,\n    id: 'outputGate',\n    std: 0.08,\n  });\n  const output = random({ height, id: 'output', std: 0.08 });\n  const outputGateConnector = multiply(outputGate, inputLayer, {\n    id: 'outputGateConnected',\n  });\n  return target(\n    { id: 'target', ...settings },\n    add(outputGateConnector, output)\n  );\n}\n","import { add } from './add';\nimport { ILayer, ILayerSettings } from './base-layer';\nimport { multiply } from './multiply';\nimport { random } from './random';\nimport { relu } from './relu';\nimport { zeros } from './zeros';\nimport { IRecurrentInput } from './recurrent-input';\n\nexport function rnnCell(\n  settings: ILayerSettings,\n  input: ILayer,\n  recurrentInput: IRecurrentInput\n): ILayer {\n  const { height } = settings;\n\n  if (typeof height !== 'number') throw new Error('height not set');\n  if (recurrentInput.setDimensions) {\n    recurrentInput.setDimensions(1, height);\n  }\n\n  // wxh\n  const weight = random({\n    id: 'weight',\n    height,\n    width: input.height,\n    std: 0.08,\n  });\n  // whh\n  const transition = random({\n    id: 'transition',\n    height,\n    width: height,\n    std: 0.08,\n  });\n  // bhh\n  const bias = zeros({ id: 'bias', height });\n\n  return relu(\n    add(\n      add(multiply(weight, input), multiply(transition, recurrentInput)),\n      bias\n    )\n  );\n}\n","import * as layer from '../layer';\nimport { layerTypes, ILayerJSON, ILayer, Target } from '../layer';\nimport { ActivationType } from '../layer/activation';\nimport { FilterType } from '../layer/filter';\nimport { InternalType } from '../layer/internal';\nimport { ModifierType } from '../layer/modifier';\nimport { OperatorType } from '../layer/operator';\nimport { BaseLayerType } from '../layer/base-layer';\nimport { TargetType } from '../layer/target';\n\nconst layerNameTypes = Object.keys(layer);\n\nexport function layerFromJSON(\n  jsonLayer: ILayerJSON,\n  inputLayer1?: ILayer,\n  inputLayer2?: ILayer\n): ILayer | null {\n  if (\n    !layerNameTypes.find((layerNameType) => layerNameType === jsonLayer.type)\n  ) {\n    return null;\n  }\n  const Layer = ((layer as unknown) as {\n    [layerType: string]:\n      | TargetType\n      | ActivationType\n      | FilterType\n      | InternalType\n      | ModifierType\n      | OperatorType;\n  })[jsonLayer.type];\n  if (Layer.prototype instanceof layerTypes.Filter) {\n    if (!inputLayer1) throw new Error('inputLayer missing');\n    return new (Layer as FilterType)(jsonLayer, inputLayer1);\n  } else if (\n    Layer.prototype instanceof layerTypes.Activation ||\n    Layer.prototype instanceof layerTypes.Modifier\n  ) {\n    if (!inputLayer1) throw new Error('inputLayer missing');\n    return new (Layer as ActivationType)(inputLayer1, jsonLayer);\n  } else if (Layer.prototype instanceof layerTypes.Internal) {\n    return new (Layer as InternalType)(jsonLayer);\n  } else if (Layer.prototype instanceof layerTypes.Operator) {\n    if (!inputLayer1) throw new Error('inputLayer1 missing');\n    if (!inputLayer2) throw new Error('inputLayer2 missing');\n    return new (Layer as OperatorType)(inputLayer1, inputLayer2, jsonLayer);\n  } else if (\n    Layer.prototype instanceof layerTypes.InternalModel ||\n    Layer.prototype instanceof layerTypes.EntryPoint ||\n    Layer.prototype instanceof layerTypes.Model\n  ) {\n    return new (Layer as BaseLayerType)(jsonLayer);\n  } else if (Layer === Target) {\n    if (!inputLayer1) throw new Error('inputLayer missing');\n    return new (Layer as TargetType)(jsonLayer, inputLayer1);\n  }\n  return null;\n}\n","import { InputOutputValue, INumberHash, ITrainingDatum } from '../lookup';\n\nexport type LookupTableProp = 'input' | 'output';\n\nexport class LookupTable {\n  length: number;\n  prop: LookupTableProp | null = null;\n  table: INumberHash = {};\n  constructor(\n    data: ITrainingDatum[] | InputOutputValue[] | InputOutputValue[][],\n    prop?: LookupTableProp\n  ) {\n    this.length = 0;\n    const table = this.table;\n    if (prop) {\n      this.prop = prop;\n      for (let i = 0; i < data.length; i++) {\n        const datum = (data as ITrainingDatum[])[i];\n        const object = datum[prop] as INumberHash;\n        for (const p in object) {\n          if (!object.hasOwnProperty(p)) continue;\n          if (table.hasOwnProperty(p)) continue;\n          table[p] = this.length++;\n        }\n      }\n    } else if (Array.isArray(data) && Array.isArray(data[0])) {\n      for (let i = 0; i < data.length; i++) {\n        const array = (data as InputOutputValue[][])[i];\n        for (let j = 0; j < array.length; j++) {\n          const object = array[j];\n          for (const p in object) {\n            if (!object.hasOwnProperty(p)) continue;\n            if (table.hasOwnProperty(p)) continue;\n            table[p] = this.length++;\n          }\n        }\n      }\n    } else {\n      for (let i = 0; i < data.length; i++) {\n        const object = (data as INumberHash[])[i];\n        for (const p in object) {\n          if (!object.hasOwnProperty(p)) continue;\n          if (table.hasOwnProperty(p)) continue;\n          table[p] = this.length++;\n        }\n      }\n    }\n  }\n}\n","\"use strict\";\nvar __assign = (this && this.__assign) || function () {\n    __assign = Object.assign || function(t) {\n        for (var s, i = 1, n = arguments.length; i < n; i++) {\n            s = arguments[i];\n            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))\n                t[p] = s[p];\n        }\n        return t;\n    };\n    return __assign.apply(this, arguments);\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.thaw = exports.Block = exports.Thaw = void 0;\n/**\n * thaw an array of items\n */\nvar Thaw = /** @class */ (function () {\n    function Thaw(items, options) {\n        var _this = this;\n        if (options === void 0) { options = {}; }\n        var _a = __assign(__assign({}, Thaw.defaultSettings), options), each = _a.each, done = _a.done;\n        this.i = 0;\n        this.isStopped = false;\n        this.items = items;\n        this.options = options;\n        this.tick = function () {\n            if (_this.isStopped)\n                return;\n            _this.timeout = setTimeout(_this.tick, 0);\n            if (Thaw.thawing)\n                return;\n            var item = _this.items[_this.i];\n            if (_this.i >= _this.items.length) {\n                if (done !== null) {\n                    Thaw.thawing = true;\n                    done();\n                    Thaw.thawing = false;\n                }\n                _this.isStopped = true;\n                clearTimeout(_this.timeout);\n                return;\n            }\n            if (each !== null) {\n                Thaw.thawing = true;\n                each(item, _this.i);\n                Thaw.thawing = false;\n            }\n            else if (item !== undefined) {\n                item();\n            }\n            _this.i++;\n        };\n        Thaw.thaws.push(this);\n        if (!options.delay) {\n            this.tick();\n        }\n    }\n    Object.defineProperty(Thaw, \"isThawing\", {\n        /**\n         * returns if Thaw.js is thawing\n         */\n        get: function () {\n            return Thaw.thawing;\n        },\n        enumerable: false,\n        configurable: true\n    });\n    /**\n     * Stops all Thaw instances\n     */\n    Thaw.stopAll = function () {\n        for (var i = 0; i < Thaw.thaws.length; i++) {\n            Thaw.thaws[i].stop();\n        }\n    };\n    /**\n     * readies thaw to continue\n     */\n    Thaw.prototype.makeReady = function () {\n        if (this.isStopped) {\n            this.isStopped = false;\n            return true;\n        }\n        return false;\n    };\n    /**\n     * Adds an item to the end of this instance of Thaw and readies Thaw to process it\n     */\n    Thaw.prototype.add = function (item) {\n        this.items.push(item);\n        if (this.makeReady()) {\n            this.tick();\n        }\n        return this;\n    };\n    /**\n     * Inserts an item just after the current item being processed in Thaw and readies Thaw to process it\n     */\n    Thaw.prototype.insert = function (item) {\n        this.items.splice(this.i, 0, item);\n        if (this.makeReady()) {\n            this.tick();\n        }\n        return this;\n    };\n    /**\n     * Adds an Array to the end of this instance of Thaw and readies Thaw to process it\n     */\n    Thaw.prototype.addArray = function (items) {\n        this.items = this.items.concat(items);\n        if (this.makeReady()) {\n            this.tick();\n        }\n        return this;\n    };\n    /**\n     * Inserts an Array just after the current item being processed in Thaw and readies Thaw to process them\n     */\n    Thaw.prototype.insertArray = function (items) {\n        var before = this.items.splice(0, this.i);\n        var after = this.items;\n        this.items = before.concat(items, after);\n        if (this.makeReady()) {\n            this.tick();\n        }\n        return this;\n    };\n    /**\n     * Stops this instance of Thaw\n     */\n    Thaw.prototype.stop = function () {\n        this.isStopped = true;\n        clearTimeout(this.timeout);\n        if (this.options.done) {\n            this.options.done();\n        }\n        return this;\n    };\n    Thaw.thawing = false;\n    Thaw.thaws = [];\n    Thaw.defaultSettings = {\n        each: null,\n        done: null\n    };\n    return Thaw;\n}());\nexports.Thaw = Thaw;\n/**\n * simple thaw\n */\nfunction thaw(items, options) {\n    return new Thaw(items, options);\n}\nexports.thaw = thaw;\nvar Block = /** @class */ (function () {\n    function Block(options, count) {\n        if (count === void 0) { count = 200; }\n        this.index = 0;\n        this.thaws = [];\n        this.count = count;\n        this.options = options;\n    }\n    /**\n     * add an item to the end of items\n     */\n    Block.prototype.add = function (item) {\n        var next = this.next();\n        next.add(item);\n        return this;\n    };\n    /**\n     * add an Array to the end of items\n     */\n    Block.prototype.addArray = function (items) {\n        var next = this.next();\n        next.addArray(items);\n        return this;\n    };\n    /**\n     * insert an item into items @ current position\n     */\n    Block.prototype.insert = function (item) {\n        var next = this.next();\n        next.insert(item);\n        return this;\n    };\n    /**\n     * insert and array into items @ current position\n     */\n    Block.prototype.insertArray = function (items) {\n        var next = this.next();\n        next.insertArray(items);\n        return this;\n    };\n    /**\n     * Stops all thaws in this block\n     */\n    Block.prototype.stop = function () {\n        for (var i = 0; i < this.thaws.length; i++) {\n            this.thaws[i].stop();\n        }\n        return this;\n    };\n    /**\n     * Get next available in block\n     */\n    Block.prototype.next = function () {\n        var thaw;\n        var thaws = this.thaws;\n        if (thaws.length < this.count) {\n            thaw = new Thaw([], this.options);\n            thaws.push(thaw);\n        }\n        else {\n            thaw = thaws[this.index] || null;\n        }\n        this.index++;\n        if (this.index >= this.count) {\n            this.index = 0;\n        }\n        return thaw;\n    };\n    return Block;\n}());\nexports.Block = Block;\nif (typeof window !== 'undefined') {\n    // @ts-ignore\n    window.Thaw = Thaw;\n    // @ts-ignore\n    window.thaw = thaw;\n    // @ts-ignore\n    window.Thaw.Block = Block;\n}\n","import { IKernelFunctionThis, KernelOutput, Texture } from 'gpu.js';\nimport { MeanSquaredError } from './estimator/mean-squared-error';\nimport { ILayer, ILayerJSON } from './layer';\nimport { Model } from './layer/types';\nimport { InputOutputValue, INumberArray, INumberHash, lookup } from './lookup';\nimport * as praxis from './praxis';\nimport { IPraxis, IPraxisSettings } from './praxis/base-praxis';\nimport { flattenLayers } from './utilities/flatten-layers';\nimport { makeKernel, release } from './utilities/kernel';\nimport { layerFromJSON } from './utilities/layer-from-json';\nimport { LookupTable } from './utilities/lookup-table';\nimport { Thaw } from 'thaw.js';\n\nexport interface IFeedForwardTrainingData<\n  InputType extends InputOutputValue | KernelOutput = number[] | Float32Array,\n  OutputType extends InputOutputValue | KernelOutput = number[] | Float32Array\n> {\n  input: InputType;\n  output: OutputType;\n}\n\nexport interface IFeedForwardNormalizedTrainingData {\n  input: Float32Array;\n  output: Float32Array;\n}\n\nexport interface IFeedForwardGPUTrainingData {\n  input: KernelOutput;\n  output: KernelOutput;\n}\n\nexport interface ITrainingStatus {\n  iterations: number;\n  error: number;\n}\n\nexport type Log = (status: string) => void;\nexport type FeedForwardCallback = (status: ITrainingStatus) => void;\n\nexport interface IFeedForwardTrainingOptions {\n  iterations?: number;\n  errorThresh?: number;\n  log?: boolean | Log;\n  logPeriod?: number;\n  learningRate?: number;\n  callback?: FeedForwardCallback;\n  callbackPeriod?: number;\n  errorCheckInterval?: number;\n  timeout?: number;\n}\n\nexport interface IFeedForwardOptions {\n  learningRate?: number;\n  binaryThresh?: number;\n  hiddenLayers?: Array<(inputLayer: ILayer, layerIndex: number) => ILayer>;\n  inputLayer?: () => ILayer;\n  outputLayer?: (inputLayer: ILayer, index: number) => ILayer;\n  praxisOpts?: Partial<IPraxisSettings>;\n  initPraxis?: (\n    layerTemplate: ILayer,\n    settings: Partial<IPraxisSettings>\n  ) => IPraxis;\n  praxis?: IPraxis;\n\n  // JSON\n  layers?: ILayer[];\n  inputLayerIndex?: number;\n  outputLayerIndex?: number;\n  sizes?: number[];\n}\n\nexport interface IFeedForwardPreppedTrainingData {\n  status: ITrainingStatus;\n  preparedData: IFeedForwardGPUTrainingData[];\n  endTime: number;\n}\n\nexport const defaults: IFeedForwardOptions = {\n  learningRate: 0.3,\n  binaryThresh: 0.5,\n  initPraxis: (\n    layerTemplate: ILayer,\n    settings: Partial<IPraxisSettings>\n  ): IPraxis =>\n    praxis.momentumRootMeanSquaredPropagation(\n      layerTemplate,\n      layerTemplate.settings.praxisOpts ?? settings\n    ),\n};\n\nexport const trainDefaults: IFeedForwardTrainingOptions = {\n  iterations: 20000,\n  errorThresh: 0.005,\n  log: false,\n  logPeriod: 10,\n  learningRate: 0.3,\n  callbackPeriod: 10,\n  errorCheckInterval: 100,\n  timeout: Infinity,\n};\n\nexport interface IFeedForwardJSON {\n  type: string;\n  sizes: number[];\n  layers: ILayerJSON[];\n  inputLayerIndex: number;\n  outputLayerIndex: number;\n}\n\nexport class FeedForward<\n  InputType extends InputOutputValue | KernelOutput = number[] | Float32Array,\n  OutputType extends InputOutputValue | KernelOutput = number[] | Float32Array\n> {\n  static _validateTrainingOptions(\n    options: Partial<IFeedForwardTrainingOptions>\n  ): void {\n    const {\n      iterations,\n      errorThresh,\n      log,\n      logPeriod,\n      learningRate,\n      callback,\n      callbackPeriod,\n      timeout,\n    } = options;\n    interface IValidation {\n      [optionName: string]: () => boolean;\n    }\n    const validations: IValidation = {\n      iterations: () => typeof iterations === 'number' && iterations > 0,\n      errorThresh: () =>\n        typeof errorThresh === 'number' && errorThresh > 0 && errorThresh < 1,\n      log: () => typeof log === 'function' || typeof log === 'boolean',\n      logPeriod: () => typeof logPeriod === 'number' && logPeriod > 0,\n      learningRate: () =>\n        typeof learningRate === 'number' &&\n        learningRate > 0 &&\n        learningRate < 1,\n      callback: () => typeof callback === 'function' || callback === null,\n      callbackPeriod: () =>\n        typeof callbackPeriod === 'number' && callbackPeriod > 0,\n      timeout: () => typeof timeout === 'number' && timeout > 0,\n    };\n    Object.keys(trainDefaults).forEach((key: string): void => {\n      if (validations.hasOwnProperty(key) && !validations[key]()) {\n        const val = options[key as keyof IFeedForwardTrainingOptions];\n        throw new Error(\n          `[${key}, ${(\n            val ?? 'undefined'\n          ).toString()}] is out of normal training range, your network will probably not train.`\n        );\n      }\n    });\n  }\n\n  /**\n   * if a method is passed in method is used\n   * if false passed in nothing is logged\n   */\n  _setLogMethod(log: Log | undefined | boolean): void {\n    if (typeof log === 'function') {\n      this.trainOpts.log = log;\n    } else if (log) {\n      // eslint-disable-next-line\n      this.trainOpts.log = console.log;\n    } else {\n      this.trainOpts.log = false;\n    }\n  }\n\n  _updateTrainingOptions(opts: Partial<IFeedForwardTrainingOptions>): void {\n    this.trainOpts = { ...trainDefaults, ...this.trainOpts, ...opts };\n    FeedForward._validateTrainingOptions(this.trainOpts);\n    this._setLogMethod(opts.log ?? this.trainOpts.log);\n    const { callback, callbackPeriod, errorCheckInterval } = this.trainOpts;\n    if (callback && callbackPeriod !== errorCheckInterval) {\n      console.warn(\n        `options.callbackPeriod with value of ${(\n          callbackPeriod ?? 'undefined'\n        ).toString()} does not match options.errorCheckInterval with value of ${(\n          errorCheckInterval ?? 'undefined'\n        ).toString()}, if logging error, it will repeat.  These values may need to match`\n      );\n    }\n  }\n\n  trainOpts: Partial<IFeedForwardTrainingOptions> = {};\n  options: IFeedForwardOptions;\n  layers: ILayer[] | null = null;\n  _inputLayer: ILayer | null = null;\n  _hiddenLayers: ILayer[] | null = null;\n  _outputLayer: ILayer | null = null;\n  _model: ILayer[] | null = null;\n  meanSquaredError: MeanSquaredError | null = null;\n  inputLookup: INumberHash | null = null;\n  inputLookupLength: number | null = null;\n  outputLookup: INumberHash | null = null;\n  outputLookupLength: number | null = null;\n  constructor(options: IFeedForwardOptions = {}) {\n    this.options = { ...defaults, ...options };\n    this._updateTrainingOptions({\n      ...trainDefaults,\n      ...options,\n    });\n  }\n\n  _connectOptionsLayers(): ILayer[] {\n    const { inputLayerIndex, outputLayerIndex, layers } = this.options;\n    if (!layers) throw new Error('this.options.layers in unexpected state');\n    if (typeof inputLayerIndex !== 'number')\n      throw new Error('inputLayerIndex not a number');\n    if (typeof outputLayerIndex !== 'number')\n      throw new Error('inputLayerIndex not a number');\n    const inputLayer = layers[inputLayerIndex];\n    if (!inputLayer) {\n      throw new Error('inputLayer not found in this.options.layers');\n    }\n    const outputLayer = layers[outputLayerIndex];\n    if (!outputLayer) {\n      throw new Error('outputLayer not found in this.options.layers');\n    }\n    this._inputLayer = inputLayer;\n    this._hiddenLayers = layers.slice(\n      inputLayerIndex,\n      outputLayerIndex - inputLayerIndex\n    );\n    this._outputLayer = outputLayer;\n    return layers;\n  }\n\n  _connectNewLayers(): ILayer[] {\n    const { inputLayer, outputLayer } = this.options;\n    if (!inputLayer) throw new Error('inputLayer not defined');\n    const layers: ILayer[] = [];\n    this._inputLayer = inputLayer();\n    const hiddenLayers = this._connectHiddenLayers(this._inputLayer);\n\n    if (!outputLayer) throw new Error('outputLayer not defined');\n    this._outputLayer = outputLayer(\n      hiddenLayers[hiddenLayers.length - 1],\n      hiddenLayers.length\n    );\n    layers.push(this._inputLayer);\n    layers.push(...hiddenLayers);\n    layers.push(this._outputLayer);\n    return flattenLayers(layers);\n  }\n\n  _connectHiddenLayers(previousLayer: ILayer): ILayer[] {\n    this._hiddenLayers = [];\n    const result: ILayer[] = [];\n    const { hiddenLayers } = this.options;\n\n    if (!hiddenLayers) throw new Error('hiddenLayers not defined');\n\n    for (let i = 0; i < hiddenLayers.length; i++) {\n      const hiddenLayer = hiddenLayers[i](previousLayer, i);\n      result.push(hiddenLayer);\n      this._hiddenLayers.push(hiddenLayer);\n      previousLayer = hiddenLayer;\n    }\n\n    return result;\n  }\n\n  initialize(): void {\n    this.layers = this.options.layers\n      ? this._connectOptionsLayers()\n      : this._connectNewLayers();\n    this.initializeLayers(this.layers);\n    this._model = this.layers.filter((l) => l instanceof Model);\n  }\n\n  initializeLayers(layers: ILayer[]): void {\n    for (let i = 0; i < layers.length; i++) {\n      const layer = layers[i];\n      // TODO: optimize for when training or just running\n      layer.setupKernels(true);\n      if (\n        layer instanceof Model &&\n        layer.praxis === null &&\n        typeof this.options.initPraxis === 'function'\n      ) {\n        layer.praxis = this.options.initPraxis(\n          layer,\n          layer.settings.praxisOpts ?? this.options.praxisOpts ?? {}\n        );\n        layer.praxis.setupKernels();\n      }\n    }\n\n    const lastLayer = layers[layers.length - 1];\n    this.meanSquaredError = new MeanSquaredError({\n      width: lastLayer.width,\n      height: lastLayer.height,\n    });\n  }\n\n  run(input: InputType): OutputType {\n    let typeSafeInput: INumberArray | KernelOutput;\n    if (Array.isArray(input) || (input as Float32Array).buffer) {\n      typeSafeInput = input as INumberArray;\n    } else {\n      if (this.inputLookup) {\n        typeSafeInput = lookup.toArray(\n          this.inputLookup,\n          input as INumberHash,\n          this.inputLookupLength as number\n        );\n      } else {\n        throw new Error('input is incompatible with net');\n      }\n    }\n\n    let output = this.runInput(typeSafeInput as KernelOutput);\n    if (output instanceof Texture) {\n      output = output.toArray();\n    }\n\n    if (this.outputLookup) {\n      return lookup.toObject(\n        this.outputLookup,\n        output as number[]\n      ) as OutputType;\n    }\n    return output as OutputType;\n  }\n\n  runInput(input: KernelOutput): KernelOutput {\n    if (!this.layers) throw new Error('not initialized');\n    this.layers[0].predict(input);\n    for (let i = 1; i < this.layers.length; i++) {\n      this.layers[i].predict();\n    }\n    return this.layers[this.layers.length - 1].weights as KernelOutput;\n  }\n\n  train(\n    data: Array<IFeedForwardTrainingData<InputType, OutputType>>,\n    options: Partial<IFeedForwardTrainingOptions> = {}\n  ): ITrainingStatus {\n    const { preparedData, status, endTime } = this._prepTraining(data, options);\n    let continueTicking = true;\n    const calculateError = (): number =>\n      this._calculateTrainingError(preparedData);\n    const trainPatterns = (): void => this._trainPatterns(preparedData);\n    while (continueTicking) {\n      continueTicking = this._trainingTick(\n        status,\n        endTime,\n        calculateError,\n        trainPatterns\n      );\n    }\n    return status;\n  }\n\n  async trainAsync(\n    data: Array<IFeedForwardTrainingData<InputType, OutputType>>,\n    options: Partial<IFeedForwardTrainingOptions> = {}\n  ): Promise<ITrainingStatus> {\n    const { preparedData, status, endTime } = this._prepTraining(data, options);\n\n    return await new Promise((resolve, reject) => {\n      try {\n        const calculateError = (): number =>\n          this._calculateTrainingError(preparedData);\n        const trainPatterns = (): void => this._trainPatterns(preparedData);\n        const thawedTrain: Thaw = new Thaw(\n          new Array(this.trainOpts.iterations),\n          {\n            delay: true,\n            each: () =>\n              this._trainingTick(\n                status,\n                endTime,\n                calculateError,\n                trainPatterns\n              ) || thawedTrain.stop(),\n            done: () => resolve(status),\n          }\n        );\n        thawedTrain.tick();\n      } catch (trainError) {\n        reject(trainError);\n      }\n    });\n  }\n\n  _trainingTick(\n    status: ITrainingStatus,\n    endTime: number,\n    calculateError: () => number,\n    trainPatterns: () => void\n  ): boolean {\n    const { trainOpts } = this;\n    if (\n      status.iterations >= (trainOpts.iterations as number) ||\n      status.error <= (trainOpts.errorThresh as number) ||\n      Date.now() >= endTime\n    ) {\n      return false;\n    }\n\n    if (\n      typeof trainOpts.log === 'function' &&\n      status.iterations % (trainOpts.logPeriod as number) === 0\n    ) {\n      status.error = calculateError();\n      trainOpts.log(\n        `iterations: ${status.iterations}, training error: ${status.error}`\n      );\n    } else if (\n      status.iterations % (trainOpts.errorCheckInterval as number) ===\n      0\n    ) {\n      status.error = calculateError();\n    } else {\n      trainPatterns();\n    }\n\n    if (\n      trainOpts.callback &&\n      status.iterations % (trainOpts.callbackPeriod as number) === 0\n    ) {\n      trainOpts.callback(Object.assign(status));\n    }\n\n    status.iterations++;\n    return true;\n  }\n\n  _prepTraining(\n    data: Array<IFeedForwardTrainingData<InputType, OutputType>>,\n    options: Partial<IFeedForwardTrainingOptions>\n  ): IFeedForwardPreppedTrainingData {\n    this._updateTrainingOptions(options);\n\n    const formattedData = this.formatData(data);\n    const endTime = this.trainOpts.timeout\n      ? Date.now() + this.trainOpts.timeout\n      : 0;\n\n    const status = {\n      error: 1,\n      iterations: 0,\n    };\n\n    this.verifyIsInitialized();\n\n    return {\n      preparedData: this.transferData(formattedData),\n      status,\n      endTime,\n    };\n  }\n\n  verifyIsInitialized(): void {\n    if (!this._model) {\n      this.initialize();\n    }\n  }\n\n  _calculateTrainingError(preparedData: IFeedForwardGPUTrainingData[]): number {\n    let sum: Float32Array | KernelOutput = new Float32Array([0]);\n    const meanSquaredError = this.meanSquaredError as MeanSquaredError;\n    for (let i = 0; i < preparedData.length; ++i) {\n      const prevSum = sum;\n      const error = this._trainPattern(\n        preparedData[i].input,\n        preparedData[i].output,\n        true\n      ) as number;\n      sum = meanSquaredError.add(sum, error);\n      release(error);\n      release(prevSum);\n    }\n    const result = meanSquaredError.divide(preparedData.length, sum);\n    release(sum);\n    if (result instanceof Texture) {\n      const resultArray: number[] = result.toArray() as number[];\n      release(result);\n      return resultArray[0];\n    }\n    return (result as number[])[0];\n  }\n\n  /**\n   * @param data\n   * @private\n   */\n  _trainPatterns(data: IFeedForwardGPUTrainingData[]): void {\n    for (let i = 0; i < data.length; ++i) {\n      this._trainPattern(data[i].input, data[i].output, false);\n    }\n  }\n\n  _trainPattern(\n    input: KernelOutput,\n    target: KernelOutput,\n    logErrorRate: boolean\n  ): KernelOutput | null {\n    // forward propagate\n    this.runInput(input);\n\n    // back propagate\n    this._calculateDeltas(target);\n    this.adjustWeights();\n\n    if (logErrorRate) {\n      if (!this._outputLayer?.errors) {\n        throw new Error('outputLayer.errors not defined');\n      }\n      return (this.meanSquaredError as MeanSquaredError).calculate(\n        this._outputLayer.errors\n      );\n    }\n    return null;\n  }\n\n  _calculateDeltas(target: KernelOutput): void {\n    const layers = this.layers as ILayer[];\n    for (let i = layers.length - 1; i > -1; i--) {\n      layers[i].compare(target);\n    }\n  }\n\n  /**\n   *\n   */\n  adjustWeights(): void {\n    const _model = this._model as ILayer[];\n    for (let i = 0; i < _model.length; i++) {\n      _model[i].learn(this.trainOpts.learningRate as number);\n    }\n  }\n\n  /**\n   *\n   * @param data\n   * @returns {*}\n   */\n  formatData(\n    data:\n      | Array<IFeedForwardTrainingData<InputType, OutputType>>\n      | IFeedForwardTrainingData<InputType, OutputType>\n  ): IFeedForwardNormalizedTrainingData[] {\n    if (!Array.isArray(data)) {\n      // turn stream datum into array\n      const tmp = [];\n      tmp.push(data);\n      data = tmp;\n    }\n\n    // turn sparse hash input into arrays with 0s as filler\n    const inputDatumCheck = data[0].input;\n    let formattedData: Array<Partial<IFeedForwardNormalizedTrainingData>>;\n    if (\n      Array.isArray(data) &&\n      !Array.isArray(inputDatumCheck) &&\n      !(inputDatumCheck instanceof Float32Array)\n    ) {\n      if (!this.inputLookup) {\n        const lookupTable = new LookupTable(data, 'input');\n        this.inputLookup = lookupTable.table;\n        this.inputLookupLength = lookupTable.length;\n      }\n      formattedData = data.map((datumParam): Partial<\n        IFeedForwardNormalizedTrainingData\n      > => {\n        const array = lookup.toArray(\n          this.inputLookup as INumberHash,\n          datumParam.input as INumberHash,\n          this.inputLookupLength as number\n        );\n        return { input: array };\n      }, this);\n    } else {\n      formattedData = data as typeof formattedData;\n    }\n\n    const outputDatumCheck = data[0].output;\n    if (\n      !Array.isArray(outputDatumCheck) &&\n      !(outputDatumCheck instanceof Float32Array)\n    ) {\n      if (!this.outputLookup) {\n        const lookupTable = new LookupTable(data, 'output');\n        this.outputLookup = lookupTable.table;\n        this.outputLookupLength = lookupTable.length;\n      }\n      formattedData = data.map(\n        (datumParam, index): IFeedForwardNormalizedTrainingData => {\n          const array = lookup.toArray(\n            this.outputLookup as INumberHash,\n            datumParam.output as INumberHash,\n            this.inputLookupLength as number\n          );\n          return {\n            input: formattedData[index].input as Float32Array,\n            output: array,\n          };\n        },\n        this\n      );\n    }\n    return formattedData as IFeedForwardNormalizedTrainingData[];\n  }\n\n  transferData(\n    formattedData: IFeedForwardNormalizedTrainingData[]\n  ): IFeedForwardGPUTrainingData[] {\n    const transferredData = new Array(formattedData.length);\n    const transferInput = makeKernel(\n      function (value: number[]): number {\n        return value[this.thread.x];\n      },\n      {\n        output: [formattedData[0].input.length],\n        immutable: true,\n      }\n    );\n    const transferOutput = makeKernel(\n      function (this: IKernelFunctionThis, value: number[]): number {\n        return value[this.thread.x];\n      },\n      {\n        output: [formattedData[0].output.length],\n        immutable: true,\n      }\n    );\n\n    for (let i = 0; i < formattedData.length; i++) {\n      const formattedDatum = formattedData[i];\n      transferredData[i] = {\n        input: transferInput(formattedDatum.input),\n        output: transferOutput(formattedDatum.output),\n      };\n    }\n    return transferredData;\n  }\n\n  /**\n   *\n   * @param data\n   * @returns {\n   *  {\n   *    error: number,\n   *    misclasses: Array\n   *  }\n   * }\n   */\n  test(): void {\n    throw new Error(`${this.constructor.name}-test is not yet implemented`);\n  }\n\n  /**\n   *\n   */\n  toJSON(): IFeedForwardJSON {\n    if (!this.layers) {\n      this.initialize();\n    }\n    if (\n      !this._model ||\n      !this.layers ||\n      !this._inputLayer ||\n      !this._hiddenLayers ||\n      !this._outputLayer\n    ) {\n      throw new Error('network is not initialized');\n    }\n    const jsonLayers = [];\n    for (let i = 0; i < this.layers.length; i++) {\n      const layer = this.layers[i];\n      const jsonLayer = layer.toJSON();\n      if (layer.hasOwnProperty('inputLayer')) {\n        jsonLayer.inputLayerIndex = this.layers.indexOf(\n          layer.inputLayer as ILayer\n        );\n      } else if (\n        layer.hasOwnProperty('inputLayer1') &&\n        layer.hasOwnProperty('inputLayer2')\n      ) {\n        jsonLayer.inputLayer1Index = this.layers.indexOf(\n          layer.inputLayer1 as ILayer\n        );\n        jsonLayer.inputLayer2Index = this.layers.indexOf(\n          layer.inputLayer2 as ILayer\n        );\n      }\n      jsonLayers.push(jsonLayer);\n    }\n\n    return {\n      type: this.constructor.name,\n      sizes:\n        this.options.sizes ??\n        [this._inputLayer.height]\n          .concat(this._hiddenLayers.map((l) => l.height))\n          .concat([this._outputLayer.height]),\n      outputLayerIndex: this.layers.indexOf(this._outputLayer),\n      layers: jsonLayers as ILayerJSON[],\n      inputLayerIndex: this.layers.indexOf(this._inputLayer),\n    };\n  }\n\n  static fromJSON(\n    json: IFeedForwardJSON,\n    getLayer?: (\n      layerJson: ILayerJSON,\n      inputLayer1?: ILayer,\n      inputLayer2?: ILayer\n    ) => ILayer\n  ): FeedForward {\n    const jsonLayers = json.layers;\n    const layers: ILayer[] = [];\n    const inputLayer = getLayer\n      ? layerFromJSON(jsonLayers[0]) ?? getLayer(jsonLayers[0])\n      : layerFromJSON(jsonLayers[0]);\n\n    if (!inputLayer) throw new Error('unable to find layer');\n\n    layers.push(inputLayer);\n\n    for (let i = 1; i < jsonLayers.length; i++) {\n      const jsonLayer = jsonLayers[i];\n      if (\n        typeof jsonLayer.inputLayerIndex === 'undefined' &&\n        typeof jsonLayer.inputLayer1Index === 'undefined' &&\n        typeof jsonLayer.inputLayer2Index === 'undefined'\n      ) {\n        const layer = getLayer\n          ? layerFromJSON(jsonLayer) ?? getLayer(jsonLayer)\n          : layerFromJSON(jsonLayer);\n        if (!layer) throw new Error('unable to find layer');\n        layers.push(layer);\n      } else if (typeof jsonLayer.inputLayerIndex === 'number') {\n        const inputLayer = layers[jsonLayer.inputLayerIndex];\n        if (!inputLayer) {\n          throw new Error('inputLayer1 not found');\n        }\n        const layer = getLayer\n          ? layerFromJSON(jsonLayer, inputLayer) ??\n            getLayer(jsonLayer, inputLayer)\n          : layerFromJSON(jsonLayer, inputLayer);\n        if (!layer) throw new Error('unable to find layer');\n        layers.push(layer);\n      } else {\n        if (typeof jsonLayer.inputLayer1Index !== 'number') {\n          throw new Error(\n            'Cannot create network from provided JSON. inputLayer1Index not defined.'\n          );\n        }\n        if (typeof jsonLayer.inputLayer2Index !== 'number') {\n          throw new Error(\n            'Cannot create network from provided JSON. inputLayer2Index not defined.'\n          );\n        }\n        const inputLayer1 = layers[jsonLayer.inputLayer1Index];\n        const inputLayer2 = layers[jsonLayer.inputLayer2Index];\n\n        if (inputLayer1 === undefined)\n          throw new Error(\n            `Cannot create network from provided JSON. layer of index ${jsonLayer.inputLayer1Index} not found.`\n          );\n        if (inputLayer2 === undefined)\n          throw new Error(\n            `Cannot create network from provided JSON. layer of index ${jsonLayer.inputLayer2Index} not found.`\n          );\n\n        const layer = getLayer\n          ? layerFromJSON(jsonLayer, inputLayer1, inputLayer2) ??\n            getLayer(jsonLayer, inputLayer1, inputLayer2)\n          : layerFromJSON(jsonLayer, inputLayer1, inputLayer2);\n\n        if (!layer) throw new Error('unable to find layer');\n        layers.push(layer);\n      }\n    }\n\n    return new this({ ...json, layers });\n  }\n\n  /**\n   *\n   * @returns {Function}\n   */\n  toFunction(): void {\n    throw new Error(\n      `${this.constructor.name}-toFunction is not yet implemented`\n    );\n  }\n\n  /**\n   * This will create a TrainStream (WriteStream) for us to send the training data to.\n   * @param opts training options\n   * @returns {TrainStream|*}\n   */\n  createTrainStream(): void {\n    throw new Error(\n      `${this.constructor.name}-createTrainStream is not yet implemented`\n    );\n  }\n}\n","export function arraysToFloat32Arrays(arrays: number[][]): Float32Array[] {\n  const result: Float32Array[] = [];\n  for (let i = 0; i < arrays.length; i++) {\n    result.push(Float32Array.from(arrays[i]));\n  }\n  return result;\n}\n\nexport function inputOutputArraysToFloat32Arrays(\n  input: number[][],\n  output: number[][]\n): Float32Array[] {\n  const result: Float32Array[] = [];\n  for (let i = 0; i < input.length; i++) {\n    result.push(Float32Array.from(input[i]));\n  }\n  for (let i = 0; i < output.length; i++) {\n    result.push(Float32Array.from(output[i]));\n  }\n  return result;\n}\n\nexport function arrayToFloat32Arrays(array: number[]): Float32Array[] {\n  const result: Float32Array[] = [];\n  for (let i = 0; i < array.length; i++) {\n    result.push(Float32Array.from([array[i]]));\n  }\n  return result;\n}\n\nexport function inputOutputArrayToFloat32Arrays(\n  input: number[],\n  output: number[]\n): Float32Array[] {\n  const result: Float32Array[] = [];\n  for (let i = 0; i < input.length; i++) {\n    result.push(Float32Array.from([input[i]]));\n  }\n  for (let i = 0; i < output.length; i++) {\n    result.push(Float32Array.from([output[i]]));\n  }\n  return result;\n}\n\nexport function arrayToFloat32Array(array: number[]): Float32Array {\n  return Float32Array.from(array);\n}\n\nexport function objectsToFloat32Arrays(\n  objects: Array<Record<string, number>>,\n  table: Record<string, number>,\n  length: number\n): Float32Array[] {\n  const results: Float32Array[] = [];\n  for (let i = 0; i < objects.length; i++) {\n    const object = objects[i];\n    const result = new Float32Array(length);\n    for (const p in object) {\n      if (object.hasOwnProperty(p)) {\n        result[table[p]] = object[p];\n      }\n    }\n    results.push(result);\n  }\n  return results;\n}\n\nexport function inputOutputObjectsToFloat32Arrays(\n  input: Array<Record<string, number>>,\n  output: Array<Record<string, number>>,\n  inputTable: Record<string, number>,\n  outputTable: Record<string, number>,\n  inputLength: number,\n  outputLength: number\n): Float32Array[] {\n  const results: Float32Array[] = [];\n  for (let i = 0; i < input.length; i++) {\n    const object = input[i];\n    const result = new Float32Array(inputLength);\n    for (const p in object) {\n      if (object.hasOwnProperty(p)) {\n        result[inputTable[p]] = object[p];\n      }\n    }\n    results.push(result);\n  }\n  for (let i = 0; i < output.length; i++) {\n    const object = output[i];\n    const result = new Float32Array(outputLength);\n    for (const p in object) {\n      if (object.hasOwnProperty(p)) {\n        result[outputTable[p]] = object[p];\n      }\n    }\n    results.push(result);\n  }\n  return results;\n}\n\nexport function objectToFloat32Arrays(\n  object: Record<string, number>\n): Float32Array[] {\n  const result: Float32Array[] = [];\n  for (const p in object) {\n    if (!object.hasOwnProperty(p)) continue;\n    result.push(Float32Array.from([object[p]]));\n  }\n  return result;\n}\n\nexport function inputOutputObjectToFloat32Arrays(\n  input: Record<string, number>,\n  output: Record<string, number>\n): Float32Array[] {\n  const result: Float32Array[] = [];\n  for (const p in input) {\n    if (!input.hasOwnProperty(p)) continue;\n    result.push(Float32Array.from([input[p]]));\n  }\n  for (const p in output) {\n    if (!output.hasOwnProperty(p)) continue;\n    result.push(Float32Array.from([output[p]]));\n  }\n  return result;\n}\n\nexport function objectToFloat32Array(\n  object: Record<string, number>,\n  table: Record<string, number>,\n  length: number\n): Float32Array {\n  const result = new Float32Array(length);\n  for (const p in object) {\n    if (object.hasOwnProperty(p)) {\n      result[table[p]] = object[p];\n    }\n  }\n  return result;\n}\n","export function max(\n  values:\n    | Float32Array\n    | {\n        [key: string]: number;\n      }\n): number {\n  if (Array.isArray(values) || values instanceof Float32Array) {\n    return Math.max(...values);\n  } else {\n    return Math.max(...Object.values(values));\n  }\n}\n","export function mse(errors: Float32Array): number {\n  // mean squared error\n  let sum = 0;\n  for (let i = 0; i < errors.length; i++) {\n    sum += errors[i] ** 2;\n  }\n  return sum / errors.length;\n}\n","import { Thaw } from 'thaw.js';\nimport { ITrainingStatus } from './feed-forward';\nimport { INumberHash, lookup } from './lookup';\nimport {\n  INeuralNetworkBinaryTestResult,\n  INeuralNetworkState,\n  INeuralNetworkTestResult,\n} from './neural-network-types';\nimport { arrayToFloat32Array } from './utilities/cast';\nimport { LookupTable } from './utilities/lookup-table';\nimport { max } from './utilities/max';\nimport { mse } from './utilities/mse';\nimport { randos } from './utilities/randos';\nimport { zeros } from './utilities/zeros';\n\ntype NeuralNetworkFormatter =\n  | ((v: INumberHash) => Float32Array)\n  | ((v: number[]) => Float32Array);\n\nexport function getTypedArrayFn(\n  value: INeuralNetworkData,\n  table: INumberHash | null\n): null | NeuralNetworkFormatter {\n  if ((value as Float32Array).buffer instanceof ArrayBuffer) {\n    return null;\n  }\n  if (Array.isArray(value)) {\n    return arrayToFloat32Array;\n  }\n  if (!table) throw new Error('table is not Object');\n  const { length } = Object.keys(table);\n  return (v: INumberHash): Float32Array => {\n    const array = new Float32Array(length);\n    for (const p in table) {\n      if (!table.hasOwnProperty(p)) continue;\n      if (typeof v[p] !== 'number') continue;\n      array[table[p]] = v[p] || 0;\n    }\n    return array;\n  };\n}\n\nexport type NeuralNetworkActivation =\n  | 'sigmoid'\n  | 'relu'\n  | 'leaky-relu'\n  | 'tanh';\n\nexport interface IJSONLayer {\n  biases: number[];\n  weights: number[][];\n}\n\nexport interface INeuralNetworkJSON {\n  type: string;\n  sizes: number[];\n  layers: IJSONLayer[];\n  inputLookup: INumberHash | null;\n  inputLookupLength: number;\n  outputLookup: INumberHash | null;\n  outputLookupLength: number;\n  options: INeuralNetworkOptions;\n  trainOpts: INeuralNetworkTrainOptionsJSON;\n}\n\nexport interface INeuralNetworkOptions {\n  inputSize: number;\n  outputSize: number;\n  binaryThresh: number;\n  hiddenLayers?: number[];\n}\n\nexport function defaults(): INeuralNetworkOptions {\n  return {\n    inputSize: 0,\n    outputSize: 0,\n    binaryThresh: 0.5,\n  };\n}\n\nexport interface INeuralNetworkTrainOptionsJSON {\n  activation: NeuralNetworkActivation | string;\n  iterations: number;\n  errorThresh: number;\n  log: boolean;\n  logPeriod: number;\n  leakyReluAlpha: number;\n  learningRate: number;\n  momentum: number;\n  callbackPeriod: number;\n  timeout: number | 'Infinity';\n  praxis?: 'adam';\n  beta1: number;\n  beta2: number;\n  epsilon: number;\n}\n\nexport interface INeuralNetworkPreppedTrainingData<T> {\n  status: ITrainingStatus;\n  preparedData: Array<INeuralNetworkDatumFormatted<T>>;\n  endTime: number;\n}\n\nexport interface INeuralNetworkTrainOptions {\n  activation: NeuralNetworkActivation | string;\n  iterations: number;\n  errorThresh: number;\n  log: boolean | ((status: INeuralNetworkState) => void);\n  logPeriod: number;\n  leakyReluAlpha: number;\n  learningRate: number;\n  momentum: number;\n  callback?: (status: { iterations: number; error: number }) => void;\n  callbackPeriod: number;\n  timeout: number;\n  praxis?: 'adam';\n  beta1: number;\n  beta2: number;\n  epsilon: number;\n}\n\nexport function trainDefaults(): INeuralNetworkTrainOptions {\n  return {\n    activation: 'sigmoid',\n    iterations: 20000, // the maximum times to iterate the training data\n    errorThresh: 0.005, // the acceptable error percentage from training data\n    log: false, // true to use console.log, when a function is supplied it is used\n    logPeriod: 10, // iterations between logging out\n    leakyReluAlpha: 0.01,\n    learningRate: 0.3, // multiply's against the input and the delta then adds to momentum\n    momentum: 0.1, // multiply's against the specified \"change\" then adds to learning rate for change\n    callbackPeriod: 10, // the number of iterations through the training data between callback calls\n    timeout: Infinity, // the max number of milliseconds to train for\n    beta1: 0.9,\n    beta2: 0.999,\n    epsilon: 1e-8,\n  };\n}\n\nexport type INeuralNetworkData = number[] | Float32Array | Partial<INumberHash>;\n\n// TODO: should be replaced by ITrainingDatum\nexport interface INeuralNetworkDatum<InputType, OutputType> {\n  input: InputType;\n  output: OutputType;\n}\n\nexport interface INeuralNetworkDatumFormatted<T> {\n  input: T;\n  output: T;\n}\n\nexport class NeuralNetwork<\n  InputType extends INeuralNetworkData,\n  OutputType extends INeuralNetworkData\n> {\n  options: INeuralNetworkOptions = defaults();\n  trainOpts: INeuralNetworkTrainOptions = trainDefaults();\n  sizes: number[] = [];\n  outputLayer = -1;\n  biases: Float32Array[] = [];\n  weights: Float32Array[][] = []; // weights for bias nodes\n  outputs: Float32Array[] = [];\n  // state for training\n  deltas: Float32Array[] = [];\n  changes: Float32Array[][] = []; // for momentum\n  errors: Float32Array[] = [];\n\n  errorCheckInterval = 1;\n\n  inputLookup: INumberHash | null = null;\n  inputLookupLength = 0;\n  outputLookup: INumberHash | null = null;\n  outputLookupLength = 0;\n\n  _formatInput: NeuralNetworkFormatter | null = null;\n  _formatOutput: NeuralNetworkFormatter | null = null;\n\n  runInput: (input: Float32Array) => Float32Array = (input: Float32Array) => {\n    this.setActivation();\n    return this.runInput(input);\n  };\n\n  calculateDeltas: (output: Float32Array) => void = (\n    output: Float32Array\n  ): void => {\n    this.setActivation();\n    return this.calculateDeltas(output);\n  };\n\n  // adam\n  biasChangesLow: Float32Array[] = [];\n  biasChangesHigh: Float32Array[] = [];\n  changesLow: Float32Array[][] = [];\n  changesHigh: Float32Array[][] = [];\n  iterations = 0;\n\n  constructor(\n    options: Partial<INeuralNetworkOptions & INeuralNetworkTrainOptions> = {}\n  ) {\n    this.options = { ...this.options, ...options };\n    this.updateTrainingOptions(options);\n\n    const { inputSize, hiddenLayers, outputSize } = this.options;\n    if (inputSize && outputSize) {\n      this.sizes = [inputSize].concat(hiddenLayers ?? []).concat([outputSize]);\n    }\n  }\n\n  /**\n   *\n   * Expects this.sizes to have been set\n   */\n  initialize(): void {\n    if (!this.sizes.length) {\n      throw new Error('Sizes must be set before initializing');\n    }\n\n    this.outputLayer = this.sizes.length - 1;\n    this.biases = new Array(this.outputLayer); // weights for bias nodes\n    this.weights = new Array(this.outputLayer);\n    this.outputs = new Array(this.outputLayer);\n\n    // state for training\n    this.deltas = new Array(this.outputLayer);\n    this.changes = new Array(this.outputLayer); // for momentum\n    this.errors = new Array(this.outputLayer);\n\n    for (let layerIndex = 0; layerIndex <= this.outputLayer; layerIndex++) {\n      const size = this.sizes[layerIndex];\n      this.deltas[layerIndex] = zeros(size);\n      this.errors[layerIndex] = zeros(size);\n      this.outputs[layerIndex] = zeros(size);\n\n      if (layerIndex > 0) {\n        this.biases[layerIndex] = randos(size);\n        this.weights[layerIndex] = new Array(size);\n        this.changes[layerIndex] = new Array(size);\n\n        for (let nodeIndex = 0; nodeIndex < size; nodeIndex++) {\n          const prevSize = this.sizes[layerIndex - 1];\n          this.weights[layerIndex][nodeIndex] = randos(prevSize);\n          this.changes[layerIndex][nodeIndex] = zeros(prevSize);\n        }\n      }\n    }\n\n    this.setActivation();\n    if (this.trainOpts.praxis === 'adam') {\n      this._setupAdam();\n    }\n  }\n\n  setActivation(activation?: NeuralNetworkActivation): void {\n    const value = activation ?? this.trainOpts.activation;\n    switch (value) {\n      case 'sigmoid':\n        this.runInput = this._runInputSigmoid;\n        this.calculateDeltas = this._calculateDeltasSigmoid;\n        break;\n      case 'relu':\n        this.runInput = this._runInputRelu;\n        this.calculateDeltas = this._calculateDeltasRelu;\n        break;\n      case 'leaky-relu':\n        this.runInput = this._runInputLeakyRelu;\n        this.calculateDeltas = this._calculateDeltasLeakyRelu;\n        break;\n      case 'tanh':\n        this.runInput = this._runInputTanh;\n        this.calculateDeltas = this._calculateDeltasTanh;\n        break;\n      default:\n        throw new Error(\n          `Unknown activation ${value}. Available activations are: 'sigmoid', 'relu', 'leaky-relu', 'tanh'`\n        );\n    }\n  }\n\n  get isRunnable(): boolean {\n    return this.sizes.length > 0;\n  }\n\n  run(input: Partial<InputType>): OutputType {\n    if (!this.isRunnable) {\n      throw new Error('network not runnable');\n    }\n    let formattedInput: Float32Array;\n    if (this.inputLookup) {\n      formattedInput = lookup.toArray(\n        this.inputLookup,\n        (input as unknown) as INumberHash,\n        this.inputLookupLength\n      );\n    } else {\n      formattedInput = (input as unknown) as Float32Array;\n    }\n    this.validateInput(formattedInput);\n    const output = this.runInput(formattedInput).slice(0);\n    if (this.outputLookup) {\n      return (lookup.toObject(\n        this.outputLookup,\n        output\n      ) as unknown) as OutputType;\n    }\n    return (output as unknown) as OutputType;\n  }\n\n  _runInputSigmoid(input: Float32Array): Float32Array {\n    this.outputs[0] = input; // set output state of input layer\n\n    let output = null;\n    for (let layer = 1; layer <= this.outputLayer; layer++) {\n      const activeLayer = this.sizes[layer];\n      const activeWeights = this.weights[layer];\n      const activeBiases = this.biases[layer];\n      const activeOutputs = this.outputs[layer];\n      for (let node = 0; node < activeLayer; node++) {\n        const weights = activeWeights[node];\n\n        let sum = activeBiases[node];\n        for (let k = 0; k < weights.length; k++) {\n          sum += weights[k] * input[k];\n        }\n        // sigmoid\n        activeOutputs[node] = 1 / (1 + Math.exp(-sum));\n      }\n      output = input = activeOutputs;\n    }\n    if (!output) {\n      throw new Error('output was empty');\n    }\n    return output;\n  }\n\n  _runInputRelu(input: Float32Array): Float32Array {\n    this.outputs[0] = input; // set output state of input layer\n\n    let output = null;\n    for (let layer = 1; layer <= this.outputLayer; layer++) {\n      const activeSize = this.sizes[layer];\n      const activeWeights = this.weights[layer];\n      const activeBiases = this.biases[layer];\n      const activeOutputs = this.outputs[layer];\n      for (let node = 0; node < activeSize; node++) {\n        const weights = activeWeights[node];\n\n        let sum = activeBiases[node];\n        for (let k = 0; k < weights.length; k++) {\n          sum += weights[k] * input[k];\n        }\n        // relu\n        activeOutputs[node] = sum < 0 ? 0 : sum;\n      }\n      output = input = activeOutputs;\n    }\n    if (!output) {\n      throw new Error('output was empty');\n    }\n    return output;\n  }\n\n  _runInputLeakyRelu(input: Float32Array): Float32Array {\n    this.outputs[0] = input; // set output state of input layer\n    const { leakyReluAlpha } = this.trainOpts;\n    let output = null;\n    for (let layer = 1; layer <= this.outputLayer; layer++) {\n      const activeSize = this.sizes[layer];\n      const activeWeights = this.weights[layer];\n      const activeBiases = this.biases[layer];\n      const activeOutputs = this.outputs[layer];\n      for (let node = 0; node < activeSize; node++) {\n        const weights = activeWeights[node];\n\n        let sum = activeBiases[node];\n        for (let k = 0; k < weights.length; k++) {\n          sum += weights[k] * input[k];\n        }\n        // leaky relu\n        activeOutputs[node] = Math.max(sum, leakyReluAlpha * sum);\n      }\n      output = input = activeOutputs;\n    }\n    if (!output) {\n      throw new Error('output was empty');\n    }\n    return output;\n  }\n\n  _runInputTanh(input: Float32Array): Float32Array {\n    this.outputs[0] = input; // set output state of input layer\n\n    let output = null;\n    for (let layer = 1; layer <= this.outputLayer; layer++) {\n      const activeSize = this.sizes[layer];\n      const activeWeights = this.weights[layer];\n      const activeBiases = this.biases[layer];\n      const activeOutputs = this.outputs[layer];\n      for (let node = 0; node < activeSize; node++) {\n        const weights = activeWeights[node];\n\n        let sum = activeBiases[node];\n        for (let k = 0; k < weights.length; k++) {\n          sum += weights[k] * input[k];\n        }\n        // tanh\n        activeOutputs[node] = Math.tanh(sum);\n      }\n      output = input = activeOutputs;\n    }\n    if (!output) {\n      throw new Error('output was empty');\n    }\n    return output;\n  }\n\n  /**\n   *\n   * Verifies network sizes are initialized\n   * If they are not it will initialize them based off the data set.\n   */\n  verifyIsInitialized(\n    preparedData: Array<INeuralNetworkDatumFormatted<Float32Array>>\n  ): void {\n    if (this.sizes.length && this.outputLayer > 0) return;\n\n    this.sizes = [];\n    this.sizes.push(preparedData[0].input.length);\n    if (!this.options.hiddenLayers) {\n      this.sizes.push(\n        Math.max(3, Math.floor(preparedData[0].input.length / 2))\n      );\n    } else {\n      this.options.hiddenLayers.forEach((size) => {\n        this.sizes.push(size);\n      });\n    }\n    this.sizes.push(preparedData[0].output.length);\n\n    this.initialize();\n  }\n\n  updateTrainingOptions(trainOpts: Partial<INeuralNetworkTrainOptions>): void {\n    const merged = { ...this.trainOpts, ...trainOpts };\n    this.validateTrainingOptions(merged);\n    this.trainOpts = merged;\n    this.setLogMethod(this.trainOpts.log);\n  }\n\n  validateTrainingOptions(options: INeuralNetworkTrainOptions): void {\n    const validations: { [fnName: string]: () => boolean } = {\n      activation: () => {\n        return ['sigmoid', 'relu', 'leaky-relu', 'tanh'].includes(\n          options.activation\n        );\n      },\n      iterations: () => {\n        const val = options.iterations;\n        return typeof val === 'number' && val > 0;\n      },\n      errorThresh: () => {\n        const val = options.errorThresh;\n        return typeof val === 'number' && val > 0 && val < 1;\n      },\n      log: () => {\n        const val = options.log;\n        return typeof val === 'function' || typeof val === 'boolean';\n      },\n      logPeriod: () => {\n        const val = options.logPeriod;\n        return typeof val === 'number' && val > 0;\n      },\n      leakyReluAlpha: () => {\n        const val = options.leakyReluAlpha;\n        return typeof val === 'number' && val > 0 && val < 1;\n      },\n      learningRate: () => {\n        const val = options.learningRate;\n        return typeof val === 'number' && val > 0 && val < 1;\n      },\n      momentum: () => {\n        const val = options.momentum;\n        return typeof val === 'number' && val > 0 && val < 1;\n      },\n      callback: () => {\n        const val = options.callback;\n        return typeof val === 'function' || val === undefined;\n      },\n      callbackPeriod: () => {\n        const val = options.callbackPeriod;\n        return typeof val === 'number' && val > 0;\n      },\n      timeout: () => {\n        const val = options.timeout;\n        return typeof val === 'number' && val > 0;\n      },\n      praxis: () => {\n        const val = options.praxis;\n        return !val || val === 'adam';\n      },\n      beta1: () => {\n        const val = options.beta1;\n        return val > 0 && val < 1;\n      },\n      beta2: () => {\n        const val = options.beta2;\n        return val > 0 && val < 1;\n      },\n      epsilon: () => {\n        const val = options.epsilon;\n        return val > 0 && val < 1;\n      },\n    };\n    for (const p in validations) {\n      const v = (options as unknown) as { [v: string]: string };\n      if (!validations[p]()) {\n        throw new Error(\n          `[${p}, ${v[p]}] is out of normal training range, your network will probably not train.`\n        );\n      }\n    }\n  }\n\n  /**\n   *\n   *  Gets JSON of trainOpts object\n   *    NOTE: Activation is stored directly on JSON object and not in the training options\n   */\n  getTrainOptsJSON(): INeuralNetworkTrainOptionsJSON {\n    const {\n      activation,\n      iterations,\n      errorThresh,\n      log,\n      logPeriod,\n      leakyReluAlpha,\n      learningRate,\n      momentum,\n      callbackPeriod,\n      timeout,\n      praxis,\n      beta1,\n      beta2,\n      epsilon,\n    } = this.trainOpts;\n    return {\n      activation,\n      iterations,\n      errorThresh,\n      log:\n        typeof log === 'function'\n          ? true\n          : typeof log === 'boolean'\n          ? log\n          : false,\n      logPeriod,\n      leakyReluAlpha,\n      learningRate,\n      momentum,\n      callbackPeriod,\n      timeout: timeout === Infinity ? 'Infinity' : timeout,\n      praxis,\n      beta1,\n      beta2,\n      epsilon,\n    };\n  }\n\n  setLogMethod(log: boolean | ((state: INeuralNetworkState) => void)): void {\n    if (typeof log === 'function') {\n      this.trainOpts.log = log;\n    } else if (log) {\n      this.trainOpts.log = this.logTrainingStatus;\n    } else {\n      this.trainOpts.log = false;\n    }\n  }\n\n  logTrainingStatus(status: INeuralNetworkState): void {\n    console.log(\n      `iterations: ${status.iterations}, training error: ${status.error}`\n    );\n  }\n\n  calculateTrainingError(\n    data: Array<INeuralNetworkDatumFormatted<Float32Array>>\n  ): number {\n    let sum = 0;\n    for (let i = 0; i < data.length; ++i) {\n      sum += this.trainPattern(data[i], true) as number;\n    }\n    return sum / data.length;\n  }\n\n  trainPatterns(data: Array<INeuralNetworkDatumFormatted<Float32Array>>): void {\n    for (let i = 0; i < data.length; ++i) {\n      this.trainPattern(data[i]);\n    }\n  }\n\n  trainingTick(\n    data: Array<INeuralNetworkDatumFormatted<Float32Array>>,\n    status: INeuralNetworkState,\n    endTime: number\n  ): boolean {\n    const {\n      callback,\n      callbackPeriod,\n      errorThresh,\n      iterations,\n      log,\n      logPeriod,\n    } = this.trainOpts;\n\n    if (\n      status.iterations >= iterations ||\n      status.error <= errorThresh ||\n      Date.now() >= endTime\n    ) {\n      return false;\n    }\n\n    status.iterations++;\n\n    if (log && status.iterations % logPeriod === 0) {\n      status.error = this.calculateTrainingError(data);\n      (log as (state: INeuralNetworkState) => void)(status);\n    } else if (status.iterations % this.errorCheckInterval === 0) {\n      status.error = this.calculateTrainingError(data);\n    } else {\n      this.trainPatterns(data);\n    }\n\n    if (callback && status.iterations % callbackPeriod === 0) {\n      callback({\n        iterations: status.iterations,\n        error: status.error,\n      });\n    }\n    return true;\n  }\n\n  prepTraining(\n    data: Array<INeuralNetworkDatum<InputType, OutputType>>,\n    options: Partial<INeuralNetworkTrainOptions> = {}\n  ): INeuralNetworkPreppedTrainingData<Float32Array> {\n    this.updateTrainingOptions(options);\n    const preparedData = this.formatData(data);\n    const endTime = Date.now() + this.trainOpts.timeout;\n\n    const status = {\n      error: 1,\n      iterations: 0,\n    };\n\n    this.verifyIsInitialized(preparedData);\n    this.validateData(preparedData);\n    return {\n      preparedData,\n      status,\n      endTime,\n    };\n  }\n\n  train(\n    data: Array<INeuralNetworkDatum<Partial<InputType>, Partial<OutputType>>>,\n    options: Partial<INeuralNetworkTrainOptions> = {}\n  ): INeuralNetworkState {\n    const { preparedData, status, endTime } = this.prepTraining(\n      data as Array<INeuralNetworkDatum<InputType, OutputType>>,\n      options\n    );\n\n    while (true) {\n      if (!this.trainingTick(preparedData, status, endTime)) {\n        break;\n      }\n    }\n    return status;\n  }\n\n  async trainAsync(\n    data: Array<INeuralNetworkDatum<InputType, OutputType>>,\n    options: Partial<INeuralNetworkTrainOptions> = {}\n  ): Promise<ITrainingStatus> {\n    const { preparedData, status, endTime } = this.prepTraining(data, options);\n\n    return await new Promise((resolve, reject) => {\n      try {\n        const thawedTrain: Thaw = new Thaw(\n          new Array(this.trainOpts.iterations),\n          {\n            delay: true,\n            each: () =>\n              this.trainingTick(preparedData, status, endTime) ||\n              thawedTrain.stop(),\n            done: () => resolve(status),\n          }\n        );\n        thawedTrain.tick();\n      } catch (trainError) {\n        reject(trainError);\n      }\n    });\n  }\n\n  trainPattern(\n    value: INeuralNetworkDatumFormatted<Float32Array>,\n    logErrorRate?: boolean\n  ): number | null {\n    // forward propagate\n    this.runInput(value.input);\n\n    // back propagate\n    this.calculateDeltas(value.output);\n    this.adjustWeights();\n\n    if (logErrorRate) {\n      return mse(this.errors[this.outputLayer]);\n    }\n    return null;\n  }\n\n  _calculateDeltasSigmoid(target: Float32Array): void {\n    for (let layer = this.outputLayer; layer >= 0; layer--) {\n      const activeSize = this.sizes[layer];\n      const activeOutput = this.outputs[layer];\n      const activeError = this.errors[layer];\n      const activeDeltas = this.deltas[layer];\n      const nextLayer = this.weights[layer + 1];\n\n      for (let node = 0; node < activeSize; node++) {\n        const output = activeOutput[node];\n\n        let error = 0;\n        if (layer === this.outputLayer) {\n          error = target[node] - output;\n        } else {\n          const deltas = this.deltas[layer + 1];\n          for (let k = 0; k < deltas.length; k++) {\n            error += deltas[k] * nextLayer[k][node];\n          }\n        }\n        activeError[node] = error;\n        activeDeltas[node] = error * output * (1 - output);\n      }\n    }\n  }\n\n  _calculateDeltasRelu(target: Float32Array): void {\n    for (let layer = this.outputLayer; layer >= 0; layer--) {\n      const currentSize = this.sizes[layer];\n      const currentOutputs = this.outputs[layer];\n      const nextWeights = this.weights[layer + 1];\n      const nextDeltas = this.deltas[layer + 1];\n      const currentErrors = this.errors[layer];\n      const currentDeltas = this.deltas[layer];\n\n      for (let node = 0; node < currentSize; node++) {\n        const output = currentOutputs[node];\n\n        let error = 0;\n        if (layer === this.outputLayer) {\n          error = target[node] - output;\n        } else {\n          for (let k = 0; k < nextDeltas.length; k++) {\n            error += nextDeltas[k] * nextWeights[k][node];\n          }\n        }\n        currentErrors[node] = error;\n        currentDeltas[node] = output > 0 ? error : 0;\n      }\n    }\n  }\n\n  _calculateDeltasLeakyRelu(target: Float32Array): void {\n    const alpha = this.trainOpts.leakyReluAlpha;\n    for (let layer = this.outputLayer; layer >= 0; layer--) {\n      const currentSize = this.sizes[layer];\n      const currentOutputs = this.outputs[layer];\n      const nextDeltas = this.deltas[layer + 1];\n      const nextWeights = this.weights[layer + 1];\n      const currentErrors = this.errors[layer];\n      const currentDeltas = this.deltas[layer];\n\n      for (let node = 0; node < currentSize; node++) {\n        const output = currentOutputs[node];\n\n        let error = 0;\n        if (layer === this.outputLayer) {\n          error = target[node] - output;\n        } else {\n          for (let k = 0; k < nextDeltas.length; k++) {\n            error += nextDeltas[k] * nextWeights[k][node];\n          }\n        }\n        currentErrors[node] = error;\n        currentDeltas[node] = output > 0 ? error : alpha * error;\n      }\n    }\n  }\n\n  _calculateDeltasTanh(target: Float32Array): void {\n    for (let layer = this.outputLayer; layer >= 0; layer--) {\n      const currentSize = this.sizes[layer];\n      const currentOutputs = this.outputs[layer];\n      const nextDeltas = this.deltas[layer + 1];\n      const nextWeights = this.weights[layer + 1];\n      const currentErrors = this.errors[layer];\n      const currentDeltas = this.deltas[layer];\n\n      for (let node = 0; node < currentSize; node++) {\n        const output = currentOutputs[node];\n\n        let error = 0;\n        if (layer === this.outputLayer) {\n          error = target[node] - output;\n        } else {\n          for (let k = 0; k < nextDeltas.length; k++) {\n            error += nextDeltas[k] * nextWeights[k][node];\n          }\n        }\n        currentErrors[node] = error;\n        currentDeltas[node] = (1 - output * output) * error;\n      }\n    }\n  }\n\n  /**\n   *\n   * Changes weights of networks\n   */\n  adjustWeights(): void {\n    const { learningRate, momentum } = this.trainOpts;\n    for (let layer = 1; layer <= this.outputLayer; layer++) {\n      const incoming = this.outputs[layer - 1];\n      const activeSize = this.sizes[layer];\n      const activeDelta = this.deltas[layer];\n      const activeChanges = this.changes[layer];\n      const activeWeights = this.weights[layer];\n      const activeBiases = this.biases[layer];\n\n      for (let node = 0; node < activeSize; node++) {\n        const delta = activeDelta[node];\n\n        for (let k = 0; k < incoming.length; k++) {\n          let change = activeChanges[node][k];\n\n          change = learningRate * delta * incoming[k] + momentum * change;\n\n          activeChanges[node][k] = change;\n          activeWeights[node][k] += change;\n        }\n        activeBiases[node] += learningRate * delta;\n      }\n    }\n  }\n\n  _setupAdam(): void {\n    this.biasChangesLow = [];\n    this.biasChangesHigh = [];\n    this.changesLow = [];\n    this.changesHigh = [];\n    this.iterations = 0;\n\n    for (let layer = 0; layer <= this.outputLayer; layer++) {\n      const size = this.sizes[layer];\n      if (layer > 0) {\n        this.biasChangesLow[layer] = zeros(size);\n        this.biasChangesHigh[layer] = zeros(size);\n        this.changesLow[layer] = new Array(size);\n        this.changesHigh[layer] = new Array(size);\n\n        for (let node = 0; node < size; node++) {\n          const prevSize = this.sizes[layer - 1];\n          this.changesLow[layer][node] = zeros(prevSize);\n          this.changesHigh[layer][node] = zeros(prevSize);\n        }\n      }\n    }\n\n    this.adjustWeights = this._adjustWeightsAdam;\n  }\n\n  _adjustWeightsAdam(): void {\n    this.iterations++;\n\n    const { iterations } = this;\n    const { beta1, beta2, epsilon, learningRate } = this.trainOpts;\n\n    for (let layer = 1; layer <= this.outputLayer; layer++) {\n      const incoming = this.outputs[layer - 1];\n      const currentSize = this.sizes[layer];\n      const currentDeltas = this.deltas[layer];\n      const currentChangesLow = this.changesLow[layer];\n      const currentChangesHigh = this.changesHigh[layer];\n      const currentWeights = this.weights[layer];\n      const currentBiases = this.biases[layer];\n      const currentBiasChangesLow = this.biasChangesLow[layer];\n      const currentBiasChangesHigh = this.biasChangesHigh[layer];\n\n      for (let node = 0; node < currentSize; node++) {\n        const delta = currentDeltas[node];\n\n        for (let k = 0; k < incoming.length; k++) {\n          const gradient = delta * incoming[k];\n          const changeLow =\n            currentChangesLow[node][k] * beta1 + (1 - beta1) * gradient;\n          const changeHigh =\n            currentChangesHigh[node][k] * beta2 +\n            (1 - beta2) * gradient * gradient;\n\n          const momentumCorrection =\n            changeLow / (1 - Math.pow(beta1, iterations));\n          const gradientCorrection =\n            changeHigh / (1 - Math.pow(beta2, iterations));\n\n          currentChangesLow[node][k] = changeLow;\n          currentChangesHigh[node][k] = changeHigh;\n          currentWeights[node][k] +=\n            (learningRate * momentumCorrection) /\n            (Math.sqrt(gradientCorrection) + epsilon);\n        }\n\n        const biasGradient = currentDeltas[node];\n        const biasChangeLow =\n          currentBiasChangesLow[node] * beta1 + (1 - beta1) * biasGradient;\n        const biasChangeHigh =\n          currentBiasChangesHigh[node] * beta2 +\n          (1 - beta2) * biasGradient * biasGradient;\n\n        const biasMomentumCorrection =\n          currentBiasChangesLow[node] / (1 - Math.pow(beta1, iterations));\n        const biasGradientCorrection =\n          currentBiasChangesHigh[node] / (1 - Math.pow(beta2, iterations));\n\n        currentBiasChangesLow[node] = biasChangeLow;\n        currentBiasChangesHigh[node] = biasChangeHigh;\n        currentBiases[node] +=\n          (learningRate * biasMomentumCorrection) /\n          (Math.sqrt(biasGradientCorrection) + epsilon);\n      }\n    }\n  }\n\n  validateData(data: Array<INeuralNetworkDatumFormatted<Float32Array>>): void {\n    const inputSize = this.sizes[0];\n    const outputSize = this.sizes[this.sizes.length - 1];\n    const { length } = data;\n    for (let i = 0; i < length; i++) {\n      const { input, output } = data[i];\n      if (input.length !== inputSize) {\n        throw new Error(\n          `input at index ${i} length ${input.length} must be ${inputSize}`\n        );\n      }\n      if (data[i].output.length !== outputSize) {\n        throw new Error(\n          `output at index ${i} length ${output.length} must be ${outputSize}`\n        );\n      }\n    }\n  }\n\n  validateInput(formattedInput: Float32Array): void {\n    const inputSize = this.sizes[0];\n    if (formattedInput.length !== inputSize) {\n      throw new Error(\n        `input length ${formattedInput.length} must match options.inputSize of ${inputSize}`\n      );\n    }\n  }\n\n  formatData(\n    data: Array<INeuralNetworkDatum<InputType, OutputType>>\n  ): Array<INeuralNetworkDatumFormatted<Float32Array>> {\n    if (!Array.isArray(data[0].input)) {\n      if (this.inputLookup) {\n        this.inputLookupLength = Object.keys(this.inputLookup).length;\n      } else {\n        const inputLookup = new LookupTable(data, 'input');\n        this.inputLookup = inputLookup.table;\n        this.inputLookupLength = inputLookup.length;\n      }\n    }\n\n    if (!Array.isArray(data[0].output)) {\n      if (this.outputLookup) {\n        this.outputLookupLength = Object.keys(this.outputLookup).length;\n      } else {\n        const lookup = new LookupTable(data, 'output');\n        this.outputLookup = lookup.table;\n        this.outputLookupLength = lookup.length;\n      }\n    }\n\n    if (!this._formatInput) {\n      this._formatInput = getTypedArrayFn(data[0].input, this.inputLookup);\n    }\n\n    if (!this._formatOutput) {\n      this._formatOutput = getTypedArrayFn(data[0].output, this.outputLookup);\n    }\n\n    // turn sparse hash input into arrays with 0s as filler\n    if (this._formatInput && this._formatOutput) {\n      const result: Array<INeuralNetworkDatumFormatted<Float32Array>> = [];\n      for (let i = 0; i < data.length; i++) {\n        result.push({\n          input: (this._formatInput as (v: INumberHash) => Float32Array)(\n            (data[i].input as unknown) as INumberHash\n          ),\n          output: (this._formatOutput as (v: INumberHash) => Float32Array)(\n            (data[i].output as unknown) as INumberHash\n          ),\n        });\n      }\n      return result;\n    }\n    if (this._formatInput) {\n      const result: Array<INeuralNetworkDatumFormatted<Float32Array>> = [];\n      for (let i = 0; i < data.length; i++) {\n        result.push({\n          input: (this._formatInput as (v: INumberHash) => Float32Array)(\n            (data[i].input as unknown) as INumberHash\n          ),\n          output: (data[i].output as unknown) as Float32Array,\n        });\n      }\n      return result;\n    }\n    if (this._formatOutput) {\n      const result: Array<INeuralNetworkDatumFormatted<Float32Array>> = [];\n      for (let i = 0; i < data.length; i++) {\n        result.push({\n          input: (data[i].input as unknown) as Float32Array,\n          output: (this._formatOutput as (v: INumberHash) => Float32Array)(\n            (data[i].output as unknown) as INumberHash\n          ),\n        });\n      }\n      return result;\n    }\n    return (data as unknown) as Array<\n      INeuralNetworkDatumFormatted<Float32Array>\n    >;\n  }\n\n  addFormat(data: INeuralNetworkDatum<InputType, OutputType>): void {\n    if (!Array.isArray(data.input) || typeof data.input[0] !== 'number') {\n      this.inputLookup = lookup.addKeys(\n        (data.input as unknown) as INumberHash,\n        this.inputLookup ?? {}\n      );\n      if (this.inputLookup) {\n        this.inputLookupLength = Object.keys(this.inputLookup).length;\n      }\n    }\n    if (!Array.isArray(data.output) || typeof data.output[0] !== 'number') {\n      this.outputLookup = lookup.addKeys(\n        (data.output as unknown) as INumberHash,\n        this.outputLookup ?? {}\n      );\n      if (this.outputLookup) {\n        this.outputLookupLength = Object.keys(this.outputLookup).length;\n      }\n    }\n  }\n\n  test(\n    data: Array<INeuralNetworkDatum<Partial<InputType>, Partial<OutputType>>>\n  ): INeuralNetworkTestResult | INeuralNetworkBinaryTestResult {\n    const { preparedData } = this.prepTraining(\n      data as Array<INeuralNetworkDatum<InputType, OutputType>>\n    );\n    // for binary classification problems with one output node\n    const isBinary = preparedData[0].output.length === 1;\n    // for classification problems\n    const misclasses = [];\n    // run each pattern through the trained network and collect\n    // error and misclassification statistics\n    let errorSum = 0;\n    if (isBinary) {\n      let falsePos = 0;\n      let falseNeg = 0;\n      let truePos = 0;\n      let trueNeg = 0;\n\n      for (let i = 0; i < preparedData.length; i++) {\n        const output = this.runInput(preparedData[i].input);\n        const target = preparedData[i].output;\n        const actual = output[0] > this.options.binaryThresh ? 1 : 0;\n        const expected = target[0];\n\n        if (actual !== expected) {\n          const misclass = preparedData[i];\n          misclasses.push({\n            input: misclass.input,\n            output: misclass.output,\n            actual,\n            expected,\n          });\n        }\n\n        if (actual === 0 && expected === 0) {\n          trueNeg++;\n        } else if (actual === 1 && expected === 1) {\n          truePos++;\n        } else if (actual === 0 && expected === 1) {\n          falseNeg++;\n        } else if (actual === 1 && expected === 0) {\n          falsePos++;\n        }\n\n        errorSum += mse(\n          output.map((value, i) => {\n            return target[i] - value;\n          })\n        );\n      }\n\n      return {\n        error: errorSum / preparedData.length,\n        misclasses,\n        total: preparedData.length,\n        trueNeg,\n        truePos,\n        falseNeg,\n        falsePos,\n        precision: truePos > 0 ? truePos / (truePos + falsePos) : 0,\n        recall: truePos > 0 ? truePos / (truePos + falseNeg) : 0,\n        accuracy: (trueNeg + truePos) / preparedData.length,\n      };\n    }\n\n    for (let i = 0; i < preparedData.length; i++) {\n      const output = this.runInput(preparedData[i].input);\n      const target = preparedData[i].output;\n      const actual = output.indexOf(max(output));\n      const expected = target.indexOf(max(target));\n\n      if (actual !== expected) {\n        const misclass = preparedData[i];\n        misclasses.push({\n          input: misclass.input,\n          output: misclass.output,\n          actual,\n          expected,\n        });\n      }\n\n      errorSum += mse(\n        output.map((value, i) => {\n          return target[i] - value;\n        })\n      );\n    }\n    return {\n      error: errorSum / preparedData.length,\n      misclasses,\n      total: preparedData.length,\n    };\n  }\n\n  toJSON(): INeuralNetworkJSON {\n    if (!this.isRunnable) {\n      this.initialize();\n    }\n    // use Array.from, keeping json small\n    const jsonLayerWeights = this.weights.map((layerWeights) => {\n      return layerWeights.map((layerWeights) => Array.from(layerWeights));\n    });\n    const jsonLayerBiases = this.biases.map((layerBiases) =>\n      Array.from(layerBiases)\n    );\n    const jsonLayers: IJSONLayer[] = [];\n    const outputLength = this.sizes.length - 1;\n    for (let i = 0; i <= outputLength; i++) {\n      jsonLayers.push({\n        weights: jsonLayerWeights[i] ?? [],\n        biases: jsonLayerBiases[i] ?? [],\n      });\n    }\n    return {\n      type: 'NeuralNetwork',\n      sizes: [...this.sizes],\n      layers: jsonLayers,\n      inputLookup: this.inputLookup ? { ...this.inputLookup } : null,\n      inputLookupLength: this.inputLookupLength,\n      outputLookup: this.outputLookup ? { ...this.outputLookup } : null,\n      outputLookupLength: this.outputLookupLength,\n      options: { ...this.options },\n      trainOpts: this.getTrainOptsJSON(),\n    };\n  }\n\n  fromJSON(json: INeuralNetworkJSON): this {\n    this.options = { ...defaults(), ...json.options };\n    if (json.hasOwnProperty('trainOpts')) {\n      const trainOpts = {\n        ...json.trainOpts,\n        timeout:\n          json.trainOpts.timeout === 'Infinity'\n            ? Infinity\n            : json.trainOpts.timeout,\n      };\n      this.updateTrainingOptions(trainOpts);\n    }\n    this.sizes = json.sizes;\n    this.initialize();\n\n    this.inputLookup = json.inputLookup ? { ...json.inputLookup } : null;\n    this.inputLookupLength = json.inputLookupLength;\n    this.outputLookup = json.outputLookup ? { ...json.outputLookup } : null;\n    this.outputLookupLength = json.outputLookupLength;\n\n    const jsonLayers = json.layers;\n    const layerWeights = this.weights.map((layerWeights, layerIndex) => {\n      return jsonLayers[layerIndex].weights.map((layerWeights) =>\n        Float32Array.from(layerWeights)\n      );\n    });\n    const layerBiases = this.biases.map((layerBiases, layerIndex) =>\n      Float32Array.from(jsonLayers[layerIndex].biases)\n    );\n    for (let i = 0; i <= this.outputLayer; i++) {\n      this.weights[i] = layerWeights[i] || [];\n      this.biases[i] = layerBiases[i] || [];\n    }\n    return this;\n  }\n\n  toFunction(\n    cb?: (source: string) => string\n  ): (input: Partial<InputType>) => OutputType {\n    const { activation, leakyReluAlpha } = this.trainOpts;\n    let needsVar = false;\n    const nodeHandle = (layerIndex: number, nodeIndex: number): string => {\n      if (layerIndex === 0) {\n        return `(input[${nodeIndex}]||0)`;\n      }\n\n      const weights: Float32Array = this.weights[layerIndex][nodeIndex];\n      const bias: number = this.biases[layerIndex][nodeIndex];\n      if (!weights) {\n        throw new Error(\n          `weights at layerIndex ${layerIndex} & nodeIndex ${nodeIndex} not found`\n        );\n      }\n      if (!bias) {\n        throw new Error(\n          `bias as layerIndex ${layerIndex} & nodeIndex ${nodeIndex} not found`\n        );\n      }\n      const weightsArray: string[] = [];\n      weights.forEach((weight: number, subNodeIndex: number): void => {\n        if (weight < 0) {\n          weightsArray.push(\n            `${weight}*${nodeHandle(layerIndex - 1, subNodeIndex)}`\n          );\n        } else {\n          weightsArray.push(\n            `+${weight}*${nodeHandle(layerIndex - 1, subNodeIndex)}`\n          );\n        }\n      });\n      const result = `(${bias.toString()}${weightsArray.join('')})`;\n\n      switch (activation) {\n        case 'sigmoid':\n          return `1/(1+1/Math.exp(${result}))`;\n        case 'relu': {\n          needsVar = true;\n          return `((v=${result})<0?0:v)`;\n        }\n        case 'leaky-relu': {\n          needsVar = true;\n          return `Math.max((v=${result}),${leakyReluAlpha}*v)`;\n        }\n        case 'tanh':\n          return `Math.tanh(${result})`;\n        default:\n          throw new Error(\n            `Unknown activation ${activation}. Available activations are: 'sigmoid', 'relu', 'leaky-relu', 'tanh'`\n          );\n      }\n    };\n\n    function checkKeys(keys: string[]): void {\n      if (keys.find((v) => v.includes('\"'))) {\n        throw new Error(`key contains '\"', which is not compatible`);\n      }\n    }\n\n    const layersAsMath: string[] = [];\n    let result: string;\n\n    let inputLookup = '';\n    if (this.inputLookup) {\n      const keys = Object.keys(this.inputLookup);\n      checkKeys(keys);\n      inputLookup = `input = new Float32Array([${Object.keys(this.inputLookup)\n        .map((key) => `input[\"${key}\"]`)\n        .join(',')}]);`;\n    }\n    if (this.sizes.length < 1) throw new Error('No layers');\n    for (\n      let nodeIndex = 0;\n      nodeIndex < this.sizes[this.outputLayer];\n      nodeIndex++\n    ) {\n      layersAsMath.push(nodeHandle(this.outputLayer, nodeIndex));\n    }\n    if (this.outputLookup) {\n      const keys = Object.keys(this.outputLookup);\n      checkKeys(keys);\n      const values = keys\n        .map((key, i) => `\"${key}\":${layersAsMath[i]}`)\n        .join(',');\n      result = `{${values}}`;\n    } else {\n      result = `[${layersAsMath.join(',')}]`;\n    }\n\n    const source = `${inputLookup}${needsVar ? 'var v;' : ''}return ${result};`;\n    // eslint-disable-next-line @typescript-eslint/no-implied-eval,no-new-func\n    return new Function('input', cb ? cb(source) : source) as (\n      input: Partial<InputType>\n    ) => OutputType;\n  }\n}\n","import {\n  alias,\n  GPU,\n  GPUFunction,\n  IKernelFunctionThis,\n  IKernelMapRunShortcut,\n  IMappedKernelResult,\n  KernelOutput,\n  Texture,\n  utils,\n} from 'gpu.js';\nimport { ITrainingStatus } from './feed-forward';\nimport { INumberHash, lookup } from './lookup';\nimport {\n  IJSONLayer,\n  INeuralNetworkDatum,\n  INeuralNetworkJSON,\n  INeuralNetworkOptions,\n  INeuralNetworkPreppedTrainingData,\n  INeuralNetworkTrainOptions,\n  NeuralNetwork,\n} from './neural-network';\nimport { release } from './utilities/kernel';\n\nexport interface INeuralNetworkGPUDatumFormatted {\n  input: KernelOutput;\n  output: KernelOutput;\n}\n\nexport interface INeuralNetworkGPUPreppedTrainingData\n  extends INeuralNetworkPreppedTrainingData<KernelOutput> {\n  status: ITrainingStatus;\n  endTime: number;\n}\n\ninterface ISizedKernelThis extends IKernelFunctionThis {\n  constants: {\n    size: number;\n  };\n}\n\nfunction weightedSumSigmoid(\n  this: ISizedKernelThis,\n  weights: number[][],\n  biases: number[],\n  inputs: number[]\n): number {\n  let sum = biases[this.thread.x];\n  for (let k = 0; k < this.constants.size; k++) {\n    sum += weights[this.thread.x][k] * inputs[k];\n  }\n  // sigmoid\n  return 1 / (1 + Math.exp(-sum));\n}\n\nfunction weightedSumRelu(\n  this: ISizedKernelThis,\n  weights: number[][],\n  biases: number[],\n  inputs: number[]\n): number {\n  let sum = biases[this.thread.x];\n  for (let k = 0; k < this.constants.size; k++) {\n    sum += weights[this.thread.x][k] * inputs[k];\n  }\n  // relu\n  return sum < 0 ? 0 : sum;\n}\n\nfunction weightedSumLeakyRelu(\n  this: ISizedKernelThis,\n  weights: number[][],\n  biases: number[],\n  inputs: number[]\n): number {\n  let sum = biases[this.thread.x];\n  for (let k = 0; k < this.constants.size; k++) {\n    sum += weights[this.thread.x][k] * inputs[k];\n  }\n  // leaky relu\n  return sum < 0 ? 0 : 0.01 * sum;\n}\n\nfunction weightedSumTanh(\n  this: ISizedKernelThis,\n  weights: number[][],\n  biases: number[],\n  inputs: number[]\n): number {\n  let sum = biases[this.thread.x];\n  for (let k = 0; k < this.constants.size; k++) {\n    sum += weights[this.thread.x][k] * inputs[k];\n  }\n  // tanh\n  return Math.tanh(sum);\n}\n\nfunction calcErrorOutput(output: number, target: number): number {\n  return target - output;\n}\n\nfunction calcDeltasSigmoid(error: number, output: number): number {\n  // sigmoid derivative\n  return error * output * (1 - output);\n}\n\nfunction calcDeltasRelu(error: number, output: number): number {\n  // relu derivative\n  return output > 0 ? error : 0;\n}\n\nfunction calcDeltasLeakyRelu(error: number, output: number): number {\n  // leaky relu derivative\n  return output > 0 ? error : 0.01 * error;\n}\n\nfunction calcDeltasTanh(error: number, output: number): number {\n  // tanh derivative\n  return (1 - output * output) * error;\n}\n\nfunction calcError(\n  x: number,\n  size: number,\n  nextWeights: number[][],\n  nextDeltas: number[]\n): number {\n  let error = 0;\n  for (let k = 0; k < size; k++) {\n    error += nextDeltas[k] * nextWeights[k][x];\n  }\n  return error;\n}\n\ninterface ILearningKernelThis extends IKernelFunctionThis {\n  constants: {\n    momentum: number;\n    learningRate: number;\n  };\n}\n\nfunction calcChanges(\n  learningRate: number,\n  momentum: number,\n  previousChange: number,\n  delta: number,\n  previousOutput: number\n): number {\n  return learningRate * delta * previousOutput + momentum * previousChange;\n}\n\nfunction addWeights(change: number, weight: number): number {\n  return change + weight;\n}\n\nfunction addBiases(\n  this: ILearningKernelThis,\n  biases: number[],\n  deltas: number[]\n): number {\n  return (\n    biases[this.thread.x] + deltas[this.thread.x] * this.constants.learningRate\n  );\n}\n\n// mean squared error, reimplemented for GPU\nfunction mse(this: ISizedKernelThis, errors: number[]): number {\n  let sum = 0;\n  for (let i = 0; i < this.constants.size; i++) {\n    sum += errors[i] ** 2;\n  }\n  return sum / this.constants.size;\n}\n\nexport interface INeuralNetworkGPUOptions extends INeuralNetworkOptions {\n  mode?: 'cpu' | 'gpu';\n}\n\nexport type BackPropagateOutput = (\n  this: IKernelFunctionThis,\n  outputs: KernelOutput,\n  targets: KernelOutput\n) => { result: KernelOutput; error: KernelOutput };\n\nexport type BackPropagateLayer = (\n  this: IKernelFunctionThis,\n  weights: KernelOutput,\n  outputs: KernelOutput,\n  deltas: KernelOutput\n) => { result: KernelOutput; error: KernelOutput };\n\nexport class NeuralNetworkGPU<InputType, OutputType> extends NeuralNetwork<\n  InputType,\n  OutputType\n> {\n  gpu: GPU;\n\n  texturizeInputData: (value: KernelOutput) => KernelOutput = () => {\n    throw new Error('not yet setup');\n  };\n\n  forwardPropagate: Array<\n    (\n      weights: KernelOutput,\n      biases: KernelOutput,\n      inputs: KernelOutput\n    ) => KernelOutput\n  > = [];\n\n  backwardPropagate: Array<BackPropagateOutput | BackPropagateLayer> = [];\n\n  changesPropagate: Array<\n    ((\n      this: IKernelFunctionThis<{\n        size: number;\n        learningRate: number;\n        momentum: number;\n      }>,\n      previousOutputs: number[],\n      deltas: number[],\n      weights: number[][],\n      previousChanges: number[][]\n    ) => IMappedKernelResult) &\n      IKernelMapRunShortcut<{ weights: number[][]; changes: number[][] }>\n  > = [];\n\n  biasesPropagate: Array<\n    (biases: KernelOutput, deltas: KernelOutput) => KernelOutput\n  > = [];\n\n  getMSE: (error: KernelOutput) => KernelOutput = () => {\n    throw new Error('not yet setup');\n  };\n\n  _addMSE: (sum: KernelOutput, error: KernelOutput) => KernelOutput = () => {\n    throw new Error('not yet setup');\n  };\n\n  _divideMSESum: (length: number, sum: KernelOutput) => KernelOutput = () => {\n    throw new Error('not yet setup');\n  };\n\n  // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n  // @ts-expect-error\n  outputs: KernelOutput[] = [];\n  // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n  // @ts-expect-error\n  deltas: KernelOutput[] = [];\n  // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n  // @ts-expect-error\n  errors: KernelOutput[] = [];\n  // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n  // @ts-expect-error\n  weights: KernelOutput[] = [];\n  // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n  // @ts-expect-error\n  changes: KernelOutput[] = [];\n  // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n  // @ts-expect-error\n  biases: KernelOutput[] = [];\n\n  constructor(options: Partial<INeuralNetworkGPUOptions> = {}) {\n    super(options);\n    this.errorCheckInterval = 100;\n    this.gpu = new GPU({ mode: options.mode });\n  }\n\n  initialize(): void {\n    super.initialize();\n    this.buildRunInput();\n    this.buildCalculateDeltas();\n    this.buildGetChanges();\n    this.buildChangeBiases();\n    this.buildGetMSE();\n  }\n\n  setActivation(): void {}\n\n  // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n  // @ts-expect-error\n  trainPattern(\n    value: INeuralNetworkGPUDatumFormatted,\n    logErrorRate?: boolean\n  ): KernelOutput | null {\n    // forward propagate\n    this.runInput(value.input);\n\n    // back propagate\n    this.calculateDeltas(value.output);\n    this.adjustWeights();\n\n    if (logErrorRate) {\n      return this.getMSE(this.errors[this.outputLayer]);\n    }\n    return null;\n  }\n\n  calculateTrainingError(data: INeuralNetworkGPUDatumFormatted[]): number {\n    let sum = new Float32Array([0]) as KernelOutput;\n    for (let i = 0; i < data.length; ++i) {\n      const prevSum = sum;\n      const error = this.trainPattern(data[i], true) as KernelOutput;\n      sum = this._addMSE(sum, error);\n      release(error);\n      release(prevSum);\n    }\n    const result = this._divideMSESum(data.length, sum);\n    release(sum);\n    return (result instanceof Texture\n      ? (result.toArray() as number[])\n      : (result as number[]))[0];\n  }\n\n  adjustWeights(): void {\n    this.getChanges();\n    this.changeBiases();\n  }\n\n  buildRunInput(): void {\n    let weightedSum = null;\n\n    switch (this.trainOpts.activation) {\n      case 'sigmoid':\n        weightedSum = weightedSumSigmoid;\n        break;\n      case 'relu':\n        weightedSum = weightedSumRelu;\n        break;\n      case 'leaky-relu':\n        weightedSum = weightedSumLeakyRelu;\n        break;\n      case 'tanh':\n        weightedSum = weightedSumTanh;\n        break;\n      default:\n        throw new Error(\n          `Unknown activation ${this.trainOpts.activation}. Available activations are: 'sigmoid', 'relu', 'leaky-relu', 'tanh'`\n        );\n    }\n\n    for (let layer = 1; layer <= this.outputLayer; layer++) {\n      this.forwardPropagate[layer] = this.gpu.createKernel(weightedSum, {\n        output: [this.sizes[layer]],\n        pipeline: true,\n        constants: {\n          size: this.sizes[layer - 1],\n        },\n        immutable: true,\n      });\n    }\n\n    this.texturizeInputData = this.gpu.createKernel(\n      function (value: number[]): number {\n        return value[this.thread.x];\n      },\n      {\n        output: [this.sizes[1]],\n        pipeline: true,\n        immutable: true,\n      }\n    );\n  }\n\n  // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n  // @ts-expect-error\n  runInput = (input: KernelOutput): KernelOutput => {\n    let output;\n    this.outputs[0] = input;\n    for (let layer = 1; layer <= this.outputLayer; layer++) {\n      release(this.outputs[layer]);\n      this.outputs[layer] = this.forwardPropagate[layer](\n        this.weights[layer],\n        this.biases[layer],\n        input\n      );\n      output = input = this.outputs[layer];\n    }\n    return output;\n  };\n\n  buildCalculateDeltas(): void {\n    let calcDeltas: GPUFunction<[number, number]>;\n    switch (this.trainOpts.activation) {\n      case 'sigmoid':\n        calcDeltas = calcDeltasSigmoid;\n        break;\n      case 'relu':\n        calcDeltas = calcDeltasRelu;\n        break;\n      case 'leaky-relu':\n        calcDeltas = calcDeltasLeakyRelu;\n        break;\n      case 'tanh':\n        calcDeltas = calcDeltasTanh;\n        break;\n      default:\n        throw new Error(\n          `Unknown activation ${this.trainOpts.activation}. Available activations are: 'sigmoid', 'relu', 'leaky-relu', 'tanh'`\n        );\n    }\n\n    calcDeltas = alias(\n      utils.getMinifySafeName(() => calcDeltas),\n      calcDeltas\n    );\n    this.gpu.addFunction(calcDeltas);\n    for (let layer = this.outputLayer; layer > 0; layer--) {\n      if (layer === this.outputLayer) {\n        // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n        // @ts-expect-error\n        this.backwardPropagate[this.outputLayer] = this.gpu.createKernelMap(\n          {\n            error: calcErrorOutput,\n          },\n          function (\n            this: IKernelFunctionThis,\n            outputs: number[],\n            targets: number[]\n          ): number {\n            const output = outputs[this.thread.x];\n            const target = targets[this.thread.x];\n            // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n            // @ts-expect-error\n            return calcDeltas(calcErrorOutput(output, target), output);\n          },\n          {\n            output: [this.sizes[this.outputLayer]],\n            pipeline: true,\n            immutable: true,\n          }\n        );\n      } else {\n        // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n        // @ts-expect-error\n        this.backwardPropagate[layer] = this.gpu.createKernelMap(\n          {\n            error: calcError,\n          },\n          function (\n            this: ISizedKernelThis,\n            nextWeights: number[][],\n            outputs: number[],\n            nextDeltas: number[]\n          ): number {\n            const output = outputs[this.thread.x];\n            // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n            // @ts-expect-error\n            return calcDeltas(\n              calcError(\n                this.thread.x,\n                this.constants.size,\n                nextWeights,\n                nextDeltas\n              ),\n              output\n            );\n          },\n          {\n            output: [this.sizes[layer]],\n            pipeline: true,\n            constants: {\n              size: this.sizes[layer + 1],\n            },\n            immutable: true,\n          }\n        );\n      }\n    }\n  }\n\n  calculateDeltas = (target: KernelOutput): void => {\n    for (let layer = this.outputLayer; layer > 0; layer--) {\n      release(this.deltas[layer]);\n      release(this.errors[layer]);\n\n      let output;\n      if (layer === this.outputLayer) {\n        // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n        // @ts-expect-error\n        output = this.backwardPropagate[layer](this.outputs[layer], target);\n      } else {\n        // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n        // @ts-expect-error\n        output = this.backwardPropagate[layer](\n          this.weights[layer + 1],\n          this.outputs[layer],\n          this.deltas[layer + 1]\n        );\n      }\n      this.deltas[layer] = output.result;\n      this.errors[layer] = output.error;\n    }\n  };\n\n  buildGetChanges(): void {\n    for (let layer = 1; layer <= this.outputLayer; layer++) {\n      // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n      // @ts-expect-error\n      this.changesPropagate[layer] = this.gpu.createKernelMap(\n        {\n          weights: addWeights,\n          changes: calcChanges,\n        },\n        function (\n          this: IKernelFunctionThis<{\n            size: number;\n            learningRate: number;\n            momentum: number;\n          }>,\n          previousOutputs: number[],\n          deltas: number[],\n          weights: number[][],\n          previousChanges: number[][]\n        ) {\n          const change = calcChanges(\n            this.constants.learningRate,\n            this.constants.momentum,\n            previousChanges[this.thread.y][this.thread.x],\n            deltas[this.thread.y],\n            previousOutputs[this.thread.x]\n          );\n          return addWeights(change, weights[this.thread.y][this.thread.x]);\n        },\n        {\n          output: [this.sizes[layer - 1], this.sizes[layer]],\n          pipeline: true,\n          constants: {\n            size: this.sizes[layer - 1],\n            learningRate: this.trainOpts.learningRate,\n            momentum: this.trainOpts.momentum,\n          },\n          immutable: true,\n        }\n      );\n    }\n  }\n\n  getChanges(): void {\n    for (let layer = 1; layer <= this.outputLayer; layer++) {\n      const weights = this.weights[layer];\n      const changes = this.changes[layer];\n      const output = this.changesPropagate[layer](\n        this.outputs[layer - 1],\n        this.deltas[layer],\n        weights,\n        changes\n      );\n      release(weights);\n      release(changes);\n      this.weights[layer] = output.weights;\n      this.changes[layer] = output.changes;\n      release(output.result);\n    }\n  }\n\n  buildChangeBiases(): void {\n    for (let layer = 1; layer <= this.outputLayer; layer++) {\n      this.biasesPropagate[layer] = this.gpu.createKernel(addBiases, {\n        output: [this.sizes[layer]],\n        pipeline: true,\n        constants: {\n          learningRate: this.trainOpts.learningRate,\n        },\n        immutable: true,\n      });\n    }\n  }\n\n  changeBiases(): void {\n    for (let layer = 1; layer <= this.outputLayer; layer++) {\n      const biases = this.biases[layer];\n      this.biases[layer] = this.biasesPropagate[layer](\n        biases,\n        this.deltas[layer]\n      );\n      release(biases);\n    }\n  }\n\n  buildGetMSE(): void {\n    this.getMSE = this.gpu.createKernel(mse, {\n      output: [1],\n      constants: {\n        size: this.sizes[this.outputLayer],\n      },\n      pipeline: true,\n      immutable: true,\n    });\n    this._addMSE = this.gpu.createKernel(\n      function (value1: number[], value2: number[]): number {\n        return value1[0] + value2[0];\n      },\n      {\n        output: [1],\n        pipeline: true,\n        immutable: true,\n      }\n    );\n    this._divideMSESum = this.gpu.createKernel(\n      function (length: number, mseSum: number[]): number {\n        const value = mseSum[0];\n        if (value > 0) {\n          return value / length;\n        }\n        return 0;\n      },\n      {\n        output: [1],\n      }\n    );\n  }\n\n  run(input: InputType): OutputType {\n    if (!this.isRunnable) {\n      throw new Error('network not runnable');\n    }\n    let formattedInput: Float32Array;\n    if (this.inputLookup) {\n      formattedInput = lookup.toArray(\n        this.inputLookup,\n        (input as unknown) as INumberHash,\n        this.inputLookupLength\n      );\n    } else {\n      formattedInput = (input as unknown) as Float32Array;\n    }\n    this.validateInput(formattedInput);\n    const outputTextures = this.runInput(formattedInput);\n    const output =\n      outputTextures instanceof Texture\n        ? outputTextures.toArray()\n        : outputTextures;\n\n    if (this.outputLookup) {\n      return (lookup.toObject(\n        this.outputLookup,\n        output as Float32Array\n      ) as unknown) as OutputType;\n    }\n\n    return (output as unknown) as OutputType;\n  }\n\n  // @ts-expect-error the underlying network works as normal, but we are working on the GPU\n  prepTraining(\n    data: Array<INeuralNetworkDatum<InputType, OutputType>>,\n    options: Partial<INeuralNetworkTrainOptions> = {}\n  ): INeuralNetworkGPUPreppedTrainingData {\n    this.updateTrainingOptions(options);\n    const preparedData = this.formatData(data);\n    const endTime = Date.now() + this.trainOpts.timeout;\n\n    const status = {\n      error: 1,\n      iterations: 0,\n    };\n\n    this.verifyIsInitialized(preparedData);\n\n    const texturizeOutputData = this.gpu.createKernel(\n      function (value: number[]): number {\n        return value[this.thread.x];\n      },\n      {\n        output: [preparedData[0].output.length],\n        pipeline: true,\n        immutable: true,\n      }\n    );\n    return {\n      preparedData: preparedData.map((set) => ({\n        input: this.texturizeInputData(set.input),\n        output: texturizeOutputData(set.output),\n      })),\n      status,\n      endTime,\n    };\n  }\n\n  // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n  // @ts-expect-error\n  toFunction(): (input: InputType) => OutputType {\n    throw new Error(\n      `${this.constructor.name}-toFunction is not yet implemented`\n    );\n  }\n\n  toJSON(): INeuralNetworkJSON {\n    if (this.sizes === null) {\n      this.initialize();\n    }\n    // use Array.from, keeping json small\n    const jsonLayerWeights = this.weights.map((layerWeights) => {\n      return (layerWeights instanceof Texture\n        ? (layerWeights.toArray() as Float32Array[])\n        : (layerWeights as Float32Array[])\n      ).map((layerWeights) => Array.from(layerWeights));\n    });\n    const jsonLayerBiases = this.biases.map((layerBiases) =>\n      Array.from(\n        layerBiases instanceof Texture\n          ? (layerBiases.toArray() as Float32Array)\n          : (layerBiases as Float32Array)\n      )\n    );\n    const jsonLayers: IJSONLayer[] = [];\n    for (let i = 0; i <= this.outputLayer; i++) {\n      jsonLayers.push({\n        weights: jsonLayerWeights[i] ?? [],\n        biases: jsonLayerBiases[i] ?? [],\n      });\n    }\n    return {\n      type: 'NeuralNetworkGPU',\n      sizes: [...this.sizes],\n      layers: jsonLayers,\n      inputLookup: this.inputLookup ? { ...this.inputLookup } : null,\n      inputLookupLength: this.inputLookupLength,\n      outputLookup: this.outputLookup ? { ...this.outputLookup } : null,\n      outputLookupLength: this.outputLookupLength,\n      options: { ...this.options },\n      trainOpts: this.getTrainOptsJSON(),\n    };\n  }\n}\n","import { KernelOutput } from 'gpu.js';\n\nimport { Internal } from './internal';\nimport { release } from '../utilities/kernel';\nimport { ILayer, ILayerSettings } from './base-layer';\n\nexport class RecurrentConnection extends Internal {\n  settings: ILayerSettings = {};\n  layer: ILayer | null = null;\n  setLayer(layer: ILayer): void {\n    this.layer = layer;\n  }\n\n  get width(): number {\n    if (!this.layer) throw new Error('layer not set');\n    return this.layer.width;\n  }\n\n  set width(value: number) {\n    throw new Error(`${this.constructor.name}-width is not yet implemented`);\n  }\n\n  get height(): number {\n    if (!this.layer) throw new Error('layer not set');\n    return this.layer.height;\n  }\n\n  set height(value: number) {\n    throw new Error(`${this.constructor.name}-height is not yet implemented`);\n  }\n\n  get deltas(): KernelOutput {\n    if (!this.layer) throw new Error('layer not set');\n    return this.layer.deltas;\n  }\n\n  set deltas(deltas: KernelOutput) {\n    if (!this.layer) throw new Error('layer not set');\n    release(this.layer.deltas);\n    this.layer.deltas = deltas;\n  }\n\n  get weights(): KernelOutput {\n    if (!this.layer) throw new Error('layer not set');\n    return this.layer.weights as KernelOutput;\n  }\n\n  set weights(weights: KernelOutput) {\n    if (!this.layer) throw new Error('layer not set');\n    release(this.layer.weights);\n    this.layer.weights = weights;\n  }\n\n  predict(): void {\n    // throw new Error(`${this.constructor.name}-predict is not yet implemented`)\n  }\n\n  compare(): void {\n    // throw new Error(`${this.constructor.name}-compare is not yet implemented`)\n  }\n\n  learn(): void {\n    throw new Error('no longer using');\n  }\n\n  setupKernels(): void {\n    // throw new Error(\n    //   `${this.constructor.name}-setupKernels is not yet implemented`\n    // )\n  }\n\n  reuseKernels(): void {\n    // throw new Error(\n    //   `${this.constructor.name}-reuseKernels is not yet implemented`\n    // )\n  }\n}\n","import { RecurrentConnection } from './layer/recurrent-connection';\nimport {\n  IRecurrentInput,\n  RecurrentInput,\n  RecurrentZeros,\n  ILayer,\n  ILayerSettings,\n} from './layer';\nimport {\n  Activation,\n  EntryPoint,\n  EntryPointType,\n  Filter,\n  Internal,\n  InternalModel,\n  Model,\n  Modifier,\n  Operator,\n  Target,\n} from './layer/types';\nimport { flattenLayers } from './utilities/flatten-layers';\nimport {\n  FeedForward,\n  IFeedForwardOptions,\n  IFeedForwardTrainingOptions,\n  ITrainingStatus,\n} from './feed-forward';\nimport { release, clone } from './utilities/kernel';\nimport { KernelOutput, Texture, TextureArrayOutput } from 'gpu.js';\nimport { OperatorType } from './layer/operator';\nimport { ModifierType } from './layer/modifier';\nimport { FilterType } from './layer/filter';\nimport { ActivationType } from './layer/activation';\nimport { TargetType } from './layer/target';\n\nexport interface IRecurrentTrainingOptions\n  extends IFeedForwardTrainingOptions {}\n\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-expect-error\nexport interface IRecurrentOptions extends IFeedForwardOptions {\n  hiddenLayers: Array<\n    (\n      inputLayer: ILayer,\n      recurrentInput: IRecurrentInput,\n      index: number\n    ) => ILayer\n  >;\n}\n\nexport interface IRecurrentPreppedTrainingData<T> {\n  status: ITrainingStatus;\n  preparedData: T[][];\n  endTime: number;\n}\n\nexport class Recurrent<\n  T extends TextureArrayOutput = TextureArrayOutput\n> extends FeedForward {\n  trainOpts: IRecurrentTrainingOptions = {};\n  // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n  // @ts-expect-error\n  options: IRecurrentOptions;\n  _outputConnection: RecurrentConnection | null = null;\n  _layerSets: ILayer[][] = [];\n  _hiddenLayerOutputIndices: number[] = [];\n  _model: ILayer[] | null = null;\n\n  // TODO: use generics in extend\n  constructor(\n    options: Partial<IRecurrentOptions & IRecurrentTrainingOptions> = {}\n  ) {\n    // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n    // @ts-expect-error\n    super(options);\n  }\n\n  _connectLayers(): {\n    inputLayer: ILayer;\n    hiddenLayers: ILayer[];\n    outputLayer: ILayer;\n  } {\n    if (!this.options.inputLayer) {\n      throw new Error('inputLayer not found');\n    }\n    if (!this.options.outputLayer) {\n      throw new Error('outputLayer not found');\n    }\n    const inputLayer = this.options.inputLayer();\n    const hiddenLayers = this._connectHiddenLayers(inputLayer);\n    const outputLayer = this.options.outputLayer(\n      hiddenLayers[hiddenLayers.length - 1],\n      -1\n    );\n    return {\n      inputLayer,\n      hiddenLayers,\n      outputLayer,\n    };\n  }\n\n  _connectLayersDeep(): ILayer[] {\n    const layers: ILayer[] = [];\n    const previousLayers = this._layerSets[this._layerSets.length - 1];\n    let usedHiddenLayerOutputIndex = 0;\n\n    function findInputLayer(inputLayer: ILayer) {\n      const index = previousLayers.indexOf(inputLayer);\n      if (index < 0) throw new Error('unable to find layer');\n      return layers[index];\n    }\n\n    function layerSettings(layer: ILayer): ILayerSettings {\n      return {\n        ...layer.settings,\n        weights: null,\n        deltas: null,\n        praxis: null,\n      };\n    }\n\n    for (let i = 0; i < previousLayers.length; i++) {\n      const previousLayer = previousLayers[i];\n      let layer: ILayer;\n\n      if (previousLayer instanceof Activation) {\n        layer = new (previousLayer.constructor as ActivationType)(\n          findInputLayer(previousLayer.inputLayer),\n          layerSettings(previousLayer)\n        );\n      } else if (previousLayer instanceof EntryPoint) {\n        layer = new (previousLayer.constructor as EntryPointType)(\n          layerSettings(previousLayer)\n        );\n      } else if (previousLayer instanceof Filter) {\n        layer = new (previousLayer.constructor as FilterType)(\n          layerSettings(previousLayer.inputLayer),\n          findInputLayer(previousLayer.inputLayer)\n        );\n      } else if (previousLayer instanceof Internal) {\n        const previousHiddenLayerOutput =\n          previousLayers[\n            this._hiddenLayerOutputIndices[usedHiddenLayerOutputIndex++]\n          ];\n        if (previousLayer instanceof RecurrentConnection) {\n          throw new Error('unfinished');\n        } else if (previousLayer instanceof RecurrentInput) {\n          layer = new RecurrentInput(previousHiddenLayerOutput);\n        } else if (previousLayer instanceof RecurrentZeros) {\n          layer = new RecurrentInput(previousHiddenLayerOutput);\n        } else {\n          throw new Error(\n            `hidden layer ${previousLayer.constructor.name} extends unknown hidden layer`\n          );\n        }\n      } else if (\n        previousLayer instanceof InternalModel ||\n        previousLayer instanceof Model\n      ) {\n        layer = previousLayer;\n      } else if (previousLayer instanceof Modifier) {\n        layer = new (previousLayer.constructor as ModifierType)(\n          findInputLayer(previousLayer.inputLayer),\n          layerSettings(previousLayer.inputLayer)\n        );\n      } else if (previousLayer instanceof Operator) {\n        layer = new (previousLayer.constructor as OperatorType)(\n          findInputLayer(previousLayer.inputLayer1),\n          findInputLayer(previousLayer.inputLayer2),\n          layerSettings(previousLayer)\n        );\n      } else if (previousLayer instanceof Target) {\n        layer = new (previousLayer.constructor as TargetType)(\n          layerSettings(previousLayer),\n          findInputLayer(previousLayer.inputLayer)\n        );\n      } else {\n        throw new Error(\n          `hidden layer ${previousLayer.constructor.name} extends unknown hidden layer`\n        );\n      }\n      layers.push(layer);\n    }\n\n    return layers;\n  }\n\n  _connectHiddenLayers(previousLayer: ILayer): ILayer[] {\n    const hiddenLayers = [];\n\n    if (!this.options.hiddenLayers) throw new Error('hiddenLayers not defined');\n\n    for (let i = 0; i < this.options.hiddenLayers.length; i++) {\n      const recurrentInput = new RecurrentZeros();\n      const hiddenLayer = this.options.hiddenLayers[i](\n        previousLayer,\n        recurrentInput,\n        i\n      );\n      previousLayer = hiddenLayer;\n      hiddenLayers.push(hiddenLayer);\n    }\n\n    return hiddenLayers;\n  }\n\n  initialize(): void {\n    this._outputConnection = new RecurrentConnection();\n    let layerSet: ILayer[];\n    if (this.options.layers) {\n      layerSet = this._connectOptionsLayers();\n    } else {\n      const { inputLayer, hiddenLayers, outputLayer } = this._connectLayers();\n      layerSet = flattenLayers([inputLayer, ...hiddenLayers, outputLayer]);\n      this._hiddenLayerOutputIndices = hiddenLayers.map((l) =>\n        layerSet.indexOf(l)\n      );\n      this._inputLayer = inputLayer;\n      this._hiddenLayers = hiddenLayers;\n      this._outputLayer = outputLayer;\n    }\n    this.layers = layerSet;\n    this._layerSets = [layerSet];\n    this._model = layerSet.filter(\n      (l) => l instanceof Model || l instanceof InternalModel\n    );\n    this.initializeLayers(layerSet);\n  }\n\n  initializeDeep(): void {\n    const layers = this._connectLayersDeep();\n    for (let i = 0; i < layers.length; i++) {\n      const layer = layers[i];\n      layer.setupKernels(true);\n      layer.reuseKernels(this._layerSets[0][i]);\n    }\n    this._layerSets.push(layers);\n  }\n\n  // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n  // @ts-expect-error\n  run(inputs: T[]): T[] {\n    while (this._layerSets.length <= inputs.length) {\n      this.initializeDeep();\n    }\n    const result = this.runInputs(inputs);\n    if (result instanceof Texture) {\n      return result.toArray() as T[];\n    }\n    return result as T[];\n  }\n\n  runInput(input: KernelOutput): KernelOutput {\n    throw new Error('use .runInputs()');\n  }\n\n  runInputs(inputs: T[]): KernelOutput {\n    while (this._layerSets.length < inputs.length) {\n      this.initializeDeep();\n    }\n    const max = inputs.length - 1; // last output will be compared with last index\n    for (let x = 0; x <= max; x++) {\n      const layerSet = this._layerSets[x];\n      layerSet[0].predict(inputs[x]);\n      for (let i = 1; i < layerSet.length; i++) {\n        layerSet[i].predict();\n      }\n    }\n    const lastLayerUsed = this._layerSets[max];\n    const result = lastLayerUsed[lastLayerUsed.length - 1].weights;\n    this.end();\n    return result as KernelOutput;\n  }\n\n  // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n  // @ts-expect-error\n  train(\n    data: T[][],\n    options: Partial<IRecurrentTrainingOptions> = {}\n  ): ITrainingStatus {\n    const { preparedData, status, endTime } = this._prepTraining(data, options);\n    let continueTicking = true;\n    const calculateError = (): number =>\n      this._calculateTrainingError(preparedData);\n    const trainPatters = (): void => this._trainPatterns(preparedData);\n    while (continueTicking) {\n      continueTicking = this._trainingTick(\n        status,\n        endTime,\n        calculateError,\n        trainPatters\n      );\n    }\n    return status;\n  }\n\n  end(): void {\n    const x = this._layerSets.length - 1;\n    const lastLayerSet = this._layerSets[x];\n    lastLayerSet[0].predict([new Float32Array([0])]);\n    for (let i = 1; i < lastLayerSet.length; i++) {\n      lastLayerSet[i].predict();\n    }\n  }\n\n  // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n  // @ts-expect-error\n  transferData(formattedData: T[][]): T[][] {\n    return formattedData;\n  }\n\n  // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n  // @ts-expect-error\n  _prepTraining(\n    data: T[][],\n    options: Partial<IRecurrentTrainingOptions>\n  ): IRecurrentPreppedTrainingData<T> {\n    this._updateTrainingOptions(options);\n    const endTime = this.trainOpts.timeout\n      ? Date.now() + this.trainOpts.timeout\n      : 0;\n\n    const status = {\n      error: 1,\n      iterations: 0,\n    };\n\n    this.verifyIsInitialized();\n\n    return {\n      preparedData: this.transferData(data),\n      status,\n      endTime,\n    };\n  }\n\n  // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n  // @ts-expect-error\n  _calculateTrainingError(data: T[][]): number {\n    if (!this.meanSquaredError) {\n      throw new Error('this.meanSquaredError not setup');\n    }\n    let sum: KernelOutput = new Float32Array(1);\n    for (let i = 0; i < data.length; ++i) {\n      const prevSum = sum;\n      const error = this._trainPattern(data[i], true) as KernelOutput;\n      sum = this.meanSquaredError.add(sum, error);\n      release(error);\n      release(prevSum);\n    }\n    const result = this.meanSquaredError.divide(data.length, sum);\n    release(sum);\n    if (result instanceof Texture) {\n      const resultArray = result.toArray() as number[];\n      return resultArray[0];\n    }\n    return (result as number[])[0];\n  }\n\n  // TODO: more types\n  // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n  // @ts-expect-error\n  formatData(data: Float32Array): Float32Array {\n    return data;\n  }\n\n  // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n  // @ts-expect-error\n  _calculateDeltas(target: T[]): void {\n    const lastLayerSet = this._layerSets[this._layerSets.length - 1];\n    // Iterate from the second to last layer backwards, propagating 0's\n    for (let i = lastLayerSet.length - 2; i >= 0; i--) {\n      lastLayerSet[i].compare();\n    }\n\n    for (let x = target.length - 2; x >= 0; x--) {\n      const layerSet = this._layerSets[x];\n      layerSet[layerSet.length - 1].compare(target[x + 1]);\n      for (let i = layerSet.length - 2; i >= 0; i--) {\n        layerSet[i].compare();\n      }\n    }\n  }\n\n  adjustWeights(): void {\n    const _model = this._model as ILayer[];\n    for (let i = 0; i < _model.length; i++) {\n      _model[i].learn(this.options.learningRate ?? 0);\n    }\n  }\n\n  // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n  // @ts-expect-error\n  _trainPatterns(data: T[][]): void {\n    for (let i = 0; i < data.length; ++i) {\n      this._trainPattern(data[i], false);\n    }\n  }\n\n  // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n  // @ts-expect-error\n  _trainPattern(inputs: T[], logErrorRate: boolean): KernelOutput | null {\n    // forward propagate\n    this.runInputs(inputs);\n\n    // back propagate\n    this._calculateDeltas(inputs);\n    this.adjustWeights();\n\n    if (logErrorRate) {\n      if (!this.meanSquaredError) {\n        throw new Error('this.meanSquaredError not setup');\n      }\n      let error: KernelOutput = new Float32Array(1);\n      for (let i = 0, max = inputs.length - 2; i <= max; i++) {\n        const layerSet = this._layerSets[i];\n        const lastLayer = layerSet[layerSet.length - 1];\n        const prevError: KernelOutput = error;\n        error = this.meanSquaredError.addAbsolute(\n          prevError,\n          lastLayer.errors as KernelOutput\n        );\n        release(prevError);\n      }\n      return clone(this.meanSquaredError.divide(inputs.length, error));\n    }\n    return null;\n  }\n}\n","import { zeros } from '../../utilities/zeros';\n\nexport interface IMatrixJSON {\n  rows: number;\n  columns: number;\n  weights: number[];\n}\n/**\n * A matrix\n */\nexport class Matrix {\n  rows = 0;\n  columns = 0;\n  weights: Float32Array;\n  deltas: Float32Array;\n\n  constructor(rows?: number, columns?: number) {\n    if (rows) this.rows = rows;\n    if (columns) this.columns = columns;\n\n    this.weights = zeros(this.rows * this.columns);\n    this.deltas = zeros(this.rows * this.columns);\n  }\n\n  getWeight(row: number, col: number): number {\n    // slow but careful accessor function\n    // we want row-major order\n    const ix = this.columns * row + col;\n\n    if (ix < 0 || ix >= this.weights.length) {\n      throw new Error('get accessor is skewed');\n    }\n\n    return this.weights[ix];\n  }\n\n  setWeight(row: number, col: number, v: number): Matrix {\n    // slow but careful accessor function\n    const ix = this.columns * row + col;\n\n    if (ix < 0 || ix >= this.weights.length) {\n      throw new Error('set accessor is skewed');\n    }\n\n    this.weights[ix] = v;\n\n    return this;\n  }\n\n  getDelta(row: number, col: number): number {\n    // slow but careful accessor function\n    // we want row-major order\n    const ix = this.columns * row + col;\n\n    if (ix < 0 || ix >= this.deltas.length) {\n      throw new Error('get accessor is skewed');\n    }\n\n    return this.deltas[ix];\n  }\n\n  setDelta(row: number, col: number, v: number): Matrix {\n    // slow but careful accessor function\n    const ix = this.columns * row + col;\n\n    if (ix < 0 || ix >= this.weights.length) {\n      throw new Error('set accessor is skewed');\n    }\n\n    this.deltas[ix] = v;\n\n    return this;\n  }\n\n  toJSON(): IMatrixJSON {\n    return {\n      rows: this.rows,\n      columns: this.columns,\n      weights: Array.from(this.weights.slice(0)),\n    };\n  }\n\n  static fromJSON(json: IMatrixJSON): Matrix {\n    const matrix = new Matrix(json.rows, json.columns);\n\n    for (let i = 0, max = json.rows * json.columns; i < max; i++) {\n      matrix.weights[i] = json.weights[i]; // copy over weights\n    }\n\n    return matrix;\n  }\n\n  static fromArray(weights: Float32Array[] | number[][]): Matrix {\n    const matrix = new Matrix(weights.length, weights[0].length);\n    matrix.fromArray(weights);\n    return matrix;\n  }\n\n  deltasToArray(): number[][] {\n    return this.toArray('deltas');\n  }\n\n  weightsToArray(): number[][] {\n    return this.toArray('weights');\n  }\n\n  toArray(prop: 'weights' | 'deltas' = 'weights'): number[][] {\n    const result: number[][] = new Array(this.rows);\n    this.iterate({\n      row: (rowIndex): void => {\n        result[rowIndex] = new Array(this.columns);\n      },\n      column: (rowIndex, columnIndex): void => {\n        if (prop === 'weights') {\n          result[rowIndex][columnIndex] = this.getWeight(rowIndex, columnIndex);\n        } else if (prop === 'deltas') {\n          result[rowIndex][columnIndex] = this.getDelta(rowIndex, columnIndex);\n        }\n      },\n    });\n    return result;\n  }\n\n  fromArray(\n    array: number[][] | Float32Array[],\n    prop: 'weights' | 'deltas' = 'weights'\n  ): this {\n    if (array.length !== this.rows) {\n      throw new Error('rows do not match');\n    }\n    if (array[0].length !== this.columns) {\n      throw new Error('columns do not match');\n    }\n    this.iterate({\n      column: (rowIndex, columnIndex): void => {\n        const value = array[rowIndex][columnIndex];\n        if (typeof value !== 'number') {\n          throw new Error('value not number');\n        }\n        if (prop === 'weights') {\n          this.setWeight(rowIndex, columnIndex, value);\n        } else if (prop === 'deltas') {\n          this.setDelta(rowIndex, columnIndex, value);\n        }\n      },\n    });\n    return this;\n  }\n\n  iterate(callbacks: {\n    column?: (rowIndex: number, columnIndex: number) => void;\n    row?: (rowIndex: number) => void;\n  }): this {\n    const rows = this.rows;\n    const columns = this.columns;\n    for (let rowIndex = 0; rowIndex < rows; rowIndex++) {\n      if (callbacks.row) {\n        callbacks.row(rowIndex);\n      }\n      for (let columnIndex = 0; columnIndex < columns; columnIndex++) {\n        if (callbacks.column) {\n          callbacks.column(rowIndex, columnIndex);\n        }\n      }\n    }\n    return this;\n  }\n}\n","import { Matrix } from '.';\nimport { randomFloat } from '../../utilities/random';\n\n/** return Matrix but filled with random numbers from gaussian\n */\nexport class RandomMatrix extends Matrix {\n  std: number;\n\n  constructor(rows: number, columns: number, std: number) {\n    super(rows, columns);\n\n    this.std = std;\n\n    for (let i = 0, max = this.weights.length; i < max; i++) {\n      this.weights[i] = randomFloat(-std, std);\n    }\n  }\n}\n","import { Value, IRNNDatum } from '../recurrent/rnn-data-types';\n\nexport interface IDataFormatter {\n  indexTable: { [value: string]: number };\n  toIndexesInputOutput: (input: Value, output?: Value) => number[];\n  toIndexes: (input: string) => number[];\n  toCharacters: (output: number[]) => string[];\n  characters: Array<string | number>;\n  specialIndexes: number[];\n  toFunctionString: () => string;\n  formatDataIn: (input?: Value, output?: Value) => number[];\n  formatDataOut: (input: number[], output: number[]) => string;\n  format: (data: Array<IRNNDatum | Value>) => number[][];\n  isSetup: boolean;\n  toJSON: () => IDataFormatterJSON;\n}\n\nexport class DataFormatter implements IDataFormatter {\n  indexTable: { [key: string]: number; [key: number]: number } = {};\n  characterTable: { [key: number]: string | number | null } = {};\n  characters: Array<string | number> = [];\n  specialIndexes: number[] = [];\n  isSetup = false;\n\n  constructor(private values?: Array<IRNNDatum | Value>, maxThreshold = 0) {\n    if (values === undefined) return;\n\n    this.setup(values, maxThreshold);\n  }\n\n  setup(values: Array<IRNNDatum | Value>, maxThreshold = 0): void {\n    if (this.isSetup) throw new Error('DataFormatter is already setup');\n    this.values = values;\n    // go over all characters and keep track of all unique ones seen\n    // count up all characters\n\n    this.buildCharactersFromIterable(values);\n    this.buildTables(maxThreshold);\n    if ((values[0] as IRNNDatum).input) {\n      this.addInputOutput();\n    }\n    this.addUnrecognized();\n    this.isSetup = true;\n  }\n\n  buildCharactersFromIterable(values: Array<IRNNDatum | Value>): void {\n    const tempCharactersTable: { [character: string]: boolean } = {};\n    for (\n      let dataFormatterIndex = 0, dataFormatterLength = values.length;\n      dataFormatterIndex < dataFormatterLength;\n      dataFormatterIndex++\n    ) {\n      const characters = values[dataFormatterIndex];\n\n      // if (typeof characters === 'string') {\n      //   const character = characters;\n      //   if (tempCharactersTable.hasOwnProperty(character)) continue;\n      //   tempCharactersTable[character] = true;\n      //   this.characters.push(character);\n      if (characters.hasOwnProperty('length')) {\n        const iteratable = characters as string[] | string;\n        for (\n          let characterIndex = 0, charactersLength = iteratable.length;\n          characterIndex < charactersLength;\n          characterIndex++\n        ) {\n          const character = iteratable[characterIndex];\n          if (tempCharactersTable.hasOwnProperty(character)) continue;\n          tempCharactersTable[character] = true;\n          this.characters.push(character);\n        }\n      } else if (typeof characters === 'number') {\n        if (tempCharactersTable.hasOwnProperty(characters)) continue;\n        tempCharactersTable[characters] = true;\n        this.characters.push(characters);\n      } else if (typeof characters === 'boolean') {\n        const character = characters.toString();\n        if (tempCharactersTable.hasOwnProperty(character)) continue;\n        tempCharactersTable[character] = true;\n        this.characters.push(character);\n      } else if (\n        Array.isArray(characters) &&\n        typeof characters[0] === 'string'\n      ) {\n        for (let i = 0; i < characters.length; i++) {\n          const character = characters[i] as string;\n          if (tempCharactersTable.hasOwnProperty(character)) continue;\n          tempCharactersTable[character] = true;\n          this.characters.push(character);\n        }\n      } else if (\n        Array.isArray(characters) &&\n        (typeof characters[0] === 'number' ||\n          typeof characters[0] === 'boolean')\n      ) {\n        for (let i = 0; i < characters.length; i++) {\n          const character = characters[i].toString();\n          if (tempCharactersTable.hasOwnProperty(dataFormatterIndex)) continue;\n          tempCharactersTable[character] = true;\n          this.characters.push(character);\n        }\n      } else if (\n        characters.hasOwnProperty('input') &&\n        characters.hasOwnProperty('output')\n      ) {\n        const { input, output } = (characters as unknown) as IRNNDatum;\n        if (Array.isArray(input)) {\n          this.addCharacters(input, tempCharactersTable);\n        } else {\n          this.addCharacters(input.toString(), tempCharactersTable);\n        }\n\n        if (Array.isArray(output)) {\n          this.addCharacters(output, tempCharactersTable);\n        } else {\n          this.addCharacters(output.toString(), tempCharactersTable);\n        }\n      } else {\n        throw new Error('Unhandled value');\n      }\n    }\n  }\n\n  addCharacters(\n    characters: string | string[] | boolean[] | number[],\n    charactersTable: { [character: string]: boolean }\n  ): void {\n    for (let i = 0; i < characters.length; i++) {\n      const character = characters[i].toString();\n      if (charactersTable.hasOwnProperty(character)) continue;\n      charactersTable[character] = true;\n      this.characters.push(character);\n    }\n  }\n\n  buildTables(maxThreshold: number): void {\n    // filter by count threshold and create pointers\n    const charactersLength = this.characters.length;\n    for (\n      let characterIndex = 0;\n      characterIndex < charactersLength;\n      characterIndex++\n    ) {\n      const character = this.characters[characterIndex];\n      if (characterIndex >= maxThreshold) {\n        // add character to dataFormatter\n        this.indexTable[character] = characterIndex;\n        this.characterTable[characterIndex] = character;\n      }\n    }\n  }\n\n  toIndexes(value: Value, maxThreshold = 0): number[] {\n    const result = [];\n    const { indexTable } = this;\n\n    switch (typeof value) {\n      case 'number':\n      case 'boolean':\n        value = value.toString();\n    }\n\n    for (let i = 0, max = value.length; i < max; i++) {\n      const character = value[i].toString();\n      let index = indexTable[character];\n      if (index === undefined) {\n        if (indexTable.unrecognized) {\n          index = indexTable.unrecognized;\n        } else {\n          throw new Error(`unrecognized character \"${character}\"`);\n        }\n      }\n      if (index < maxThreshold) continue;\n      result.push(index);\n    }\n    return result;\n  }\n\n  toIndexesInputOutput(\n    input: Value,\n    output?: Value,\n    maxThreshold = 0\n  ): number[] {\n    const result: number[] = this.toIndexesValue(input, maxThreshold, true);\n\n    if (typeof output === 'undefined') return result;\n    return result.concat(this.toIndexesValue(output, maxThreshold, false));\n  }\n\n  toIndexesValue(\n    value: Value,\n    maxThreshold: number,\n    isInput: boolean\n  ): number[] {\n    if (typeof value === 'string') {\n      value = value.split('');\n    } else if (typeof value === 'number' || typeof value === 'boolean') {\n      value = value.toString().split('');\n    } else if (\n      Array.isArray(value) &&\n      (typeof (value as number[])[0] === 'number' ||\n        typeof (value as boolean[])[0] === 'boolean' ||\n        typeof (value as string[])[0] === 'string')\n    ) {\n      value = (value as string[]).map((v) => v.toString());\n    } else {\n      throw new Error('unrecognized value');\n    }\n    if (isInput) {\n      value = value.concat(['stop-input', 'start-output']);\n    }\n    return this.toIndexes(value, maxThreshold);\n  }\n\n  toCharacters(indices: number[], maxThreshold = 0): string[] {\n    const result: string[] = [];\n    const { indexTable, characterTable } = this;\n\n    for (let i = 0, max = indices.length; i < max; i++) {\n      const index = indices[i];\n      if (index < maxThreshold) continue;\n      let character = characterTable[index];\n      if (character === undefined) {\n        if (indexTable.unrecognized) {\n          character = characterTable[indexTable.unrecognized];\n        } else {\n          throw new Error(`unrecognized index \"${index}\"`);\n        }\n      } else if (character !== null) {\n        result.push(character.toString());\n      }\n    }\n\n    return result;\n  }\n\n  toString(indices: number[], maxThreshold: number): string {\n    return this.toCharacters(indices, maxThreshold).join('');\n  }\n\n  addInputOutput(): void {\n    this.addSpecial('stop-input');\n    this.addSpecial('start-output');\n  }\n\n  addUnrecognized(): void {\n    this.addSpecial('unrecognized');\n  }\n\n  static fromAllPrintable(\n    maxThreshold: number,\n    values = ['\\n']\n  ): DataFormatter {\n    for (let i = 32; i <= 126; i++) {\n      values.push(String.fromCharCode(i));\n    }\n    return new DataFormatter(values, maxThreshold);\n  }\n\n  static fromAllPrintableInputOutput(\n    maxThreshold: number,\n    values = ['\\n']\n  ): DataFormatter {\n    const dataFormatter = DataFormatter.fromAllPrintable(maxThreshold, values);\n    dataFormatter.addInputOutput();\n    dataFormatter.addUnrecognized();\n    return dataFormatter;\n  }\n\n  static fromStringInputOutput(\n    string: string,\n    maxThreshold: number\n  ): DataFormatter {\n    const values = Array.from(new Set(string)).join('');\n    const dataFormatter = new DataFormatter(values.split(''), maxThreshold);\n    dataFormatter.addInputOutput();\n    dataFormatter.addUnrecognized();\n    dataFormatter.isSetup = true;\n    return dataFormatter;\n  }\n\n  static fromArrayInputOutput(\n    data: IRNNDatum[],\n    maxThreshold?: number\n  ): DataFormatter {\n    const values: Array<string | string[]> = [];\n\n    for (let i = 0; i < data.length; i++) {\n      const datum = data[i];\n      values.push(validateAndCast(datum.input), validateAndCast(datum.output));\n    }\n    const flatArray: string[] = Array.isArray(values)\n      ? (values as string[][]).flat()\n      : values;\n    const dataFormatter = new DataFormatter(\n      Array.from(new Set(flatArray)),\n      maxThreshold\n    );\n    dataFormatter.addInputOutput();\n    dataFormatter.addUnrecognized();\n    dataFormatter.isSetup = true;\n    return dataFormatter;\n  }\n\n  static fromString(string: string, maxThreshold = 0): DataFormatter {\n    const values = Array.from(new Set(string)).join('');\n    return new DataFormatter(values.split(''), maxThreshold);\n  }\n\n  toJSON(): IDataFormatterJSON {\n    return {\n      indexTable: this.indexTable,\n      characterTable: this.characterTable,\n      values: this.values as Value[],\n      characters: this.characters,\n      specialIndexes: this.specialIndexes,\n    };\n  }\n\n  /** TODO: Type better, The type of json is not \"string that is a valid JSON\", it is a POJO in the shape of DataFormatter.\n   * this method re-hydrates the the data as an instance of DataFormatter.\n   */\n  static fromJSON(json: IDataFormatterJSON): DataFormatter {\n    const dataFormatter = new DataFormatter();\n    dataFormatter.indexTable = json.indexTable;\n    dataFormatter.characterTable = json.characterTable;\n    dataFormatter.values = json.values;\n    dataFormatter.characters = json.characters;\n    dataFormatter.specialIndexes = json.specialIndexes;\n    return dataFormatter;\n  }\n\n  addSpecial(special: string | number, character = null): void {\n    const specialIndex = (this.indexTable[special] = this.characters.length);\n    this.characterTable[specialIndex] = character;\n    this.specialIndexes.push(this.characters.length);\n    this.characters.push(special);\n  }\n\n  toFunctionString(): string {\n    return `\nvar characterTable = ${JSON.stringify(this.characterTable)};\nvar indexTable = ${JSON.stringify(this.indexTable)};\nvar characters = ${JSON.stringify(this.characters)};\nvar dataFormatter = {\n  toIndexes: function ${this.toIndexes.toString()},\n  toIndexesInputOutput: function ${this.toIndexesInputOutput.toString()},\n  toCharacters: function ${this.toCharacters.toString()},\n  toIndexesValue: function ${this.toIndexesValue.toString()},\n};`;\n  }\n\n  formatDataIn(input?: Value, output?: Value): number[] {\n    if (input === undefined) return [];\n    if (Array.isArray(input) && typeof input[0] === 'number') {\n      return input as number[];\n    }\n    if (this.indexTable?.hasOwnProperty('stop-input')) {\n      return this.toIndexesInputOutput(input, output);\n    }\n    return this.toIndexes(input);\n  }\n\n  formatDataOut(input: number[], output: number[]): string {\n    return this.toCharacters(output).join('');\n  }\n\n  format(data: Array<IRNNDatum | Value>): number[][] {\n    if (\n      typeof data[0] === 'number' &&\n      !Array.isArray(data[0]) &&\n      (!data[0].hasOwnProperty('input') || !data[0].hasOwnProperty('output'))\n    ) {\n      return data as number[][];\n    }\n    const result: number[][] = [];\n    if (\n      typeof data[0] === 'string' ||\n      typeof data[0] === 'number' ||\n      Array.isArray(data[0])\n    ) {\n      if (!this.isSetup) {\n        this.setup(data);\n        for (let i = 0; i < data.length; i++) {\n          result.push(this.formatDataIn(validateAndCast(data[i] as Value)));\n        }\n      } else {\n        for (let i = 0, max = data.length; i < max; i++) {\n          result.push(this.formatDataIn(data[i] as Value));\n        }\n      }\n    } else if ((data[0] as IRNNDatum).input && (data[0] as IRNNDatum).output) {\n      if (!this.isSetup) {\n        this.setup(data);\n      }\n      for (let i = 0, max = data.length; i < max; i++) {\n        result.push(\n          this.formatDataIn(\n            validateAndCast((data[i] as IRNNDatum).input),\n            validateAndCast((data[i] as IRNNDatum).output)\n          )\n        );\n      }\n    } else {\n      throw new Error('unrecognized data');\n    }\n    return result;\n  }\n}\n\nfunction validateAndCast(value: Value): string | string[] {\n  if (typeof value === 'string') return value;\n  if (typeof value === 'number') return value.toString();\n  if (typeof value === 'boolean') return value.toString();\n  if (Array.isArray(value) && typeof value[0] === 'string')\n    return value as string[];\n  if (typeof value[0] === 'boolean') {\n    return (value as boolean[]).map((v: boolean) => v.toString());\n  }\n  if (typeof value[0] === 'number') {\n    return (value as number[]).map((v: number) => v.toString());\n  }\n  throw new Error(\n    'unrecognized value, expected string[], string, number[], number, boolean[], or boolean'\n  );\n}\n\nexport interface IDataFormatterJSON {\n  indexTable: { [key: string]: number; [key: number]: number };\n  characterTable: { [key: number]: string | number | null };\n  values: Value[];\n  characters: Array<string | number>;\n  specialIndexes: number[];\n}\n","import { Matrix } from '.';\n\n/**\n * add {left} and {right} matrix weights into {into}\n */\nexport function add(product: Matrix, left: Matrix, right: Matrix): void {\n  for (let i = 0; i < left.weights.length; i++) {\n    product.weights[i] = left.weights[i] + right.weights[i];\n    product.deltas[i] = 0;\n  }\n}\n","import { Matrix } from '.';\n\n/**\n * adds {from} deltas to {left} and {right} deltas\n */\nexport function addB(product: Matrix, left: Matrix, right: Matrix): void {\n  for (let i = 0; i < product.deltas.length; i++) {\n    left.deltas[i] = product.deltas[i];\n    right.deltas[i] = product.deltas[i];\n  }\n}\n","import { Matrix } from '.';\n\n/**\n * makes matrix weights and deltas all ones\n */\nexport function allOnes(product: Matrix): void {\n  for (let i = 0; i < product.weights.length; i++) {\n    product.weights[i] = 1;\n    product.deltas[i] = 0;\n  }\n}\n","import { Matrix } from '.';\n\nexport function cloneNegative(product: Matrix, left: Matrix): void {\n  product.rows = left.rows;\n  product.columns = left.columns;\n  product.weights = left.weights.slice(0);\n  product.deltas = left.deltas.slice(0);\n\n  for (let i = 0; i < left.weights.length; i++) {\n    product.weights[i] = -left.weights[i];\n    product.deltas[i] = 0;\n  }\n}\n","import { Matrix } from '.';\n\n/**\n * multiply {left} and {right} matrix weights to {into}\n */\nexport function multiply(product: Matrix, left: Matrix, right: Matrix): void {\n  const leftRows = left.rows;\n  const leftColumns = left.columns;\n  const rightColumns = right.columns;\n\n  // loop over rows of left\n  for (let leftRow = 0; leftRow < leftRows; leftRow++) {\n    const leftRowBase = leftColumns * leftRow;\n    const rightRowBase = rightColumns * leftRow;\n\n    // loop over cols of right\n    for (let rightColumn = 0; rightColumn < rightColumns; rightColumn++) {\n      // dot product loop\n      let dot = 0;\n\n      // loop over columns of left\n      for (let leftColumn = 0; leftColumn < leftColumns; leftColumn++) {\n        const rightColumnBase = rightColumns * leftColumn;\n        const leftIndex = leftRowBase + leftColumn;\n        const rightIndex = rightColumnBase + rightColumn;\n        dot += left.weights[leftIndex] * right.weights[rightIndex];\n        left.deltas[leftIndex] = 0;\n        right.deltas[rightIndex] = 0;\n      }\n\n      product.weights[rightRowBase + rightColumn] = dot;\n    }\n  }\n}\n","import { Matrix } from '.';\n\n/**\n * multiplies {from} deltas to {left} and {right}\n */\nexport function multiplyB(product: Matrix, left: Matrix, right: Matrix): void {\n  const leftRows = left.rows;\n  const leftColumns = left.columns;\n  const rightColumns = right.columns;\n\n  // loop over rows of left\n  for (let leftRowRoot = 0; leftRowRoot < leftRows; leftRowRoot++) {\n    const leftRowBase = leftColumns * leftRowRoot;\n    const rightRowBase = rightColumns * leftRowRoot;\n\n    // loop over cols of right\n    for (let rightColumn = 0; rightColumn < rightColumns; rightColumn++) {\n      // loop over columns of left\n      for (let leftColumn = 0; leftColumn < leftColumns; leftColumn++) {\n        const rightColumnBase = rightColumns * leftColumn;\n        const leftRow = leftRowBase + leftColumn;\n        const rightRow = rightColumnBase + rightColumn;\n        const backPropagateValue = product.deltas[rightRowBase + rightColumn];\n        left.deltas[leftRow] += right.weights[rightRow] * backPropagateValue;\n        right.deltas[rightRow] += left.weights[leftRow] * backPropagateValue;\n      }\n    }\n  }\n}\n","import { Matrix } from '.';\n\nexport function multiplyElement(\n  product: Matrix,\n  left: Matrix,\n  right: Matrix\n): void {\n  const { weights } = left;\n\n  for (let i = 0; i < weights.length; i++) {\n    product.weights[i] = left.weights[i] * right.weights[i];\n    product.deltas[i] = 0;\n  }\n}\n","import { Matrix } from '.';\n\n/**\n * multiplies {left} and {right} weight by {from} deltas into {left} and {right} deltas\n */\nexport function multiplyElementB(\n  product: Matrix,\n  left: Matrix,\n  right: Matrix\n): void {\n  for (let i = 0; i < left.weights.length; i++) {\n    left.deltas[i] = right.weights[i] * product.deltas[i];\n    right.deltas[i] = left.weights[i] * product.deltas[i];\n  }\n}\n","import { Matrix } from '.';\n\n/**\n *\n * relu {m} weights to {into} weights\n */\nexport function relu(product: Matrix, left: Matrix): void {\n  for (let i = 0; i < left.weights.length; i++) {\n    product.weights[i] = Math.max(0, left.weights[i]); // relu\n    product.deltas[i] = 0;\n  }\n}\n","import { Matrix } from '.';\n\n/**\n * adds {from} deltas to {m} deltas when {m} weights are above other a threshold of 0\n */\nexport function reluB(product: Matrix, left: Matrix): void {\n  for (let i = 0; i < product.deltas.length; i++) {\n    left.deltas[i] = left.weights[i] > 0 ? product.deltas[i] : 0;\n  }\n}\n","import { Matrix } from '.';\n\nexport function rowPluck(\n  product: Matrix,\n  left: Matrix,\n  rowPluckIndex: number\n): void {\n  const { columns } = left;\n  const rowBase = columns * rowPluckIndex;\n\n  for (let column = 0; column < columns; column++) {\n    product.weights[column] = left.weights[rowBase + column];\n    product.deltas[column] = 0;\n  }\n}\n","import { Matrix } from '.';\n\n/**\n * adds {from} deltas into {m} deltas\n */\nexport function rowPluckB(\n  product: Matrix,\n  left: Matrix,\n  rowIndex: number\n): void {\n  const { columns } = left;\n  const rowBase = columns * rowIndex;\n\n  for (let column = 0; column < columns; column++) {\n    left.deltas[rowBase + column] = product.deltas[column];\n  }\n}\n","import { Matrix } from '.';\n\nexport function sigmoid(product: Matrix, left: Matrix): void {\n  // sigmoid nonlinearity\n  for (let i = 0; i < left.weights.length; i++) {\n    product.weights[i] = 1 / (1 + Math.exp(-left.weights[i]));\n    product.deltas[i] = 0;\n  }\n}\n\n// function sig(x) {\n//   // helper function for computing sigmoid\n//   return 1 / (1 + Math.exp(-x));\n// }\n","import { Matrix } from '.';\n\nexport function sigmoidB(product: Matrix, left: Matrix): void {\n  for (let i = 0; i < product.deltas.length; i++) {\n    const mwi = product.weights[i];\n    left.deltas[i] = mwi * (1 - mwi) * product.deltas[i];\n  }\n}\n","import { Matrix } from '.';\n\nexport function softmax(matrix: Matrix): Matrix {\n  // probability volume\n  const result = new Matrix(matrix.rows, matrix.columns);\n  let maxVal = -999999;\n\n  for (let i = 0; i < matrix.weights.length; i++) {\n    if (matrix.weights[i] > maxVal) {\n      maxVal = matrix.weights[i];\n    }\n  }\n\n  let s = 0;\n  for (let i = 0; i < matrix.weights.length; i++) {\n    result.weights[i] = Math.exp(matrix.weights[i] - maxVal);\n    s += result.weights[i];\n  }\n\n  for (let i = 0; i < matrix.weights.length; i++) {\n    result.weights[i] /= s;\n  }\n\n  // no backward pass here needed\n  // since we will use the computed probabilities outside\n  // to set gradients directly on m\n  return result;\n}\n","import { Matrix } from '.';\n\nexport function tanh(product: Matrix, left: Matrix): void {\n  // tanh nonlinearity\n  for (let i = 0; i < left.weights.length; i++) {\n    product.weights[i] = Math.tanh(left.weights[i]);\n    product.deltas[i] = 0;\n  }\n}\n","import { Matrix } from '.';\n\nexport function tanhB(product: Matrix, left: Matrix): void {\n  for (let i = 0; i < product.deltas.length; i++) {\n    // grad for z = tanh(x) is (1 - z^2)\n    const mwi = product.weights[i];\n    left.deltas[i] = (1 - mwi * mwi) * product.deltas[i];\n  }\n}\n","import { Matrix } from '.';\nimport { add } from './add';\nimport { addB } from './add-b';\nimport { allOnes } from './all-ones';\nimport { cloneNegative } from './clone-negative';\nimport { multiply } from './multiply';\nimport { multiplyB } from './multiply-b';\nimport { multiplyElement } from './multiply-element';\nimport { multiplyElementB } from './multiply-element-b';\nimport { relu } from './relu';\nimport { reluB } from './relu-b';\nimport { rowPluck } from './row-pluck';\nimport { rowPluckB } from './row-pluck-b';\nimport { sigmoid } from './sigmoid';\nimport { sigmoidB } from './sigmoid-b';\nimport { softmax } from './softmax';\nimport { tanh } from './tanh';\nimport { tanhB } from './tanh-b';\n\ntype PropagateIndex = (product: Matrix, left: Matrix, index: number) => void;\ntype PropagateProduct = (product: Matrix) => void;\ntype PropagateProductFromLeft = (product: Matrix, left: Matrix) => void;\ntype PropagateProductFromLeftRight = (\n  product: Matrix,\n  left: Matrix,\n  right: Matrix\n) => void;\ntype PropagateFunction =\n  | PropagateIndex\n  | PropagateProduct\n  | PropagateProductFromLeft\n  | PropagateProductFromLeftRight;\n\nexport interface IState {\n  name: string;\n  product: Matrix;\n  left?: Matrix;\n  right?: Matrix;\n  forwardFn: PropagateFunction;\n  backpropagationFn: PropagateFunction;\n}\n\nexport class Equation {\n  states: IState[] = [];\n  inputValue?: Float32Array;\n  inputRow = 0;\n\n  add(left: Matrix, right: Matrix): Matrix {\n    if (left.weights.length !== right.weights.length) {\n      throw new Error('misaligned matrices');\n    }\n\n    const product = new Matrix(left.rows, left.columns);\n\n    this.states.push({\n      name: 'add',\n      product,\n      left,\n      right,\n      forwardFn: add,\n      backpropagationFn: addB,\n    });\n\n    return product;\n  }\n\n  allOnes(rows: number, columns: number): Matrix {\n    const product = new Matrix(rows, columns);\n\n    this.states.push({\n      name: 'allOnes',\n      product,\n      left: product,\n      forwardFn: allOnes,\n      backpropagationFn: () => {},\n    });\n\n    return product;\n  }\n\n  cloneNegative(matrix: Matrix): Matrix {\n    const product = new Matrix(matrix.rows, matrix.columns);\n\n    this.states.push({\n      name: 'cloneNegative',\n      product,\n      left: matrix,\n      forwardFn: cloneNegative,\n      backpropagationFn: () => {},\n    });\n\n    return product;\n  }\n\n  /**\n   * connects two matrices together by subtract\n   */\n  subtract(left: Matrix, right: Matrix): Matrix {\n    if (left.weights.length !== right.weights.length) {\n      throw new Error('misaligned matrices');\n    }\n\n    return this.add(\n      this.add(this.allOnes(left.rows, left.columns), this.cloneNegative(left)),\n      right\n    );\n  }\n\n  /**\n   * connects two matrices together by multiply\n   */\n  multiply(left: Matrix, right: Matrix): Matrix {\n    if (left.columns !== right.rows) {\n      throw new Error('misaligned matrices');\n    }\n\n    const product = new Matrix(left.rows, right.columns);\n\n    this.states.push({\n      name: 'multiply',\n      product,\n      left,\n      right,\n      forwardFn: multiply,\n      backpropagationFn: multiplyB,\n    });\n\n    return product;\n  }\n\n  /**\n   * connects two matrices together by multiplyElement\n   */\n  multiplyElement(left: Matrix, right: Matrix): Matrix {\n    if (left.weights.length !== right.weights.length) {\n      throw new Error('misaligned matrices');\n    }\n\n    const product = new Matrix(left.rows, left.columns);\n\n    this.states.push({\n      name: 'multiplyElement',\n      product,\n      left,\n      right,\n      forwardFn: multiplyElement,\n      backpropagationFn: multiplyElementB,\n    });\n\n    return product;\n  }\n\n  /**\n   * connects a matrix to relu\n   */\n  relu(matrix: Matrix): Matrix {\n    const product = new Matrix(matrix.rows, matrix.columns);\n\n    this.states.push({\n      name: 'relu',\n      product,\n      left: matrix,\n      forwardFn: relu,\n      backpropagationFn: reluB,\n    });\n\n    return product;\n  }\n\n  /**\n   * input a matrix\n   */\n  input(input: Matrix): Matrix {\n    this.states.push({\n      name: 'input',\n      product: input,\n      forwardFn: (product: Matrix) => {\n        if (!this.inputValue) return;\n        if (this.inputValue.length !== product.weights.length) {\n          throw new Error('this.inputValue is of wrong dimensions');\n        }\n        product.weights = input.weights = this.inputValue;\n      },\n      backpropagationFn: () => {},\n    });\n\n    return input;\n  }\n\n  /**\n   * connects a matrix via a row\n   */\n  inputMatrixToRow(matrix: Matrix): Matrix {\n    // eslint-disable-next-line @typescript-eslint/no-this-alias\n    const self = this;\n    const product = new Matrix(matrix.columns, 1);\n\n    this.states.push({\n      name: 'inputMatrixToRow',\n      product,\n      left: matrix,\n      get right() {\n        return (self.inputRow as unknown) as Matrix;\n      },\n      forwardFn: rowPluck,\n      backpropagationFn: rowPluckB,\n    });\n\n    return product;\n  }\n\n  /**\n   * connects a matrix to sigmoid\n   */\n  sigmoid(matrix: Matrix): Matrix {\n    const product = new Matrix(matrix.rows, matrix.columns);\n\n    this.states.push({\n      name: 'sigmoid',\n      product,\n      left: matrix,\n      forwardFn: sigmoid,\n      backpropagationFn: sigmoidB,\n    });\n\n    return product;\n  }\n\n  /**\n   * connects a matrix to tanh\n   */\n  tanh(matrix: Matrix): Matrix {\n    const product = new Matrix(matrix.rows, matrix.columns);\n\n    this.states.push({\n      name: 'tanh',\n      product,\n      left: matrix,\n      forwardFn: tanh,\n      backpropagationFn: tanhB,\n    });\n\n    return product;\n  }\n\n  /**\n   *\n   * Observe a matrix for debugging\n   */\n  observe(matrix: Matrix): Matrix {\n    this.states.push({\n      name: 'observe',\n      product: new Matrix(),\n      forwardFn: () => {},\n      backpropagationFn: () => {},\n    });\n\n    return matrix;\n  }\n\n  /**\n   * Run index through equations via forward propagation\n   */\n  runIndex(rowIndex = 0): Matrix {\n    this.inputRow = rowIndex;\n    let state = this.states[0];\n\n    for (let i = 0, max = this.states.length; i < max; i++) {\n      state = this.states[i];\n\n      if (!state.hasOwnProperty('forwardFn')) continue;\n      (state.forwardFn as PropagateProductFromLeftRight)(\n        state.product,\n        state.left as Matrix,\n        state.right as Matrix\n      );\n    }\n\n    return state.product;\n  }\n\n  /**\n   * Run value through equations via forward propagation\n   */\n  runInput(inputValue: Float32Array): Matrix {\n    this.inputValue = inputValue;\n    let state = this.states[0];\n\n    for (let i = 0, max = this.states.length; i < max; i++) {\n      state = this.states[i];\n\n      if (!state.hasOwnProperty('forwardFn')) continue;\n      (state.forwardFn as PropagateProductFromLeftRight)(\n        state.product,\n        state.left as Matrix,\n        state.right as Matrix\n      );\n    }\n\n    return state.product;\n  }\n\n  /**\n   * Run value through equations via back propagation\n   */\n  backpropagate(): Matrix {\n    let i = this.states.length;\n    let state = this.states[0];\n\n    while (i-- > 0) {\n      state = this.states[i];\n\n      if (!state.hasOwnProperty('backpropagationFn')) continue;\n      (state.backpropagationFn as PropagateProductFromLeftRight)(\n        state.product,\n        state.left as Matrix,\n        state.right as Matrix\n      );\n    }\n\n    return state.product;\n  }\n\n  /**\n   * Run index through equations via back propagation\n   */\n  backpropagateIndex(rowIndex = 0): Matrix {\n    this.inputRow = rowIndex;\n\n    let i = this.states.length;\n    let state = this.states[0];\n\n    while (i-- > 0) {\n      state = this.states[i];\n\n      if (!state.hasOwnProperty('backpropagationFn')) continue;\n      (state.backpropagationFn as PropagateProductFromLeftRight)(\n        state.product,\n        state.left as Matrix,\n        state.right as Matrix\n      );\n    }\n\n    return state.product;\n  }\n\n  /**\n   * Predict a target value from equation\n   */\n  predictTarget(input: Float32Array, target: Float32Array): number {\n    let errorSum = 0;\n    const output = this.runInput(input);\n\n    for (let i = 0; i < output.weights.length; i++) {\n      const error = output.weights[i] - target[i];\n      // set gradients into log probabilities\n      errorSum += Math.abs(error);\n      // write gradients into log probabilities\n      output.deltas[i] = error;\n    }\n\n    return errorSum;\n  }\n\n  /**\n   * Predict a target index from equation\n   */\n  predictTargetIndex(input: number, target: number): number {\n    const output = this.runIndex(input);\n    // set gradients into log probabilities\n    const logProbabilities = output; // interpret output as log probabilities\n    const probabilities = softmax(output); // compute the softmax probabilities\n\n    // write gradients into log probabilities\n    logProbabilities.deltas = probabilities.weights.slice(0);\n    logProbabilities.deltas[target] -= 1;\n\n    // accumulate base 2 log prob and do smoothing\n    return -Math.log2(probabilities.weights[target]);\n  }\n}\n","import { Matrix } from '.';\n\nexport function maxI(matrix: Matrix): number {\n  // argmax of array w\n  const { weights } = matrix;\n  let maxv = weights[0];\n  let maxix = 0;\n\n  for (let i = 1; i < weights.length; i++) {\n    const v = weights[i];\n    if (v < maxv) continue;\n\n    maxix = i;\n    maxv = v;\n  }\n\n  return maxix;\n}\n","import { Matrix } from '.';\nimport { randomFloat } from '../../utilities/random';\n\nexport function sampleI(matrix: Matrix): number {\n  // sample argmax from w, assuming w are\n  // probabilities that sum to one\n  const r = randomFloat(0, 1);\n  const w = matrix.weights;\n  let x = 0;\n  let i = 0;\n\n  while (true) {\n    x += w[i];\n\n    if (x > r) {\n      return i;\n    }\n\n    i++;\n  }\n}\n","import { Log } from '../feed-forward';\nimport { INeuralNetworkTrainOptions } from '../neural-network';\nimport {\n  DataFormatter,\n  IDataFormatter,\n  IDataFormatterJSON,\n} from '../utilities/data-formatter';\nimport { randomFloat } from '../utilities/random';\nimport { zeros } from '../utilities/zeros';\nimport { IMatrixJSON, Matrix } from './matrix';\nimport { copy } from './matrix/copy';\nimport { Equation } from './matrix/equation';\nimport { maxI } from './matrix/max-i';\nimport { RandomMatrix } from './matrix/random-matrix';\nimport { sampleI } from './matrix/sample-i';\nimport { softmax } from './matrix/softmax';\nimport { IRNNDatum, Value } from './rnn-data-types';\n\nexport interface IRNNModel {\n  isInitialized: boolean;\n  input: Matrix;\n  hiddenLayers: IRNNHiddenLayerModel[];\n  output: Matrix;\n  equations: Equation[];\n  allMatrices: Matrix[];\n  equationConnections: Matrix[][];\n  outputConnector: RandomMatrix | Matrix;\n}\n\nexport interface IRNNOptions {\n  inputSize: number;\n  inputRange: number;\n  hiddenLayers: number[];\n  outputSize: number;\n  decayRate: number;\n  smoothEps: number;\n  regc: number;\n  clipval: number;\n  maxPredictionLength: number;\n  dataFormatter: IDataFormatter;\n  json?: IRNNJSON;\n}\n\nexport interface IRNNJSONOptions {\n  inputSize: number;\n  inputRange: number;\n  hiddenLayers: number[];\n  outputSize: number;\n  decayRate: number;\n  smoothEps: number;\n  regc: number;\n  clipval: number;\n  maxPredictionLength: number;\n  dataFormatter: IDataFormatterJSON;\n}\n\nexport interface IRNNTrainingOptions {\n  iterations: number;\n  errorThresh: number;\n  log: boolean | ((status: string) => void);\n  logPeriod: number;\n  learningRate: number;\n  callback?: (status: IRNNStatus) => void;\n  callbackPeriod: number;\n  timeout: number;\n}\n\nexport interface IRNNJSONTrainOptions {\n  iterations: number;\n  errorThresh: number;\n  log: boolean | ((status: string) => void);\n  logPeriod: number;\n  learningRate: number;\n  callback?: (status: IRNNStatus) => void;\n  callbackPeriod: number;\n  timeout: number | 'Infinity';\n}\n\nexport const trainDefaults: IRNNTrainingOptions = {\n  iterations: 20000,\n  errorThresh: 0.005,\n  log: false,\n  logPeriod: 10,\n  learningRate: 0.01,\n  callbackPeriod: 10,\n  timeout: Infinity,\n};\n\nexport interface IRNNHiddenLayer {\n  [key: string]: RandomMatrix | Matrix;\n}\n\nexport interface IRNNHiddenLayerModel extends IRNNHiddenLayer {\n  // wxh\n  weight: RandomMatrix;\n  // whh\n  transition: RandomMatrix;\n  // bhh\n  bias: Matrix;\n}\n\nexport const defaults = (): IRNNOptions => {\n  return {\n    inputSize: 20,\n    inputRange: 20,\n    hiddenLayers: [20, 20],\n    outputSize: 20,\n    decayRate: 0.999,\n    smoothEps: 1e-8,\n    regc: 0.000001,\n    clipval: 5,\n    maxPredictionLength: 100,\n    dataFormatter: new DataFormatter(),\n  };\n};\n\nexport interface IRNNStatus {\n  iterations: number;\n  error: number;\n}\n\nexport interface IRNNPreppedTrainingData {\n  status: IRNNStatus;\n  preparedData: number[][];\n  endTime: number;\n}\n\nexport class RNN {\n  options: IRNNOptions = { ...defaults() };\n  trainOpts: IRNNTrainingOptions = { ...trainDefaults };\n  stepCache: { [index: number]: Float32Array } = {};\n  runs = 0;\n  ratioClipped = 0;\n  model: IRNNModel = Object.seal({\n    isInitialized: false,\n    input: new Matrix(0, 0),\n    hiddenLayers: [],\n    output: new Matrix(0, 0),\n    equations: [],\n    allMatrices: [],\n    equationConnections: [],\n    outputConnector: new RandomMatrix(0, 0, 0.08),\n  });\n\n  initialLayerInputs: Matrix[] = [];\n\n  constructor(options: Partial<IRNNOptions & IRNNTrainingOptions> = {}) {\n    this.options = { ...this.options, ...options };\n    this.updateTrainingOptions({\n      ...trainDefaults,\n      // ...options,\n    });\n\n    if (options.json) {\n      this.fromJSON(options.json);\n    }\n  }\n\n  initialize(): void {\n    const { dataFormatter } = this.options;\n    if (dataFormatter?.characters.length) {\n      this.options.inputSize = this.options.inputRange = this.options.outputSize =\n        dataFormatter.characters.length;\n    }\n    this.model = this.mapModel();\n  }\n\n  createHiddenLayers(): IRNNHiddenLayer[] {\n    const { hiddenLayers, inputSize } = this.options;\n    const hiddenLayersModel: IRNNHiddenLayer[] = [];\n    // 0 is end, so add 1 to offset\n    hiddenLayersModel.push(this.getHiddenLayer(hiddenLayers[0], inputSize));\n    let prevSize = hiddenLayers[0];\n\n    for (let d = 1; d < hiddenLayers.length; d++) {\n      // loop over depths\n      const hiddenSize = hiddenLayers[d];\n      hiddenLayersModel.push(this.getHiddenLayer(hiddenSize, prevSize));\n      prevSize = hiddenSize;\n    }\n    return hiddenLayersModel;\n  }\n\n  getHiddenLayer(hiddenSize: number, prevSize: number): IRNNHiddenLayer {\n    return {\n      // wxh\n      weight: new RandomMatrix(hiddenSize, prevSize, 0.08),\n      // whh\n      transition: new RandomMatrix(hiddenSize, hiddenSize, 0.08),\n      // bhh\n      bias: new Matrix(hiddenSize, 1),\n    };\n  }\n\n  getEquation(\n    equation: Equation,\n    inputMatrix: Matrix,\n    previousResult: Matrix,\n    hiddenLayer: IRNNHiddenLayer\n  ): Matrix {\n    if (!hiddenLayer.weight || !hiddenLayer.transition || !hiddenLayer.bias) {\n      throw new Error('hiddenLayer does not have expected properties');\n    }\n    const relu = equation.relu.bind(equation);\n    const add = equation.add.bind(equation);\n    const multiply = equation.multiply.bind(equation);\n\n    return relu(\n      add(\n        add(\n          multiply(hiddenLayer.weight, inputMatrix),\n          multiply(hiddenLayer.transition, previousResult)\n        ),\n        hiddenLayer.bias\n      )\n    );\n  }\n\n  createInputMatrix(): RandomMatrix {\n    const { inputRange, inputSize } = this.options;\n    if (inputRange < 1)\n      throw new Error('this.options.inputRange not an expected number');\n    if (inputSize < 1)\n      throw new Error('this.options.inputSize not an expected number');\n\n    // 0 is end, so add 1 to offset\n    return new RandomMatrix(inputRange + 1, inputSize, 0.08);\n  }\n\n  createOutputMatrices(): { outputConnector: RandomMatrix; output: Matrix } {\n    const { outputSize, hiddenLayers } = this.options;\n    const lastHiddenSize = last(hiddenLayers);\n\n    // 0 is end, so add 1 to offset\n    return {\n      // whd\n      outputConnector: new RandomMatrix(outputSize + 1, lastHiddenSize, 0.08),\n      // 0 is end, so add 1 to offset\n      // bd\n      output: new Matrix(outputSize + 1, 1),\n    };\n  }\n\n  bindEquation(): void {\n    const { model } = this;\n    const { hiddenLayers } = this.options;\n    const equation = new Equation();\n    const outputs: Matrix[] = [];\n    const equationConnection =\n      model.equationConnections.length > 0\n        ? last(model.equationConnections)\n        : this.initialLayerInputs;\n    // 0 index\n    let output = this.getEquation(\n      equation,\n      equation.inputMatrixToRow(model.input),\n      equationConnection[0],\n      model.hiddenLayers[0]\n    );\n    outputs.push(output);\n    // 1+ indices\n    for (let i = 1, max = hiddenLayers.length; i < max; i++) {\n      if (!equationConnection[i]) {\n        throw new Error(`Cannot find equation at index ${i}`);\n      }\n      output = this.getEquation(\n        equation,\n        output,\n        equationConnection[i],\n        model.hiddenLayers[i]\n      );\n      outputs.push(output);\n    }\n\n    model.equationConnections.push(outputs);\n    equation.add(\n      equation.multiply(model.outputConnector, output),\n      model.output\n    );\n    model.equations.push(equation);\n  }\n\n  mapModel(): IRNNModel {\n    const allMatrices: Matrix[] = [];\n    this.initialLayerInputs = this.options.hiddenLayers.map(\n      (size) => new Matrix(size, 1)\n    );\n\n    const input = this.createInputMatrix();\n    allMatrices.push(input);\n\n    const hiddenLayers = this.createHiddenLayers() as IRNNHiddenLayerModel[];\n    if (!hiddenLayers.length) throw new Error('net.hiddenLayers not set');\n    for (let i = 0, max = hiddenLayers.length; i < max; i++) {\n      const hiddenMatrix: IRNNHiddenLayerModel = hiddenLayers[i];\n      for (const property in hiddenMatrix) {\n        if (!hiddenMatrix.hasOwnProperty(property)) continue;\n        allMatrices.push(hiddenMatrix[property]);\n      }\n    }\n\n    const { output, outputConnector } = this.createOutputMatrices();\n    allMatrices.push(outputConnector);\n    allMatrices.push(output);\n\n    return Object.seal({\n      isInitialized: true,\n      input,\n      hiddenLayers,\n      output,\n      equations: [],\n      allMatrices,\n      equationConnections: [],\n      outputConnector,\n    });\n  }\n\n  trainInput(input: number[]): number {\n    this.runs++;\n    const { model } = this;\n    const max = input.length;\n    let log2ppl = 0;\n    let equation;\n    while (model.equations.length <= input.length + 1) {\n      // last is zero\n      this.bindEquation();\n    }\n    for (\n      let inputIndex = -1, inputMax = input.length;\n      inputIndex < inputMax;\n      inputIndex++\n    ) {\n      // start and end tokens are zeros\n      const equationIndex = inputIndex + 1;\n      equation = model.equations[equationIndex];\n\n      const source = inputIndex === -1 ? 0 : input[inputIndex] + 1; // first step: start with START token\n      const target = inputIndex === max - 1 ? 0 : input[inputIndex + 1] + 1; // last step: end with END token\n      log2ppl += equation.predictTargetIndex(source, target);\n    }\n    return Math.pow(2, log2ppl / (max - 1)) / 100;\n  }\n\n  backpropagate(input: number[]): void {\n    let i = input.length;\n    const { model } = this;\n    const { equations } = model;\n    while (i > 0) {\n      equations[i].backpropagateIndex(input[i - 1] + 1);\n      i--;\n    }\n    equations[0].backpropagateIndex(0);\n  }\n\n  adjustWeights(): void {\n    const { regc, clipval, decayRate, smoothEps } = this.options;\n    const { trainOpts, model, stepCache } = this;\n    const { learningRate } = trainOpts;\n    const { allMatrices } = model;\n    let numClipped = 0;\n    let numTot = 0;\n    for (let matrixIndex = 0; matrixIndex < allMatrices.length; matrixIndex++) {\n      const matrix = allMatrices[matrixIndex];\n      const { weights, deltas } = matrix;\n      if (!(matrixIndex in stepCache)) {\n        stepCache[matrixIndex] = zeros(matrix.rows * matrix.columns);\n      }\n      const cache = stepCache[matrixIndex];\n      for (let i = 0; i < weights.length; i++) {\n        let r = deltas[i];\n        const w = weights[i];\n        // rmsprop adaptive learning rate\n        cache[i] = cache[i] * decayRate + (1 - decayRate) * r * r;\n        // gradient clip\n        if (r > clipval) {\n          r = clipval;\n          numClipped++;\n        } else if (r < -clipval) {\n          r = -clipval;\n          numClipped++;\n        }\n        numTot++;\n        // update (and regularize)\n        weights[i] =\n          w + (-learningRate * r) / Math.sqrt(cache[i] + smoothEps) - regc * w;\n      }\n    }\n    this.ratioClipped = numClipped / numTot;\n  }\n\n  get isRunnable(): boolean {\n    if (this.model && this.model.equations.length === 0) {\n      console.error(`No equations bound, did you run train()?`);\n      return false;\n    }\n\n    return true;\n  }\n\n  checkRunnable(): void {\n    if (!this.isRunnable) {\n      throw new Error('Network not runnable');\n    }\n  }\n\n  run(rawInput: Value = [], isSampleI = false, temperature = 1): string {\n    const maxPredictionLength: number =\n      this.options.maxPredictionLength +\n      (rawInput !== null ? (rawInput as string).length : 0) +\n      (this.options.dataFormatter\n        ? this.options.dataFormatter.specialIndexes.length\n        : 0);\n\n    this.checkRunnable();\n\n    const input: number[] =\n      this.options.dataFormatter && (rawInput as string).length > 0\n        ? this.options.dataFormatter.formatDataIn(rawInput)\n        : (rawInput as number[]);\n    const { model } = this;\n    const output = [];\n    let i = 0;\n    while (true) {\n      const previousIndex =\n        i === 0 ? 0 : i < input.length ? input[i - 1] + 1 : output[i - 1];\n      while (model.equations.length <= i) {\n        this.bindEquation();\n      }\n      const equation = model.equations[i];\n      // sample predicted letter\n      const outputMatrix = equation.runIndex(previousIndex);\n      const logProbabilities = new Matrix(\n        model.output.rows,\n        model.output.columns\n      );\n      copy(logProbabilities, outputMatrix);\n      if (temperature !== 1 && isSampleI) {\n        /**\n         * scale log probabilities by temperature and re-normalize\n         * if temperature is high, logProbabilities will go towards zero\n         * and the softmax outputs will be more diffuse. if temperature is\n         * very low, the softmax outputs will be more peaky\n         */\n        for (let j = 0, max = logProbabilities.weights.length; j < max; j++) {\n          logProbabilities.weights[j] /= temperature;\n        }\n      }\n\n      const probs = softmax(logProbabilities);\n      const nextIndex = isSampleI ? sampleI(probs) : maxI(probs);\n\n      i++;\n      if (nextIndex === 0) {\n        // END token predicted, break out\n        break;\n      }\n      if (i >= maxPredictionLength) {\n        // something is wrong\n        break;\n      }\n\n      output.push(nextIndex);\n    }\n\n    /**\n     * we slice the input length here, not because output contains it, but it will be erroneous as we are sending the\n     * network what is contained in input, so the data is essentially guessed by the network what could be next, till it\n     * locks in on a value.\n     * Kind of like this, values are from input:\n     * 0 -> 4 (or in English: \"beginning on input\" -> \"I have no idea? I'll guess what they want next!\")\n     * 2 -> 2 (oh how interesting, I've narrowed down values...)\n     * 1 -> 9 (oh how interesting, I've now know what the values are...)\n     * then the output looks like: [4, 2, 9,...]\n     * so we then remove the erroneous data to get our true output\n     */\n    return this.options.dataFormatter.formatDataOut(\n      input,\n      output.slice(input.length).map((value) => value - 1)\n    );\n  }\n\n  /**\n   *\n   * Verifies network sizes are initialized\n   * If they are not it will initialize them\n   */\n  verifyIsInitialized(): void {\n    if (!this.model.isInitialized) {\n      this.initialize();\n    }\n  }\n\n  /**\n   *\n   * @param options\n   *    Supports all `trainDefaults` properties\n   *    also supports:\n   *       learningRate: (number),\n   *       momentum: (number),\n   *       activation: 'sigmoid', 'relu', 'leaky-relu', 'tanh'\n   */\n  updateTrainingOptions(options: Partial<IRNNTrainingOptions>): void {\n    this.trainOpts = { ...trainDefaults, ...options };\n    this.validateTrainingOptions(this.trainOpts as INeuralNetworkTrainOptions);\n    this.setLogMethod(options.log ?? this.trainOpts.log);\n    // TODO: Remove this?\n    // this.activation = options.activation || this.activation;\n  }\n\n  validateTrainingOptions(options: INeuralNetworkTrainOptions): void {\n    const validations: { [fnName: string]: () => boolean } = {\n      iterations: () => {\n        const val = options.iterations;\n        return typeof val === 'number' && val > 0;\n      },\n      errorThresh: () => {\n        const val = options.errorThresh;\n        return typeof val === 'number' && val > 0 && val < 1;\n      },\n      log: () => {\n        const val = options.log;\n        return typeof val === 'function' || typeof val === 'boolean';\n      },\n      logPeriod: () => {\n        const val = options.logPeriod;\n        return typeof val === 'number' && val > 0;\n      },\n      learningRate: () => {\n        const val = options.learningRate;\n        return typeof val === 'number' && val > 0 && val < 1;\n      },\n      callback: () => {\n        const val = options.callback;\n        return typeof val === 'function' || val === undefined;\n      },\n      callbackPeriod: () => {\n        const val = options.callbackPeriod;\n        return typeof val === 'number' && val > 0;\n      },\n      timeout: () => {\n        const val = options.timeout;\n        return typeof val === 'number' && val > 0;\n      },\n    };\n    for (const p in validations) {\n      const v = (options as unknown) as { [v: string]: string };\n      if (!validations[p]()) {\n        throw new Error(\n          `[${p}, ${v[p]}] is out of normal training range, your network will probably not train.`\n        );\n      }\n    }\n  }\n\n  setLogMethod(log: Log | undefined | boolean): void {\n    if (typeof log === 'function') {\n      this.trainOpts.log = log;\n    } else if (log) {\n      this.trainOpts.log = console.log;\n    } else {\n      this.trainOpts.log = false;\n    }\n  }\n\n  protected prepTraining(\n    data: Array<Value | IRNNDatum>,\n    options: Partial<IRNNTrainingOptions>\n  ): IRNNPreppedTrainingData {\n    this.updateTrainingOptions(options);\n    const preparedData = this.options.dataFormatter.format(data);\n    const endTime = Date.now() + (this.trainOpts.timeout ?? 0);\n\n    const status = {\n      error: 1,\n      iterations: 0,\n    };\n\n    this.verifyIsInitialized();\n\n    return {\n      preparedData,\n      status,\n      endTime,\n    };\n  }\n\n  train(\n    data: Array<Value | IRNNDatum>,\n    trainOpts: Partial<IRNNTrainingOptions> = {}\n  ): IRNNStatus {\n    this.trainOpts = trainOpts = {\n      ...trainDefaults,\n      ...trainOpts,\n    };\n    const {\n      iterations,\n      errorThresh,\n      logPeriod,\n      callback,\n      callbackPeriod,\n    } = this.trainOpts;\n    const log = trainOpts.log === true ? console.log : trainOpts.log;\n    let error = Infinity;\n    let i;\n\n    let inputs: number[][];\n    if (this.options?.dataFormatter) {\n      inputs = this.options.dataFormatter.format(data);\n    } else if (\n      Array.isArray(data) &&\n      Array.isArray(data[0]) &&\n      typeof (data as number[][])[0][0] === 'number'\n    ) {\n      inputs = data as number[][];\n    } else {\n      throw new Error('training not in expected format of number[][]');\n    }\n\n    this.verifyIsInitialized();\n\n    for (i = 0; i < iterations && error > errorThresh; i++) {\n      let sum = 0;\n      for (let j = 0; j < inputs.length; j++) {\n        const err = this.trainPattern(inputs[j], true);\n        sum += err;\n      }\n      error = sum / data.length;\n\n      if (isNaN(error)) {\n        throw new Error(\n          'Network error rate is unexpected NaN, check network configurations and try again. Most probably input format is not correct or training data is not enough. '\n        );\n      }\n      if (log && i % logPeriod === 0) {\n        log(`iterations: ${i}, training error: ${error}`);\n      }\n      if (callback && i % callbackPeriod === 0) {\n        callback({ error, iterations: i });\n      }\n    }\n\n    return {\n      error,\n      iterations: i,\n    };\n  }\n\n  addFormat(): void {\n    throw new Error('not yet implemented');\n  }\n\n  toJSON(): IRNNJSON {\n    if (!this.model.isInitialized) {\n      this.initialize();\n    }\n    const { model, options } = this;\n\n    return {\n      type: this.constructor.name,\n      options: { ...options, dataFormatter: options.dataFormatter.toJSON() },\n      trainOpts: {\n        ...this.trainOpts,\n        timeout:\n          this.trainOpts.timeout === Infinity\n            ? 'Infinity'\n            : this.trainOpts.timeout,\n      },\n      input: model.input.toJSON(),\n      hiddenLayers: model.hiddenLayers.map((hiddenLayer) => {\n        const layers: { [index: string]: IMatrixJSON } = {};\n        for (const p in hiddenLayer) {\n          if (!hiddenLayer.hasOwnProperty(p)) continue;\n          layers[p] = hiddenLayer[p].toJSON();\n        }\n        return layers;\n      }),\n      outputConnector: this.model.outputConnector.toJSON(),\n      output: this.model.output.toJSON(),\n    };\n  }\n\n  fromJSON(json: IRNNJSON): this {\n    const { options } = json;\n    const allMatrices = [];\n    const input = Matrix.fromJSON(json.input);\n    allMatrices.push(input);\n    const hiddenLayers: IRNNHiddenLayerModel[] = [];\n\n    json.hiddenLayers.forEach((hiddenLayer) => {\n      const layers: { [index: string]: Matrix } = {};\n      for (const p in hiddenLayer) {\n        layers[p] = Matrix.fromJSON(hiddenLayer[p]);\n        allMatrices.push(layers[p]);\n      }\n      hiddenLayers.push(layers as IRNNHiddenLayerModel);\n    });\n\n    const outputConnector = Matrix.fromJSON(json.outputConnector);\n    allMatrices.push(outputConnector);\n    const output = Matrix.fromJSON(json.output);\n    allMatrices.push(output);\n\n    if (options.dataFormatter) {\n      this.options = {\n        ...defaults(),\n        ...options,\n        dataFormatter: DataFormatter.fromJSON(options.dataFormatter),\n      };\n    } else {\n      this.options = {\n        ...defaults(),\n        ...options,\n        dataFormatter: new DataFormatter(),\n      };\n    }\n\n    this.model = Object.seal({\n      isInitialized: true,\n      input,\n      hiddenLayers,\n      output,\n      allMatrices,\n      outputConnector,\n      equations: [],\n      equationConnections: [],\n    });\n    this.initialLayerInputs = this.options.hiddenLayers.map(\n      (size) => new Matrix(size, 1)\n    );\n    this.bindEquation();\n    return this;\n  }\n\n  toFunction(cb?: (src: string) => string): RNNFunction {\n    const { model } = this;\n    const { equations } = this.model;\n    const equation = equations[1];\n    const { states } = equation;\n    const jsonString = JSON.stringify(this.toJSON());\n\n    function previousConnectionIndex(m: Matrix): number {\n      const connection = model.equationConnections[0];\n      const { states } = equations[0];\n      for (let i = 0, max = states.length; i < max; i++) {\n        if (states[i].product === m) {\n          return i;\n        }\n      }\n      return connection.indexOf(m);\n    }\n\n    function matrixOrigin(m: Matrix, stateIndex: number): string {\n      for (let i = 0, max = states.length; i < max; i++) {\n        const state = states[i];\n\n        if (i === stateIndex) {\n          const j = previousConnectionIndex(m);\n          if (j > -1 && (m === state.left || m === state.right)) {\n            return `typeof prevStates[${j}] === 'object' ? prevStates[${j}].product : new Matrix(${m.rows}, ${m.columns})`;\n          }\n          return `new Matrix(${m.rows}, ${m.columns})`;\n        }\n\n        if (m === state.product) return `states[${i}].product`;\n        if (m === state.right) return `states[${i}].right`;\n        if (m === state.left) return `states[${i}].left`;\n      }\n      return '';\n    }\n\n    function matrixToString(m: Matrix, stateIndex: number): string {\n      if (!m || !m.rows || !m.columns) return 'null';\n\n      if (m === model.input) return `json.input`;\n      if (m === model.outputConnector) return `json.outputConnector`;\n      if (m === model.output) return `json.output`;\n\n      for (let i = 0, max = model.hiddenLayers.length; i < max; i++) {\n        const hiddenLayer = model.hiddenLayers[i];\n        for (const p in hiddenLayer) {\n          if (!hiddenLayer.hasOwnProperty(p)) continue;\n          if (hiddenLayer[p] !== m) continue;\n          return `json.hiddenLayers[${i}].${p}`;\n        }\n      }\n\n      return matrixOrigin(m, stateIndex);\n    }\n\n    function toInner(fnString: string): string {\n      // crude, but should be sufficient for now\n      // function() { body }\n      const fnParts = fnString.toString().split('{');\n      fnParts.shift();\n      // body }\n      const fnBodyString = fnParts.join('{');\n      const fnBodyParts = fnBodyString.split('}');\n      fnBodyParts.pop();\n      // body\n      return fnBodyParts\n        .join('}')\n        .split('\\n')\n        .join('\\n        ')\n        .replace('product.deltas[i] = 0;', '')\n        .replace('product.deltas[column] = 0;', '')\n        .replace('left.deltas[leftIndex] = 0;', '')\n        .replace('right.deltas[rightIndex] = 0;', '')\n        .replace('product.deltas = left.deltas.slice(0);', '');\n    }\n\n    function fileName(fnName: string): string {\n      return `src/recurrent/matrix/${fnName.replace(/[A-Z]/g, function (value) {\n        return `-${value.toLowerCase()}`;\n      })}.js`;\n    }\n\n    const statesRaw = [];\n    const usedFunctionNames: { [methodName: string]: boolean } = {};\n    const innerFunctionsSwitch = [];\n    for (let i = 0, max = states.length; i < max; i++) {\n      const state = states[i];\n      statesRaw.push(`states[${i}] = {\n      name: '${state.forwardFn.name}',\n      left: ${state.left ? matrixToString(state.left, i) : 'undefined'},\n      right: ${state.right ? matrixToString(state.right, i) : 'undefined'},\n      product: ${matrixToString(state.product, i)}\n    }`);\n\n      const fnName = state.forwardFn.name;\n      if (!usedFunctionNames[fnName]) {\n        usedFunctionNames[fnName] = true;\n        innerFunctionsSwitch.push(\n          `        case '${fnName}': //compiled from ${fileName(fnName)}\n          ${toInner(state.forwardFn.toString())}\n          break;`\n        );\n      }\n    }\n\n    const src = `\n  if (typeof rawInput === 'undefined') rawInput = [];\n  if (typeof isSampleI === 'undefined') isSampleI = false;\n  if (typeof temperature === 'undefined') temperature = 1;\n  var json = ${jsonString};\n  ${\n    this.options.dataFormatter\n      ? `${this.options.dataFormatter.toFunctionString()};\n  Object.assign(dataFormatter, json.options.dataFormatter);`\n      : ''\n  }\n  ${\n    this.options.dataFormatter &&\n    typeof this.options.dataFormatter.formatDataIn === 'function'\n      ? `const formatDataIn = function (input, output) { ${toInner(\n          this.options.dataFormatter.formatDataIn.toString()\n        )} }.bind(dataFormatter);`\n      : ''\n  }\n  ${\n    this.options.dataFormatter !== null &&\n    typeof this.options.dataFormatter.formatDataOut === 'function'\n      ? `const formatDataOut = function formatDataOut(input, output) { ${toInner(\n          this.options.dataFormatter.formatDataOut.toString()\n        )} }.bind(dataFormatter);`\n      : ''\n  }\n  var maxPredictionLength =\n    ${this.options.maxPredictionLength} +\n    rawInput.length +\n    ${\n      this.options.dataFormatter\n        ? this.options.dataFormatter.specialIndexes.length\n        : 0\n    };\n  var input = ${\n    this.options.dataFormatter &&\n    typeof this.options.dataFormatter.formatDataIn === 'function'\n      ? 'formatDataIn(rawInput)'\n      : 'rawInput'\n  };\n  var _i = 0;\n  var output = [];\n  var states = [];\n  var prevStates;\n  while (true) {\n    var previousIndex = (_i === 0\n        ? 0\n        : _i < input.length\n          ? input[_i - 1] + 1\n          : output[_i - 1])\n          ;\n    var rowPluckIndex = previousIndex;\n    prevStates = states;\n    states = [];\n    ${statesRaw.join(';\\n    ')};\n    for (var stateIndex = 0, stateMax = ${\n      statesRaw.length\n    }; stateIndex < stateMax; stateIndex++) {\n      var state = states[stateIndex];\n      var product = state.product;\n      var left = state.left;\n      var right = state.right;\n      switch (state.name) {\n${innerFunctionsSwitch.join('\\n')}\n      }\n    }\n\n    var logProbabilities = state.product;\n    if (temperature !== 1 && isSampleI) {\n      for (var q = 0, nq = logProbabilities.weights.length; q < nq; q++) {\n        logProbabilities.weights[q] /= temperature;\n      }\n    }\n\n    var probs = softmax(logProbabilities);\n    var nextIndex = isSampleI ? sampleI(probs) : maxI(probs);\n\n    _i++;\n    if (nextIndex === 0) {\n      break;\n    }\n    if (_i >= maxPredictionLength) {\n      break;\n    }\n\n    output.push(nextIndex);\n  }\n  ${\n    this.options.dataFormatter &&\n    typeof this.options.dataFormatter.formatDataOut === 'function'\n      ? 'return formatDataOut(input, output.slice(input.length).map(function(value) { return value - 1; }))'\n      : 'return output.slice(input.length).map(function(value) { return value - 1; })'\n  };\n  function Matrix(rows, columns) {\n    this.rows = rows;\n    this.columns = columns;\n    this.weights = zeros(rows * columns);\n  }\n  ${zeros.toString()}\n  ${softmax.toString().replace('_1.Matrix', 'Matrix')}\n  ${randomFloat.toString()}\n  ${sampleI.toString()}\n  ${maxI.toString()}`;\n    // eslint-disable-next-line\n    return new Function(\n      'rawInput',\n      'isSampleI',\n      'temperature',\n      cb ? cb(src) : src\n    ) as RNNFunction;\n  }\n\n  trainPattern(input: number[], logErrorRate?: boolean): number {\n    const error = this.trainInput(input);\n    this.backpropagate(input);\n    this.adjustWeights();\n\n    if (logErrorRate) {\n      return error;\n    }\n    return 0;\n  }\n}\n\nexport interface IRNNJSON {\n  type: string;\n  options: IRNNJSONOptions;\n  trainOpts: IRNNJSONTrainOptions;\n  input: IMatrixJSON;\n  hiddenLayers: Array<{ [index: string]: IMatrixJSON }>;\n  outputConnector: IMatrixJSON;\n  output: IMatrixJSON;\n}\n\nexport function last<T>(values: T[]): T {\n  return values[values.length - 1];\n}\n\nexport type RNNFunction = (\n  rawInput?: Array<Value | IRNNDatum> | string,\n  isSampleI?: boolean,\n  temperature?: number\n) => string;\n","import { Matrix } from '.';\n\nexport function copy(product: Matrix, left: Matrix): void {\n  product.rows = left.rows;\n  product.columns = left.columns;\n  product.weights = left.weights.slice(0);\n  product.deltas = left.deltas.slice(0);\n}\n","import { Matrix } from './matrix';\nimport { Equation } from './matrix/equation';\nimport { RandomMatrix } from './matrix/random-matrix';\nimport { IRNNHiddenLayer, RNN } from './rnn';\n\nexport interface IGRUHiddenLayer extends IRNNHiddenLayer {\n  updateGateInputMatrix: RandomMatrix;\n  updateGateHiddenMatrix: RandomMatrix;\n  updateGateBias: Matrix;\n  resetGateInputMatrix: RandomMatrix;\n  resetGateHiddenMatrix: RandomMatrix;\n  resetGateBias: Matrix;\n  cellWriteInputMatrix: RandomMatrix;\n  cellWriteHiddenMatrix: RandomMatrix;\n  cellWriteBias: Matrix;\n}\n\nexport class GRU extends RNN {\n  getHiddenLayer(hiddenSize: number, prevSize: number): IRNNHiddenLayer {\n    return getGRUHiddenLayer(hiddenSize, prevSize);\n  }\n\n  getEquation(\n    equation: Equation,\n    inputMatrix: Matrix,\n    previousResult: Matrix,\n    hiddenLayer: IRNNHiddenLayer\n  ): Matrix {\n    return getGRUEquation(\n      equation,\n      inputMatrix,\n      previousResult,\n      hiddenLayer as IGRUHiddenLayer\n    );\n  }\n}\n\nexport function getGRUHiddenLayer(\n  hiddenSize: number,\n  prevSize: number\n): IGRUHiddenLayer {\n  return {\n    // update Gate\n    // wzxh\n    updateGateInputMatrix: new RandomMatrix(hiddenSize, prevSize, 0.08), // wzhh\n    updateGateHiddenMatrix: new RandomMatrix(hiddenSize, hiddenSize, 0.08), // bz\n    updateGateBias: new Matrix(hiddenSize, 1),\n    // reset Gate\n    // wrxh\n    resetGateInputMatrix: new RandomMatrix(hiddenSize, prevSize, 0.08), // wrhh\n    resetGateHiddenMatrix: new RandomMatrix(hiddenSize, hiddenSize, 0.08), // br\n    resetGateBias: new Matrix(hiddenSize, 1),\n    // cell write parameters\n    // wcxh\n    cellWriteInputMatrix: new RandomMatrix(hiddenSize, prevSize, 0.08), // wchh\n    cellWriteHiddenMatrix: new RandomMatrix(hiddenSize, hiddenSize, 0.08), // bc\n    cellWriteBias: new Matrix(hiddenSize, 1),\n  };\n}\n\nexport function getGRUEquation(\n  equation: Equation,\n  inputMatrix: Matrix,\n  previousResult: Matrix,\n  hiddenLayer: IGRUHiddenLayer\n): Matrix {\n  if (\n    !hiddenLayer.updateGateInputMatrix ||\n    !hiddenLayer.updateGateHiddenMatrix ||\n    !hiddenLayer.updateGateBias ||\n    !hiddenLayer.resetGateInputMatrix ||\n    !hiddenLayer.resetGateHiddenMatrix ||\n    !hiddenLayer.resetGateBias ||\n    !hiddenLayer.cellWriteInputMatrix ||\n    !hiddenLayer.cellWriteHiddenMatrix ||\n    !hiddenLayer.cellWriteBias\n  ) {\n    throw new Error('hiddenLayer does not have expected properties');\n  }\n\n  const sigmoid = equation.sigmoid.bind(equation);\n  const add = equation.add.bind(equation);\n  const multiply = equation.multiply.bind(equation);\n  const multiplyElement = equation.multiplyElement.bind(equation);\n  const tanh = equation.tanh.bind(equation);\n  const allOnes = equation.allOnes.bind(equation);\n  const cloneNegative = equation.cloneNegative.bind(equation);\n\n  // update gate\n  const updateGate = sigmoid(\n    add(\n      add(\n        multiply(hiddenLayer.updateGateInputMatrix, inputMatrix),\n        multiply(hiddenLayer.updateGateHiddenMatrix, previousResult)\n      ),\n      hiddenLayer.updateGateBias\n    )\n  );\n\n  // reset gate\n  const resetGate = sigmoid(\n    add(\n      add(\n        multiply(hiddenLayer.resetGateInputMatrix, inputMatrix),\n        multiply(hiddenLayer.resetGateHiddenMatrix, previousResult)\n      ),\n      hiddenLayer.resetGateBias\n    )\n  );\n\n  // cell\n  const cell = tanh(\n    add(\n      add(\n        multiply(hiddenLayer.cellWriteInputMatrix, inputMatrix),\n        multiply(\n          hiddenLayer.cellWriteHiddenMatrix,\n          multiplyElement(resetGate, previousResult)\n        )\n      ),\n      hiddenLayer.cellWriteBias\n    )\n  );\n\n  // compute hidden state as gated, saturated cell activations\n  // negate updateGate\n  return add(\n    multiplyElement(\n      add(\n        allOnes(updateGate.rows, updateGate.columns),\n        cloneNegative(updateGate)\n      ),\n      cell\n    ),\n    multiplyElement(previousResult, updateGate)\n  );\n}\n","export class ArrayLookupTable {\n  length = 0;\n  table: { [key: string]: number } = {};\n\n  constructor(\n    data: Array<{\n      input: Array<Record<string, number>>;\n      output: Array<Record<string, number>>;\n    }>,\n    public prop: 'input' | 'output'\n  ) {\n    for (let i = 0; i < data.length; i++) {\n      const datum = data[i];\n      const ioValue = datum[prop];\n      for (let j = 0; j < ioValue.length; j++) {\n        const value = ioValue[j];\n        for (const p in value) {\n          if (!value.hasOwnProperty(p)) continue;\n          if (this.table.hasOwnProperty(p)) continue;\n          this.table[p] = this.length++;\n        }\n      }\n    }\n  }\n}\n","import {\n  FormattableData,\n  InputOutputValue,\n  INumberArray,\n  INumberHash,\n  ITrainingDatum,\n  lookup,\n} from '../lookup';\nimport { ArrayLookupTable } from '../utilities/array-lookup-table';\nimport {\n  arraysToFloat32Arrays,\n  arrayToFloat32Arrays,\n  inputOutputArraysToFloat32Arrays,\n  inputOutputArrayToFloat32Arrays,\n  inputOutputObjectsToFloat32Arrays,\n  inputOutputObjectToFloat32Arrays,\n  objectToFloat32Array,\n  objectToFloat32Arrays,\n} from '../utilities/cast';\nimport { LookupTable } from '../utilities/lookup-table';\nimport { randomFloat } from '../utilities/random';\nimport { IMatrixJSON, Matrix } from './matrix';\nimport { Equation } from './matrix/equation';\nimport { maxI } from './matrix/max-i';\nimport { RandomMatrix } from './matrix/random-matrix';\nimport { sampleI } from './matrix/sample-i';\nimport { softmax } from './matrix/softmax';\nimport {\n  defaults as rnnDefaults,\n  IRNNHiddenLayer,\n  IRNNHiddenLayerModel,\n  IRNNOptions,\n  IRNNStatus,\n  IRNNTrainingOptions,\n  last,\n  RNN,\n  trainDefaults as rnnTrainDefaults,\n} from './rnn';\n\nexport type ValuesOf<\n  T extends InputOutputValue | InputOutputValue[]\n> = T[number];\n\nexport interface IRNNTimeStepOptions extends IRNNTimeStepJSONOptions {\n  inputSize: number;\n  inputRange: number;\n  hiddenLayers: number[];\n  outputSize: number;\n  decayRate: number;\n  smoothEps: number;\n  regc: number;\n  clipval: number;\n  maxPredictionLength: number;\n  json?: IRNNTimeStepJSON;\n}\n\nexport interface IRNNTimeStepJSONOptions {\n  inputSize: number;\n  inputRange: number;\n  hiddenLayers: number[];\n  outputSize: number;\n  decayRate: number;\n  smoothEps: number;\n  regc: number;\n  clipval: number;\n  maxPredictionLength: number;\n}\n\nexport interface IRNNTimeStepJSON {\n  type: string;\n  options: IRNNTimeStepJSONOptions;\n  hiddenLayers: Array<{ [index: string]: IMatrixJSON }>;\n  outputConnector: IMatrixJSON;\n  output: IMatrixJSON;\n  inputLookup: INumberHash | null;\n  inputLookupLength: number;\n  outputLookup: INumberHash | null;\n  outputLookupLength: number;\n}\n\nexport interface IMisclass {\n  value: FormattableData;\n  actual: FormattableData;\n}\n\nexport interface ITestResults {\n  misclasses: IMisclass[];\n  error: number;\n  total: number;\n}\n\nexport interface IRNNTimeStepModel {\n  isInitialized: boolean;\n  hiddenLayers: IRNNHiddenLayer[];\n  output: Matrix;\n  equations: Equation[];\n  allMatrices: Matrix[];\n  equationConnections: Matrix[][];\n  outputConnector: RandomMatrix | Matrix;\n}\n\nexport const defaults = (): IRNNOptions => {\n  return {\n    ...rnnDefaults(),\n    inputSize: 1,\n    hiddenLayers: [20],\n    outputSize: 1,\n    inputRange: 0,\n  };\n};\n\nexport class RNNTimeStep extends RNN {\n  inputLookupLength = 0;\n  inputLookup: INumberHash | null = null;\n  outputLookup: INumberHash | null = null;\n  outputLookupLength = 0;\n\n  // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n  // @ts-expect-error\n  model: IRNNTimeStepModel = Object.seal({\n    isInitialized: false,\n    hiddenLayers: [],\n    output: new Matrix(0, 0),\n    equations: [],\n    allMatrices: [],\n    equationConnections: [],\n    outputConnector: new RandomMatrix(0, 0, 0.08),\n  });\n\n  // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n  // @ts-expect-error\n  options: IRNNTimeStepOptions = defaults();\n  constructor(\n    options: Partial<IRNNTimeStepOptions & IRNNTrainingOptions> = {}\n  ) {\n    super();\n    this.options = { ...this.options, ...options };\n    this.updateTrainingOptions({\n      ...trainDefaults,\n      ...options,\n    });\n\n    if (options.json) {\n      this.fromJSON(options.json);\n    }\n  }\n\n  createInputMatrix(): RandomMatrix {\n    throw new Error('Input Matrices do not exist on RNNTimeStep');\n  }\n\n  createOutputMatrices(): { outputConnector: RandomMatrix; output: Matrix } {\n    const { outputSize } = this.options;\n    const lastHiddenSize = last(this.options.hiddenLayers);\n\n    // whd\n    const outputConnector = new RandomMatrix(outputSize, lastHiddenSize, 0.08);\n    // bd\n    const output = new RandomMatrix(outputSize, 1, 0.08);\n    return { output, outputConnector };\n  }\n\n  bindEquation(): void {\n    const { model, options } = this;\n    const { hiddenLayers, inputSize } = options;\n    const layers = model.hiddenLayers;\n    const equation = new Equation();\n    const outputs = [];\n    const equationConnection =\n      model.equationConnections.length > 0\n        ? model.equationConnections[model.equationConnections.length - 1]\n        : this.initialLayerInputs;\n    // 0 index\n    let output = this.getEquation(\n      equation,\n      equation.input(new Matrix(inputSize, 1)),\n      equationConnection[0],\n      layers[0]\n    );\n    outputs.push(output);\n    // 1+ indices\n    for (let i = 1, max = hiddenLayers.length; i < max; i++) {\n      output = this.getEquation(\n        equation,\n        output,\n        equationConnection[i],\n        layers[i]\n      );\n      outputs.push(output);\n    }\n\n    model.equationConnections.push(outputs);\n    equation.add(\n      equation.multiply(model.outputConnector, output),\n      model.output\n    );\n    model.equations.push(equation);\n  }\n\n  initialize(): void {\n    this.model = this.mapModel();\n  }\n\n  // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n  // @ts-expect-error\n  mapModel(): IRNNTimeStepModel {\n    const allMatrices: Matrix[] = [];\n    this.initialLayerInputs = this.options.hiddenLayers.map(\n      (size) => new Matrix(size, 1)\n    );\n\n    const hiddenLayers = this.createHiddenLayers();\n    for (let i = 0, max = hiddenLayers.length; i < max; i++) {\n      const hiddenMatrix = hiddenLayers[i];\n      for (const property in hiddenMatrix) {\n        if (!hiddenMatrix.hasOwnProperty(property)) continue;\n        allMatrices.push(hiddenMatrix[property]);\n      }\n    }\n\n    const { outputConnector, output } = this.createOutputMatrices();\n\n    allMatrices.push(outputConnector);\n    allMatrices.push(output);\n    return Object.seal({\n      isInitialized: true,\n      hiddenLayers,\n      output,\n      equations: [],\n      allMatrices,\n      equationConnections: [],\n      outputConnector,\n    });\n  }\n\n  backpropagate(): void {\n    for (let i = this.model.equations.length - 1; i > -1; i--) {\n      this.model.equations[i].backpropagate();\n    }\n  }\n\n  // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n  // @ts-expect-error\n  run<InputType extends InputOutputValue | InputOutputValue[]>(\n    rawInput: InputType\n  ): ValuesOf<InputType> {\n    const shape = lookup.dataShape(rawInput).join(',');\n    switch (shape) {\n      case 'array,number':\n        // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n        // @ts-expect-error\n        return this.runArray(rawInput as Float32Array);\n      case 'array,array,number':\n        // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n        // @ts-expect-error\n        return this.runArrayOfArray(rawInput as Float32Array[]);\n      case 'object,number':\n        // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n        // @ts-expect-error\n        return this.runObject(rawInput as INumberHash); // Backward compatibility, will be result of `unknown` and need casting.  Better to just use net.runObject() directly\n      case 'array,object,number':\n        // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n        // @ts-expect-error\n        return this.runArrayOfObject(rawInput as INumberHash[]);\n      default:\n        throw new Error(`Unrecognized data shape ${shape}`);\n    }\n  }\n\n  forecast<InputType extends InputOutputValue | InputOutputValue[]>(\n    rawInput: InputType,\n    count = 1\n  ): InputType {\n    const shape = lookup.dataShape(rawInput).join(',');\n    switch (shape) {\n      case 'array,number':\n        // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n        // @ts-expect-error\n        return this.forecastArray(rawInput as Float32Array, count);\n      case 'array,array,number':\n        // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n        // @ts-expect-error\n        return this.forecastArrayOfArray(rawInput as Float32Array[], count);\n      case 'object,number':\n        // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n        // @ts-expect-error\n        return this.runObject(rawInput as INumberHash);\n      case 'array,object,number':\n        // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n        // @ts-expect-error\n        return this.forecastArrayOfObject(rawInput as INumberHash[], count);\n      default:\n        throw new Error(`Unrecognized data shape ${shape}`);\n    }\n  }\n\n  forecastArray(input: Float32Array, count = 1): Float32Array {\n    this.checkRunnable();\n    const { model } = this;\n    const { equations } = model;\n    const length = input.length + count;\n    while (equations.length <= length) {\n      this.bindEquation();\n    }\n    let lastOutput;\n    let equationIndex = 0;\n    if (this.options.inputSize === 1) {\n      for (let i = 0; i < input.length; i++) {\n        lastOutput = equations[equationIndex++].runInput(\n          Float32Array.from([input[i]])\n        );\n      }\n    } else {\n      for (let i = 0; i < input.length; i++) {\n        lastOutput = equations[equationIndex++].runInput(Float32Array.from([]));\n      }\n    }\n    if (!lastOutput) {\n      throw new Error('lastOutput not set');\n    }\n    const result = [lastOutput.weights[0]];\n    for (let i = 0, max = count - 1; i < max; i++) {\n      lastOutput = equations[equationIndex++].runInput(lastOutput.weights);\n      result.push(lastOutput.weights[0]);\n    }\n    this.end();\n    return Float32Array.from(result);\n  }\n\n  forecastArrayOfArray(input: Float32Array[], count = 1): Float32Array[] {\n    this.checkRunnable();\n    const { model } = this;\n    const { equations } = model;\n    const length = input.length + count;\n    while (equations.length <= length) {\n      this.bindEquation();\n    }\n    let lastOutput;\n    let equationIndex = 0;\n    for (let i = 0; i < input.length; i++) {\n      lastOutput = equations[equationIndex++].runInput(input[i]);\n    }\n    if (!lastOutput) {\n      throw new Error('lastOutput not set');\n    }\n    const result = [Float32Array.from(lastOutput.weights)];\n    for (let i = 0, max = count - 1; i < max; i++) {\n      lastOutput = equations[equationIndex++].runInput(lastOutput.weights);\n      result.push(Float32Array.from(lastOutput.weights.slice(0)));\n    }\n    this.end();\n    return result;\n  }\n\n  forecastArrayOfObject(input: INumberHash[], count = 1): INumberHash[] {\n    if (!this.inputLookup) {\n      throw new Error('this.inputLookup not set');\n    }\n    if (!this.outputLookup) {\n      throw new Error('this.outputLookup not set');\n    }\n    const formattedData = input.map((value) =>\n      lookup.toArray(\n        this.inputLookup as INumberHash,\n        value,\n        this.inputLookupLength\n      )\n    );\n    return this.forecastArrayOfArray(formattedData, count).map((value) =>\n      lookup.toObject(this.outputLookup as INumberHash, value)\n    );\n  }\n\n  // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n  // @ts-expect-error\n  train(\n    data: FormattableData[],\n    trainOpts: Partial<IRNNTrainingOptions> = {}\n  ): IRNNStatus {\n    this.trainOpts = trainOpts = {\n      ...rnnTrainDefaults,\n      ...trainOpts,\n    };\n    // Don't destructure here because this.setSize() can reset this.options.\n    if (this.options.inputSize === 1 && this.options.outputSize === 1) {\n      this.setSize(data);\n    }\n    this.verifySize();\n\n    const formattedData = this.formatData(data);\n    let error = Infinity;\n    let i;\n\n    this.verifyIsInitialized();\n    const {\n      iterations,\n      errorThresh,\n      logPeriod,\n      callback,\n      callbackPeriod,\n    } = this.trainOpts;\n    const log = trainOpts.log === true ? console.log : trainOpts.log;\n    for (i = 0; i < iterations && error > errorThresh; i++) {\n      let sum = 0;\n      for (let j = 0; j < formattedData.length; j++) {\n        const err = this.trainPattern(formattedData[j], true);\n        sum += err;\n      }\n      error = sum / formattedData.length;\n\n      if (isNaN(error))\n        throw new Error(\n          'Network error rate is unexpected NaN, check network configurations and try again. Most probably input format is not correct or training data is not enough. '\n        );\n      if (log && i % logPeriod === 0) {\n        log(`iterations: ${i}, training error: ${error}`);\n      }\n      if (callback && i % callbackPeriod === 0) {\n        callback({ error, iterations: i });\n      }\n    }\n\n    return {\n      error,\n      iterations: i,\n    };\n  }\n\n  trainArrayOfArray(input: Float32Array[]): number {\n    if (input.length < 2) {\n      throw new Error('input must be an array of 2 or more');\n    }\n    const { equations } = this.model;\n    while (equations.length < input.length) {\n      this.bindEquation();\n    }\n    let errorSum = 0;\n    for (let i = 0, max = input.length - 1; i < max; i++) {\n      errorSum += equations[i].predictTarget(input[i], input[i + 1]);\n    }\n    this.end();\n    return errorSum / input.length;\n  }\n\n  // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n  // @ts-expect-error\n  trainPattern(input: Float32Array[], logErrorRate?: boolean): number {\n    const error = this.trainArrayOfArray(input);\n    this.backpropagate();\n    this.adjustWeights();\n\n    if (logErrorRate) {\n      return error;\n    }\n    return 0;\n  }\n\n  setSize(data: FormattableData[]): void {\n    let size = 0;\n    const dataShape = lookup.dataShape(data).join(',');\n    switch (dataShape) {\n      case 'array,array,number':\n      case 'array,object,number':\n      case 'array,datum,array,number':\n      case 'array,datum,object,number':\n        size = 1;\n        // probably 1\n        break;\n      case 'array,array,array,number':\n        size = (data as number[][][])[0][0].length;\n        break;\n      case 'array,array,object,number':\n        // inputs and outputs should match\n        size = Object.keys(lookup.toTable2D(data as INumberHash[][])).length;\n        break;\n      case 'array,datum,array,array,number':\n        size = ((data as unknown) as Array<{\n          [key: string]: number[][];\n        }>)[0].input[0].length;\n        break;\n      case 'array,datum,array,object,number':\n        size = Object.keys(\n          lookup.toInputTable2D(\n            data as Array<{ input: Array<{ [key: string]: number }> }>\n          )\n        ).length;\n        break;\n      default:\n        throw new Error('unknown data shape or configuration');\n    }\n    this.options = Object.seal({\n      ...this.options,\n      inputSize: size,\n      outputSize: size,\n    });\n  }\n\n  verifySize(): void {\n    if (this.options.inputSize || this.options.outputSize) {\n      if (this.options.inputSize !== this.options.outputSize) {\n        throw new Error('manually set inputSize and outputSize mismatch');\n      }\n    }\n  }\n\n  runArray(input: Float32Array): number {\n    this.checkRunnable();\n    const { equations } = this.model;\n    while (equations.length <= input.length) {\n      this.bindEquation();\n    }\n    let lastOutput;\n    for (let i = 0; i < input.length; i++) {\n      lastOutput = equations[i].runInput(new Float32Array([input[i]]));\n    }\n    this.end();\n    return (lastOutput as Matrix).weights[0];\n  }\n\n  runArrayOfArray(input: Float32Array[]): Float32Array {\n    this.checkRunnable();\n    const { model } = this;\n    const { equations } = model;\n    while (equations.length <= input.length) {\n      this.bindEquation();\n    }\n    let lastOutput;\n    for (let i = 0; i < input.length; i++) {\n      const outputMatrix = equations[i].runInput(input[i]);\n      lastOutput = outputMatrix.weights;\n    }\n    this.end();\n    return lastOutput ?? Float32Array.from([]);\n  }\n\n  runObject(input: INumberHash): INumberHash {\n    if (!this.inputLookup) {\n      throw new Error('this.inputLookup not set');\n    }\n    if (!this.outputLookup) {\n      throw new Error('this.outputLookup not set');\n    }\n    if (!this.outputLookupLength) {\n      throw new Error('this.outputLookupLength not set');\n    }\n    if (this.inputLookup === this.outputLookup) {\n      const inputArray = lookup.toArrayShort(this.inputLookup, input);\n      return lookup.toObjectPartial(\n        this.outputLookup,\n        this.forecastArray(\n          inputArray,\n          this.outputLookupLength - inputArray.length\n        ),\n        inputArray.length\n      );\n    }\n    return lookup.toObject(\n      this.outputLookup,\n      this.forecastArray(\n        lookup.toArray(this.inputLookup, input, this.inputLookupLength),\n        this.outputLookupLength\n      )\n    );\n  }\n\n  runArrayOfObject(input: INumberHash[]): INumberHash {\n    if (this.inputLookup === null) {\n      throw new Error('this.inputLookup not set');\n    }\n    if (this.outputLookup === null) {\n      throw new Error('this.outputLookup not set');\n    }\n    const formattedInput = input.map((value) =>\n      lookup.toArray(\n        this.inputLookup as INumberHash,\n        value,\n        this.inputLookupLength\n      )\n    );\n    return this.forecastArrayOfArray(formattedInput, 1).map((value) =>\n      lookup.toObject(this.outputLookup as INumberHash, value)\n    )[0];\n  }\n\n  runArrayOfObjectOfArray(input: INumberHash[]): INumberHash {\n    if (!this.inputLookup) {\n      throw new Error('this.inputLookup not set');\n    }\n    if (!this.outputLookup) {\n      throw new Error('this.outputLookup not set');\n    }\n    return lookup.toObject(\n      this.outputLookup,\n      this.runArrayOfArray(\n        lookup.toArrays(this.inputLookup, input, this.inputLookupLength)\n      )\n    );\n  }\n\n  end(): void {\n    this.model.equations[this.model.equations.length - 1].runInput(\n      new Float32Array(this.options.outputSize)\n    );\n  }\n\n  requireInputOutputOfOne(): void {\n    if (this.options.inputSize !== 1) {\n      throw new Error('inputSize must be 1 for this data size');\n    }\n    if (this.options.outputSize !== 1) {\n      throw new Error('outputSize must be 1 for this data size');\n    }\n  }\n\n  // Handles data shape of 'array,number'\n  formatArray(data: number[]): Float32Array[][] {\n    const result = [];\n    this.requireInputOutputOfOne();\n    for (let i = 0; i < data.length; i++) {\n      result.push(Float32Array.from([data[i]]));\n    }\n    return [result];\n  }\n\n  // Handles data shape of 'array,array,number'\n  formatArrayOfArray(data: number[][]): Float32Array[][] {\n    const result = [];\n    const { inputSize, outputSize } = this.options;\n    if (inputSize === 1 && outputSize === 1) {\n      for (let i = 0; i < data.length; i++) {\n        result.push(arrayToFloat32Arrays(data[i]));\n      }\n      return result;\n    }\n    if (inputSize !== data[0].length) {\n      throw new Error('inputSize must match data input size');\n    }\n    if (outputSize !== data[0].length) {\n      throw new Error('outputSize must match data output size');\n    }\n    for (let i = 0; i < data.length; i++) {\n      result.push(Float32Array.from(data[i]));\n    }\n    return [result];\n  }\n\n  // Handles data shape of 'array,object,number'\n  formatArrayOfObject(data: INumberHash[]): Float32Array[][] {\n    this.requireInputOutputOfOne();\n    if (!this.inputLookup) {\n      const lookupTable = new LookupTable(data);\n      this.inputLookup = this.outputLookup = lookupTable.table;\n      this.inputLookupLength = this.outputLookupLength = lookupTable.length;\n    }\n    const result = [];\n    for (let i = 0; i < data.length; i++) {\n      result.push(objectToFloat32Arrays(data[i]));\n    }\n    return result;\n  }\n\n  // Handles data shape of 'array,object,number' when this.options.inputSize > 1\n  formatArrayOfObjectMulti(data: INumberHash[]): Float32Array[][] {\n    if (!this.inputLookup) {\n      const lookupTable = new LookupTable(data);\n      this.inputLookup = this.outputLookup = lookupTable.table;\n      this.inputLookupLength = this.outputLookupLength = lookupTable.length;\n    }\n    const result = [];\n    for (let i = 0; i < data.length; i++) {\n      result.push([\n        objectToFloat32Array(data[i], this.inputLookup, this.inputLookupLength),\n      ]);\n    }\n    return result;\n  }\n\n  // Handles data shape of 'array,datum,array,number'\n  formatArrayOfDatumOfArray(data: ITrainingDatum[]): Float32Array[][] {\n    const result = [];\n    this.requireInputOutputOfOne();\n    for (let i = 0; i < data.length; i++) {\n      const datum = data[i];\n      result.push(\n        inputOutputArrayToFloat32Arrays(\n          datum.input as number[],\n          datum.output as number[]\n        )\n      );\n    }\n    return result;\n  }\n\n  // Handles data shape of 'array,datum,object,number'\n  formatArrayOfDatumOfObject(data: ITrainingDatum[]): Float32Array[][] {\n    this.requireInputOutputOfOne();\n    if (!this.inputLookup) {\n      const inputLookup = new LookupTable(data, 'input');\n      this.inputLookup = inputLookup.table;\n      this.inputLookupLength = inputLookup.length;\n    }\n    if (!this.outputLookup) {\n      const outputLookup = new LookupTable(data, 'output');\n      this.outputLookup = outputLookup.table;\n      this.outputLookupLength = outputLookup.length;\n    }\n    const result = [];\n    for (let i = 0; i < data.length; i++) {\n      const datum = data[i];\n      result.push(\n        inputOutputObjectToFloat32Arrays(\n          datum.input as INumberHash,\n          datum.output as INumberHash\n        )\n      );\n    }\n    return result;\n  }\n\n  // Handles data shape of 'array,array,array,number'\n  formatArrayOfArrayOfArray(data: number[][][]): Float32Array[][] {\n    const result = [];\n    for (let i = 0; i < data.length; i++) {\n      result.push(arraysToFloat32Arrays(data[i]));\n    }\n    return result;\n  }\n\n  // Handles data shape of 'array,array,object,number'\n  formatArrayOfArrayOfObject(data: INumberHash[][]): Float32Array[][] {\n    if (!this.inputLookup) {\n      const lookupTable = new LookupTable(data);\n      this.inputLookup = this.outputLookup = lookupTable.table;\n      this.inputLookupLength = this.outputLookupLength = lookupTable.length;\n    }\n    const result = [];\n    for (let i = 0; i < data.length; i++) {\n      const array = [];\n      for (let j = 0; j < data[i].length; j++) {\n        array.push(\n          objectToFloat32Array(\n            data[i][j],\n            this.inputLookup,\n            this.inputLookupLength\n          )\n        );\n      }\n      result.push(array);\n    }\n    return result;\n  }\n\n  // Handles data shape of 'array,datum,array,array,number'\n  formatArrayOfDatumOfArrayOfArray(data: ITrainingDatum[]): Float32Array[][] {\n    const result = [];\n    const { inputSize, outputSize } = this.options;\n    if (inputSize !== (data[0].input as INumberArray[][])[0].length) {\n      throw new Error('inputSize must match data input size');\n    }\n    if (outputSize !== (data[0].output as INumberArray[][])[0].length) {\n      throw new Error('outputSize must match data output size');\n    }\n    for (let i = 0; i < data.length; i++) {\n      const datum = data[i];\n      result.push(\n        inputOutputArraysToFloat32Arrays(\n          datum.input as number[][],\n          datum.output as number[][]\n        )\n      );\n    }\n    return result;\n  }\n\n  // 'Handles data shape of array,datum,array,object,number'\n  formatArrayOfDatumOfArrayOfObject(\n    data: Array<{\n      input: Array<Record<string, number>>;\n      output: Array<Record<string, number>>;\n    }>\n  ): Float32Array[][] {\n    if (!this.inputLookup) {\n      const inputLookup = new ArrayLookupTable(data, 'input');\n      this.inputLookup = inputLookup.table;\n      this.inputLookupLength = inputLookup.length;\n    }\n    if (!this.outputLookup) {\n      const outputLookup = new ArrayLookupTable(data, 'output');\n      this.outputLookup = outputLookup.table;\n      this.outputLookupLength = outputLookup.length;\n    }\n    if (!this.outputLookupLength) {\n      throw new Error('this.outputLookupLength not set to usable number');\n    }\n    const result = [];\n    for (let i = 0; i < data.length; i++) {\n      const datum = data[i];\n      result.push(\n        inputOutputObjectsToFloat32Arrays(\n          datum.input,\n          datum.output,\n          this.inputLookup,\n          this.outputLookup,\n          this.inputLookupLength,\n          this.outputLookupLength\n        )\n      );\n    }\n    return result;\n  }\n\n  formatData(data: FormattableData[]): Float32Array[][] {\n    const dataShape = lookup.dataShape(data).join(',');\n    switch (dataShape) {\n      case 'array,number':\n        return this.formatArray(data as number[]);\n      case 'array,array,number':\n        return this.formatArrayOfArray(data as number[][]);\n      case 'array,object,number':\n        if (this.options.inputSize === 1) {\n          return this.formatArrayOfObject(data as INumberHash[]);\n        } else {\n          return this.formatArrayOfObjectMulti(data as INumberHash[]);\n        }\n      case 'array,datum,array,number':\n        return this.formatArrayOfDatumOfArray(data as ITrainingDatum[]);\n      case 'array,datum,object,number':\n        return this.formatArrayOfDatumOfObject(data as ITrainingDatum[]);\n      case 'array,array,array,number':\n        return this.formatArrayOfArrayOfArray(data as number[][][]);\n      case 'array,array,object,number':\n        return this.formatArrayOfArrayOfObject(data as INumberHash[][]);\n      case 'array,datum,array,array,number':\n        return this.formatArrayOfDatumOfArrayOfArray(data as ITrainingDatum[]);\n      case 'array,datum,array,object,number':\n        return this.formatArrayOfDatumOfArrayOfObject(\n          data as Array<{\n            input: Array<Record<string, number>>;\n            output: Array<Record<string, number>>;\n          }>\n        );\n      default:\n        throw new Error('unknown data shape or configuration');\n    }\n  }\n\n  test(data: FormattableData[]): ITestResults {\n    // for classification problems\n    const misclasses = [];\n    // run each pattern through the trained network and collect\n    // error and misclassification statistics\n    let errorSum = 0;\n    const formattedData = this.formatData(data);\n    for (let i = 0; i < formattedData.length; i++) {\n      const input = formattedData[i];\n      const output = this.run(input.splice(0, input.length - 1));\n      const target = input[input.length - 1];\n      let errors = 0;\n      let errorCount = 0;\n      for (let j = 0; j < output.length; j++) {\n        errorCount++;\n        const error = target[j] - output[j];\n        // mse\n        errors += error * error;\n      }\n      errorSum += errors / errorCount;\n      const errorsAbs = Math.abs(errors);\n      if (errorsAbs > this.trainOpts.errorThresh) {\n        const misclass = (data as number[][][])[i];\n        misclasses.push({\n          value: misclass,\n          actual: output,\n        });\n      }\n    }\n    return {\n      error: errorSum / formattedData.length,\n      misclasses,\n      total: formattedData.length,\n    };\n  }\n\n  // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n  // @ts-expect-error\n  addFormat(value: FormattableData): void {\n    const dataShape = lookup.dataShape(value).join(',');\n    switch (dataShape) {\n      case 'array,array,number':\n      case 'datum,array,array,number':\n      case 'array,number':\n      case 'datum,array,number':\n        return;\n      case 'datum,object,number': {\n        this.inputLookup = lookup.addKeys(\n          (value as ITrainingDatum).input as INumberHash,\n          this.inputLookup ?? {}\n        );\n        if (this.inputLookup) {\n          this.inputLookupLength = Object.keys(this.inputLookup).length;\n        }\n        this.outputLookup = lookup.addKeys(\n          (value as ITrainingDatum).output as INumberHash,\n          this.outputLookup ?? {}\n        );\n        if (this.outputLookup) {\n          this.outputLookupLength = Object.keys(this.outputLookup).length;\n        }\n        break;\n      }\n      case 'object,number': {\n        this.inputLookup = this.outputLookup = lookup.addKeys(\n          value as INumberHash,\n          this.inputLookup ?? {}\n        );\n        if (this.inputLookup) {\n          this.inputLookupLength = this.outputLookupLength = Object.keys(\n            this.inputLookup\n          ).length;\n        }\n        break;\n      }\n      case 'array,object,number': {\n        const typedValue = value as INumberHash[];\n        for (let i = 0; i < typedValue.length; i++) {\n          this.inputLookup = this.outputLookup = lookup.addKeys(\n            typedValue[i],\n            this.inputLookup ?? {}\n          );\n          if (this.inputLookup) {\n            this.inputLookupLength = this.outputLookupLength = Object.keys(\n              this.inputLookup\n            ).length;\n          }\n        }\n        break;\n      }\n      case 'datum,array,object,number': {\n        const typedValue = value as ITrainingDatum;\n        const typedInput = typedValue.input as INumberHash[];\n        for (let i = 0; i < typedInput.length; i++) {\n          this.inputLookup = lookup.addKeys(\n            typedInput[i],\n            this.inputLookup ?? {}\n          );\n          if (this.inputLookup) {\n            this.inputLookupLength = Object.keys(this.inputLookup).length;\n          }\n        }\n        const typedOutput = typedValue.output as INumberHash[];\n        for (let i = 0; i < typedOutput.length; i++) {\n          this.outputLookup = lookup.addKeys(\n            typedOutput[i],\n            this.outputLookup ?? {}\n          );\n          if (this.outputLookup) {\n            this.outputLookupLength = Object.keys(this.outputLookup).length;\n          }\n        }\n        break;\n      }\n\n      default:\n        throw new Error('unknown data shape or configuration');\n    }\n  }\n\n  // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n  // @ts-expect-error\n  toJSON(): IRNNTimeStepJSON {\n    if (!this.model) {\n      this.initialize();\n    }\n    const { model } = this;\n    const options = { ...this.options, ...rnnDefaults };\n\n    return {\n      type: this.constructor.name,\n      options,\n      hiddenLayers: model.hiddenLayers.map((hiddenLayer) => {\n        const layers: { [index: string]: IMatrixJSON } = {};\n        for (const p in hiddenLayer) {\n          if (!hiddenLayer.hasOwnProperty(p)) continue;\n          layers[p] = hiddenLayer[p].toJSON();\n        }\n        return layers;\n      }),\n      outputConnector: model.outputConnector.toJSON(),\n      output: model.output.toJSON(),\n      inputLookup: this.inputLookup,\n      inputLookupLength: this.inputLookupLength,\n      outputLookup: this.outputLookup,\n      outputLookupLength: this.outputLookupLength,\n    };\n  }\n\n  // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n  // @ts-expect-error\n  fromJSON(json: IRNNTimeStepJSON): this {\n    const { options } = json;\n    const allMatrices = [];\n    const hiddenLayers: IRNNHiddenLayerModel[] = [];\n\n    // backward compatibility for hiddenSizes\n    json.hiddenLayers.forEach((hiddenLayer) => {\n      const layers: { [index: string]: Matrix } = {};\n      for (const p in hiddenLayer) {\n        layers[p] = Matrix.fromJSON(hiddenLayer[p]);\n        allMatrices.push(layers[p]);\n      }\n      hiddenLayers.push(layers as IRNNHiddenLayerModel);\n    });\n\n    const outputConnector = Matrix.fromJSON(json.outputConnector);\n    allMatrices.push(outputConnector);\n    const output = Matrix.fromJSON(json.output);\n    allMatrices.push(output);\n\n    // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n    // @ts-expect-error\n    this.options = { ...defaults(), ...options };\n    this.inputLookup = json.inputLookup;\n    this.inputLookupLength = json.inputLookupLength;\n    this.outputLookup = json.outputLookup;\n    this.outputLookupLength = json.outputLookupLength;\n\n    this.model = Object.seal({\n      isInitialized: true,\n      hiddenLayers,\n      output,\n      allMatrices,\n      outputConnector,\n      equations: [],\n      equationConnections: [],\n    });\n    this.initialLayerInputs = options.hiddenLayers.map(\n      (size) => new Matrix(size, 1)\n    );\n    this.bindEquation();\n    return this;\n  }\n\n  // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n  // @ts-expect-error\n  toFunction(cb?: (src: string) => string): RNNTimeStepFunction {\n    const {\n      model,\n      inputLookup,\n      inputLookupLength,\n      outputLookup,\n      outputLookupLength,\n    } = this;\n    const { inputSize } = this.options;\n    const { equations } = model;\n    const equation = equations[1];\n    const { states } = equation;\n    const jsonString = JSON.stringify(this.toJSON());\n\n    function previousConnectionIndex(m: Matrix) {\n      const connection = model.equationConnections[0];\n      const { states } = equations[0];\n      for (let i = 0, max = states.length; i < max; i++) {\n        if (states[i].product === m) {\n          return i;\n        }\n      }\n      return connection.indexOf(m);\n    }\n\n    function matrixOrigin(m: Matrix, stateIndex: number): string {\n      for (let i = 0, max = states.length; i < max; i++) {\n        const state = states[i];\n\n        if (i === stateIndex) {\n          const j = previousConnectionIndex(m);\n          switch (m) {\n            case state.left:\n              if (j > -1) {\n                return `typeof prevStates[${j}] === 'object' ? prevStates[${j}].product : new Matrix(${m.rows}, ${m.columns})`;\n              }\n            // eslint-disable-next-line no-fallthrough\n            case state.right:\n              if (j > -1) {\n                return `typeof prevStates[${j}] === 'object' ? prevStates[${j}].product : new Matrix(${m.rows}, ${m.columns})`;\n              }\n            // eslint-disable-next-line no-fallthrough\n            case state.product:\n              return `new Matrix(${m.rows}, ${m.columns})`;\n            default:\n              throw Error('unknown state');\n          }\n        }\n\n        if (m === state.product) return `states[${i}].product`;\n        if (m === state.right) return `states[${i}].right`;\n        if (m === state.left) return `states[${i}].left`;\n      }\n      return '';\n    }\n\n    function matrixToString(m: Matrix, stateIndex: number): string {\n      if (!m || !m.rows || !m.columns) return 'null';\n      if (m === model.outputConnector) return `json.outputConnector`;\n      if (m === model.output) return `json.output`;\n\n      for (let i = 0, max = model.hiddenLayers.length; i < max; i++) {\n        const hiddenLayer = model.hiddenLayers[i];\n        for (const p in hiddenLayer) {\n          if (!hiddenLayer.hasOwnProperty(p)) continue;\n          if (hiddenLayer[p] !== m) continue;\n          return `json.hiddenLayers[${i}].${p}`;\n        }\n      }\n\n      return matrixOrigin(m, stateIndex);\n    }\n\n    function formatInputData() {\n      if (!inputLookup) return '';\n      if (inputSize === 1) {\n        if (inputLookup === outputLookup) {\n          return `function lookupInput(input) {\n            var table = ${JSON.stringify(inputLookup)};\n            var result = [];\n            for (var p in table) {\n              if (!input.hasOwnProperty(p)) break;\n              result.push(Float32Array.from([input[p]]));\n            }\n            return result;\n          }`;\n        }\n        return `function lookupInput(input) {\n          var table = ${JSON.stringify(inputLookup)};\n          var result = [];\n          for (var p in table) {\n            result.push(Float32Array.from([input[p]]));\n          }\n          return result;\n        }`;\n      }\n      return `function lookupInput(rawInputs) {\n        var table = ${JSON.stringify(inputLookup)};\n        var result = [];\n        for (var i = 0; i < rawInputs.length; i++) {\n          var rawInput = rawInputs[i];\n          var input = new Float32Array(${inputLookupLength});\n          for (var p in table) {\n            input[table[p]] = rawInput.hasOwnProperty(p) ? rawInput[p] : 0;\n          }\n          result.push(input);\n        }\n        return result;\n      }`;\n    }\n\n    function formatOutputData() {\n      if (!outputLookup) return '';\n      if (inputSize === 1) {\n        if (inputLookup === outputLookup) {\n          return `function lookupOutputPartial(output, input) {\n            var table = ${JSON.stringify(outputLookup)};\n            var offset = input.length;\n            var result = {};\n            var i = 0;\n            for (var p in table) {\n              if (i++ < offset) continue;\n              result[p] = output[table[p] - offset][0];\n            }\n            return result;\n          }`;\n        }\n        return `function lookupOutput(output) {\n          var table = ${JSON.stringify(outputLookup)};\n          var result = {};\n          for (var p in table) {\n            result[p] = output[table[p]][0];\n          }\n          return result;\n        }`;\n      }\n      return `function lookupOutput(output) {\n        var table = ${JSON.stringify(outputLookup)};\n        var result = {};\n        for (var p in table) {\n          result[p] = output[table[p]];\n        }\n        return result;\n      }`;\n    }\n\n    function toInner(fnString: string) {\n      // crude, but should be sufficient for now\n      // function() { body }\n      // crude, but should be sufficient for now\n      // function() { body }\n      const fnParts = fnString.toString().split('{');\n      fnParts.shift();\n      // body }\n      const fnBodyString = fnParts.join('{');\n      const fnBodyParts = fnBodyString.split('}');\n      fnBodyParts.pop();\n      // body\n      return fnBodyParts\n        .join('}')\n        .split('\\n')\n        .join('\\n        ')\n        .replace('product.deltas[i] = 0;', '')\n        .replace('product.deltas[column] = 0;', '')\n        .replace('left.deltas[leftIndex] = 0;', '')\n        .replace('right.deltas[rightIndex] = 0;', '')\n        .replace('product.deltas = left.deltas.slice(0);', '');\n    }\n\n    function fileName(fnName: string) {\n      return `src/recurrent/matrix/${fnName.replace(/[A-Z]/g, function (value) {\n        return `-${value.toLowerCase()}`;\n      })}.js`;\n    }\n\n    const statesRaw = [];\n    const usedFunctionNames: { [methodName: string]: boolean } = {};\n    const innerFunctionsSwitch = [];\n    for (let i = 0, max = states.length; i < max; i++) {\n      const state = states[i];\n      statesRaw.push(`states[${i}] = {\n      name: '${state.forwardFn.name}',\n      left: ${state.left ? matrixToString(state.left, i) : 'undefined'},\n      right: ${state.right ? matrixToString(state.right, i) : 'undefined'},\n      product: ${matrixToString(state.product, i)}\n    }`);\n\n      const fnName = state.forwardFn.name;\n      if (!usedFunctionNames[fnName]) {\n        usedFunctionNames[fnName] = true;\n        if (state.name === 'input') {\n          innerFunctionsSwitch.push(`case '${fnName}':`);\n          innerFunctionsSwitch.push(\n            inputLookup && inputSize === 1\n              ? 'product.weights = _i < input.length ? input[_i]: prevStates[prevStates.length - 1].product.weights;'\n              : inputSize === 1\n              ? 'product.weights = [input[_i]];'\n              : 'product.weights = input[_i];'\n          );\n          innerFunctionsSwitch.push('break;');\n        } else {\n          innerFunctionsSwitch.push(\n            `        case '${fnName}':${\n              fnName !== 'forwardFn'\n                ? ` //compiled from ${fileName(fnName)}`\n                : ''\n            }\n          ${toInner(state.forwardFn.toString())}\n          break;`\n          );\n        }\n      }\n    }\n\n    const forceForecast = inputSize === 1 && this.outputLookup;\n    const src = `\n  var input = ${this.inputLookup ? 'lookupInput(rawInput)' : 'rawInput'};\n  var json = ${jsonString};\n  var output = [];\n  var states = [];\n  var prevStates;\n  var state;\n  var max = ${\n    forceForecast\n      ? inputLookup === outputLookup\n        ? inputLookupLength\n        : `input.length + ${outputLookupLength - 1}`\n      : 'input.length'\n  };\n  for (var _i = 0; _i < max; _i++) {\n    prevStates = states;\n    states = [];\n    ${statesRaw.join(';\\n    ')};\n    for (var stateIndex = 0, stateMax = ${\n      statesRaw.length\n    }; stateIndex < stateMax; stateIndex++) {\n      state = states[stateIndex];\n      var product = state.product;\n      var left = state.left;\n      var right = state.right;\n\n      switch (state.name) {\n${innerFunctionsSwitch.join('\\n')}\n      }\n    }\n    ${\n      inputSize === 1 && inputLookup\n        ? 'if (_i >= input.length - 1) { output.push(state.product.weights); }'\n        : 'output = state.product.weights;'\n    }\n  }\n  ${\n    outputLookup\n      ? outputLookup === inputLookup\n        ? 'return lookupOutputPartial(output, input)'\n        : 'return lookupOutput(output)'\n      : inputSize === 1\n      ? 'return output[0]'\n      : 'return output'\n  };\n  ${formatInputData()}\n  ${formatOutputData()}\n\n  function Matrix(rows, columns) {\n    this.rows = rows;\n    this.columns = columns;\n    this.weights = new Float32Array(rows * columns);\n  }\n  ${softmax.toString().replace('_2.default', 'Matrix')}\n  ${randomFloat.toString()}\n  ${sampleI.toString()}\n  ${maxI.toString()}`;\n    // eslint-disable-next-line\n    return new Function('rawInput', cb ? cb(src) : src) as RNNTimeStepFunction;\n  }\n}\n\nexport type RNNTimeStepFunction = <\n  InputType extends InputOutputValue | InputOutputValue[]\n>(\n  rawInput?: InputType,\n  isSampleI?: boolean,\n  temperature?: number\n) => ValuesOf<InputType>;\n\nexport const trainDefaults = { ...rnnTrainDefaults };\n","import { getGRUHiddenLayer, getGRUEquation, IGRUHiddenLayer } from './gru';\nimport { Matrix } from './matrix';\nimport { Equation } from './matrix/equation';\nimport { RNNTimeStep } from './rnn-time-step';\nimport { IRNNHiddenLayer } from './rnn';\n\nexport class GRUTimeStep extends RNNTimeStep {\n  getHiddenLayer(hiddenSize: number, prevSize: number): IRNNHiddenLayer {\n    return getGRUHiddenLayer(hiddenSize, prevSize);\n  }\n\n  getEquation(\n    equation: Equation,\n    inputMatrix: Matrix,\n    previousResult: Matrix,\n    hiddenLayer: IRNNHiddenLayer\n  ): Matrix {\n    return getGRUEquation(\n      equation,\n      inputMatrix,\n      previousResult,\n      hiddenLayer as IGRUHiddenLayer\n    );\n  }\n}\n","import { Matrix } from './matrix';\nimport { Equation } from './matrix/equation';\nimport { RandomMatrix } from './matrix/random-matrix';\nimport { IRNNHiddenLayer, RNN } from './rnn';\n\nexport interface ILSTMHiddenLayer extends IRNNHiddenLayer {\n  inputMatrix: Matrix;\n  inputHidden: Matrix;\n  inputBias: Matrix;\n  forgetMatrix: Matrix;\n  forgetHidden: Matrix;\n  forgetBias: Matrix;\n  outputMatrix: Matrix;\n  outputHidden: Matrix;\n  outputBias: Matrix;\n  cellActivationMatrix: Matrix;\n  cellActivationHidden: Matrix;\n  cellActivationBias: Matrix;\n}\n\nexport class LSTM extends RNN {\n  getHiddenLayer(hiddenSize: number, prevSize: number): IRNNHiddenLayer {\n    return getHiddenLSTMLayer(hiddenSize, prevSize);\n  }\n\n  getEquation(\n    equation: Equation,\n    inputMatrix: Matrix,\n    previousResult: Matrix,\n    hiddenLayer: IRNNHiddenLayer\n  ): Matrix {\n    return getLSTMEquation(\n      equation,\n      inputMatrix,\n      previousResult,\n      hiddenLayer as ILSTMHiddenLayer\n    );\n  }\n}\n\nexport function getHiddenLSTMLayer(\n  hiddenSize: number,\n  prevSize: number\n): ILSTMHiddenLayer {\n  return {\n    // gates parameters\n    // wix\n    inputMatrix: new RandomMatrix(hiddenSize, prevSize, 0.08), // wih\n    inputHidden: new RandomMatrix(hiddenSize, hiddenSize, 0.08), // bi\n    inputBias: new Matrix(hiddenSize, 1),\n    // wfx\n    forgetMatrix: new RandomMatrix(hiddenSize, prevSize, 0.08), // wfh\n    forgetHidden: new RandomMatrix(hiddenSize, hiddenSize, 0.08), // bf\n    forgetBias: new Matrix(hiddenSize, 1),\n    // wox\n    outputMatrix: new RandomMatrix(hiddenSize, prevSize, 0.08), // woh\n    outputHidden: new RandomMatrix(hiddenSize, hiddenSize, 0.08), // bo\n    outputBias: new Matrix(hiddenSize, 1),\n    // cell write params\n    // wcx\n    cellActivationMatrix: new RandomMatrix(hiddenSize, prevSize, 0.08), // wch\n    cellActivationHidden: new RandomMatrix(hiddenSize, hiddenSize, 0.08), // bc\n    cellActivationBias: new Matrix(hiddenSize, 1),\n  };\n}\n\nexport function getLSTMEquation(\n  equation: Equation,\n  inputMatrix: Matrix,\n  previousResult: Matrix,\n  hiddenLayer: ILSTMHiddenLayer\n): Matrix {\n  if (\n    !hiddenLayer.inputMatrix ||\n    !hiddenLayer.inputHidden ||\n    !hiddenLayer.inputBias ||\n    !hiddenLayer.forgetMatrix ||\n    !hiddenLayer.forgetHidden ||\n    !hiddenLayer.forgetBias ||\n    !hiddenLayer.outputMatrix ||\n    !hiddenLayer.outputHidden ||\n    !hiddenLayer.outputBias ||\n    !hiddenLayer.cellActivationMatrix ||\n    !hiddenLayer.cellActivationHidden ||\n    !hiddenLayer.cellActivationBias\n  ) {\n    throw new Error('hiddenLayer does not have expected properties');\n  }\n\n  const sigmoid = equation.sigmoid.bind(equation);\n  const add = equation.add.bind(equation);\n  const multiply = equation.multiply.bind(equation);\n  const multiplyElement = equation.multiplyElement.bind(equation);\n  const tanh = equation.tanh.bind(equation);\n\n  const inputGate = sigmoid(\n    add(\n      add(\n        multiply(hiddenLayer.inputMatrix, inputMatrix),\n        multiply(hiddenLayer.inputHidden, previousResult)\n      ),\n      hiddenLayer.inputBias\n    )\n  );\n\n  const forgetGate = sigmoid(\n    add(\n      add(\n        multiply(hiddenLayer.forgetMatrix, inputMatrix),\n        multiply(hiddenLayer.forgetHidden, previousResult)\n      ),\n      hiddenLayer.forgetBias\n    )\n  );\n\n  // output gate\n  const outputGate = sigmoid(\n    add(\n      add(\n        multiply(hiddenLayer.outputMatrix, inputMatrix),\n        multiply(hiddenLayer.outputHidden, previousResult)\n      ),\n      hiddenLayer.outputBias\n    )\n  );\n\n  // write operation on cells\n  const cellWrite = tanh(\n    add(\n      add(\n        multiply(hiddenLayer.cellActivationMatrix, inputMatrix),\n        multiply(hiddenLayer.cellActivationHidden, previousResult)\n      ),\n      hiddenLayer.cellActivationBias\n    )\n  );\n\n  // compute new cell activation\n  const retainCell = multiplyElement(forgetGate, previousResult); // what do we keep from cell\n  const writeCell = multiplyElement(inputGate, cellWrite); // what do we write to cell\n  const cell = add(retainCell, writeCell); // new cell contents\n\n  // compute hidden state as gated, saturated cell activations\n  return multiplyElement(outputGate, tanh(cell));\n}\n","import { getHiddenLSTMLayer, getLSTMEquation, ILSTMHiddenLayer } from './lstm';\nimport { Matrix } from './matrix';\nimport { Equation } from './matrix/equation';\nimport { RNNTimeStep } from './rnn-time-step';\nimport { IRNNHiddenLayer } from './rnn';\n\nexport class LSTMTimeStep extends RNNTimeStep {\n  getHiddenLayer(hiddenSize: number, prevSize: number): IRNNHiddenLayer {\n    return getHiddenLSTMLayer(hiddenSize, prevSize);\n  }\n\n  getEquation(\n    equation: Equation,\n    inputMatrix: Matrix,\n    previousResult: Matrix,\n    hiddenLayer: IRNNHiddenLayer\n  ): Matrix {\n    return getLSTMEquation(\n      equation,\n      inputMatrix,\n      previousResult,\n      hiddenLayer as ILSTMHiddenLayer\n    );\n  }\n}\n","import { FeedForward, IFeedForwardJSON } from '../feed-forward';\nimport { recurrentZeros } from '../layer/recurrent-zeros';\nimport { Recurrent } from '../recurrent';\nimport { IRNNJSON, RNN } from '../recurrent/rnn';\nimport { INeuralNetworkJSON, NeuralNetwork } from '../neural-network';\nimport { GRU } from '../recurrent/gru';\nimport { LSTM } from '../recurrent/lstm';\nimport { NeuralNetworkGPU } from '../neural-network-gpu';\nimport { IRNNTimeStepJSON, RNNTimeStep } from '../recurrent/rnn-time-step';\nimport { LSTMTimeStep } from '../recurrent/lstm-time-step';\nimport { GRUTimeStep } from '../recurrent/gru-time-step';\nimport { ILayer } from '../layer';\n\ninterface LineDrawInfo {\n  className: string;\n  color: string;\n  width: number;\n}\n\ninterface NodeDrawInfo {\n  className: string;\n  color: string;\n}\n\ninterface BaseDrawArgs {\n  pixelX: number;\n  pixelY: number;\n  radius: number;\n  row: number;\n  column: number;\n}\n\ninterface InputDrawArgs extends BaseDrawArgs {\n  line: LineDrawInfo;\n  inputs: NodeDrawInfo & { labels?: string[] | null };\n  fontSize: string;\n  fontClassName: string;\n}\n\nexport function drawInput({\n  pixelX,\n  pixelY,\n  radius,\n  inputs,\n  row,\n  line,\n  fontSize,\n  fontClassName,\n}: InputDrawArgs): string {\n  let svg = `<rect\n              x=\"${pixelX / 2 - radius}\"\n              y=\"${pixelY / 2 + row * pixelY - radius}\"\n              width=\"${2 * radius}\"\n              height=\"${2 * radius}\"\n              stroke=\"black\"\n              stroke-width=\"1\"\n              fill=\"${inputs.color}\"\n              class=\"${inputs.className}\" />\n            <line\n              x1=\"${pixelX / 4}\"\n              y1=\"${pixelY / 2 + row * pixelY}\"\n              x2=\"${pixelX / 2 - radius}\"\n              y2=\"${pixelY / 2 + row * pixelY}\"\n              style=\"stroke:${line.color};stroke-width:${line.width}\"\n              class=\"${line.className}\" />`;\n  if (inputs.labels) {\n    svg += `<text\n              x=\"${pixelX / 8}\"\n              y=\"${pixelY / 2 + row * pixelY - 5}\"\n              fill=\"black\"\n              font-size=\"${fontSize}\"\n              class=\"${fontClassName}\">${inputs.labels[row]}</text>`;\n  }\n  return svg;\n}\n\nexport interface NeuronDrawArgs extends BaseDrawArgs {\n  column: number;\n  hidden: NodeDrawInfo;\n}\n\nexport function drawNeuron({\n  pixelX,\n  pixelY,\n  row,\n  column,\n  radius,\n  hidden,\n}: NeuronDrawArgs): string {\n  return `<circle\n            cx=\"${pixelX / 2 + column * pixelX}\"\n            cy=\"${pixelY / 2 + row * pixelY}\"\n            r=\"${radius}\"\n            stroke=\"black\"\n            stroke-width=\"1\"\n            fill=\"${hidden.color}\"\n            class=\"${hidden.className}\" />`;\n}\n\nexport interface OutputDrawArgs extends BaseDrawArgs {\n  column: number;\n  line: LineDrawInfo;\n  outputs: NodeDrawInfo;\n}\n\nexport function drawOutput({\n  pixelX,\n  pixelY,\n  row,\n  column,\n  line,\n  outputs,\n  radius,\n}: OutputDrawArgs): string {\n  return `<circle\n            cx=\"${pixelX / 2 + column * pixelX}\"\n            cy=\"${pixelY / 2 + row * pixelY}\"\n            r=\"${radius}\"\n            stroke=\"black\"\n            stroke-width=\"1\"\n            fill=\"${outputs.color}\"\n            class=\"${outputs.className}\" />\n          <line\n            x1=\"${pixelX / 2 + column * pixelX + radius}\"\n            y1=\"${pixelY / 2 + row * pixelY}\"\n            x2=\"${pixelX / 2 + column * pixelX + pixelX / 4}\"\n            y2=\"${pixelY / 2 + row * pixelY}\"\n            style=\"stroke:${line.color};stroke-width:${line.width}\"\n            class=\"${line.className}\" />`;\n}\n\nexport interface BackwardConnectionsDrawArgs extends BaseDrawArgs {\n  column: number;\n  lineY: number;\n  previousConnectionIndex: number;\n  line: LineDrawInfo;\n}\n\nexport function drawBackwardConnections({\n  pixelX,\n  pixelY,\n  row,\n  column,\n  radius,\n  lineY,\n  line,\n  previousConnectionIndex,\n}: BackwardConnectionsDrawArgs): string {\n  return `<line\n            x1=\"${pixelX / 2 + (column - 1) * pixelX + radius}\"\n            y1=\"${lineY / 2 + previousConnectionIndex * lineY}\"\n            x2=\"${pixelX / 2 + column * pixelX - radius}\"\n            y2=\"${pixelY / 2 + row * pixelY}\"\n            style=\"stroke:${line.color};stroke-width:${line.width}\"\n            class=\"${line.className}\" />`;\n}\n\nexport interface NeuralNetworkDrawOptions {\n  sizes: number[];\n  height: number;\n  width: number;\n  radius: number;\n  line: LineDrawInfo;\n  inputs: NodeDrawInfo & { labels?: string[] | null };\n  hidden: NodeDrawInfo;\n  outputs: NodeDrawInfo;\n  fontSize: string;\n  fontClassName: string;\n}\n\nexport function neuralNetworkToInnerSVG(\n  options: NeuralNetworkDrawOptions\n): string {\n  const { sizes, height, width } = options;\n  let svg = '';\n  const pixelX = width / sizes.length;\n  for (let column = 0; column < sizes.length; column++) {\n    const size = sizes[column];\n    const pixelY = height / size;\n    for (let row = 0; row < size; row++) {\n      if (column === 0) {\n        svg += drawInput({ pixelX, pixelY, row, column, ...options });\n      } else {\n        if (column === sizes.length - 1) {\n          svg += drawOutput({ pixelX, pixelY, row, column, ...options });\n        } else {\n          svg += drawNeuron({ pixelX, pixelY, row, column, ...options });\n        }\n        const previousSize = sizes[column - 1];\n        const lineY = height / previousSize;\n        for (\n          let previousConnectionIndex = 0;\n          previousConnectionIndex < previousSize;\n          previousConnectionIndex++\n        ) {\n          svg += drawBackwardConnections({\n            pixelX,\n            pixelY,\n            row,\n            column,\n            lineY,\n            previousConnectionIndex,\n            ...options,\n          });\n        }\n      }\n    }\n  }\n  return svg;\n}\n\nexport interface RecurrentConnectionsDrawArgs extends BaseDrawArgs {\n  column: number;\n  recurrentLine: LineDrawInfo;\n}\n\nexport function drawRecurrentConnections({\n  pixelX,\n  pixelY,\n  row,\n  column,\n  radius,\n  recurrentLine,\n}: RecurrentConnectionsDrawArgs): string {\n  const moveX = pixelX / 2 + column * pixelX + radius + 1;\n  const moveY = pixelY / 2 + row * pixelY;\n  const x = moveX - radius * 2 - 2;\n  const y = moveY;\n  const x1 = x + 100;\n  const y1 = y + 50;\n  const x2 = moveX - 100;\n  const y2 = moveY + 50;\n  return `<path\n              d=\"M ${moveX} ${moveY} C ${x1} ${y1}, ${x2} ${y2}, ${x} ${y}\"\n              stroke=\"${recurrentLine.color}\"\n              stroke-width=\"${recurrentLine.width}\"\n              fill=\"transparent\"\n              stroke-linecap=\"round\"\n              marker-end=\"url(#arrow)\"\n              class=\"${recurrentLine.className}\" />`;\n}\n\nexport interface RecurrentNeuralNetworkDrawOptions\n  extends NeuralNetworkDrawOptions {\n  recurrentLine: LineDrawInfo;\n}\n\nexport function rnnToInnerSVG(\n  options: RecurrentNeuralNetworkDrawOptions\n): string {\n  const { width, height, recurrentLine, sizes, radius } = options;\n  const pixelX = width / sizes.length;\n  let svg = `<defs>\n              <marker id=\"arrow\" markerWidth=\"10\" markerHeight=\"10\" refX=\"8\" refY=\"3\" orient=\"auto\" markerUnits=\"strokeWidth\">\n                <path d=\"M0,0 L0,6 L9,3 z\" fill=\"${recurrentLine.color}\" />\n              </marker>\n            </defs>`;\n  svg += neuralNetworkToInnerSVG(options);\n  for (let column = 1; column < sizes.length; column++) {\n    const size = sizes[column];\n    const pixelY = height / size;\n    for (let row = 0; row < size; row++) {\n      svg += drawRecurrentConnections({\n        pixelX,\n        pixelY,\n        row,\n        column,\n        radius,\n        recurrentLine,\n      });\n    }\n  }\n  return svg;\n}\n\nexport function getFeedForwardLayers(network: FeedForward): ISimpleNet {\n  const { options } = network;\n  if (!options) {\n    throw new Error('options not defined');\n  }\n  if (!options.inputLayer) {\n    throw new Error('options.inputLater not defined');\n  }\n  if (!options.hiddenLayers) {\n    throw new Error('options.hiddenLayers not defined');\n  }\n  if (options.hiddenLayers.length < 1) {\n    throw new Error('options.hiddenLayers is empty');\n  }\n  if (!options.outputLayer) {\n    throw new Error('options.outputLayer not defined');\n  }\n  const inputLayer = options.inputLayer();\n  const hiddenLayers = [];\n  hiddenLayers.push(options.hiddenLayers[0](inputLayer, 0));\n  for (let i = 1; i < options.hiddenLayers.length; i++) {\n    hiddenLayers.push(options.hiddenLayers[i](hiddenLayers[i - 1], i));\n  }\n  const outputLayer = options.outputLayer(\n    hiddenLayers[hiddenLayers.length - 1],\n    hiddenLayers.length\n  );\n  return {\n    inputSize: inputLayer.height,\n    hiddenLayers: hiddenLayers.map((hiddenLayer: ILayer) => hiddenLayer.height),\n    outputSize: outputLayer.height,\n  };\n}\n\nexport function getRecurrentLayers(network: Recurrent): ISimpleNet {\n  const hiddenLayers: ILayer[] = [];\n  const { options } = network;\n  if (!options.inputLayer) {\n    throw new Error('inputLayer not defined');\n  }\n  if (!options.outputLayer) {\n    throw new Error('outputLayer not defined');\n  }\n  const inputLayer = options.inputLayer();\n  hiddenLayers.push(options.hiddenLayers[0](inputLayer, recurrentZeros(), 0));\n  for (let i = 1; i < options.hiddenLayers.length; i++) {\n    hiddenLayers.push(\n      options.hiddenLayers[i](hiddenLayers[i - 1], recurrentZeros(), i)\n    );\n  }\n  const outputLayer = options.outputLayer(\n    hiddenLayers[hiddenLayers.length - 1],\n    -1\n  );\n  return {\n    inputSize: inputLayer.height,\n    hiddenLayers: hiddenLayers.map((hiddenLayer: ILayer) => hiddenLayer.height),\n    outputSize: outputLayer.height,\n  };\n}\n\nexport function wrapOuterSVG(\n  svgBody: string,\n  width: number,\n  height: number\n): string {\n  // language=html\n  return `<svg\n            xmlns=\"http://www.w3.org/2000/svg\"\n            xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n            version=\"1.1\"\n            width=\"${width}\"\n            height=\"${height}\">${svgBody}</svg>`;\n}\n\nexport function getNeuralNetworkJSONSizes(json: INeuralNetworkJSON): number[] {\n  return json.sizes;\n}\n\nexport function getNeuralNetworkSizes<InputType, OutputType>(\n  net:\n    | NeuralNetwork<InputType, OutputType>\n    | NeuralNetworkGPU<InputType, OutputType>\n): number[] {\n  const { options, sizes } = net;\n  const { inputSize, outputSize, hiddenLayers } = options;\n  if (!sizes) {\n    if (typeof inputSize === 'number' && inputSize < 1) {\n      throw new Error('inputSize not set');\n    }\n    if (typeof outputSize === 'number' && outputSize < 1) {\n      throw new Error('outputSize not set');\n    }\n    if (hiddenLayers?.some((v) => v < 1)) {\n      throw new Error('hiddenLayers not set');\n    }\n  }\n  return typeof inputSize === 'number' &&\n    Array.isArray(hiddenLayers) &&\n    typeof outputSize === 'number'\n    ? [inputSize].concat(hiddenLayers).concat([outputSize])\n    : sizes;\n}\n\nexport function getRNNSizes(\n  net: RNN | LSTM | GRU | RNNTimeStep | LSTMTimeStep | GRUTimeStep | IRNNJSON\n): number[] {\n  const { options } = net;\n  const { inputSize, outputSize, hiddenLayers } = options;\n  return [inputSize].concat(hiddenLayers).concat([outputSize]);\n}\n\nexport function defaultOptions(): RecurrentNeuralNetworkDrawOptions {\n  return {\n    line: {\n      width: 0.5,\n      color: 'black',\n      className: 'connection',\n    },\n    recurrentLine: {\n      width: 1,\n      color: 'red',\n      className: 'recurrence',\n    },\n    inputs: {\n      color: 'rgba(0, 128, 0, 0.5)',\n      labels: null,\n      className: 'input',\n    },\n    outputs: {\n      color: 'rgba(100, 149, 237, 0.5)',\n      className: 'output',\n    },\n    hidden: {\n      color: 'rgba(255, 127, 80, 0.5)',\n      className: 'hidden-neuron',\n    },\n    fontSize: '14px',\n    fontClassName: 'label',\n    radius: 8,\n    width: 400,\n    height: 250,\n    sizes: [],\n  };\n}\n\nexport interface ISimpleNet {\n  inputSize: number;\n  hiddenLayers: number[];\n  outputSize: number;\n}\nexport interface ISizes {\n  sizes: number[];\n}\n\nexport function toSVG<\n  T extends\n    | ISimpleNet\n    | ISizes\n    | Recurrent\n    | FeedForward\n    | IFeedForwardJSON\n    | RNNTimeStep\n    | IRNNTimeStepJSON\n    | LSTMTimeStep\n    | GRUTimeStep\n    | RNN\n    | IRNNJSON\n    | GRU\n    | LSTM\n    | NeuralNetwork<InputType, OutputType>\n    | INeuralNetworkJSON\n    | NeuralNetworkGPU<InputType, OutputType>,\n  InputType,\n  OutputType\n>(\n  net: T,\n  options?:\n    | Partial<RecurrentNeuralNetworkDrawOptions>\n    | Partial<NeuralNetworkDrawOptions>\n): string {\n  const mergedOptions = { ...defaultOptions(), ...options };\n  const { width, height, inputs } = mergedOptions;\n\n  // Get network size array for NeuralNetwork or NeuralNetworkGPU\n  let sizes: number[] = [];\n  if (net instanceof NeuralNetwork || net instanceof NeuralNetworkGPU) {\n    sizes = getNeuralNetworkSizes(net);\n  }\n  // get network size for Recurrent\n  else if (net instanceof Recurrent) {\n    const { inputSize, hiddenLayers, outputSize } = getRecurrentLayers(net);\n    sizes = [inputSize].concat(hiddenLayers).concat([outputSize]);\n  }\n  // get network size for FeedForward\n  else if (net instanceof FeedForward) {\n    const { inputSize, hiddenLayers, outputSize } = getFeedForwardLayers(net);\n    sizes = [inputSize].concat(hiddenLayers).concat([outputSize]);\n  }\n  // handle json, recurrent first\n  else if (\n    net instanceof RNN ||\n    net instanceof LSTM ||\n    net instanceof GRU ||\n    net instanceof RNNTimeStep ||\n    net instanceof LSTMTimeStep ||\n    net instanceof GRUTimeStep\n  ) {\n    return wrapOuterSVG(\n      rnnToInnerSVG({\n        ...mergedOptions,\n        sizes: checkSizes(\n          getRNNSizes(\n            (net as unknown) as\n              | RNN\n              | LSTM\n              | GRU\n              | RNNTimeStep\n              | LSTMTimeStep\n              | GRUTimeStep\n          ),\n          inputs.labels\n        ),\n      }),\n      width,\n      height\n    );\n  }\n  // handle json, NeuralNetwork\n  else if (net.hasOwnProperty('type')) {\n    switch ((net as INeuralNetworkJSON).type) {\n      case 'NeuralNetwork':\n      case 'NeuralNetworkGPU':\n        return wrapOuterSVG(\n          neuralNetworkToInnerSVG({\n            ...mergedOptions,\n            sizes: checkSizes(\n              getNeuralNetworkJSONSizes(net as INeuralNetworkJSON),\n              inputs.labels\n            ),\n          }),\n          width,\n          height\n        );\n      case 'RNN':\n      case 'GRU':\n      case 'LSTM':\n      case 'RNNTimeStep':\n      case 'GRUTimeStep':\n      case 'LSTMTimeStep':\n        return wrapOuterSVG(\n          rnnToInnerSVG({\n            ...mergedOptions,\n            sizes: checkSizes(getRNNSizes(net as IRNNJSON), inputs.labels),\n          }),\n          width,\n          height\n        );\n      default:\n        throw new Error('unrecognized network');\n    }\n  } else if (\n    net.hasOwnProperty('inputSize') &&\n    net.hasOwnProperty('hiddenLayers') &&\n    net.hasOwnProperty('outputSize')\n  ) {\n    const { inputSize, hiddenLayers, outputSize } = net as ISimpleNet;\n    sizes = [inputSize, ...hiddenLayers, outputSize];\n  } else if (net.hasOwnProperty('sizes')) {\n    sizes = (net as ISizes).sizes;\n  } else {\n    throw new Error('unrecognized network');\n  }\n  return wrapOuterSVG(\n    neuralNetworkToInnerSVG({\n      ...mergedOptions,\n      sizes: checkSizes(sizes, inputs.labels),\n    }),\n    width,\n    height\n  );\n}\n\nexport function checkSizes(\n  sizes: number[],\n  labels: string[] | null | undefined\n): number[] {\n  if (!sizes) {\n    throw new Error('sizes not set');\n  }\n  if (sizes.some((size: number) => size < 1)) {\n    throw new Error('sizes not set correctly');\n  }\n  if (labels && labels.length !== sizes[0]) {\n    throw new Error('not enough labels for inputs');\n  }\n  return sizes;\n}\n","import * as activation from './activation';\nimport CrossValidate from './cross-validate';\nimport { FeedForward } from './feed-forward';\nimport * as layer from './layer';\nimport { layerTypes } from './layer';\nimport { likely } from './likely';\nimport { lookup } from './lookup';\nimport { NeuralNetwork } from './neural-network';\nimport { NeuralNetworkGPU } from './neural-network-gpu';\nimport * as praxis from './praxis';\nimport { Recurrent } from './recurrent';\nimport { GRU } from './recurrent/gru';\nimport { GRUTimeStep } from './recurrent/gru-time-step';\nimport { LSTM } from './recurrent/lstm';\nimport { LSTMTimeStep } from './recurrent/lstm-time-step';\nimport { RNN } from './recurrent/rnn';\nimport { RNNTimeStep } from './recurrent/rnn-time-step';\nimport { DataFormatter } from './utilities/data-formatter';\nimport { max } from './utilities/max';\nimport { mse } from './utilities/mse';\nimport { ones, ones2D } from './utilities/ones';\nimport * as random from './utilities/random';\nimport { randomWeight } from './utilities/random-weight';\nimport { randos } from './utilities/randos';\nimport { range } from './utilities/range';\nimport { toArray } from './utilities/to-array';\nimport { toSVG } from './utilities/to-svg';\nimport { zeros } from './utilities/zeros';\n\nconst recurrent = {\n  RNNTimeStep,\n  LSTMTimeStep,\n  GRUTimeStep,\n  RNN,\n  LSTM,\n  GRU,\n};\n\nconst utilities = {\n  max,\n  mse,\n  ones,\n  ones2D,\n  random,\n  randomWeight,\n  randos,\n  range,\n  toArray,\n  DataFormatter,\n  zeros,\n  toSVG,\n};\n\nexport {\n  activation,\n  CrossValidate,\n  likely,\n  layer,\n  layerTypes,\n  lookup,\n  praxis,\n  FeedForward,\n  NeuralNetwork,\n  NeuralNetworkGPU,\n  Recurrent,\n  recurrent,\n  utilities,\n};\n","/**\n *\n * @param start\n * @param end\n * @returns {Array}\n */\nexport function range(start: number, end: number): number[] {\n  const result: number[] = [];\n  for (; start < end; start++) {\n    result.push(start);\n  }\n  return result;\n}\n","export function toArray(\n  values: number[] | Float32Array | { [key: string]: number }\n): Float32Array {\n  if (Array.isArray(values)) {\n    return Float32Array.from(values);\n  }\n\n  return Float32Array.from(Object.values(values));\n}\n","export interface ILikelyNet<InputType, OutputType> {\n  run: (input: InputType) => OutputType;\n}\n\nexport function likely<\n  NetworkType extends ILikelyNet<\n    Parameters<NetworkType['run']>[0],\n    ReturnType<NetworkType['run']>\n  >\n>(\n  input: Parameters<NetworkType['run']>[0],\n  net: NetworkType\n): ReturnType<NetworkType['run']> | null {\n  if (!net) {\n    throw new TypeError(\n      `Required parameter 'net' is of type ${typeof net}. Must be of type 'brain.NeuralNetwork'`\n    );\n  }\n\n  const output = net.run(input);\n  let maxProp = null;\n  let maxValue = -1;\n\n  Object.entries(output).forEach(([key, value]) => {\n    if (\n      typeof value !== 'undefined' &&\n      typeof value === 'number' &&\n      value > maxValue\n    ) {\n      maxProp = key;\n      maxValue = value;\n    }\n  });\n\n  return maxProp;\n}\n"]}