예제 #1
0
파일: sdwSSA.cs 프로젝트: clorton/IDM-CMS
        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();
        }
예제 #2
0
파일: sdwSSA.cs 프로젝트: clorton/IDM-CMS
        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;
            }
        }
예제 #3
0
파일: sdwSSA.cs 프로젝트: clorton/IDM-CMS
        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);
            }
        }
예제 #4
0
파일: sdwSSA.cs 프로젝트: clorton/IDM-CMS
        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];
            }
        }
예제 #5
0
파일: sdwSSA.cs 프로젝트: clorton/IDM-CMS
        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();
            }
        }