private void CrossEntropy2(ref StateDependentGammaInfo gammaInfo, double tempRareEvent) { IBoolean tempRareEventExpression = new EqualTo(_reExpression, new ConstantValue(tempRareEvent)); var startPC = Enumerable.Repeat(1.0, _reactions.NumReactions).ToArray(); var endPC = new double[_reactions.NumReactions]; var rateUpdateMethod = new ReactionRatesUpdateMethod(_reactions.UpdateRatesIteration2); for (int i = 0; i < _crossEntropyRuns; i++) { StartRealization(); var n = new List <int[]>(); var lambda = new List <double[]>(); double weight = 1.0; for (int j = 0; j < _reactions.NumReactions; j++) { n.Add(new int[(gammaInfo.IntermediatePropensityCutoff[j]).Length + 1]); lambda.Add(new double[(gammaInfo.IntermediatePropensityCutoff[j]).Length + 1]); } while (CurrentTime < duration) { if (tempRareEventExpression.Value) { gammaInfo.UpdateGamma(weight, n, lambda); break; } GenericStepOnce(ref weight, gammaInfo, ref startPC, ref endPC, ref n, ref lambda, rateUpdateMethod, ref _binIndex, null); } } gammaInfo.SetIntermediateGamma(); }
protected virtual void GenericStepOnce(ref double weight, StateDependentGammaInfo tempGammaInfo, ref double[] startPC, ref double[] endPC, ref List <int[]> tempN, ref List <double[]> tempLambda, ReactionRatesUpdateMethod reactionRateUpdateMethod, ref int[] indexArray, BinEdgesUpdateMethod binEdgesUpdateMethod) { double b0 = reactionRateUpdateMethod(tempGammaInfo.IntermediateGamma, tempGammaInfo.IntermediatePropensityCutoff, tempGammaInfo.PreviousIntermediatePropensityCutoff, ref _gammaIndex, ref _binIndex); double a0 = _reactions.CurrentRates.Sum(); if (b0 > 0.0) { double r = rng.GenerateUniformOO(); double tau = Math.Log(1.0 / r) / b0; CurrentTime += tau; if (CurrentTime < duration) { int mu = SelectAndFireReaction(b0); AccumulateBiasingParameters(ref tempN, ref tempLambda, tau, mu, indexArray); binEdgesUpdateMethod?.Invoke(ref startPC, ref endPC, a0, mu); weight *= Math.Exp((b0 - a0) * tau) / tempGammaInfo.IntermediateGamma[mu][_gammaIndex[mu]]; } } else { CurrentTime = duration; } }
private void UpdateBiasingParameters(StateDependentGammaInfo gammaInfo, double intermediateRareEvent) { _biasingParameters.RareEvent.Thresholds.Add(intermediateRareEvent); for (int i = 0; i < _reactions.Reactions.Count; i++) { var tempRareEventInfo = new BiasingParameters.RareEventInfo { BinCount = gammaInfo.IntermediateGamma[i].Count() }; gammaInfo.IntermediateGamma[i].CopyTo(tempRareEventInfo.Gammas, 0); gammaInfo.IntermediatePropensityCutoff[i].CopyTo(tempRareEventInfo.Thresholds, 0); UpdateReactionInfo(tempRareEventInfo, i); } }
private void RunCrossEntropy() { int iter = 1; var gammaInfo = new StateDependentGammaInfo(_reactions.NumReactions, _gammaSize, _binCountThreshold); double intermediateRareEvent = _rareEventType == 1 ? 0 : _reExpression.Value; while (Math.Abs(intermediateRareEvent - _rareEventValue) > double.Epsilon && iter < 15) { Console.WriteLine("\nCross Entropy iteration " + iter + ":"); var startPC = Enumerable.Repeat(1.0, _reactions.NumReactions).ToArray(); var endPC = new double[_reactions.NumReactions]; bool rareEventFlag = false; gammaInfo.UpdateStructure(); CrossEntropy1(ref gammaInfo, ref intermediateRareEvent, ref startPC, ref endPC, ref rareEventFlag); Console.WriteLine(" Intermediate rare event: " + intermediateRareEvent); if (rareEventFlag) { Console.WriteLine("\nReached the rare event. Exiting multilevel cross entropy simulation..."); UpdateBiasingParameters(gammaInfo, intermediateRareEvent); break; } gammaInfo.UpdatePropensityCutoff(startPC, endPC); gammaInfo.UpdateStructure(); CrossEntropy2(ref gammaInfo, intermediateRareEvent); gammaInfo.MergeBins(); UpdateBiasingParameters(gammaInfo, intermediateRareEvent); iter++; } _biasingParameters.WriteParametersToJsonFile(modelInfo.Name + "_sdwSSA_CEinfo.json"); if (iter == 15) { throw new ApplicationException("multilevel cross entropy did not converged in 15 iterations."); } for (int i = 0; i < _reactions.NumReactions; i++) { _gamma[i] = gammaInfo.IntermediateGamma[i]; _propensityCutoff[i] = gammaInfo.IntermediatePropensityCutoff[i]; } }
private void CrossEntropy1(ref StateDependentGammaInfo gammaInfo, ref double intermediateRareEvent, ref double[] startPC, ref double[] endPC, ref bool rareEventFlag) { var maxRareEventValue = new double[_crossEntropyRuns]; int counter = 0; var rateUpdateMethod = new ReactionRatesUpdateMethod(_reactions.UpdateRatesIteration1); var binEdgesUpdateMethod = new BinEdgesUpdateMethod(UpdateBinEdges); for (int i = 0; i < _crossEntropyRuns; i++) { StartRealization(); double currentMin = _rareEventType * (_rareEventValue - _reExpression.Value); var n = new List <int[]>(); var lambda = new List <double[]>(); double weight = 1.0; for (int j = 0; j < _reactions.NumReactions; j++) { n.Add(new int[(gammaInfo.IntermediatePropensityCutoff[j]).Length + 1]); lambda.Add(new double[(gammaInfo.IntermediatePropensityCutoff[j]).Length + 1]); } while (CurrentTime < duration) { if (_rareEventTest.Value) { counter++; gammaInfo.UpdateGamma(weight, n, lambda); break; } GenericStepOnce(ref weight, gammaInfo, ref startPC, ref endPC, ref n, ref lambda, rateUpdateMethod, ref _gammaIndex, binEdgesUpdateMethod); double tempMin = _rareEventType * (_rareEventValue - _reExpression.Value); currentMin = Math.Min(currentMin, tempMin); } maxRareEventValue[i] = currentMin; } Array.Sort(maxRareEventValue); double ireComp = maxRareEventValue[(int)Math.Ceiling(_crossEntropyRuns * _crossEntropyThreshold)]; double pastIntermediateRareEvent = intermediateRareEvent; intermediateRareEvent = ireComp < 0 ? _rareEventValue : _rareEventType * (_rareEventValue - ireComp); if ((pastIntermediateRareEvent - intermediateRareEvent) * _rareEventType >= 0) { _crossEntropyThreshold *= 0.8; Console.WriteLine("Cross entropy threshold changed to : " + _crossEntropyThreshold); if (_crossEntropyThreshold * _crossEntropyRuns * 0.8 < _crossEntropyMinDataSize) { _crossEntropyRuns = (int)Math.Ceiling(_crossEntropyMinDataSize / _crossEntropyThreshold); Console.WriteLine("Number of cross entropy simulations changed to : " + _crossEntropyRuns); } } if (intermediateRareEvent >= _rareEventValue && counter >= (int)(_crossEntropyRuns * _crossEntropyThreshold)) { rareEventFlag = true; gammaInfo.SetIntermediateGamma(); } }