private static UncertainValue Integrate_Adaptive(MultiFunctor f, CoordinateTransform[] map, IntegrationRegion r, EvaluationSettings settings) { // Create an evaluation rule GenzMalik75Rule rule = new GenzMalik75Rule(r.Dimension); // Use it on the whole region and put the answer in a linked list rule.Evaluate(f, map, r); LinkedList<IntegrationRegion> regionList = new LinkedList<IntegrationRegion>(); regionList.AddFirst(r); // Iterate until convergence while (f.EvaluationCount < settings.EvaluationBudget) { // Add up value and errors in all regions. // While we are at it, take note of the region with the largest error. double value = 0.0; double error = 0.0; LinkedListNode<IntegrationRegion> regionNode = regionList.First; double maxError = 0.0; LinkedListNode<IntegrationRegion> maxErrorNode = null; while (regionNode != null) { IntegrationRegion region = regionNode.Value; value += region.Value; error += region.Error; //error += MoreMath.Sqr(region.Error); if (region.Error > maxError) { maxError = region.Error; maxErrorNode = regionNode; } regionNode = regionNode.Next; } // Check for convergence. if ((error <= settings.AbsolutePrecision) || (error <= settings.RelativePrecision * Math.Abs(value))) { return (new UncertainValue(value, error)); } // Split the region with the largest error, and evaluate each subregion. IntegrationRegion maxErrorRegion = maxErrorNode.Value; regionList.Remove(maxErrorNode); IList<IntegrationRegion> subRegions = maxErrorRegion.Split(maxErrorRegion.SplitIndex); /* Countdown cnt = new Countdown(2); ThreadPool.QueueUserWorkItem((object state) => { rule.Evaluate(f, subRegions[0]); cnt.Signal(); }); ThreadPool.QueueUserWorkItem((object state) => { rule.Evaluate(f, subRegions[1]); cnt.Signal(); }); cnt.Wait(); foreach (IntegrationRegion subRegion in subRegions) { regionList.AddLast(subRegion); } */ foreach (IntegrationRegion subRegion in subRegions) { rule.Evaluate(f, map, subRegion); regionList.AddLast(subRegion); } } throw new NonconvergenceException(); }
private static UncertainValue Integrate_Adaptive(MultiFunctor f, CoordinateTransform[] map, IntegrationRegion r, EvaluationSettings settings) { // Create an evaluation rule GenzMalik75Rule rule = new GenzMalik75Rule(r.Dimension); // Use it on the whole region and put the answer in a linked list rule.Evaluate(f, map, r); LinkedList <IntegrationRegion> regionList = new LinkedList <IntegrationRegion>(); regionList.AddFirst(r); // Iterate until convergence while (f.EvaluationCount < settings.EvaluationBudget) { // Add up value and errors in all regions. // While we are at it, take note of the region with the largest error. double value = 0.0; double error = 0.0; LinkedListNode <IntegrationRegion> regionNode = regionList.First; double maxError = 0.0; LinkedListNode <IntegrationRegion> maxErrorNode = null; while (regionNode != null) { IntegrationRegion region = regionNode.Value; value += region.Value; error += region.Error; //error += MoreMath.Sqr(region.Error); if (region.Error > maxError) { maxError = region.Error; maxErrorNode = regionNode; } regionNode = regionNode.Next; } // Check for convergence. if ((error <= settings.AbsolutePrecision) || (error <= settings.RelativePrecision * Math.Abs(value))) { return(new UncertainValue(value, error)); } // Split the region with the largest error, and evaluate each subregion. IntegrationRegion maxErrorRegion = maxErrorNode.Value; regionList.Remove(maxErrorNode); IList <IntegrationRegion> subRegions = maxErrorRegion.Split(maxErrorRegion.SplitIndex); /* * Countdown cnt = new Countdown(2); * ThreadPool.QueueUserWorkItem((object state) => { rule.Evaluate(f, subRegions[0]); cnt.Signal(); }); * ThreadPool.QueueUserWorkItem((object state) => { rule.Evaluate(f, subRegions[1]); cnt.Signal(); }); * cnt.Wait(); * foreach (IntegrationRegion subRegion in subRegions) { * regionList.AddLast(subRegion); * } */ foreach (IntegrationRegion subRegion in subRegions) { rule.Evaluate(f, map, subRegion); regionList.AddLast(subRegion); } } throw new NonconvergenceException(); }