// TimeSpan already does that // public string GetTime(TimeFormat format = TimeFormat.MINUTES) // { // TimeSpan formattedTime = TimeSpan.FromMilliseconds(_duration); // string formattedValue = ""; // switch (format) // TODO : Do something with format // { // case TimeFormat.MILLISECONDS: // formattedValue = _duration+""; // break; // case TimeFormat.SECONDS: // formattedValue = formattedTime.TotalMinutes; // break; // case TimeFormat.MINUTES: // formattedValue = total.Minutes + ":" + total.Seconds + "." + total.Milliseconds; // break; // } // return formatedValue; // } #endregion #region functions /// <summary> /// Starts the timer and sets its starting time to the current time. /// </summary> public void Start() { if(_temporalState == TemporalState.Started) { throw new TimerAlreadyStartedException(); } else if(_temporalState == TemporalState.Ended) { throw new TimerEndedException(); } _startTime = Time.time*1000f; _temporalState = TemporalState.Started; }
/// <summary> /// Initializes a new instance of the <see cref="UnityEzExp.EzTimer"/> class. /// </summary> public EzTimer() { _temporalState = TemporalState.NotStarted; _startTime = 0f; _breaks = new List <float>(); _endTime = 0f; _duration = 0f; }
/// <summary> /// Copy an instance of the <see cref="UnityEzExp.EzTimer"/>. /// </summary> /// <param name="toCopy">Instance to copy.</param> public EzTimer(EzTimer toCopy): this() { _temporalState = toCopy._temporalState; _startTime = toCopy._startTime; foreach(float b in toCopy._breaks) { _breaks.Add(b); } _endTime = toCopy._endTime; // forces duration to be computed before assigning it _duration = toCopy.GetRawDuration(); }
/// <summary> /// Initialize the temporalInstancts variable to the /// length of the observation sequence. /// </summary> /// <param name="observations"> /// A sequence of observations. /// </param> public void InitializeObservation(int[] observations) { int T = observations.Length; tempInstancts = new TemporalState[T]; for (int t = 0; t < T; t++) { tempInstancts[t] = new TemporalState(States); } }
/// <summary> /// Cancels the trial. The main timer is reset to 0 and the trial can be started again. /// </summary> public void ResetTrial() { _trialState = TemporalState.NotStarted; _mainTimer.Reset(); foreach (EzTimer timer in _timers.Values) { if (timer.GetState() == TemporalState.Started) { timer.Reset(); } } }
/// <summary> /// Starts this trial (starts all timers by default and set state to started). /// </summary> public void StartTrial() { if (_trialState == TemporalState.Started) { throw new TemporalStateException("The trial has already been started"); } else if (_trialState == TemporalState.Ended) { throw new TemporalStateException("The trial has already been ended"); } // StartAllTimers(); // StartTimer("main"); _trialState = TemporalState.Started; _mainTimer.Start(); }
/// <summary> /// Ends the trial. The main timer is stopped along with all timers not stopped already. /// </summary> public void EndTrial() { if (_trialState == TemporalState.NotStarted) { throw new TemporalStateException("The trial was not started yet."); } else if (_trialState == TemporalState.Ended) { throw new TemporalStateException("The trial has already been ended."); } // EndTimer("main"); _trialState = TemporalState.Ended; _mainTimer.Stop(); foreach (EzTimer timer in _timers.Values) { if (timer.GetState() == TemporalState.Started) { timer.Stop(); } } }
/// <summary> /// Stops the timer and sets its ending time to the current time. /// </summary> public void Stop() { _endTime = Time.time * 1000f; _temporalState = TemporalState.Ended; _duration = ComputeDuration(); }
/// <summary> /// Runs the Baum-Welch learning algorithm for hidden Markov models. /// </summary> /// <remarks> /// Learning problem. Given a training observation sequence O = {o1, o2, ..., oK} /// and general structure of HMM (numbers of hidden and visible states), determine /// HMM parameters M = (A, B, pi) that best fit training data. /// </remarks> /// <para> /// The Baum–Welch algorithm is a particular case of a generalized expectation-maximization /// (GEM) algorithm. It can compute maximum likelihood estimates and posterior mode estimates /// for the parameters (transition and emission probabilities) of an HMM, when given only /// emissions as training data. /// </para> /// /// <para> /// The algorithm has two steps: /// - Calculating the forward probability and the backward probability for each HMM state; /// - On the basis of this, determining the frequency of the transition-emission pair values /// and dividing it by the probability of the entire string. This amounts to calculating /// the expected count of the particular transition-emission pair. Each time a particular /// transition is found, the value of the quotient of the transition divided by the probability /// of the entire string goes up, and this value can then be made the new value of the transition. /// </para> /// <param name="observations">A sequence of observations.</param> /// <returns></returns> private void baum_welch(int[][] observations) { if (observations == null) { throw new ArgumentNullException("observations"); } int N = observations.Length; var multipleTempInstants = new TemporalState[N][]; for (int k = 0; k < N; k++) { // 1. Calculating the forward probability and the // backward probability for each HMM state. InitializeObservation(observations[k]); forward(observations[k]); backward(observations[k]); int T = observations[k].Length; // 2. Determining the frequency of the transition-emission pair values // and dividing it by the probability of the entire string. // Calculate gamma values update(T); // Calculate xi for (int t = 0; t < T - 1; t++) { tempInstancts[t].Xi = calcXi(t, observations[k][t + 1]); } multipleTempInstants[k] = tempInstancts; } // 3. Continue with parameter re-estimation // 3.1 Re-estimation of initial state probabilities for (int i = 0; i < States; i++) { double sum = 0; for (int k = 0; k < N; k++) { sum += multipleTempInstants[k][0].Gamma[i]; } Probabilities[i] = sum / N; } // 3.2 Re-estimation of transition probabilities for (int i = 0; i < States; i++) { for (int j = 0; j < States; j++) { double den = 0, num = 0; for (int k = 0; k < N; k++) { int T = observations[k].Length; for (int t = 0; t < T - 1; t++) { num += multipleTempInstants[k][t].Xi.getValue(i, j); den += multipleTempInstants[k][t].Gamma[i]; } } // Remove from the matrix if needed if (den != 0) { double result = num / den; if (result != 0) { Transitions.setValue(i, j, result); } else { Transitions.Remove(i, j); } } else { Transitions.Remove(i, j); } } } // 3.3 Re-estimation of emission probabilities for (int i = 0; i < States; i++) { for (int j = 0; j < Symbols; j++) { double den = 0, num = 0; for (int k = 0; k < N; k++) { int T = observations[k].Length; for (int t = 0; t < T; t++) { if (observations[k][t] == j) { num += multipleTempInstants[k][t].Gamma[i]; } } for (int t = 0; t < T; t++) { den += multipleTempInstants[k][t].Gamma[i]; } } // Remove from the matrix if needed if (num != 0) { Emissions.setValue(i, j, num / den); } else { Emissions.Remove(i, j); } } } }
/// <summary> /// Runs the Baum-Welch learning algorithm for hidden Markov models. /// </summary> /// <remarks> /// Learning problem. Given a training observation sequence O = {o1, o2, ..., oK} /// and general structure of HMM (numbers of hidden and visible states), determine /// HMM parameters M = (A, B, pi) that best fit training data. /// </remarks> /// <para> /// The Baum–Welch algorithm is a particular case of a generalized expectation-maximization /// (GEM) algorithm. It can compute maximum likelihood estimates and posterior mode estimates /// for the parameters (transition and emission probabilities) of an HMM, when given only /// emissions as training data. /// </para> /// /// <para> /// The algorithm has two steps: /// - Calculating the forward probability and the backward probability for each HMM state; /// - On the basis of this, determining the frequency of the transition-emission pair values /// and dividing it by the probability of the entire string. This amounts to calculating /// the expected count of the particular transition-emission pair. Each time a particular /// transition is found, the value of the quotient of the transition divided by the probability /// of the entire string goes up, and this value can then be made the new value of the transition. /// </para> /// <param name="observations">A sequence of observations.</param> /// <returns></returns> private void baum_welch(int[][] observations) { if (observations == null) throw new ArgumentNullException("observations"); int N = observations.Length; var multipleTempInstants = new TemporalState[N][]; for (int k = 0; k < N; k++) { // 1. Calculating the forward probability and the // backward probability for each HMM state. InitializeObservation(observations[k]); forward(observations[k]); backward(observations[k]); int T = observations[k].Length; // 2. Determining the frequency of the transition-emission pair values // and dividing it by the probability of the entire string. // Calculate gamma values update(T); // Calculate xi for (int t = 0; t < T - 1; t++) tempInstancts[t].Xi = calcXi(t, observations[k][t + 1]); multipleTempInstants[k] = tempInstancts; } // 3. Continue with parameter re-estimation // 3.1 Re-estimation of initial state probabilities for (int i = 0; i < States; i++) { double sum = 0; for (int k = 0; k < N; k++) sum += multipleTempInstants[k][0].Gamma[i]; Probabilities[i] = sum / N; } // 3.2 Re-estimation of transition probabilities for (int i = 0; i < States; i++) { for (int j = 0; j < States; j++) { double den = 0, num = 0; for (int k = 0; k < N; k++) { int T = observations[k].Length; for (int t = 0; t < T - 1; t++) { num += multipleTempInstants[k][t].Xi.getValue(i, j); den += multipleTempInstants[k][t].Gamma[i]; } } // Remove from the matrix if needed if (den != 0) { double result = num / den; if (result != 0) Transitions.setValue(i, j, result); else Transitions.Remove(i, j); } else Transitions.Remove(i, j); } } // 3.3 Re-estimation of emission probabilities for (int i = 0; i < States; i++) { for (int j = 0; j < Symbols; j++) { double den = 0, num = 0; for (int k = 0; k < N; k++) { int T = observations[k].Length; for (int t = 0; t < T; t++) { if (observations[k][t] == j) num += multipleTempInstants[k][t].Gamma[i]; } for (int t = 0; t < T; t++) den += multipleTempInstants[k][t].Gamma[i]; } // Remove from the matrix if needed if (num != 0) Emissions.setValue(i, j, num / den); else Emissions.Remove(i, j); } } }