/// <summary> /// 함수의 [a,b] 구간을 적분합니다. /// </summary> /// <param name="func">적분할 함수</param> /// <param name="a">적분 시작 위치</param> /// <param name="b">적분 끝 위치</param> /// <returns>적분 값</returns> public override double Integrate(Func <double, double> func, double a, double b) { func.ShouldNotBeNull("func"); if (IsDebugEnabled) { log.Debug(@"Simpson 적분법을 이용하여 적분을 수행합니다. func=[{0}], a=[{1}], b=[{2}]", func, a, b); } func.ShouldNotBeNull("unaryFunc"); if (a > b) { return(Integrate(func, b, a)); } _steps = GetSteps(a, b, _steps); double h = (b - a) / (2.0 * _steps); double hdiv3 = h / 3; double fo = 0; double fe = 0; double N = 2 * _steps - 3; ParallelTool.ForWithStep(1, (int)N + 1, 2, () => 0.0, (i, loopState, local) => local + func(a + h * i), local => { lock (_syncLock) fo += local; }); ParallelTool.ForWithStep(1, (int)N + 1, 2, () => 0.0, (i, loopState, local) => local + func(a + h * (i + 1)), local => { lock (_syncLock) fe += local; }); //for(int i = 1; i <= N; i += 2) //{ // fo += func(a + h * i); // 홀수항 (odd) // fe += func(a + h * (i + 1)); // 짝수항 (even) //} var result = (func(a) + func(b) + 4.0 * (fo + func(b - h)) + 2.0 * fe) * hdiv3; if (IsDebugEnabled) { log.Debug(@"적분결과=[{0}]", result); } return(result); }
/// <summary> /// 함수의 [a,b] 구간을 적분합니다. /// </summary> /// <param name="func">적분할 함수</param> /// <param name="a">적분 시작 위치</param> /// <param name="b">적분 끝 위치</param> /// <returns>적분 값</returns> public override double Integrate(Func <double, double> func, double a, double b) { func.ShouldNotBeNull("func"); if (IsDebugEnabled) { log.Debug(@"중점접(MidValue)를 이용하여 적분을 수행합니다. func=[{0}], a=[{1}], b=[{2}]", func, a, b); } func.ShouldNotBeNull("f"); if (a > b) { MathTool.Swap(ref a, ref b); } int n = GetSteps(a, b, Steps); double h = (b - a) / n; double hdiv2 = h / 2; double n2 = n * 2; double result = 0; ParallelTool.ForWithStep(1, (int)(n2 + 1), 2, () => 0.0, (i, loopState, local) => local + func(a + i * hdiv2), local => { lock (_syncLock) result += local; }); //for(int i = 1; i < n2; i += 2) // result += func(a + i * hdiv2); result *= h; if (IsDebugEnabled) { log.Debug(@"적분 결과=[{0}]", result); } return(result); }
public void AddWeekOfYearsTest() { const int maxAddWeeks = 40; Action <CultureInfo> @AddWeekOfYearsAction = (culture) => { var currentCulture = culture; Enumerable .Range(2000, 20) .RunEach(year => { const int step = 10; YearAndWeek prevResult = new YearAndWeek(); var maxWeek = WeekTool.GetEndYearAndWeek(year, currentCulture); for (var week = 1; week < maxWeek.Week; week += step) { for (var addWeeks = -maxAddWeeks; addWeeks <= maxAddWeeks; addWeeks += step) { var current = new YearAndWeek(year, week); var result = WeekTool.AddWeekOfYears(current, addWeeks, currentCulture); if (addWeeks != 0 && prevResult.Week.HasValue) { if (result.Year == prevResult.Year) { Assert.AreEqual(prevResult.Week + step, result.Week, @"Prev=[{0}], Result=[{1}], addWeeks=[{2}]", prevResult, result, addWeeks); } } result.Week.Should().Have.Value(); result.Week.Value.Should().Be.GreaterThan(0); result.Week.Value.Should().Be.LessThanOrEqualTo(TimeSpec.MaxWeeksPerYear); prevResult = result; if (IsDebugEnabled) { log.Debug("Current=[{0}], Added=[{1}], AddWeeks=[{2}]", current, result, addWeeks); } } } }); }; Parallel.For(0, CultureTestData.Default.Count(), i => @AddWeekOfYearsAction(CultureTestData.Default[i])); var rule = WeekOfYearRuleKind.Iso8601; ParallelTool.ForWithStep(2000, 2020, 2, year => { const int step = 10; var prevResult = new YearAndWeek(); var maxWeek = WeekTool.GetEndYearAndWeek(year, null, rule); for (var week = 1; week < maxWeek.Week; week += step) { for (var addWeeks = -maxAddWeeks; addWeeks <= maxAddWeeks; addWeeks += step) { var current = new YearAndWeek(year, week); var result = WeekTool.AddWeekOfYears(current, addWeeks, null, rule); if (addWeeks != 0 && prevResult.Week.HasValue) { if (result.Year == prevResult.Year) { Assert.AreEqual(prevResult.Week + step, result.Week, @"Prev={0}, Result={1}, addWeeks={2}", prevResult, result, addWeeks); } } result.Week.Should().Have.Value(); result.Week.Value.Should().Be.GreaterThan(0); result.Week.Value.Should().Be.LessThanOrEqualTo(TimeSpec.MaxWeeksPerYear); prevResult = result; if (IsDebugEnabled) { log.Debug("Current=[{0}], Added=[{1}], AddWeeks=[{2}]", current, result, addWeeks); } } } }); }