def calculateTransientTime(self, inputs, outputs, epsilon, proximityLength = None): # inputs: input of reserovoir # outputs: output of reservoir # epsilon: given constant # proximity length: number of steps for which all states have to be epsilon close to declare convergance # initializes two initial states as far as possible from each other in [-1,1] regime and tests when they converge-> this is transient time length = inputs.shape[0] if inputs is not None else outputs.shape[0] if proximityLength is None: proximityLength = int(length * 0.1) if proximityLength < 3: proximityLength = 3 initial_x = B.empty((2, self.n_reservoir, 1)) initial_x[0] = - B.ones((self.n_reservoir, 1)) initial_x[1] = B.ones((self.n_reservoir, 1)) countedConsecutiveSteps = 0 length = inputs.shape[0] if inputs is not None else outputs.shape[0] for t in range(length): if B.max(B.ptp(initial_x, axis=0)) < epsilon: if countedConsecutiveSteps >= proximityLength: return t - proximityLength else: countedConsecutiveSteps += 1 else: countedConsecutiveSteps = 0 u = inputs[t].reshape(-1, 1) if inputs is not None else None o = outputs[t].reshape(-1, 1) if outputs is not None else None for i in range(initial_x.shape[0]): self.update(u, o, initial_x[i]) #transient time could not be determined raise ValueError("Transient time could not be determined - maybe the proximityLength is too big.")
def getEquilibriumState(inputs, outputs, epsilon = 1e-3): # inputs: input of reserovoir # outputs: output of reservoir # epsilon: given constant # returns the equilibrium state when esn is fed with the first state of input x = B.empty((2, self.n_reservoir, 1)) while not B.max(B.ptp(x, axis=0)) < epsilon: x[0] = x[1] u = inputs[0].reshape(-1, 1) if inputs is not None else None o = outputs[0].reshape(-1, 1) if outputs is not None else None self.update(u, o, x[1]) return x[1]
def reduceTransientTime(self, inputs, outputs, initialTransientTime, epsilon = 1e-3, proximityLength = 50): # inputs: input of reserovoir # outputs: output of reservoir # epsilon: given constant # proximity length: number of steps for which all states have to be epsilon close to declare convergance # initialTransientTime: transient time with calculateTransientTime() method estimated # finds initial state with lower transient time and sets internal state to this state # returns the new transient time by calculating the convergence time of initial states found with SWD and Equilibrium method def getEquilibriumState(inputs, outputs, epsilon = 1e-3): # inputs: input of reserovoir # outputs: output of reservoir # epsilon: given constant # returns the equilibrium state when esn is fed with the first state of input x = B.empty((2, self.n_reservoir, 1)) while not B.max(B.ptp(x, axis=0)) < epsilon: x[0] = x[1] u = inputs[0].reshape(-1, 1) if inputs is not None else None o = outputs[0].reshape(-1, 1) if outputs is not None else None self.update(u, o, x[1]) return x[1] def getStateAtGivenPoint(inputs, outputs, targetTime): # inputs: input of reserovoir # outputs: output of reservoir # targetTime: time at which the state is wanted # propagates the inputs/outputs till given point in time and returns the state of the reservoir at this point x = B.zeros((self.n_reservoir, 1)) length = inputs.shape[0] if inputs is not None else outputs.shape[0] length = min(length, targetTime) for t in range(length): u = inputs[t].reshape(-1, 1) if inputs is not None else None o = outputs[t].reshape(-1, 1) if outputs is not None else None self.update(u, o, x) return x length = inputs.shape[0] if inputs is not None else outputs.shape[0] if proximityLength is None: proximityLength = int(length * 0.1) if proximityLength < 3: proximityLength = 3 x = B.empty((2, self.n_reservoir, 1)) equilibriumState = getEquilibriumState(inputs, outputs) if inputs is None: swdPoint, _ = hp.SWD(outputs, int(initialTransientTime*0.8)) else: swdPoint, _ = hp.SWD(inputs, int(initialTransientTime * 0.8)) swdState = getStateAtGivenPoint(inputs, outputs, swdPoint) x[0] = equilibriumState x[1] = swdState transientTime = 0 countedConsecutiveSteps = 0 for t in range(length): if B.max(B.ptp(x, axis=0)) < epsilon: countedConsecutiveSteps += 1 if countedConsecutiveSteps > proximityLength: transientTime = t - proximityLength break else: countedConsecutiveSteps = 0 u = inputs[t].reshape(-1, 1) if inputs is not None else None o = outputs[t].reshape(-1, 1) if outputs is not None else None for i in range(x.shape[0]): self.update(u, o, x[i]) self._x = x[0] return transientTime