public FiniteStateMCLog RandomVisits(int numOfSteps) { var log = new FiniteStateMCLog(numOfSteps); var inverseTemp = 1 / T; var stateProbabilities = _stateEnergies.Select(e => Math.Exp(-(e * inverseTemp))).ToArray(); var p = StateEnergies.Divide(T).Negative().Exp(); p = p.Divide(p.Sum()); var cumulativeProbability = p.CumSum(); Stream trajectoriesStream = null; if (OutputStream != null) { trajectoriesStream = OutputStream; } else if (OutputFileName != null) { trajectoriesStream = new FileStream(OutputFileName, FileMode.Create, FileAccess.Write, FileShare.Read); } Action <int> writeFunction; BitWriter bs = null; var numOfBits = (int)Math.Ceiling(Math.Log(StateEnergies.Length, 2.0)); switch (OutputStyle) { case 1: writeFunction = (state => { trajectoriesStream.WriteByte((byte)(1 << state)); }); break; case 2: bs = new BitWriter(trajectoriesStream); writeFunction = (state => { bs.WriteBits((ulong)state, numOfBits); }); break; default: writeFunction = (state => { trajectoriesStream.WriteByte((byte)state); }); break; } for (int stepIndex = 0; stepIndex < numOfSteps; stepIndex++) { var randomNum = _random.NextDouble(); CurrentState = cumulativeProbability.IndexOfFirstGreater(randomNum); _stateVisits[CurrentState]++; log.VisitLog[stepIndex] = CurrentState; // Write trajectories if (trajectoriesStream != null) { writeFunction(CurrentState); } } // Dispose of the stream only if this funcion created it if (trajectoriesStream != null && OutputStream == null) { trajectoriesStream.Dispose(); } double sum = _stateVisits.Sum(); log.MeanOccupancy = _stateVisits.Select(v => v / sum).ToArray(); log.Entropy = -log.MeanOccupancy.Select(m => (m + 1e-16) * Math.Log(m + 1e-16)).Sum(); log.TheoreticalEntropy = -p.MultiplyElements(p.Ln()).Sum(); return(log); }
public FiniteStateMCLog RunAndLog(int numOfSteps, int intervalBetweenLogEntries) { var numOfLogEntries = numOfSteps / intervalBetweenLogEntries; var log = new FiniteStateMCLog(numOfLogEntries); Stream trajectoriesStream = null; if (OutputStream != null) { trajectoriesStream = OutputStream; } else if (OutputFileName != null) { trajectoriesStream = new FileStream(OutputFileName, FileMode.Create, FileAccess.Write, FileShare.Read); } Action <int> writeFunction; BitWriter bs = null; var numOfBits = (int)Math.Ceiling(Math.Log(StateEnergies.Length, 2.0)); switch (OutputStyle) { case 1: writeFunction = (state => { trajectoriesStream.WriteByte((byte)(1 << state)); }); break; case 2: bs = new BitWriter(trajectoriesStream); writeFunction = (state => { bs.WriteBits((ulong)state, numOfBits); }); break; default: writeFunction = (state => { trajectoriesStream.WriteByte((byte)state); }); break; } for (int stepIndex = 0; stepIndex < numOfSteps; stepIndex++) { var nextState = _random.Next(_stateEnergies.Length); var shouldAccept = (_stateEnergies[CurrentState] > _stateEnergies[nextState]) || (_random.NextDouble() < Math.Exp((_stateEnergies[CurrentState] - _stateEnergies[nextState]) / T)); if (shouldAccept) { CurrentState = nextState; } if (stepIndex % intervalBetweenLogEntries == 0) { _stateVisits[CurrentState]++; log.VisitLog[stepIndex / intervalBetweenLogEntries] = CurrentState; // Write trajectories if (trajectoriesStream != null) { writeFunction(CurrentState); } } } // Dispose of the stream only if this funcion created it if (trajectoriesStream != null && OutputStream == null) { trajectoriesStream.Dispose(); } double sum = _stateVisits.Sum(); log.MeanOccupancy = _stateVisits.Select(v => v / sum).ToArray(); log.Entropy = -log.MeanOccupancy.Select(m => (m + 1e-16) * Math.Log(m + 1e-16)).Sum(); var p = StateEnergies.Divide(T).Negative().Exp(); p = p.Divide(p.Sum()); log.TheoreticalEntropy = -p.MultiplyElements(p.Ln()).Sum(); return(log); }