in

.NET Opensource

Community for opensource projects by Christoph Rüegg

numerical Integration

Last post 04-01-2007 11:25 by MovGP0. 2 replies.
Page 1 of 1 (3 items)
Sort Posts: Previous Next
  • 03-31-2007 22:23

    • MovGP0
    • Top 10 Contributor
      Male
    • Joined on 11-21-2005
    • Austria
    • Posts 49

    numerical Integration

    Hi, I've implemented a very simple class for doing integration. This is nothing special, but because Iridium hasn't integration till now this might be helpful anyway.

     
    // A very simple integration class
    // Licensed under the terms of CC-GNU LGPL 2.1
    // http://creativecommons.org/licenses/LGPL/2.1/
    // coded by mailto:movgp0/AT/gmail.com
    using System;

    namespace MathNet.Numerics.Integration
    {
        /// <summary>
        /// Methods for the integration of any function.
        /// </summary>
        public class IntegrateFunction
        {
            // TODO: Calculate epsilon (Error)
            // TODO: Integration of multidimensional functions.

            /// <summary>
            /// The delegate prototype which a function to integrate must match.
            /// </summary>
            /// <param name="value">The argument of the function. </param>
            /// <returns>The result of the function. </returns>
            public delegate double IntegrateableFunction(double value);

            /// <summary>Defines the algorithm that is used for integration. </summary>
            public enum IntegrationMethod
            {
                /// <summary>
                /// Calculates a straight line from start- to the endpoint of a given segment.
                /// </summary>
                ChordTrapezoid,
                /// <summary>
                /// Calculates a tangent in the point between the start- and entpoint of a given segment.
                /// </summary>
                TangentTrapezoid,
                /// <summary>
                /// Interpolation using a quadratic Polynom using a midpoint between the start- and endpoint.
                /// </summary>
                Simpson,
                /// <summary>This one is not implemented yet.</summary>
                Hermit
            }
            /// <summary>
            /// Integrates any function that matches the IntegrateableFunction-Delegate
            /// <see cref="IntegrateableFunction"/>
            /// </summary>
            /// <param name="Method">
            /// The Algorithm that should get used for integration.
            /// </param>
            /// <param name="From">
            /// The startpoint of the range in which the function
            /// has to be integrated.
            /// </param>
            /// <param name="Steps">The number of steps used for integration. The higher this value the lower the error, but the longer the algorithm will run.</param>
            /// <param name="To">
            /// The endpoint of the range in which the function
            /// has to be integrated.
            /// </param>
            /// <param name="Function">The function to integrate. </param>
            /// <returns>The integrated Value of the function in the given range. </returns>
            public static double IntegrateFunction(IntegrationMethod Method, double From, int Steps, double To, IntegrateableFunction Function)
            {
                double value = 0d;
                switch(Method)
                {
                    case IntegrationMethod.ChordTrapezoid:
                        double a, b;
                        for (b = From; b += StepWidth; b < To)
                        {
                            value += (b - a) / 2d * (Function(a) + Function(b));
                            a = b;
                        }
                        // calculate the remaining part
                        b = To;
                        value += (b - a) / 2d * (Function(a) + Function(b));
                        return value;
                    case IntegrationMethod.TangentTrapezoid:
                        double a, b;
                        for (b = From; b += StepWidth; b < To)
                        {
                            value += (b - a) * Function((a + b) / 2d);
                            a = b;
                        }
                        // calculate the remaining part
                        b = To;
                        value += (b - a) * Function((a + b) / 2d);
                        return value;
                    case IntegrationMethod.Simpson:
                        double a, b;
                        for (b = From; b += StepWidth; b < To)
                        {
                            value += (b - a) / 6d * (Function(a) + 4 * Function((a + b) / 2d) + Function(b));
                            a = b;
                        }
                        // calculate the remaining part
                        b = To;
                        value += (b - a) / 6d * (Function(a) + 4 * Function((a + b) / 2d) + Function(b));
                        return value;
                    case IntegrationMethod.Hermit:
                        throw new NotImplementedException();
                        break;
                    default:
                        throw new NotImplementedException();
                        break;
                };
            }
        }
        /// <summary>
        /// Methods for the integration of a list of values.
        /// </summary>
        public class Integrate
        {
            /// <summary>
            /// Declares the implemented integration methods.
            /// </summary>
            public enum IntegrationMethod {
                /// <summary>
                /// This algorithm just sums the values.
                /// </summary>
                Simple,
                /// <summary>
                /// This algorithm adds the mean between the last and the current value.
                /// </summary>
                Trapezium
            };

            /// <summary>
            /// The value that is currently accumulated.
            /// </summary>
            private double value = 0d;

            /// <summary>
            /// The last value that got added for integration.
            /// This is used by the Trapezium-based Integration-Algorithm.
            /// </summary>
            private double last = 0d;

            /// <summary>
            /// Declares if the current value is the first to be added for integration.
            /// This is used by the Trapezium-based Integration-Algorithm.
            /// </summary>
            private bool isFirst = true;
           
            /// <summary>
            /// Stores the Integration method that was declared during the Construction of the object.
            /// </summary>
            private IntegrationMethod method;

            /// <summary>
            /// Returns the Integration Algorithm that is currently in use.
            /// </summary>
            public IntegrationMethod CurrentIntegrationMethod
            {
                get{
                    return method;
                }
            }
            /// <summary>
            /// Constructs a new Integration-Objects.
            /// </summary>
            /// <param name="method">The Integration-Algorithm to use.</param>
            public Integrate(IntegrationMethod method)
            {
                this.method = method;
            }

            /// <summary>
            /// Integrates a new value to the stored value.
            /// The width of the segment is calculated to be 1.
            /// </summary>
            /// <param name="value">The value that should get added.</param>
            public void AddNext(double value)
            {
                AddNext(value, 1d);
            }

            /// <summary>
            /// Integrates a new value to the stored value.
            /// </summary>
            /// <param name="value">The value that should get added.</param>
            /// <param name="width">The width of the current step.</param>
            public void AddNext(double value, double width)
            {
                switch(this.method)
                {
                    case IntegrationMethod.Simple:
                        this.value += value;
                        break;
                    case IntegrationMethod.Trapezium:
                        if(isFirst)
                        {
                            this.last = value;
                            isFirst = false;
                            return;
                        }
                        this.value += (last + value)/2d * width;
                        break;
                    default: throw new NotImplementedException();
                        break;
                }
            }
            /// <summary>
            /// The value that is current accumulated during integration.
            /// </summary>
            /// <returns>The current Value.</returns>
            public double Value()
            {
                return value;
            }

            // TODO: calculate epsilon (rounding error)
        }
    }

  • 03-31-2007 23:22 In reply to

    Re: numerical Integration

    Great, thanks!

    Would you double-license it under the terms of the GNU LGPL 2.1, so we could use it as a starting point for Iridium? (Math.NET Numerics = LGPL, Symbolics = GPL)

    Filed under: ,
  • 04-01-2007 11:25 In reply to

    • MovGP0
    • Top 10 Contributor
      Male
    • Joined on 11-21-2005
    • Austria
    • Posts 49

    Re: numerical Integration

    I prefer the CC-Licenses because they are simpler to use, but the CC LGPL 2.1 is ok too. done

    Anyway the class is not very good. Ie. there is missing:

    • a Next-Function that takes two arguments: a value and the width of the step, so that steps with greather or lower width than one unit will be possible. (done)
    • the possibility to give a function as argument that should get integrated (this would make it really useful) (done)
    • The calculation of the error (ε)
Page 1 of 1 (3 items)
Powered by Community Server (Non-Commercial Edition), by Telligent Systems