import * as nn from "./nn" ; import * as dataset from "./dataset" ; import { Example2D , shuffle , DataGenerator } from "./dataset" ; /** Suffix added to the state when storing if a control is hidden or not. */ const HIDE_STATE_SUFFIX = "_hide" ; /** A map between names and activation functions. */ export let activations = { "relu" : nn . Activations . RELU , "tanh" : nn . Activations . TANH , "sigmoid" : nn . Activations . SIGMOID , "linear" : nn . Activations . LINEAR , "sinx" : nn . Activations . SINX } ; /** A map between names and regularization functions. */ export let regularizations = { "none" : null , "L1" : nn . RegularizationFunction . L1 , "L2" : nn . RegularizationFunction . L2 } ; /** A map between dataset names and functions that generate classification data. */ export let datasets = { "circle" : dataset . classifyCircleData , "xor" : dataset . classifyXORData , "gauss" : dataset . classifyTwoGaussData , "spiral" : dataset . classifySpiralData , "byod" : dataset . classifyBYOData } ; /** A map between dataset names and functions that generate regression data. */ export let regDatasets = { "reg-plane" : dataset . regressPlane , "reg-gauss" : dataset . regressGaussian } ; export function getKeyFromValue ( obj , value ) { for ( let key in obj ) { if ( obj [ key ] === value ) { return key ; } } return undefined ; } function endsWith ( s , suffix ) { return s . substr ( - suffix . length ) === suffix ; } function getHideProps ( obj ) { let result = [ ] ; for ( let prop in obj ) { if ( endsWith ( prop , HIDE_STATE_SUFFIX ) ) { result . push ( prop ) ; } } return result ; } /**
 * The data type of a state variable. Used for determining the
 * (de)serialization method.
 */ export enum Type { STRING , NUMBER , ARRAY_NUMBER , ARRAY_STRING , BOOLEAN , OBJECT } export enum Problem { CLASSIFICATION , REGRESSION } export let problems = { "classification" : Problem . CLASSIFICATION , "regression" : Problem . REGRESSION } ; export interface Property { name : string ; type : Type ; keyMap ? : { [ key ] : any ; } ; } export class State { private static PROPS : Property [ ] = [ { name : "activation" , type : Type . OBJECT , keyMap : activations } , { name : "regularization" , type : Type . OBJECT , keyMap : regularizations } , { name : "batchSize" , type : Type . NUMBER } , { name : "dataset" , type : Type . OBJECT , keyMap : datasets } , { name : "regDataset" , type : Type . OBJECT , keyMap : regDatasets } , { name : "learningRate" , type : Type . NUMBER } , { name : "trueLearningRate" , type : Type . NUMBER } , { name : "regularizationRate" , type : Type . NUMBER } , { name : "noise" , type : Type . NUMBER } , { name : "networkShape" , type : Type . ARRAY_NUMBER } , { name : "seed" , type : Type . STRING } , { name : "showTestData" , type : Type . BOOLEAN } , { name : "discretize" , type : Type . BOOLEAN } , { name : "percTrainData" , type : Type . NUMBER } , { name : "x" , type : Type . BOOLEAN } , { name : "y" , type : Type . BOOLEAN } , { name : "xTimesY" , type : Type . BOOLEAN } , { name : "xSquared" , type : Type . BOOLEAN } , { name : "ySquared" , type : Type . BOOLEAN } , { name : "cosX" , type : Type . BOOLEAN } , { name : "sinX" , type : Type . BOOLEAN } , { name : "cosY" , type : Type . BOOLEAN } , { name : "sinY" , type : Type . BOOLEAN } , { name : "collectStats" , type : Type . BOOLEAN } , { name : "tutorial" , type : Type . STRING } , { name : "problem" , type : Type . OBJECT , keyMap : problems } , { name : "initZero" , type : Type . BOOLEAN } , { name : "hideText" , type : Type . BOOLEAN } ] ; [ key ] : any ; totalCapacity = 0.0 ; reqCapacity = 2 ; maxCapacity = 0 ; sugCapacity = 0 ; lossCapacity = 0 ; trueLearningRate = 0.0 ; learningRate = 1.0 ; regularizationRate = 0 ; showTestData = false ; noise = 35 ; batchSize = 10 ; discretize = false ; tutorial : string = null ; percTrainData = 50 ; activation = nn . Activations . SIGMOID ; regularization : nn . RegularizationFunction = null ; problem = Problem . CLASSIFICATION ; initZero = false ; hideText = false ; collectStats = false ; numHiddenLayers = 1 ; hiddenLayerControls : any [ ] = [ ] ; networkShape : number [ ] = [ 1 ] ; x = true ; y = true ; xTimesY = false ; xSquared = false ; ySquared = false ; cosX = false ; sinX = false ; cosY = false ; sinY = false ; byod = false ; data : Example2D [ ] = [ ] ; dataset : dataset . DataGenerator = dataset . classifyTwoGaussData ; regDataset : dataset . DataGenerator = dataset . regressPlane ; seed : string ; shiftDown : boolean ; /**
     * Deserializes the state from the url hash.
     */ static deserializeState ( ) { let map = { } ; for ( let keyvalue of window . location . hash . slice ( 1 ) . split ( "&" ) ) { let [ name , value ] = keyvalue . split ( "=" ) ; map [ name ] = value ; } let state = new State ( ) ; function hasKey ( name ) { return name in map && map [ name ] != null && map [ name ] . trim ( ) !== "" ; } function parseArray ( value ) { return value . trim ( ) === "" ? [ ] : value . split ( "," ) ; } State . PROPS . forEach ( ( { name , type , keyMap } ) => { switch ( type ) { case Type . OBJECT : if ( keyMap == null ) { throw Error ( "A key-value map must be provided for state " + "variables of type Object" ) ; } if ( hasKey ( name ) && map [ name ] in keyMap ) { state [ name ] = keyMap [ map [ name ] ] ; } break ; case Type . NUMBER : if ( hasKey ( name ) ) { state [ name ] = + map [ name ] ; } break ; case Type . STRING : if ( hasKey ( name ) ) { state [ name ] = map [ name ] ; } break ; case Type . BOOLEAN : if ( hasKey ( name ) ) { state [ name ] = ( map [ name ] === "false" ? false : true ) ; } break ; case Type . ARRAY_NUMBER : if ( name in map ) { state [ name ] = parseArray ( map [ name ] ) . map ( Number ) ; } break ; case Type . ARRAY_STRING : if ( name in map ) { state [ name ] = parseArray ( map [ name ] ) ; } break ; default : throw Error ( "Encountered an unknown type for a state variable" ) ; } } ) ; getHideProps ( map ) . forEach ( prop => { state [ prop ] = ( map [ prop ] === "true" ) ; } ) ; state . numHiddenLayers = state . networkShape . length ; if ( state . seed == null ) { state . seed = Math . random ( ) . toFixed ( 5 ) ; } Math . seedrandom ( state . seed ) ; state . shiftDown = false ; return state ; } /**
     * Serializes the state into the url hash.
     */ serialize ( ) { let props = [ ] ; State . PROPS . forEach ( ( { name , type , keyMap } ) => { let value = this [ name ] ; if ( value == null ) { return ; } if ( type === Type . OBJECT ) { value = getKeyFromValue ( keyMap , value ) ; } else if ( type === Type . ARRAY_NUMBER || type === Type . ARRAY_STRING ) { value = value . join ( "," ) ; } props . push ( `${ name }=${ value }` ) ; } ) ; getHideProps ( this ) . forEach ( prop => { props . push ( `${ prop }=${ this [ prop ] }` ) ; } ) ; window . location . hash = props . join ( "&" ) ; } /** Returns all the hidden properties. */ getHiddenProps ( ) { let result = [ ] ; for ( let prop in this ) { if ( endsWith ( prop , HIDE_STATE_SUFFIX ) && String ( this [ prop ] ) === "true" ) { result . push ( prop . replace ( HIDE_STATE_SUFFIX , "" ) ) ; } } return result ; } setHideProperty ( name , hidden ) { this [ name + HIDE_STATE_SUFFIX ] = hidden ; } }