Integration

May 27, 2014 at 1:05 PM
Hi Dmitry,

one question about integrating.
I want to implement such a feature, like Derivate.cs,
Like this,
http://de.pluspedia.org/w/images/thumb/3/3d/Bestimmtes_Integral_Berechnung.png/300px-Bestimmtes_Integral_Berechnung.png

It were such a powerful feature and the last thing i've really need.
I've asked you these some time ago.

It should be simular to implement like derivate or not?
Like cos(2x),

Cos-Class, Integrate-Method, UnaryExpression should integrate the function itself, like "Sin", the Argument should be the same, "2x", and the Argument should be derived and the reciprocal value multiplied with the integrated function, the result should be "1/2*sin(2x)

and added with a constant like +C,

What do you think about these feature?
Do you mean its really hard to implement?

Best Regards
Ronny
Coordinator
May 27, 2014 at 7:35 PM
It'll be harder than a differentiation.

"sin(x)dx = -cos(x) + C" (simple)

but

"(x * ln(x)^2) dx" (integration by parts).

Differentiation uses only a "table" values and 5 rules (+, -, *, / and chain rule).
For integrals you need more complex algorithm (there is no "table" values ​​of the integral for fractions). And possible implementation of integral needs a equation solving.

You can try implement this feature, but it can be difficult. And if it will not work I'll not merge with main repo.
May 28, 2014 at 7:47 AM
ok, I think at the Moment its to hard. But one other feature were Complex Numbers, do you mean its also hard to implement?
The .Net Framework allready includes a Class for complex numbers, should it be possible to include it in your library?

Regards
Coordinator
May 28, 2014 at 2:16 PM
It can be not hard. But may be you will need to change/add some lines in Lexer (it has to understand where a "normal" number and where a complex number).
Coordinator
May 28, 2014 at 2:19 PM
And you will need to add support of complex numbers in Add, Sub, Mul, Div, Sqrt.
May 29, 2014 at 11:16 AM
Hi Dmitry,

is there a easy way to set the decimal digits in the result?
For example, I have a Matrix, with a few Functions inside,
the result looks really large, every number in it was very long.
If allready exists such a feature, I would prefer this, before I implement
it by myself.

Thanks
Regards
Ronny
Coordinator
May 29, 2014 at 5:24 PM
You can change a return value of Calculate function to decimal, but if you use sin, cos and etc. you need to override these functions. And also you need to change ParametersCollection.

Or create a generic IExpression<T> where T can be double, decimal and etc. But the xFunc application will use IExpression<double>.
May 29, 2014 at 8:37 PM
thats not what I mean :)
I want to set the length of decimal places.

The Result shows me a large number of decimalplaces in a 4x4 Matrix.
Is there a easy way to fixture the size of the results?

Regards
Coordinator
May 30, 2014 at 6:17 AM
You can replace the ToString method in Number.cs and Variable.cs to change output format.

number.ToString("F2", CultureInfo.InvariantCulture); // 2 places
May 30, 2014 at 8:45 AM
thanks, but the problem with this solution is that this would be a fixed value.
But I only want that the computed Matrix or Vector-Result has a limited decimal place.

Regards
Coordinator
May 30, 2014 at 12:00 PM
Something like this:

string.Format("{0:#,0.##}", 12.5354646) // 12.54
string.Format("{0:#,0.##}", 12) // 12
Jun 1, 2014 at 9:36 AM
thx,

When its to difficult to implement the Integration-Feature, it should be easy to implement
the Integration-Result. Like the Derivate-Function.

For example, if I want the result of these integral, f(x)=cos(x) dx from 0 to 1, the result is the surface and I should iterate
and add in small steps the parts of the surfaces to get the result. Its only a approximation but it should work.

What do you think about that?
Regards
Coordinator
Jun 1, 2014 at 4:15 PM
Yes, it will work. You need to use one of numerical integration methods (rectangle, trapezoidal, Gaussian quadrature and etc.).
Jun 1, 2014 at 4:20 PM
thanks for the note ;)
I will implement this feature.

Regards
Jun 2, 2014 at 12:31 PM
I have implemented the numeric integration.
I have added a DefiniteIntegral-Class which works in the most cases pretty well,
but in a few expressions, it will create a wrong result.

for example,

Thats my Integral-Syntax,

integral("cos(x^3)", "x", -1, 1)

Here is my Integral-Method, I used the rectangle-method with 1000 Values,
I know its not your thing and your code, but maybe, you could help,
    double Rectangle ( ExpressionParameters parameters ) {
        if (parameters == null)
            parameters = new ExpressionParameters();

        parameters.AngleMeasurement = AngleMeasurement.Radian;

        var result  = 0.0;
        var left    = ( double ) this.Left.Calculate(parameters);
        var right   = ( double ) this.Right.Calculate(parameters);

        if ( right <= left )
            throw new InvalidOperationException ( "Invalid Intergral-Bounds" );

        var n       = 1000;    // number of rectangles
        var dx      = (right - left) / (double)n;

        var param = default(Parameter);
        foreach (var p in parameters.Parameters.Collection) {
            if ( p.Key == this.Variable.Name ) {
                param = p;
                break;
            }
        }
        if (param == null) {
            param = new Parameter(
                this.Variable.Name, 0, ParameterType.Normal);

            parameters.Parameters.Add(param);
        }
        for ( var x = left; x <= right; x+=dx ) {
            param.Value = x;
            var z = (double)this.Body.Calculate(parameters);
            result += (dx * z);
        }
        return result;
    }
Regards
Ronny
Jun 2, 2014 at 3:40 PM
Hi Dmitry,

I've implemented the Simpson-Method, it brings a lot of better results.

double Simpson (ExpressionParameters parameters) {
        if (parameters == null)
            parameters = new ExpressionParameters();

        parameters.AngleMeasurement = AngleMeasurement.Radian;

        var a = (double)this.Left.Calculate(parameters);
        var b = (double)this.Right.Calculate(parameters);

        if (b <= a)
            throw new InvalidOperationException("Invalid Intergral-Bounds");

        var n = 1000;    // number of rectangles
        var h = (b - a) / (double)n;

        var param = default(Parameter);
        foreach (var p in parameters.Parameters.Collection) {
            if (p.Key == this.Variable.Name) {
                param = p;
                break;
            }
        }
        if (param == null) {
            param = new Parameter(
                this.Variable.Name, 0, ParameterType.Normal);

            parameters.Parameters.Add(param);
        }

        var sum = 0.0;
        for (var i = 1; i <= n - 3; i = i + 2) {
            param.Value = a + i * h;
            sum += ( double ) this.Body.Calculate(parameters);
        }

        param.Value = a + (n - 1) * h;
        sum += (double)this.Body.Calculate(parameters);
        sum *= 4;

        var sum2 = 0.0;
        for (var i = 2; i <= n - 4; i += 2) {
            param.Value = a + i * h;
            sum2 += (double)this.Body.Calculate(parameters);
        }

        param.Value = a + (n - 2) * h;
        sum2 += (double)this.Body.Calculate(parameters);
        sum2 *= 2;

        sum += sum2;
        param.Value = a;
        sum += ( double ) this.Body.Calculate(parameters);

        param.Value = b;
        sum += (double)this.Body.Calculate(parameters);

        return h / 3 * sum;
    }

do you want a pull request of the DefiniteIntegral-Class?
Regards
Coordinator
Jun 2, 2014 at 5:52 PM
"do you want a pull request of the DefiniteIntegral-Class?"
This class should have implemented only one method of numeric integration (better Simpson or Gaussian).

What is it?
"var param = default(Parameter);
    foreach (var p in parameters.Parameters.Collection) {
        if (p.Key == this.Variable.Name) {
            param = p;
            break;
        }
    }
if (param == null) {
        param = new Parameter(
            this.Variable.Name, 0, ParameterType.Normal);

        parameters.Parameters.Add(param);
    }"
You try to get a variable from collection. You can use LINQ. (like parameters.Parameters.Collection.First(p => p.Key == this.Variable.Name))
or don't have a reference and use parameters["name of var"] instead the "param" variable.

P.S. Maybe is better to implement one Integral class, which will represent definite (integral(cos(x), -1, 1)) and indefinite (integral(cos(x)) integrals.
Jun 2, 2014 at 6:07 PM
parameters["key"] is very slow, I have used it ago. Linq is also slow.
I calculate thousands of values and I need every millisecond.
Parameter-Reference is at the Moment the fastest way.

Regards
Jun 2, 2014 at 6:11 PM
var param = default(Parameter);

its the same, like Parameter param = null;
I mean you know it ;)

but I really like the var-keyword,
and so thats my prefered way of variable-declarations.