Posted on Leave a comment

Introduction to Numerical Integration using C

Numerical integration plays a crucial role in many applications related to embedded systems, such as control systems, signal processing, and digital filters. However, implementing numerical integration algorithms on embedded systems presents unique challenges due to limited computing resources such as memory, processing power, and clock speed.

To address these challenges, developers must carefully choose numerical integration methods that are well-suited for embedded systems. The choice of method depends on the specific requirements of the problem being solved and the available computing resources.

Some of the most commonly used numerical integration methods in embedded systems include the Trapezoidal Rule, Simpson’s Rule, and the Midpoint Rule. These methods are relatively simple to implement and require minimal memory and processing power, making them well-suited for use in low-power embedded systems.

In addition to these basic methods, more advanced numerical integration methods can also be used in embedded systems with larger amounts of memory and processing power. These methods include Gaussian Quadrature, Monte Carlo Integration, Romberg Integration, Adaptive Quadrature, Runge-Kutta Method, Newton-Cotes Formulas, and Chebyshev Quadrature.

Implementing numerical integration algorithms on embedded systems requires careful consideration of factors such as memory usage, processing power, and clock speed. Developers must also optimize their code to ensure efficient use of available resources and avoid memory leaks, stack overflows, and other common pitfalls.

Despite these challenges, numerical integration remains an essential tool for many applications related to embedded systems. With the right choice of method and careful optimization of code, developers can achieve high accuracy and efficiency in numerical integration calculations on embedded systems.

The Need for Numerical Integration

In many cases, it is not possible to find the exact analytical solution for a definite integral, either due to the complexity of the function or the limits of integration. In such cases, numerical integration provides a useful alternative for approximating the integral by dividing the interval into smaller subintervals, and then computing the area under the curve for each subinterval.

Here’s a list of functions that can solve definite integrals in embedded C:

  • Trapezoidal Rule
  • Simpson’s Rule
  • Gaussian Quadrature
  • Monte Carlo Integration
  • Romberg Integration
  • Adaptive Quadrature
  • Runge-Kutta Method (for solving ODEs)

Each of these methods has its advantages and disadvantages, and the choice of which method to use depends on the specific problem being solved and the available computing resources.

The Trapezoidal Rule and Simpson’s Rule are commonly used in embedded systems with limited RAM. These methods are relatively simple to implement and require minimal memory usage, making them well-suited for use in microcontrollers with limited resources. Additionally, these methods provide reasonably accurate results for many common functions, which further makes them popular choices for numerical integration in embedded systems.

Depending on the availability of RAM, different methods are available.

If the RAM is up to 32K, then integration methods considered, such as:

The Trapezoidal Rule and Simpson’s Rule are commonly used in embedded systems with limited RAM. These methods are relatively simple to implement and require minimal memory usage, making them well-suited for use in microcontrollers with limited resources. Additionally, these methods provide reasonably accurate results for many common functions, which further makes them popular choices for numerical integration in embedded systems.

If the RAM is increased to 60K, then some of the more computationally intensive integration methods can also be considered, such as:

  • Gaussian Quadrature: This method uses a weighted sum of function values at specific points to approximate the integral. It can provide higher accuracy than the Trapezoidal Rule and Simpson’s Rule for certain functions, but requires more memory and computational resources.
  • Monte Carlo Integration: This method uses random sampling to approximate the integral. It can provide accurate results for high-dimensional integrals, but can require a large number of function evaluations to achieve acceptable accuracy.
  • Romberg Integration: This method uses a recursive procedure to improve the accuracy of the Trapezoidal Rule. It can provide higher accuracy than the Trapezoidal Rule and Simpson’s Rule, but requires more memory and computational resources.
  • Adaptive Quadrature: This method adaptively subdivides the integration interval into smaller subintervals to achieve a desired level of accuracy. It can provide accurate results for functions with complex behavior, but can require a large number of function evaluations for high accuracy.

Note that the choice of integration method also depends on the specific requirements of the application and the available computing resources.

With an increased RAM of 512K, there are many numerical integration methods that can be used. Some of the most popular methods include:

  1. Gaussian Quadrature: This method provides high accuracy for a wide range of integrals but requires more memory than the Trapezoidal Rule or Simpson’s Rule.
  2. Monte Carlo Integration: This method involves randomly sampling points within the integration domain and is particularly useful for high-dimensional integrals. However, it requires a larger amount of memory than the Trapezoidal Rule or Simpson’s Rule due to the need to store a large number of random points.
  3. Romberg Integration: This method is a recursive extension of the Trapezoidal Rule and can achieve higher accuracy for a given number of function evaluations. However, it requires more memory to store the intermediate results of each recursive step.
  4. Adaptive Quadrature: This method dynamically adjusts the number of function evaluations based on the local behavior of the integrand, which can lead to higher accuracy for a given number of function evaluations. However, it requires more memory to store the intermediate results of each recursive step.
  5. Runge-Kutta Method: This method is commonly used for solving differential equations but can also be used for numerical integration. It provides higher accuracy than simple integration methods such as Trapezoidal Rule and Simpson’s Rule, but requires more memory to store the intermediate results of each step.
  6. Newton-Cotes Formulas: These are a family of numerical integration formulas that can achieve higher accuracy than simple integration methods. However, they require more memory to store the intermediate results of each step.
  7. Chebyshev Quadrature: This method uses the roots of Chebyshev polynomials to approximate the integral and can achieve high accuracy with fewer function evaluations than other methods. However, it requires more memory to store the coefficients of the Chebyshev polynomials.

Overall, the choice of numerical integration method will depend on the specific requirements of the problem being solved and the available computing resources. With a larger amount of RAM, more memory-intensive methods can be used, which can provide higher accuracy for a given number of function evaluations.

Posted on Leave a comment

German Language vlog 11 – Ordinal Numbers

Ordinal Numbers are called ‘Ordnungszahlen’ in German.

Ordinal Numbers are first, second, third, and so on in English.

In german, there are few rules to make them. But they are easy to understand and once you get to practice you can easily understand them.

Note: The spelling of ‘1’ and ‘3’ are different as they are irregular.

Beispiel

Fünfte
Fifth

Frage: Was ist zehnte in Englisch Ziffer?
Antwort:
Zehnte gleich Tenth in Englisch.

Posted on Leave a comment

German Language vlog 10 – Fraction Numbers

In this video, you will learn about German Fraction Numbers or Deutsch Bruchzahlen.

For example,
1/2 = ein halb
1 1/3 = eins ein Drittel (one and one third)
2 4/5 = zwei vier Fünftel (two and four fifth)
5/6 = fünf sechstel (five sixth)

Frage: Was ist acht zehntel in Dezimalzahl?
Antwort:
acht zehntel ist 8/10
8/10 = 0.8
0,8 = null komma acht
0.8 = null punkt acht

Frage: Was ist sechsundzwanzig drittel zehntel in Dezimalzahl?
Antwort:
sechsundzwanzig drittel ist 26/3
26/3 = 12,0
12,0 = zwölf komma null
12.0 = zwölf punkt null

Posted on Leave a comment

German Language vlog 9 – Decimal Numbers

Deutsch Dezimal Zahlen
German Decimal Numbers

Beispiel

Frage: Was ist eins punkt sieben plus drei?
Antwort:
eins punkt sieben = 1.7
oder
eins komma siben = 1,7

drei = 3

1.7 + 3 = 4.7
eins punkt sieben gleich vier punkt sieben

Frage: Was ist dreiundvierzig punkt acht minus zwei?
Antwort:
dreiundvierzig ist 43
zwei ist 2

43 – 2 = 41
41 ist einsundvierzig

Posted on Leave a comment

German Language vlog 8 – Basic Numbers

These are the basic numbers that are used in the german language.

In this video, I have shown the whole numbers which are positive and integers.

The way german write their number is totally different from the english world.

For example / Beispiel

In English –
21: twenty-one.
11: eleven
12: twelve
13: thirteen

in German –
21 is Zweiundzwanzig
11 is elf
12 is zwölf
13 is dreizehn

Only by practicing you can tell the subtle changes in their spelling.

The very core of arithmetics is Addition and Subtraction.
Addition is “die Addition” in German.
And Subtraction is “die Subtraktion” in German.

Beispiel

Frage: Was ist zwei plus drei?
Antwort:
2 + 3 = 5
Zwei plus drei gleich fünf.

Frage: Was ist fünf plus dreiundsiebzig?
Antwort:
5 + 73 = 78
fünf plus dreiundsiebzig gleich achtundsiebzig.

Frage: Was ist sechzig plus fünfhundertacht?
Antwort:
60 + 508 = 568
fünfhundertacht plus sechzig gleich fünfhundertachtundsechzig.

Frage: Was ist sechsundzwanzig plus fünfundsiebzig?
Antwort:
26 + 75 = 101
es ist gleich hunderteins.

Frage: Was ist sechs minus eins
Antwort:
6 – 1 = 5
Sechs minus eins gleich fünf.

Frage: Was ist acht minus drei?
Antwort:
8 – 3 = 5
acht minus drei gleich fünf.

Posted on Leave a comment

How to Perform Discrete Fourier Transform on N-Point Sequence using STM32L476G

x(n) = { 0, 1, 0, 1}

Here x(n) is a 4 point sequence

Now to perform Fourier transform on this sequence.

DFT Formula

Here X(k) is the DFT of x(n)

‘k’ is the index representing individual frequency component

‘N’ is the Length of the sample sequence

‘n’ is an index of the element of the sequence in x(n)

For example: if we calculate the value for k =1

This will give us the X(1)

So, if the sequence is sampled at 4Hz and the sampling frequency is equal to two times the max frequency. Then X(1) gives us the 1 Hz frequency component.

To calculate Euler identity

Here is the code:

/*
* Author: ABHAY KANT
* Discrete Fourier Transform using STM32L476vg on STM32L476g-Disco board.
* computes N point DFT
* computes magnitude of N/2 Points of dft
* computes phase of N/2 points of dft
* NOTE: DFT array is named xfft. It DOES NOT Calcultes DFT using FFT algo.
* Limitations: for a 2000 point sequence it takes a lot of time.
               And as the number of points increase the computational time also increases.
a rough estimate of time for a 2000 point dft it takes roughly ~ 60 seconds. 
*/
asm("nop");
//int xn[6] = {1,1,2,2,3,3};

int16_t Len = 1024; 
float xn[Len];

float xfft[Len * 2];

/*
 * calculating phase and mag for only N/2 since the value generated after N/2 are conjugate 
 */
float phase[Len/2], mag[Len/2];
int	k = 1;
int	N = 0;
int	n = 0;
float	real = 0;
float	imag = 0;
float	param = 0;
int	freq = 10;
int i;

/*
 * These two "for loops" are used to initalize the array with zero's
 */
for(n=0;n<=Len;n++){xn[n] = 0;}
for(n=0;n<=Len*2;n++){xfft[n] = 0;}



/*
 * Generating a sine Wave 
 */

	for(i=0; i<Len/2; i++){
		xn[i+512] = sin((2 * 3.1415926 * i * freq)/Len);
	}

N = Len;				
/* Note: if Len/8 then it will only calculate the 1/8 th term from 0 only.*/
/*
 * This loop calculates the x[n].e^(-j2.PI.n.k/N)
 */

	for(k=0 ; k<N ; k++){

		for(n=0 ; n<N; n++){
		param = ((2 * M_PI * n * k)/N);
		real = real + ( xn[n] * cos(param) );
		imag = imag + ((-1) * xn[n] * sin(param) );
		}
		xfft[2 * k] = real;
		xfft[(2 * k) + 1] = imag;
		real = 0;
		imag = 0;
	}



/*
 * Calculate phase angle of each frequency component
 */
float temp;
for(k=0; k<N/2;k++)
{
	temp = xfft[(2 * k ) + 1] / xfft[2 * k];
	phase[k] = atan(temp);
}

/*
 * Calculate Magnitude of each frequency 
 */

for(k=0; k<N/2;k++)
{
	temp = sqrt( (xfft[(2 * k ) + 1] * xfft[(2 * k ) + 1] ) + ( xfft[2 * k] * xfft[2 * k] ) );
	mag[k] = temp;
}
asm("nop");  //added to support for creating breakpoint during debug