# Definite Integrals

## Recommended Posts

I want to create a script and I need to compute defined integrals.

He's somebody who write a function to calculate defined integrals or how can I do that?

Thanks!

When the words fail... music speaks

##### Share on other sites

I found an example but is written in C++

```/* Copyright (C) Henry Golding, 2008.
*
* This software is provided "as is" without express or implied
* warranties. You may freely copy and compile this source into
* applications you distribute provided that the copyright text
* below is included in the resulting source code, for example:
* "Portions Copyright (C) Henry Golding, 2008"
*/
#include <cassert>

// Returns the area of a trapezoid of a given height where sideA
// and sideB are the uneven sides
float CalculateTrapezoidArea(float sideA, float sideB, float height)
{
// Area of a trapezoid: A = (a+b)h / 2 (Wikipedia)
return ( ( (sideA+sideB) * height  ) / 2.0f );
}

// Approximates the area under the curve of function pointed to by pFunc
// (which must take and return a float) in the range x=start to x=end.
// Accuracy is determined by number of steps used between these values.
float ApproximateIntegral(float (*pFunc)(float), float start, float end, unsigned steps)
{
// pFunc is a pointer to a function that takes and returns a float, which we will use as f(x).
// The general method is to calculate points at step intervals and calculate area of
// the trapezoid underneath then add areas together

int   i;    // counter
float diff; // the difference between steps - used as trapezoid height later
float* xValues = new float[steps + 2]; // start, end and steps in between
float* yValues = new float[steps + 2]; // for calculated results

// set start and end x values
xValues[0] = start;
xValues[steps + 1] = end;

// Interpolate x values for number of steps
// Loop from second element to penultimate element
diff = (end - start) / (steps + 1);
for (i = 1; i <= steps; ++i)
{
xValues[i] = xValues[i - 1] + diff;
}

// now we have all the x values, calculate all corresponding y values (or f(x))
for (i = 0; i < steps + 2; ++i)
{
yValues[i] = (*pFunc)(xValues[i]);
}

// now calculate the area under each trapezoid
// a will be first y of pair, b will be second y, h will be diff from earlier
float finalArea = 0.0f;

// we always need to do n-1 traps where n is the number of points we have
for (i = 0; i < steps + 1; ++i)
{
finalArea += CalculateTrapezoidArea(yValues[i], yValues[i+1], diff);
}

delete[] xValues;
delete[] yValues;

return finalArea;
}

// A test function which returns y = x^2 - 4
float test(float x)
{
return (x * x) - 4.0f;
}

// Test harness for the integral calculation functions
int main()
{
float result;

// check trapezoid area
// a = 5, b = 10, h = 3, result should = 22.5
result = CalculateTrapezoidArea(5.0f, 10.0f, 3.0f);
assert( result == 22.5f);

// check integral calculation
// result of y = x^2 - 4 is approx -10.67f between -2 and 2
result = ApproximateIntegral(test, -2.0f, 2.0f, 1);
assert( result == -8.0f ); // correct calculation but only one step so very inaccurate

result = ApproximateIntegral(test, -2.0f, 2.0f, 1000);
assert( result == -10.666637f ); //more accurate

return 0;
}```

I wrote this in AutoIt, but is not so accurate:

```Func TrapezoidArea(\$a,\$b,\$h)
Return (((\$a+\$b)*\$h)/2)
EndFunc

Func Integral(\$func,\$x1,\$x2,\$step)
Local \$AREA = 0
\$func = StringLower(\$func)
For \$INDEX = \$x1 To \$x2 Step \$step
\$valA = Execute(StringReplace(\$func,"x","\$INDEX"))
\$valB = \$valA + \$step
\$AREA += TrapezoidArea(\$valA,\$valB,\$step)
Next
Return \$AREA
EndFunc```
Edited by Andreik

When the words fail... music speaks

##### Share on other sites

Maybe the inacuracy is because you are calculating from \$x1 To \$x2 but you should calculate from \$x1 To \$x2 - \$Step.

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

##### Share on other sites

Now it's more better:

```Func TrapezoidArea(\$a,\$b,\$h)
Return (((\$a+\$b)*\$h)/2)
EndFunc

Func Integral(\$FUNCTION,\$X1,\$X2,\$STEP)
Local \$Area = 0
Local \$xValues[\$STEP+2]
Local \$yValues[\$STEP+2]
\$FUNCTION = StringLower(\$FUNCTION)
\$xValues[0] = \$X1
\$xValues[\$STEP+1] = \$X2
Local \$DIFF = (\$X2-\$X1)/(\$STEP+1)
For \$INDEX = 1 To \$STEP
\$xValues[\$INDEX] = \$xValues[\$INDEX - 1] + \$DIFF
Next
For \$INDEX = 0 To \$STEP+2
If \$INDEX >= \$STEP+2 Then ExitLoop
\$yValues[\$INDEX] = Execute(StringReplace(\$FUNCTION,"x","\$xValues[\$INDEX]"))
Next
For \$INDEX = 0 To \$STEP+1
If \$INDEX >= \$STEP+1 Then ExitLoop
\$Area += TrapezoidArea(\$yValues[\$INDEX],\$yValues[\$INDEX+1],\$DIFF)
Next
Return Round(\$Area,5)
EndFunc

MsgBox(0,"",Integral("x",0,1,1000))```
Edited by Andreik

When the words fail... music speaks

##### Share on other sites

Your first approach looked simpler to me, but it needed a small change

```Func TrapezoidArea(\$a,\$b,\$h)
Return (((\$a+\$b)*\$h)/2)
EndFunc

Func Integral(\$func,\$x1,\$x2,\$step)
Local \$AREA = 0
\$func = StringLower(\$func)
\$last = Execute(StringReplace(\$func,"x",\$x1))
For \$INDEX = \$x1 + \$step To \$x2+\$step Step \$step
\$valA = Execute(StringReplace(\$func,"x","\$INDEX"))
\$AREA += TrapezoidArea(\$valA,\$last,\$step)
\$last = \$valA
Next
Return Round(\$Area,5)
EndFunc

MsgBox(0,"",Integral("x^2",0,1,.001000))```

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

##### Share on other sites

Your first approach looked simpler to me, but it needed a small change

```Func TrapezoidArea(\$a,\$b,\$h)
Return (((\$a+\$b)*\$h)/2)
EndFunc

Func Integral(\$func,\$x1,\$x2,\$step)
Local \$AREA = 0
\$func = StringLower(\$func)
\$last = Execute(StringReplace(\$func,"x",\$x1))
For \$INDEX = \$x1 + \$step To \$x2+\$step Step \$step
\$valA = Execute(StringReplace(\$func,"x","\$INDEX"))
\$AREA += TrapezoidArea(\$valA,\$last,\$step)
\$last = \$valA
Next
Return Round(\$Area,5)
EndFunc

MsgBox(0,"",Integral("x^2",0,1,.001000))```
It`s more simple then second example but the second example it`s still more accurate.

Maybe if I change Round(\$Area,5) with Round(\$Area,2) will be better.

Please test the second example , looks to run in real time with a good result.

BTW I like your changes, it`s more simple.

Edited by Andreik

When the words fail... music speaks

##### Share on other sites

It`s more simple then second example but the second example it`s still more accurate.

Maybe if I change Round(\$Area,5) with Round(\$Area,2) will be better.

Please test the second example , looks to run in real time with a good result.

BTW I like your changes, it`s more simple.

`For \$INDEX = \$x1 + \$step To \$x2 + \$step Step \$step`

It should be

`For \$INDEX = \$x1 + \$step To \$x2  Step \$step`

But for some values of \$step the final loop seems not to get executed, so to ensure it is, and that another calculation isn't made beyond \$x2 I tried this

`For \$INDEX = \$x1 + \$step To \$x2 + \$step/2 Step \$step`

That seems to improve it. Your second method still gives slightly different results (perhaps more accurate) sometimes but I don't see why.

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

##### Share on other sites

`For \$INDEX = \$x1 + \$step To \$x2 + \$step Step \$step`

It should be

`For \$INDEX = \$x1 + \$step To \$x2  Step \$step`

But for some values of \$step the final loop seems not to get executed, so to ensure it is, and that another calculation isn't made beyond \$x2 I tried this

`For \$INDEX = \$x1 + \$step To \$x2 + \$step/2 Step \$step`

That seems to improve it. Your second method still gives slightly different results (perhaps more accurate) sometimes but I don't see why.

You are right, in my first example the distance between \$x2-\$step and \$x2 is not executed, from here is the difference result.

In second example the range between \$x1 and \$x2 is divided exactly in several intervals, resulting greater accuracy.

Edited by Andreik

When the words fail... music speaks

##### Share on other sites

This appears to work, also.

```; Approximates the area under the curve of  \$Equation
Local \$Equation = "x^2 - 4"

Local \$dfx = ApproxAreaUnderCurve(-2, 2, \$Equation)
MsgBox(0, "", "Approximate Integral = " & \$dfx)

; \$Start,\$End - The limits (start and end ) along x-axis
; \$sEq is equation eg. "3*x^2 - 4*x + 4"
; \$NoOfSteps ( Optional,default = 1000) Number of Trapezoids to use in calculation.
; (The higher the number of Trapezoids = The thinner the Trapezoids = The better the approximation of area)
; Returns the approximate area under a curve scribed by the equation, \$sEq.
Func ApproxAreaUnderCurve(\$Start, \$End, \$sEq, \$NoOfSteps = 10000)
Local \$xStep = (\$End - \$Start) / \$NoOfSteps ; Individual step length along X-axis (Width of Trapezoid)
;ConsoleWrite(" \$xStep = " & \$xStep & @CRLF)
Local \$area
Local \$yLST = StringReplace(\$sEq, "x", "\$x") ; Equation will return Left Side of Trapezoid (y value)
;ConsoleWrite( " \$yLST = " & \$yLST & @CRLF)
Local \$yRST = StringReplace(\$sEq, "x", "(\$x + \$xStep)"); Equation will return Right Side of Trapezoid (y value)
;ConsoleWrite( " \$yRST = " & \$yRST & @CRLF)
For \$x = \$Start To \$End - \$xStep Step \$xStep
\$area += \$xStep * (Execute(\$yLST) + Execute(\$yRST)) / 2 ; Accumulative areas of Trapezoids
Next
Return Round(\$area, 8)
EndFunc   ;==>ApproxAreaUnderCurve```

##### Share on other sites

This appears to work, also.

```; Approximates the area under the curve of  \$Equation
Local \$Equation = "x^2 - 4"

Local \$dfx = ApproxAreaUnderCurve(-2, 2, \$Equation)
MsgBox(0, "", "Approximate Integral = " & \$dfx)

; \$Start,\$End - The limits (start and end ) along x-axis
; \$sEq is equation eg. "3*x^2 - 4*x + 4"
; \$NoOfSteps ( Optional,default = 1000) Number of Trapezoids to use in calculation.
; (The higher the number of Trapezoids = The thinner the Trapezoids = The better the approximation of area)
; Returns the approximate area under a curve scribed by the equation, \$sEq.
Func ApproxAreaUnderCurve(\$Start, \$End, \$sEq, \$NoOfSteps = 10000)
Local \$xStep = (\$End - \$Start) / \$NoOfSteps ; Individual step length along X-axis (Width of Trapezoid)
;ConsoleWrite(" \$xStep = " & \$xStep & @CRLF)
Local \$area
Local \$yLST = StringReplace(\$sEq, "x", "\$x") ; Equation will return Left Side of Trapezoid (y value)
;ConsoleWrite( " \$yLST = " & \$yLST & @CRLF)
Local \$yRST = StringReplace(\$sEq, "x", "(\$x + \$xStep)"); Equation will return Right Side of Trapezoid (y value)
;ConsoleWrite( " \$yRST = " & \$yRST & @CRLF)
For \$x = \$Start To \$End - \$xStep Step \$xStep
\$area += \$xStep * (Execute(\$yLST) + Execute(\$yRST)) / 2 ; Accumulative areas of Trapezoids
Next
Return Round(\$area, 8)
EndFunc   ;==>ApproxAreaUnderCurve```
Just tested. Work fine. Thanks Malkey!

When the words fail... music speaks

## Create an account

Register a new account