Psycho Li Psycho Li - 2 days ago 4
C# Question

C# trapezoidal rule sum of y value

Our teacher asked us to use C# to do a trapezoidal rule solution;
He wants us to break it down into three methods.
Below is the the question and my code so far:


Numerical integration is a technique that is particular suitable for
computer applications. In exercise we will try to implement the
trapezoidal rule. The integral of a mathematical function is the area
between the curve and the x-axis. If the area is divided into little
trapezoids, then the integral is approximated by the area of these
geometrical figures.

You will try to find the area under the curve y = 6x^2-7x+2 in the
region from x = 0.5 to x = 1.5 (N.B. your answer should work out to
about be 1.54, however the actual answer is 1.5). The area is given by
the formula

(xb - xa) / 2N * (y0 + 2*y1 + 2*y2 + ⋯ + 2*yn + y(n+1))

where y0 and y1 are the height of the vertical lines i.e. the value of
the function.

This problem can be decomposed into three parts as follows:


  • Write a method called EvaluateQuadraticValue(double x, double a, double b, double c) that takes four double arguments: the value of x,
    the coefficient of the x2 term, the coefficient of the x and the

    constant. The method will compute and return the result value of y

    given by the expression y = ax2+ba+c.

  • Write a method called ComputeQuadraticValues(double startX, double increments, int numberOfIntervals, double a, double b, double c) that
    takes six arguments: the start value of x, the increments and the

    number of intervals and the coefficients of the quadratic equation.

    This method will figure out the values of x0, x1, x2 etc. by invoking
    the previous question. The results of the methods calls are collected
    and returned as a double array.

  • Write a method called ApplyTrapeziodalRule(double startX, double endX, int numberOfIntervals, double a, double b, double c) . The

    arguments are described in the previous question. This method calls

    the previous method and process the double array that is returned to

    compute the area under the curve by applying the formula

    (xb - xa) / 2N * (y0 + 2*y1 + 2*y2 + ⋯ + 2*yn + y(n+1))




And my code so far:

public static double EvaluateQuadraticValue(double x, double a, double b, double c)
{
double y = a * Math.Pow(x, 2) + b * x + c;
Console.WriteLine("The y coordinate for this x is: {0}", y);
return y;
}

public static double[] ComputeQuadraticValues(double startX, double increments, int numberOfIntervals, double a, double b, double c)
{

double[] xPoints = new double[numberOfIntervals];
for (int index = 0; index < numberOfIntervals; index++)
{
xPoints[index] = startX;
Console.WriteLine("X{0} is {1}: ",index, xPoints[index]);
EvaluateQuadraticValue(startX, a, b, c);
startX = startX + increments;
}
return xPoints;
}

public static void ApplyTrapeziodalRule(double startX, double endX, int numberOfIntervals, double a, double b, double c)
{
double increments = Convert.ToInt32(Console.ReadLine());
double[] xPoints = ComputeQuadraticValues(startX, increments, numberOfIntervals, a, b, c);
//double[] values = a * Math.Pow(xPoints[i], 2) + b * xPoints[i] + c;
//double y = xPoints.Sum();
/*for (int i = 0; i < numberOfIntervals; i++)
{

}*/
//Console.WriteLine(y + " sum");
}


Currently I'm having trouble with the third method.
Since my double array from
ComputeQuadraticValues()
are x0, x1, x2 etc. How do I use this array to get (y0 + 2*y1 + 2*y2 + ...... + 2*yn + y(n+1))?

Any hints or tips are appreciated!

Answer

I agree with @MartinLiversage and also think there are some other tricky parts in the excersise. I'll try to do my best giving you a good answer. Let me know how this works for you.

This is the curve represented by 6x^2-7x+2 and you're required to compute the area in blue:

enter image description here

What you're doing is a numerical method, and the logic behind is that if you manage to split the area in an infinite number of points, you'll get the total area more accurately. The more points you add, more accurate the result will be.

The thing is that in Computer Sciences, infinity is not possible, because resources are limited and eventually you'll need to set a limit.

I've set 10 as number of interval (N) so you'll get 11 points and the sample is readable.

Now, your first method is just the helper in order to evaluate a function in the form ax^2 + bx + c.

public static double EvaluateQuadraticValue(double x, double a, double b, double c)
{
    double y = a*Math.Pow(x,2) + b*x + c;
    return y;
}

The second is where I think the problem is. I'd implement it like this:

public static double[] ComputeQuadraticValues(double startX, double increments, int numberOfIntervals, double a, double b, double c)
{
    //We need numberOfInterval + 1 values
    double[] yPoints = new double[numberOfIntervals+1];

    for (int index = 0; index <= numberOfIntervals; index++, startX += increments)
    {
        //evaluate the function and get the y value for this x
        yPoints[index] = EvaluateQuadraticValue(startX, a, b, c);
        //Console.WriteLine("({0}, {1})", startX, yPoints[index]);
    }

    return yPoints;
}

And the last is the one who gets called by your Main() function:

public static void ApplyTrapezoidalRule(double startX, double endX, int numberOfIntervals, double a, double b, double c)
{
    double increments = (endX - startX)/numberOfIntervals;
    Console.WriteLine("increment: " + increments);

    //compute the function value for each X (generated from startX + increment).
    double[] yPoints = ComputeQuadraticValues(startX, increments, numberOfIntervals, a, b, c);

    var first = (double)(endX - startX)/(2*numberOfIntervals);
    Console.WriteLine("({0} - {1})/2*{2} = {3}", endX, startX, numberOfIntervals, first);

    var sum = yPoints[0];
    for (int i = 1; i <= numberOfIntervals; i++)
        sum += 2 * yPoints[i];
    sum += yPoints[numberOfIntervals];

    var result = first * sum;

    Console.WriteLine("result: " + result);
}

I've declared more variables so you'll see the process and the code is again more readable.

You can see this fiddle and play with the numberOfIntervals you pass in. Note that the value will be more accurate if you increase the number of intervals.

Hope this helps!

Comments