/// <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(@"사다리꼴 적분법(Trapizoidal)을 이용하여 적분을 수행합니다. func=[{0}], a=[{1}], b=[{2}]", func, a, b);

            func.ShouldNotBeNull("func");

            if(a > b) MathTool.Swap<double>(ref a, ref b);

            double result = 0;

            int n = GetSteps(a, b);
            double h = (b - a) / n;
            double x = a;

            Parallel.For(1, n, () => 0.0, (i, loopState, local) => local + func(a + h * i),
                         local => { lock(_syncLock) result += local; });

            //for(int i = 1; i < n; i++)
            //{
            //    x += h;
            //    result += func(x);
            //}

            result = h * ((func(a) + func(b)) / 2 + result);

            if(IsDebugEnabled)
                log.Debug(@"적분결과=[{0}]", result);

            return result;
        }
Exemple #2
0
        /// <summary>
        /// 지정된 Function을 수행합니다.
        /// </summary>
        /// <param name="tryFunc">수행할 action</param>
        /// <param name="exceptionAction">예외 시 수행할 action</param>
        /// <param name="finallyAction">뒷처리를 위한 action</param>
        /// <param name="valueFactory">예외 시 반환할 기본 값을 생성하는 Factory</param>
        public static T TryFunction <T>(Func <T> tryFunc, Func <T> valueFactory = null, Action <Exception> exceptionAction = null,
                                        Action finallyAction = null)
        {
            tryFunc.ShouldNotBeNull("tryFunc");

            try {
                return(tryFunc());
            }
            catch (Exception ex) {
                if (exceptionAction != null)
                {
                    exceptionAction(ex);
                }
                else
                {
                    if (log.IsWarnEnabled)
                    {
                        log.Warn("작업 중에 예외가 발생했습니다만 무시합니다.");
                        log.Warn(ex);
                    }
                }
            }
            finally {
                if (finallyAction != null)
                {
                    finallyAction();
                }
            }
            return((valueFactory != null) ? valueFactory() : default(T));
        }
        /// <summary>
        /// Samples a function equidistant within the provided interval.
        /// </summary>
        /// <param name="function">The real-domain function to sample.</param>
        /// <param name="intervalBegin">The real domain interval begin where to start sampling.</param>
        /// <param name="intervalEnd">The real domain interval end where to stop sampling.</param>
        /// <param name="sampleCount">The number of samples to generate.</param>
        /// <param name="samplePoints">The real domain points where the samples are taken at.</param>
        /// <typeparam name="T">The value type of the function to sample.</typeparam>
        /// <returns>The generated sample vector.</returns>
        /// <exception cref="ArgumentNullException" />
        /// <exception cref="ArgumentOutOfRangeException" />
        public static T[] EquidistantInterval <T>(Func <double, T> function, double intervalBegin, double intervalEnd, int sampleCount,
                                                  out double[] samplePoints)
        {
            function.ShouldNotBeNull("function");
            sampleCount.ShouldBePositiveOrZero("sampleCount");

            if (sampleCount == 0)
            {
                samplePoints = new double[0];

                return(new T[0]);
            }

            if (sampleCount == 1)
            {
                samplePoints = new double[] { (intervalBegin + intervalEnd) / 2.0 };
                return(new T[] { function(samplePoints[0]) });
            }

            var step = (intervalEnd - intervalBegin) / (sampleCount - 1);

            samplePoints = PLinqTool.Generate(sampleCount, i => intervalBegin + i * step).ToArray();
            samplePoints[samplePoints.Length - 1] = intervalEnd;

            var result =
                samplePoints
                .AsParallel()
                .AsOrdered()
                .Select(x => function(x))
                .ToArray();

            result[result.Length - 1] = function(intervalEnd);

            return(result);
        }
Exemple #4
0
        /// <summary>
        /// 정렬이 되었다면, 지정된 갯수의 최상위 요소중 <paramref name="count"/> 수만큼 반환합니다.
        /// </summary>
        /// <typeparam name="TSource">요소의 수형</typeparam>
        /// <typeparam name="TKey">요소 비교를 위한 Key의 수형</typeparam>
        /// <param name="source">요소 집합</param>
        /// <param name="keySelector">요소로부터 Key를 추출하는 Selector</param>
        /// <param name="count">취할 요소의 수</param>
        /// <returns></returns>
        public static IEnumerable <TSource> TakeTop <TSource, TKey>(this ParallelQuery <TSource> source,
                                                                    Func <TSource, TKey> keySelector,
                                                                    int count = 1)
        {
            keySelector.ShouldNotBeNull("keySelector");

            if (IsDebugEnabled)
            {
                log.Debug("최상의 요소 중 [{0}]만큼 열거합니다.", count);
            }

            var comparer = new DescendingDefaultComparer <TKey>();

            return
                (source.Aggregate(() => new SortedTopN <TKey, TSource>(count, comparer),
                                  (accum, item) => {
                accum.Add(keySelector(item), item);
                return accum;
            },
                                  (accum1, accum2) => {
                foreach (var item in accum2)
                {
                    accum1.Add(item);
                }
                return accum1;
            },
                                  accum => accum.Values));
        }
Exemple #5
0
        /// <summary>
        /// 여러 단계의 매핑을 거쳐야 할 때, 매핑함수 chain을 만들도록 해준다.
        /// </summary>
        /// <typeparam name="TNextOutput"></typeparam>
        /// <param name="nextFunc"></param>
        /// <param name="degreeOfParallelism"></param>
        /// <returns></returns>
        public Pipeline <TInput, TNextOutput> Next <TNextOutput>(Func <TOutput, TNextOutput> nextFunc, int degreeOfParallelism = 1)
        {
            nextFunc.ShouldNotBeNull("nextFunc");
            degreeOfParallelism.ShouldBePositive("degreeOfParallelism");

            return(new InternalPipeline <TNextOutput>(this, nextFunc, degreeOfParallelism));
        }
Exemple #6
0
        /// <summary>
        /// 컬럼명=속성명 매핑함수를 이용하여 지정된 DataReader의 컬럼명을 속성명으로 매핑한다.
        /// </summary>
        /// <param name="reader">instance of IDataReader</param>
        /// <param name="mappingFunc">mapping function</param>
        /// <param name="propertyNamesToExclude">매핑에서 제외할 속성명</param>
        /// <returns>instance of <see cref="INameMap"/></returns>
        public static INameMap Mapping(this IDataReader reader, Func<string, string> mappingFunc, params string[] propertyNamesToExclude) {
            reader.ShouldNotBeNull("reader");
            mappingFunc.ShouldNotBeNull("mappingFunc");

            if(IsDebugEnabled)
                log.Debug("지정된 DataReader의 컬럼명을 속성명으로 매핑합니다...");

            var nameMap = new NameMap();
            var excludeNames = (propertyNamesToExclude != null) ? propertyNamesToExclude.ToList() : new List<string>();

            for(int i = 0; i < reader.FieldCount; i++) {
                var columnName = reader.GetName(i);

                if(columnName.IsNotWhiteSpace()) {
                    var propertyName = mappingFunc(columnName);

                    if(propertyName.IsNotWhiteSpace() && excludeNames.Contains(propertyName, StringComparer.Ordinal) == false)
                        nameMap.Add(columnName, propertyName);
                }
            }

            if(IsDebugEnabled)
                log.Debug("컬럼명-속성명 매핑 결과 = " + nameMap.CollectionToString());

            return nameMap;
        }
Exemple #7
0
        /// <summary>
        /// <paramref name="table"/>의 정보를 Persistent object로 변환하여 제공합니다.
        /// </summary>
        /// <typeparam name="T">Persistent object 의 수형</typeparam>
        /// <param name="table"><see cref="DataTable"/></param>
        /// <param name="rowMapper">매핑 함수</param>
        /// <param name="firstResult">Persistent object를 만들 첫번째 레코드 인덱스 (0부터 시작)</param>
        /// <param name="maxResults">Persistent object를 만들 최대 레코드 수 (0이거나 null이면 DataReader 끝까지)</param>
        /// <returns>Persistent object의 컬렉션</returns>
        public static IList <T> Map <T>(this DataTable table, Func <DataRow, T> rowMapper, int firstResult = 0, int maxResults = 0)
        {
            table.ShouldNotBeNull("table");
            rowMapper.ShouldNotBeNull("rowMapper");

            if (IsDebugEnabled)
            {
                log.Debug("Mapping Function를 이용하여 DataTable로부터 [{0}] 수형의 객체를 생성합니다. firstResult=[{1}], maxResults=[{2}]",
                          typeof(T).Name, firstResult, maxResults);
            }

            var firstCount = Math.Max(0, firstResult);
            var maxCount   = maxResults;

            if (maxCount <= 0)
            {
                maxCount = Int32.MaxValue;
            }

            return
                (table.Rows
                 .Cast <DataRow>()
                 .Skip(firstCount)
                 .Take(maxCount)
                 .Select(rowMapper)
                 .ToList());
        }
        /// <summary>
        /// y = func(x) 함수의 [lower, upper] 구간에 대해, 근을 찾는다 ( func(x) = 0 인 x 값 )
        /// </summary>
        /// <param name="func">근을 찾을 함수</param>
        /// <param name="lower">근을 찾을 구간의 하한</param>
        /// <param name="upper">근을 찾을 구간의 상한</param>
        /// <param name="tryCount">시도 횟수</param>
        /// <param name="tolerance">근의 오차허용범위</param>
        /// <returns>근에 해당하는 x 값. 해를 못찾으면 <see cref="double.NaN"/>을 반환한다.</returns>
        public override double FindRoot(Func<double, double> func,
                                        double lower,
                                        double upper,
                                        int tryCount = MathTool.DefaultTryCount,
                                        double tolerance = MathTool.Epsilon) {
            func.ShouldNotBeNull("func");
            tolerance = Math.Abs(tolerance);

            if(IsDebugEnabled)
                log.Debug(@"Find root by NewtonRapson... func=[{0}], lower=[{1}], upper=[{2}], tryCount=[{3}], tolerance=[{4}]",
                          func, lower, upper, tryCount, tolerance);

            if(tryCount < DefaultTryCount)
                tryCount = DefaultTryCount;

            double x = (lower + upper) / 2;

            if(Math.Abs(func(x).Clamp(RootY, tolerance) - RootY) < double.Epsilon)
                return x;

            for(int i = 0; i < tryCount; i++) {
                double prevX = x;
                x -= func(x) / gfunc(func, x);

                if(IsDebugEnabled)
                    log.Debug(@"root value=[{0}]", x);

                if(Math.Abs(x - prevX) < Math.Abs(prevX) * tolerance)
                    return x;
            }
            return double.NaN;
        }
Exemple #9
0
        /// <summary>
        /// Computes a sequential exclusive prefix scan over the array using the specified function.
        /// </summary>
        public static void ExclusiveScanInPlaceSerial <T>(T[] array, Func <T, T, T> function, int fromInclusive, int toExclusive)
        {
            array.ShouldNotBeEmpty("array");
            function.ShouldNotBeNull("function");

            if (IsDebugEnabled)
            {
                log.Debug("순차방식의 배타적 스캔을 시작합니다... fromInclusive={0}, toExclusive={1}", fromInclusive, toExclusive);
            }

            var total = array[fromInclusive];

            array[fromInclusive] = default(T);

            for (var i = fromInclusive + 1; i < toExclusive; i++)
            {
                var prevTotal = total;
                total = function(total, array[i]);

                if (IsDebugEnabled)
                {
                    log.Debug("순차방식 ExclusiveScan... array[{0}]={1}, total={2}", i, array[i], total);
                }

                array[i] = prevTotal;
            }
        }
Exemple #10
0
        /// <summary>
        /// 비동기 방식의 작업을 수행할 때 예외처리를 담당해 줍니다. 비동기 방식 작업을 수행할 때에는 이 함수를 호출하시기 바랍니다.
        /// </summary>
        /// <param name="asyncFunc">비동기 방식 작업을 수행하는 Function</param>
        /// <param name="valueFactory">함수 실행 실패 시의 반환할 값 생성 함수</param>
        /// <param name="ageAction">예외 처리를 담당하는 Action</param>
        /// <param name="finallyAction">Finally Block 처리를 담당하는 Action</param>
        /// <returns>함수 반환 값</returns>
        public static T TryFunctionAsync <T>(Func <T> asyncFunc, Func <T> valueFactory = null, Action <AggregateException> ageAction = null,
                                             Action finallyAction = null)
        {
            asyncFunc.ShouldNotBeNull("asyncFunc");

            try {
                return(asyncFunc());
            }
            catch (AggregateException age) {
                if (ageAction != null)
                {
                    ageAction(age);
                }
                else
                {
                    if (log.IsErrorEnabled)
                    {
                        log.Error("비동기 작업 함수 실행 시 AggregateException 예외가 발생했습니다!!!");
                        log.Error(age.Flatten());
                    }
                    age.Handle(ex => false);
                }
            }
            finally {
                if (finallyAction != null)
                {
                    finallyAction();
                }
            }
            return((valueFactory != null) ? valueFactory() : default(T));
        }
Exemple #11
0
        /// <summary>
        /// <paramref name="millisecondsDelayed"/> 이후에 <paramref name="function"/>을 수행하는 작업을 생성합니다.
        /// </summary>
        /// <typeparam name="TResult">작업 결과 수형</typeparam>
        /// <param name="factory">Task Factory</param>
        /// <param name="millisecondsDelayed">실행 전에 지연할 시간(밀리초)</param>
        /// <param name="function">실행할 함수</param>
        /// <param name="cancellationToken">작업 취소용 토큰</param>
        /// <param name="creationOptions">작업 생성 옵션</param>
        /// <param name="scheduler">작업 스케쥴러</param>
        /// <returns>일정 시간 이후에 함수를 실행하는 작업</returns>
        public static Task <TResult> StartNewDelayed <TResult>(this TaskFactory <TResult> factory,
                                                               int millisecondsDelayed,
                                                               Func <TResult> function,
                                                               CancellationToken?cancellationToken = null,
                                                               TaskCreationOptions?creationOptions = null,
                                                               TaskScheduler scheduler             = null)
        {
            factory.ShouldNotBeNull("factory");
            millisecondsDelayed.ShouldBePositiveOrZero("millisecondsDelayed");
            function.ShouldNotBeNull("function");
            scheduler = scheduler ?? factory.GetTargetScheduler();

            if (IsDebugEnabled)
            {
                log.Debug("일정 시간 이후에 지정한 함수를 수행하는 작업을 생성합니다. 작업지연 시간=[{0}] msecs", millisecondsDelayed);
            }

            var tcs   = new TaskCompletionSource <object>();
            var timer = new Timer(obj => ((TaskCompletionSource <object>)obj).SetResult(null),
                                  tcs,
                                  millisecondsDelayed,
                                  Timeout.Infinite);

            return(tcs.Task.ContinueWith(_ => {
                timer.Dispose();
                return function();
            },
                                         cancellationToken ?? factory.CancellationToken,
                                         ContinuationOptionsFromCreationOptions(creationOptions ?? factory.CreationOptions),
                                         scheduler));
        }
Exemple #12
0
        public Pareto(double scale, double shape, Func <Random> randomFactory = null)
        {
            SetParameters(scale, shape);

            randomFactory.ShouldNotBeNull("randomFactory");
            _random = randomFactory();
        }
        /// <summary>
        /// <see cref="ExecuteInstance{T}(IAdoRepository,INameMapper,System.Data.Common.DbCommand,IAdoParameter[])"/> 를 비동기적으로 수행하여,
        /// DataReader로부터 T 수형의 인스턴스를 매핑한다.
        /// </summary>
        /// <typeparam name="T">결과 셋으로 표현할 엔티티의 수형</typeparam>
        /// <param name="repository"><see cref="IAdoRepository"/></param>
        /// <param name="nameMapper">DataReader 컬럼과 엔티티의 속성명의 Name 매퍼</param>
        /// <param name="targetFactory">대상 객체 생성 함수</param>
        /// <param name="firstResult">첫번째 레코드 인덱스 (0부터 시작)</param>
        /// <param name="maxResults">최대 레코드 갯수(0이면 끝까지)</param>
        /// <param name="additionalMapping">추가적인 매핑 함수</param>
        /// <param name="query">실행할 SQL문 또는 Procedure Name</param>
        /// <param name="parameters">패러미터</param>
        /// <returns>매핑한 엔티티 컬렉션을 결과값으로 가지는 Task</returns>
        public static Task <IList <T> > ExecuteInstanceAsParallelAsync <T>(this IAdoRepository repository,
                                                                           INameMapper nameMapper,
                                                                           Func <T> targetFactory,
                                                                           int firstResult,
                                                                           int maxResults,
                                                                           Action <AdoResultRow, T> additionalMapping,
                                                                           string query,
                                                                           params IAdoParameter[] parameters)
        {
            nameMapper.ShouldNotBeNull("nameMapper");
            targetFactory.ShouldNotBeNull("targetFactory");
            query.ShouldNotBeWhiteSpace("query");

            if (IsDebugEnabled)
            {
                log.Debug("비동기적으로 ExecuteReader()을 수행하고, 병렬로 매핑하여 결과를 IList<{0}>으로 매핑합니다... " +
                          "query=[{1}], firstResult=[{2}], maxResults=[{3}]", typeof(T).Name, query, firstResult, maxResults);
            }

            return
                (Task.Factory
                 .StartNew(() => {
                using (var reader = repository.ExecuteReader(query, parameters))
                    return reader.MapAsParallel <T>(targetFactory, nameMapper, firstResult, maxResults,
                                                    additionalMapping);
            }));
        }
        /// <summary>
        /// TInput 수형의 시퀀스를 매핑 함수를 통해 TOutput 시퀀스로 변환합니다.
        /// </summary>
        public static IEnumerable <TOutput> Map <TInput, TOutput>(this IEnumerable <TInput> inputs, Func <TInput, TOutput> mapping)
        {
            inputs.ShouldNotBeNull("inputs");
            mapping.ShouldNotBeNull("mapping");

            return(inputs.Select(mapping));
        }
        /// <summary>
        /// 비동기적으로 ExecuteReader()을 수행하고, 병렬 방식으로 매핑하여 결과를 IPageList{T} 으로 반환하는 Task를 빌드합니다
        /// </summary>
        /// <typeparam name="T">결과 셋으로 표현할 엔티티의 수형</typeparam>
        /// <param name="repository"><see cref="IAdoRepository"/></param>
        /// <param name="rowMapFunc">DataReader로부터 {T} 수형의 인스턴스로 변환하는 메소드</param>
        /// <param name="query">실행할 SQL문 또는 Procedure Name</param>
        /// <param name="pageIndex">결과셋의 Page Index (0부터 시작)</param>
        /// <param name="pageSize">결과셋 Paging 시의 Page Size</param>
        /// <param name="parameters">패러미터</param>
        /// <returns>매핑한 엔티티 컬렉션을 결과값으로 가지는 Task</returns>
        public static Task <IPagingList <T> > ExecuteInstanceAsParallelAsync <T>(this IAdoRepository repository,
                                                                                 Func <AdoResultRow, T> rowMapFunc,
                                                                                 string query,
                                                                                 int pageIndex,
                                                                                 int pageSize,
                                                                                 params IAdoParameter[] parameters)
        {
            rowMapFunc.ShouldNotBeNull("converter");
            query.ShouldNotBeWhiteSpace("query");

            if (IsDebugEnabled)
            {
                log.Debug("비동기적으로 ExecuteReader()을 수행하고, 병렬 방식으로 매핑하여 결과를 IPageList<{0}>으로 반환하는 Task를 빌드합니다... " +
                          @"query=[{1}]", typeof(T).Name, query);
            }

            var itemsTask = Task.Factory.StartNew(() => {
                using (var reader = repository.ExecuteReader(query, parameters))
                    return(reader.MapAsParallel <T>(rowMapFunc, pageIndex * pageSize, pageSize));
            });

            var totalItemCountTask = repository.CountAsync(query, parameters);

            var result = new PagingList <T>(itemsTask.Result, pageIndex, pageSize, totalItemCountTask.Result);

            return(Task.Factory.FromResult((IPagingList <T>)result));
        }
        /// <summary>
        /// Depth-First Scan for Adjacent Graph
        /// </summary>
        /// <typeparam name="T">탐색할 Node의 수형</typeparam>
        /// <param name="source">Graph의 시작 Point</param>
        /// <param name="getAdjacent">현재 Node와 연결된 인접한 노드들을 찾아주는 함수</param>
        /// <returns>Depth-Firth Algorithm으로 탐색한 노드들의 컬렉션</returns>
        public static IEnumerable <T> GraphDepthFirstScan <T>(this T source, Func <T, IEnumerable <T> > getAdjacent)
        {
            source.ShouldNotBeNull("source");
            getAdjacent.ShouldNotBeNull("getAdjacent");

            var toScan  = new Stack <T>(new[] { source });
            var scanned = new HashSet <T>();

            while (toScan.Count > 0)
            {
                T current = toScan.Pop();

                yield return(current);

                scanned.Add(current);

                foreach (T item in getAdjacent(current))
                {
                    if (scanned.Contains(item) == false)
                    {
                        toScan.Push(item);
                    }
                }
            }
        }
        /// <summary>
        /// 계층 구조 순서대로 Scan을 수행한다.
        /// </summary>
        /// <typeparam name="T">Scan할 요소의 수형</typeparam>
        /// <param name="source">Scan 대상</param>
        /// <param name="startWith">계층 구조에서 시작할 위치를 지정해주는 함수 (보통 계층구조상의 Root 요소를 반환하는 함수)</param>
        /// <param name="connectBy">첫번째 요소가 두번째 요소의 부모인지 판단하는 함수 (두 요소사이에 계층구조가 있음을 파악한다)</param>
        /// <param name="canYieldLevel">계층구조상의 지정된 Level 정보를 반환할 것인가를 결정하는 함수</param>
        /// <param name="parent">부모 노드</param>
        /// <returns>계층 구조상의 순서대로 제공되는 리스트</returns>
        public static IEnumerable <Node <T> > ByHierarchy <T>(this IEnumerable <T> source,
                                                              Func <T, bool> startWith,
                                                              Func <T, T, bool> connectBy,
                                                              Func <int, bool> canYieldLevel = null,
                                                              Node <T> parent = null)
        {
            source.ShouldNotBeNull("source");
            startWith.ShouldNotBeNull("startWith");
            connectBy.ShouldNotBeNull("connectBy");

            canYieldLevel = canYieldLevel ?? (_ => true);
            var level = (parent == null) ? 0 : parent.Level + 1;
            var items = source.Where(startWith);

            foreach (var item in items)
            {
                var newNode = new Node <T>(level, parent, item);

                if (canYieldLevel(level))
                {
                    yield return(newNode);
                }

                var item1 = item;
                foreach (var childNode in ByHierarchy <T>(source,
                                                          possibleChild => connectBy(item1, possibleChild),
                                                          connectBy,
                                                          canYieldLevel,
                                                          newNode))
                {
                    yield return(childNode);
                }
            }
        }
Exemple #18
0
        /// <summary>
        /// SharedCache에 해당 키에 해당하는 값이 있으면 그 값을 반환하고, 없으면, <paramref name="valueFactory"/>로 값을 생성해서 값을 저장 후 그 값을 반환합니다.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sharedCache"></param>
        /// <param name="key"></param>
        /// <param name="valueFactory"></param>
        /// <returns></returns>
        public static T GetOrAdd <T>(this IndexusProviderBase sharedCache, string key, Func <T> valueFactory)
        {
            sharedCache.ShouldNotBeNull("sharedCache");
            key.ShouldNotBeWhiteSpace("key");
            valueFactory.ShouldNotBeNull("valueFactory");

            if (IsDebugEnabled)
            {
                log.Debug("SharedCache에서 Key[{0}]에 해당하는 값을 로드합니다.", key);
            }

            T result;

            if (sharedCache.TryGet <T>(key, out result))
            {
                return(result);
            }

            result = valueFactory();
            if (sharedCache.TryAdd(key, result))
            {
                return(result);
            }

            throw new InvalidOperationException(string.Format("ShardCached에 Key[{0}]에 해당하는 값을 저장하는데 실패했습니다.", key));
        }
Exemple #19
0
        /// <summary>
        /// IDataReader 정보를 <paramref name="rowMapFunc"/>가 병렬 방식으로 처리하여 대상 객체로 빌드합니다.
        /// </summary>
        /// <typeparam name="T">대상 객체의 수형</typeparam>
        /// <param name="reader">DataReader</param>
        /// <param name="rowMapFunc">대상 객체를 빌드하는 함수</param>
        /// <param name="firstResult">첫번째 레코드 인덱스 (0부터 시작합니다. null이면 0으로 간주)</param>
        /// <param name="maxResults">매핑할 최대 레코드 수 (0이면, IDataReader의 끝까지 매핑합니다)</param>
        /// <returns>매핑된 대상 객체의 컬렉션</returns>
        public static IList <T> MapAsParallel <T>(this IDataReader reader, Func <AdoResultRow, T> rowMapFunc, int firstResult = 0,
                                                  int maxResults = 0)
        {
            reader.ShouldNotBeNull("reader");
            rowMapFunc.ShouldNotBeNull("rowMapFunc");

            Guard.Assert(reader.IsClosed == false, "IDataReader가 이미 닫혀있습니다!!!");

            if (IsDebugEnabled)
            {
                log.Debug("IDataReader를 읽어 수형[{0}]으로 매핑하여, 컬렉션으로 반환합니다...", typeof(T).Name);
            }

            var resultSet = new AdoResultSet(reader, firstResult, maxResults);

            if (resultSet.Count == 0)
            {
                return(new List <T>());
            }

            return
                (resultSet.Values
                 .AsParallel()
                 .AsOrdered()
                 .Select(rowMapFunc)
                 .ToList());
        }
Exemple #20
0
        /// <summary>
        /// <paramref name="source"/> 작업 결과가 <paramref name="predicate"/>에 만족하는 Task만 필터링합니다.
        /// </summary>
        /// <typeparam name="TSource"></typeparam>
        /// <param name="source"></param>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public static Task <TSource> Where <TSource>(this Task <TSource> source, Func <TSource, bool> predicate)
        {
            source.ShouldNotBeNull("source");
            predicate.ShouldNotBeNull("predicate");

            // predicate를 실행하고, source의 필터링된 정보를 반환하기 위해, Continuation을 생성합니다.
            // predicate에서 false를 반환하면, 작업을 취소하고, 예외를 일으키는 작업을 반환합니다.

            var cts = new CancellationTokenSource();

            return
                (source
                 .ContinueWith(antecedent => {
                var result = antecedent.Result;

                // 결과가 만족할 수 없다면, 작업을 취소시킵니다.
                if (predicate(result) == false)
                {
                    cts.CancelAndThrow();
                }

                return result;
            },
                               cts.Token,
                               TaskContinuationOptions.ExecuteSynchronously,
                               TaskScheduler.Default));
        }
Exemple #21
0
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="TInput"></typeparam>
        /// <typeparam name="TOutput"></typeparam>
        /// <param name="inputs"></param>
        /// <param name="parallelOptions"></param>
        /// <param name="outputFactory"></param>
        /// <returns></returns>
        public static IList <TOutput> MapProperty <TInput, TOutput>(IList <TInput> inputs, ParallelOptions parallelOptions,
                                                                    Func <TOutput> outputFactory)
        {
            outputFactory.ShouldNotBeNull("outputFactory");

            return(Map(inputs, parallelOptions, input => input.MapProperty(outputFactory, true)));
        }
        /// <summary>
        /// Command의 Parameter 정보와 속성 정보를 매핑한다. (ParameterName = 속성명) 형식
        /// </summary>
        /// <param name="command">instance of DbCommand to execute</param>
        /// <param name="mappingFunc">Mapping function. input = parameter name of command , result = property name of persistent object </param>
        /// <param name="propertyNamesToExclude">매핑에서 제외할 속성명</param>
        /// <returns>instance of <see cref="INameMap"/>, Key = parameter name of a specified command, Value = property name of persistent object</returns>
        public static INameMap Mapping(this DbCommand command, Func <string, string> mappingFunc, params string[] propertyNamesToExclude)
        {
            command.ShouldNotBeNull("command");
            mappingFunc.ShouldNotBeNull("mappingFunc");

            if (IsDebugEnabled)
            {
                log.Debug("Command 파라미터명을 속성명으로 매핑합니다...");
            }

            var nameMap      = new NameMap();
            var excludeNames = (propertyNamesToExclude != null) ? propertyNamesToExclude.ToList() : new List <string>();

            foreach (IDataParameter parameter in command.Parameters)
            {
                var paramName = parameter.ParameterName.RemoveParameterPrefix();

                if (paramName.IsNotWhiteSpace())
                {
                    var propertyName = mappingFunc(paramName);

                    if (propertyName.IsNotWhiteSpace() && excludeNames.Contains(propertyName, StringComparer.Ordinal) == false)
                    {
                        nameMap.Add(paramName, propertyName);
                    }
                }
            }

            if (IsDebugEnabled)
            {
                log.Debug("Command 파라미터명-속성명 매핑 결과 = " + nameMap.CollectionToString());
            }

            return(nameMap);
        }
        /// <summary>
        /// 컬럼명=속성명 매핑함수를 이용하여 지정된 DataReader의 컬럼명을 속성명으로 매핑한다.
        /// </summary>
        /// <param name="reader">instance of IDataReader</param>
        /// <param name="mappingFunc">mapping function</param>
        /// <param name="propertyNamesToExclude">매핑에서 제외할 속성명</param>
        /// <returns>instance of <see cref="INameMap"/></returns>
        public static INameMap Mapping(this IDataReader reader, Func <string, string> mappingFunc, params string[] propertyNamesToExclude)
        {
            reader.ShouldNotBeNull("reader");
            mappingFunc.ShouldNotBeNull("mappingFunc");

            if (IsDebugEnabled)
            {
                log.Debug("지정된 DataReader의 컬럼명을 속성명으로 매핑합니다...");
            }

            var nameMap      = new NameMap();
            var excludeNames = (propertyNamesToExclude != null) ? propertyNamesToExclude.ToList() : new List <string>();

            for (int i = 0; i < reader.FieldCount; i++)
            {
                var columnName = reader.GetName(i);

                if (columnName.IsNotWhiteSpace())
                {
                    var propertyName = mappingFunc(columnName);

                    if (propertyName.IsNotWhiteSpace() && excludeNames.Contains(propertyName, StringComparer.Ordinal) == false)
                    {
                        nameMap.Add(columnName, propertyName);
                    }
                }
            }

            if (IsDebugEnabled)
            {
                log.Debug("컬럼명-속성명 매핑 결과 = " + nameMap.CollectionToString());
            }

            return(nameMap);
        }
        /// <summary>
        /// <paramref name="table"/>의 정보를 Persistent object로 병렬로 변환하여 제공합니다.
        /// </summary>
        /// <typeparam name="T">Persistent object 의 수형</typeparam>
        /// <param name="table"><see cref="DataTable"/></param>
        /// <param name="rowMapper">매핑 함수</param>
        /// <param name="firstResult">Persistent object를 만들 첫번째 레코드 인덱스 (0부터 시작)</param>
        /// <param name="maxResults">Persistent object를 만들 최대 레코드 수 (0이거나 null이면 DataReader 끝까지)</param>
        /// <returns>Persistent object의 컬렉션</returns>
        public static ParallelQuery <T> MapAsParallel <T>(this DataTable table, Func <DataRow, T> rowMapper, int firstResult = 0,
                                                          int maxResults = 0)
        {
            table.ShouldNotBeNull("table");
            rowMapper.ShouldNotBeNull("rowMapper");

            if (IsDebugEnabled)
            {
                log.Debug("Mapping Function를 이용하여 DataTable로부터 [{0}] 수형의 객체를 병렬로 생성합니다. firstResult=[{1}], maxResults=[{2}]",
                          typeof(T).FullName, firstResult, maxResults);
            }

            var firstCount = Math.Max(0, firstResult);
            var maxCount   = maxResults;

            if (maxCount <= 0)
            {
                maxCount = table.Rows.Count;
            }

            return
                (table.Rows
                 .Cast <DataRow>()
                 .AsParallel()
                 .AsOrdered()
                 .Skip(firstCount)
                 .Take(maxCount)
                 .Select(rowMapper));
        }
Exemple #25
0
        /// <summary>
        /// <paramref name="reader"/>의 레코드 정보를 <paramref name="nameMap"/>를 통해 매핑을 수행하는데, 계속조건 (<paramref name="continuationCondition"/>) 이 만족할때까지만 수행한다.
        /// </summary>
        /// <typeparam name="T">대상 객체</typeparam>
        /// <param name="reader">IDataReader 객체</param>
        /// <param name="targetFactory">대상 객체 생성용 Factory</param>
        /// <param name="nameMap">DB 컬럼명- 클래스 속성명 매핑 정보</param>
        /// <param name="continuationCondition">진행 조건 (False가 나올 때까지 진행합니다)</param>
        /// <param name="additionalMapping">컬럼-속성 단순 값 매핑 이외에 부가적인 매핑을 수행하기 위해 제공되는 델리게이트</param>
        /// <returns>매핑된 대상 객체 컬렉션</returns>
        public static IEnumerable <T> MapWhile <T>(this IDataReader reader,
                                                   Func <T> targetFactory,
                                                   INameMap nameMap,
                                                   Func <IDataReader, bool> continuationCondition,
                                                   Action <IDataReader, T> additionalMapping = null)
        {
            targetFactory.ShouldNotBeNull("targetFactory");
            nameMap.ShouldNotBeNull("nameMap");

            var columNames     = nameMap.Keys.ToArray();
            var targetAccessor = GetDynamicAccessor <T>();

            Func <IDataReader, T> @readerMapFunc = dr => {
                var target = targetFactory();

                columNames.RunEach(colName =>
                                   targetAccessor.SetPropertyValue(target,
                                                                   nameMap[colName],
                                                                   dr.AsValue(colName)));

                if (additionalMapping != null)
                {
                    additionalMapping(dr, target);
                }

                return(target);
            };

            return(MapWhile(reader, readerMapFunc, continuationCondition));
        }
Exemple #26
0
        /// <summary>
        /// 사용자가 제공하는 다음 조각 크기를 구하는 함수에 따라, 분할을 수행하는 분할자를 제공합니다.
        /// </summary>
        /// <typeparam name="TSource"></typeparam>
        /// <param name="source"></param>
        /// <param name="nextChunkSizeFunc"></param>
        /// <returns></returns>
        public static OrderablePartitioner <TSource> Create <TSource>(IEnumerable <TSource> source, Func <int, int> nextChunkSizeFunc)
        {
            source.ShouldNotBeNull("source");
            nextChunkSizeFunc.ShouldNotBeNull("nextChunkSizeFunc");

            return(new ChunkPartitioner <TSource>(source, nextChunkSizeFunc));
        }
Exemple #27
0
        /// <summary>
        /// <paramref name="function"/>을 수행할 때, 예외가 발생하면 try-finally block이나 종료자를 수행하지 않고 빠져나가도록 Wrapping합니다.
        /// (이런 수행 방식을 Fail Fast라고 합니다.)
        /// </summary>
        /// <typeparam name="T">함수의 반환 값의 수형</typeparam>
        /// <param name="function">수행할 함수</param>
        /// <returns></returns>
        public static Func <T> WithFailFast <T>(this Func <T> function)
        {
            function.ShouldNotBeNull("function");

            return(() => {
                try {
                    return function();
                }
                catch (Exception ex) {
                    if (log.IsWarnEnabled)
                    {
                        log.Warn("지정된 함수 실행에 실패하여, FailFast로 마무리 짓습니다.");
                        log.Warn(ex);
                    }

                    // 디버깅 모드라면, 디버깅 중단을 알립니다.
                    if (Debugger.IsAttached)
                    {
                        Debugger.Break();
                    }
                    else
                    {
                        // NET-3.5에서는 string 인자 하나만 받는 메소드 밖에 없다.
                        Environment.FailFast("예기치 못한 예외가 발생했습니다. Fail fast 방식으로 빠져나갑니다." + Environment.NewLine + ex);
                    }
                }

                throw new InvalidOperationException("여기까지 오면 잘못된 작업이 수행된 것입니다^^");
            });
        }
Exemple #28
0
        /// <summary>
        /// EAP (Event-based Asynchronous Pattern : 이벤트기반 비동기 패턴) 작업에서, 작업 완료시의 후속조치를 정의합니다.
        /// </summary>
        /// <typeparam name="T">비동기 작업 결과물의 수형</typeparam>
        /// <param name="tcs">비동기 작업을 표현하는 delegate</param>
        /// <param name="e">비동기 작업완료 이벤트 인자</param>
        /// <param name="getResult">작업완료 시에 결과 반환 메소드</param>
        /// <param name="unregisterHandler">작업완료 이벤트 핸들러를 등록취소하는 Action</param>
        public static void HandleCompletion <T>(TaskCompletionSource <T> tcs,
                                                AsyncCompletedEventArgs e,
                                                Func <T> getResult,
                                                Action unregisterHandler)
        {
            tcs.ShouldNotBeNull("tcs");
            e.ShouldNotBeNull("e");

            if (e.UserState != tcs)
            {
                return;
            }

            getResult.ShouldNotBeNull("getResult");

            if (e.Cancelled)
            {
                tcs.TrySetCanceled();
            }

            else if (e.Error != null)
            {
                tcs.TrySetException(e.Error);
            }

            else
            {
                tcs.TrySetResult(getResult());
            }

            if (unregisterHandler != null)
            {
                unregisterHandler();
            }
        }
        /// <summary>
        /// Samples a function equidistant within the provided interval.
        /// </summary>
        /// <param name="function">The real-domain function to sample.</param>
        /// <param name="intervalBegin">The real domain interval begin where to start sampling.</param>
        /// <param name="intervalEnd">The real domain interval end where to stop sampling.</param>
        /// <param name="sampleCount">The number of samples to generate.</param>
        /// <typeparam name="T">The value type of the function to sample.</typeparam>
        /// <returns>The generated sample vector.</returns>
        public static T[] EquidistantInterval <T>(Func <double, T> function, double intervalBegin, double intervalEnd, int sampleCount)
        {
            function.ShouldNotBeNull("function");
            sampleCount.ShouldBePositiveOrZero("sampleCount");

            if (sampleCount == 0)
            {
                return(new T[0]);
            }

            if (sampleCount == 1)
            {
                return new T[] { function((intervalBegin + intervalEnd) / 2.0) }
            }
            ;

            var step = (intervalEnd - intervalBegin) / (sampleCount - 1);

            return
                (Enumerable.Range(0, sampleCount)
                 .AsParallel()
                 .AsOrdered()
                 .Select(i => (i != sampleCount - 1) ? function(intervalBegin + step * i) : function(intervalEnd))
                 .ToArray());
        }
        /// <summary>
        /// 이분법으로 y = func(x) 함수의 [lower, upper] 구간에 대해, 근을 찾는다 (y=0 이되는 x 값)
        /// </summary>
        /// <param name="func">근을 찾을 함수</param>
        /// <param name="lower">근을 찾을 구간의 하한</param>
        /// <param name="upper">근을 찾을 구간의 상한</param>
        /// <param name="tryCount">시도 횟수</param>
        /// <param name="tolerance">근의 오차허용범위</param>
        /// <returns>근에 해당하는 x 값. 해를 못찾으면 <see cref="double.NaN"/>을 반환한다.</returns>
        public override double FindRoot(Func<double, double> func,
                                        double lower,
                                        double upper,
                                        int tryCount = MathTool.DefaultTryCount,
                                        double tolerance = MathTool.Epsilon) {
            func.ShouldNotBeNull("func");
            tolerance = Math.Abs(tolerance);

            if(IsDebugEnabled)
                log.Debug("Bisection을 이용하여, root 값을 찾습니다... func=[{0}], lower=[{1}], upper=[{2}], tryCount=[{3}], tolerance=[{4}]",
                          func, lower, upper, tryCount, tolerance);

            if(lower > upper)
                MathTool.Swap(ref lower, ref upper);

            var fa = func(lower);
            var fb = func(upper);

            if(Math.Abs(fa - RootY) < tolerance)
                return lower;
            if(Math.Abs(fb - RootY) < tolerance)
                return upper;

            Guard.Assert(Math.Abs(lower - upper) > tolerance, "상하한이 같은 값을 가지면 근을 구할 수 없습니다.");

            if(tryCount < DefaultTryCount)
                tryCount = DefaultTryCount;

            for(var k = 0; k < tryCount; k++) {
                var x = (lower + upper) / 2.0;

                if(Math.Abs(upper - x) < tolerance || Math.Abs(lower - x) < tolerance)
                    return x;

                var y = func(x);

                if(IsDebugEnabled)
                    log.Debug(@"Find root...  x=[{0}], y=[{1}]", x, y);

                // 해를 만족하던가, upper-lower의 변화가 매우 작던가..
                if(Math.Abs(y - RootY) < tolerance) {
                    if(IsDebugEnabled)
                        log.Debug("Iteration count=[{0}]", k);

                    return x;
                }

                if(fa * y > 0) {
                    lower = x;
                    fa = y;
                }
                else {
                    upper = x;
                    fb = y;
                }
            }

            return double.NaN;
        }
        /// <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>
        /// <paramref name="source"/>의 항목들을 <paramref name="bucketSelector"/>를 통해 그룹핑하여 빈도수를 나타냅니다. (히스토그램 처럼)
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="TBucket"></typeparam>
        /// <param name="source"></param>
        /// <param name="bucketSelector"></param>
        /// <returns></returns>
        public static IEnumerable <KeyValuePair <TBucket, int> > Frequency <T, TBucket>(this IEnumerable <T> source,
                                                                                        Func <T, TBucket> bucketSelector)
        {
            source.ShouldNotBeNull("source");
            bucketSelector.ShouldNotBeNull("bucketSelector");

            return(source.GroupBy(x => bucketSelector(x)).Select(g => new KeyValuePair <TBucket, int>(g.Key, g.Count())));
        }
Exemple #33
0
        /// <summary>
        /// 생성자
        /// </summary>
        /// <param name="getter">Indexer 요소 조회 함수</param>
        /// <param name="setter">Indexer 요소 설정 함수</param>
        public NamedIndexer(Func <TIndex, TResult> getter, Action <TIndex, TResult> setter)
        {
            getter.ShouldNotBeNull("getter");
            setter.ShouldNotBeNull("setter");

            _getter = getter;
            _setter = setter;
        }
Exemple #34
0
 /// <summary>
 /// sequence 를 지정된 수형으로 변환한 sequence로 만듭니다.
 /// Nullable로 변환시에는 x=>(double?)x 와 같은 expression을 넣어줘야 제대로 됩니다.
 /// </summary>
 /// <typeparam name="TResult">변환할 수형</typeparam>
 /// <param name="iterator">반복자</param>
 /// <param name="converter">시퀀스 요소의 변환방식을 표현한 변환 메소드</param>
 /// <returns>변환된 시퀀스</returns>
 public static IEnumerable <TResult> ConvertUnsafe <TResult>(this IEnumerator iterator, Func <object, TResult> converter)
 {
     converter.ShouldNotBeNull("converter");
     while (iterator.MoveNext())
     {
         yield return(converter(iterator.Current));
     }
 }
Exemple #35
0
        /// <summary>
        /// Initializes a new instance of the Weibull class.
        /// </summary>
        /// <param name="shape">The shape of the Weibull distribution.</param>
        /// <param name="scale">The scale of the Weibull distribution.</param>
        /// <param name="randomFactory">난수발생기 Factory</param>
        public Weibull(double shape, double scale, Func<Random> randomFactory = null) {
            randomFactory.ShouldNotBeNull("randomFactory");

            if(IsDebugEnabled)
                log.Debug(@"Weibull 분포를 표현하는 인스턴스를 생성했습니다. shape=[{0}], scale=[{1}]", shape, scale);

            SetParameters(shape, scale);
            _random = (randomFactory != null) ? randomFactory() : MathTool.GetRandomFactory().Invoke();
        }
Exemple #36
0
        /// <summary>
        /// y = func(x) 함수의 [lower, upper] 구간에 대해, 근을 찾는다 ( func(x) = 0 인 x 값 )
        /// </summary>
        /// <param name="func">근을 찾을 함수</param>
        /// <param name="lower">근을 찾을 구간의 하한</param>
        /// <param name="upper">근을 찾을 구간의 상한</param>
        /// <param name="tryCount">시도 횟수</param>
        /// <param name="tolerance">근의 오차허용범위</param>
        /// <returns>근에 해당하는 x 값. 해를 못찾으면 <see cref="double.NaN"/>을 반환한다.</returns>
        public override double FindRoot(Func<double, double> func,
                                        double lower,
                                        double upper,
                                        int tryCount = MathTool.DefaultTryCount,
                                        double tolerance = MathTool.Epsilon) {
            func.ShouldNotBeNull("func");
            tolerance = Math.Abs(tolerance);

            if(IsDebugEnabled)
                log.Debug(@"Find root by Secant... func=[{0}], lower=[{1}], upper=[{2}], tryCount=[{3}], tolerance=[{4}]",
                          func, lower, upper, tryCount, tolerance);

            if(lower > upper)
                MathTool.Swap(ref lower, ref upper);

            if(Math.Abs(func(lower).Clamp(RootY, tolerance) - RootY) < double.Epsilon)
                return lower;
            if(Math.Abs(func(upper).Clamp(RootY, tolerance) - RootY) < double.Epsilon)
                return upper;

            if(tryCount < DefaultTryCount)
                tryCount = DefaultTryCount;

            double root, xt;
            var y1 = func(lower);
            var y2 = func(upper);

            if(Math.Abs(y1) < Math.Abs(y2)) {
                root = lower;
                xt = upper;

                MathTool.Swap(ref y1, ref y2);
            }
            else {
                xt = lower;
                root = upper;
            }

            for(var i = 0; i < tryCount; i++) {
                var dx = (xt - root) * y2 / (y2 - y1);
                xt = root;
                y1 = y2;
                root += dx;
                y2 = func(root);

                if(IsDebugEnabled)
                    log.Debug(@"Secant root=[{0}]", root);

                if((Math.Abs(dx - RootY) < double.Epsilon) || (Math.Abs((y2 - y1) - RootY) < double.Epsilon))
                    return root;
                // if(Math.Abs(Math.Abs(dx).Clamp(RootY, tolerance) - RootY) < double.Epsilon || Math.Abs(Math.Abs(y2 - y1).Clamp(RootY, tolerance) - RootY) < double.Epsilon)
                //		return root;
            }

            return double.NaN;
        }
        /// <summary>
        /// y = func(x) 함수의 [lower, upper] 구간에서 f(x)의 최소 값이 되는 x를 구합니다.
        /// </summary>
        /// <param name="func">함수</param>
        /// <param name="lower">구간의 하한</param>
        /// <param name="upper">구간의 상한</param>
        /// <param name="tryCount">시도횟수</param>
        /// <param name="tolerance">허용 오차</param>
        /// <returns>f(x)가 최소값이 되는 x 값, 검색 실패시에는 double.NaN을 반환한다</returns>
        public override double FindMiminum(Func<double, double> @func,
                                           double lower,
                                           double upper,
                                           int tryCount = MathTool.DefaultTryCount,
                                           double tolerance = MathTool.Epsilon) {
            @func.ShouldNotBeNull("func");
            tolerance = Math.Abs(tolerance);

            if(IsDebugEnabled)
                log.Debug("Find root by GoldenSectionMinimumFinder... " +
                          "func=[{0}], lower=[{1}], upper=[{2}], tryCount=[{3}], tolerance=[{4}]",
                          func, lower, upper, tryCount, tolerance);

            if(tryCount < MathTool.DefaultTryCount)
                tryCount = MathTool.DefaultTryCount;

            if(lower > upper)
                MathTool.Swap(ref lower, ref upper);

            var t = GodenRatio * (upper - lower);
            var c = lower + t;
            var d = upper - t;

            var fc = @func(c);
            var fd = @func(d);

            for(var i = 0; i < tryCount; i++) {
                if(fc > fd) {
                    lower = c;
                    c = d;
                    fc = fd;
                    d = upper - GodenRatio * (upper - lower);

                    if(Math.Abs(d - c) <= tolerance)
                        return c;

                    fd = @func(d);
                }
                else {
                    upper = d;
                    d = c;
                    fd = fc;
                    c = lower + GodenRatio * (upper - lower);

                    if(Math.Abs(d - c) <= tolerance)
                        return d;

                    fc = @func(c);
                }
            }

            return double.NaN;
        }
Exemple #38
0
        /// <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;
        }
Exemple #40
0
        /// <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(@"Romberg 적분법을 이용하여 적분을 수행합니다. func=[{0}], a=[{1}], b=[{2}]", func, a, b);

            if(a > b)
                MathTool.Swap(ref a, ref b);

            if((_rom == null) || (_rom.GetLength(1) == _order))
                _rom = new double[2,_order];

            double h = (b - a);
            _rom[0, 0] = 0.5d * h * (func(a) + func(b));

            for(int i = 2, ipower = 1; i <= _order; i++, ipower *= 2, h /= 2) {
                // approximation using the trapezoid rule.
                double sum = 0;
                for(var j = 1; j <= ipower; j++)
                    sum += func(a + h * (j - 0.5));

                // Richardson extrapolation 
                _rom[1, 0] = 0.5 * (_rom[0, 0] + (h * sum));

                for(int k = 1, kpower = 4; k < i; k++, kpower *= 4)
                    _rom[1, k] = (kpower * _rom[1, k - 1] - _rom[0, k - 1]) / (kpower - 1);

                // save the extrapolated value for the next integration
                for(int j = 0; j < i; j++)
                    _rom[0, j] = _rom[1, j];
            }

            if(IsDebugEnabled)
                log.Debug(@"적분결과=[{0}]", _rom[0, _order - 1]);

            return _rom[0, _order - 1];
        }
Exemple #41
0
        // Methods
        public GoldenSection(Func<double, double> func, double a, double b, int n) {
            func.ShouldNotBeNull("func");

            int num = 0;
            double num2 = 0.0;
            double num3 = 0.0;
            double x = 0.0;
            double num5 = 0.0;
            double num6 = 0.0;
            double num7 = 0.0;

            num2 = (3.0 - Math.Sqrt(5.0)) / 2.0;
            num3 = (Math.Sqrt(5.0) - 1.0) / 2.0;
            x = a + (num2 * (b - a));
            num5 = a + (num3 * (b - a));
            num6 = func(x);
            num7 = func(num5);
            for(num = 1; num <= n; num++) {
                if(num6 <= num7) {
                    b = num5;
                    num5 = x;
                    num7 = num6;
                    x = a + (num2 * (b - a));
                    num6 = func(x);
                }
                else {
                    a = x;
                    x = num5;
                    num6 = num7;
                    num5 = a + (num3 * (b - a));
                    num7 = func(num5);
                }
            }
            resultA = a;
            resultB = b;
        }
Exemple #42
0
        /// <summary>
        /// 원본 속성명-속성값 정보를 대상 인스턴스의 속성명에 값을 설정한다.
        /// </summary>
        /// <param name="source">원본 정보 (Name-Value)</param>
        /// <param name="targetFactory">복사 대상 인스턴스 생성 델리게이트</param>
        /// <param name="mapOptions">매핑 옵션</param>
        /// <param name="propertyNamesToExclude">복사 제외 속성 명</param>
        public static object Map(IDictionary source, Func<object> targetFactory, MapPropertyOptions mapOptions,
                                 params string[] propertyNamesToExclude) {
            targetFactory.ShouldNotBeNull("targetFactory");

            var target = targetFactory();

            if(IsDebugEnabled)
                log.Debug("원본의 속성-값을 대상 인스턴스의 속성 값으로 복사합니다... " +
                          @"source=[{0}], target=[{1}], mapOptions=[{2}], propertyNamesToExclude=[{3}]",
                          source, target, mapOptions, propertyNamesToExclude.CollectionToString());

            var excludes = new List<string>(propertyNamesToExclude);
            var accessor = DynamicAccessorFactory.CreateDynamicAccessor(target.GetType(), mapOptions.SuppressException);
            var targetPropertyNames = accessor.GetPropertyNames().Except(excludes).ToList();

            foreach(string name in source.Keys) {
                var sourceName = name;
                if(excludes.Any(epn => StringTool.EqualTo(epn, sourceName)))
                    continue;

                var canSetPropertyValue = targetPropertyNames.Any(tpn => StringTool.EqualTo(tpn, sourceName));

                if(canSetPropertyValue) {
                    if(mapOptions.IgnoreCase) {
                        var targetPropertyName = targetPropertyNames.FirstOrDefault(tpn => StringTool.EqualTo(tpn, sourceName));

                        if(targetPropertyName.IsNotWhiteSpace())
                            accessor.SetPropertyValue(target, targetPropertyName, source[sourceName]);
                    }
                    else {
                        accessor.SetPropertyValue(target, sourceName, source[sourceName]);
                    }
                }
            }
            return target;
        }
Exemple #43
0
 public Rayleigh(double scale, Func<Random> randomFactory) {
     SetParameters(scale);
     randomFactory.ShouldNotBeNull("randomFactory");
     _random = randomFactory();
 }
Exemple #44
0
        public Pareto(double scale, double shape, Func<Random> randomFactory = null) {
            SetParameters(scale, shape);

            randomFactory.ShouldNotBeNull("randomFactory");
            _random = randomFactory();
        }
Exemple #45
0
 public CompressAdapter(Func<ICompressor> @compressorFactory) {
     @compressorFactory.ShouldNotBeNull("compressorFactory");
     @_compressorFactory = @compressorFactory;
 }
        /// <summary>
        /// 생성자
        /// </summary>
        /// <param name="repositoryFactory"></param>
        protected AbstractSessionStateStoreProvider(Func<ICacheRepository> repositoryFactory) {
            repositoryFactory.ShouldNotBeNull("repositoryFactory");

            CacheRepository = repositoryFactory.Invoke();
        }
Exemple #47
0
        /// <summary>
        /// Command의 Parameter 정보와 속성 정보를 매핑한다. (ParameterName = 속성명) 형식
        /// </summary>
        /// <param name="command">instance of DbCommand to execute</param>
        /// <param name="mappingFunc">Mapping function. input = parameter name of command , result = property name of persistent object </param>
        /// <param name="propertyNamesToExclude">매핑에서 제외할 속성명</param>
        /// <returns>instance of <see cref="INameMap"/>, Key = parameter name of a specified command, Value = property name of persistent object</returns>
        public static INameMap Mapping(this DbCommand command, Func<string, string> mappingFunc, params string[] propertyNamesToExclude) {
            command.ShouldNotBeNull("command");
            mappingFunc.ShouldNotBeNull("mappingFunc");

            if(IsDebugEnabled)
                log.Debug("Command 파라미터명을 속성명으로 매핑합니다...");

            var nameMap = new NameMap();
            var excludeNames = (propertyNamesToExclude != null) ? propertyNamesToExclude.ToList() : new List<string>();

            foreach(IDataParameter parameter in command.Parameters) {
                var paramName = parameter.ParameterName.RemoveParameterPrefix();

                if(paramName.IsNotWhiteSpace()) {
                    var propertyName = mappingFunc(paramName);

                    if(propertyName.IsNotWhiteSpace() && excludeNames.Contains(propertyName, StringComparer.Ordinal) == false)
                        nameMap.Add(paramName, propertyName);
                }
            }

            if(IsDebugEnabled)
                log.Debug("Command 파라미터명-속성명 매핑 결과 = " + nameMap.CollectionToString());

            return nameMap;
        }
        protected AbstractOutputCacheProvider(Func<ICacheRepository> cacheRepositoryFactory) {
            cacheRepositoryFactory.ShouldNotBeNull("cacheRepositoryFactory");

            CacheRepository = cacheRepositoryFactory();
        }
Exemple #49
0
 /// <summary>
 /// 지정한 작업 생성 함수로 생성되는 작업을 순차 수행을 위한 작업 큐에 넣습니다.
 /// </summary>
 /// <param name="taskFactory"></param>
 public void Enqueue(Func<Task> taskFactory) {
     taskFactory.ShouldNotBeNull("taskFactory");
     EnqueueInternal(taskFactory);
 }