Little bit of a 2 parter. First of all im trying to do this in all c. First of all I'll go ahead and post my program
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <omp.h>
#include <string.h>
double f(double x);
void Trap(double a, double b, int n, double* integral_p);
int main(int argc, char* argv[]) {
double integral=0.0; //Integral Result
double a=6, b=10; //Left and Right Points
int n; //Number of Trapezoids (Higher=more accurate)
int degree;
if (argc != 3) {
printf("Error: Invalid Command Line arguements, format:./trapezoid N filename");
exit(0);
}
n = atoi(argv[2]);
FILE *fp = fopen( argv[1], "r" );
# pragma omp parallel
Trap(a, b, n, &integral);
printf("With n = %d trapezoids....\n", n);
printf("of the integral from %f to %f = %.15e\n",a, b, integral);
return 0;
}
double f(double x) {
double return_val;
return_val = pow(3.0*x,5)+pow(2.5*x,4)+pow(-1.5*x,3)+pow(0*x,2)+pow(1.7*x,1)+4;
return return_val;
}
void Trap(double a, double b, int n, double* integral_p) {
double h, x, my_integral;
double local_a, local_b;
int i, local_n;
int my_rank = omp_get_thread_num();
int thread_count = omp_get_num_threads();
h = (b-a)/n;
local_n = n/thread_count;
local_a = a + my_rank*local_n*h;
local_b = local_a + local_n*h;
my_integral = (f(local_a) + f(local_b))/2.0;
for (i = 1; i <= local_n-1; i++) {
x = local_a + i*h;
my_integral += f(x);
}
my_integral = my_integral*h;
# pragma omp critical
*integral_p += my_integral;
}
As you can see, it calculates trapezoidal rule given an interval.
First of all it DOES work, if you hardcode the values and the function. But I need to read from a file in the format of
5
3.0 2.5 -1.5 0.0 1.7 4.0
6 10
Which means:
It is of degree 5 (no more than 50 ever)
3.0x^5 +2.5x^4 −1.5x^3 +1.7x+4 is the polynomial (we skip ^2 since it's 0)
and the Interval is from 6 to 10
My main concern is the f(x) function which I have hardcoded. I have NO IDEA how to make it take up to 50 besides literally typing out 50 POWS and reading in the values to see what they could be.......Anyone else have any ideas perhaps?
Also what would be the best way to read in the file? fgetc? Im not really sure when it comes to reading in C input (especially since everything i read in is an INT, is there some way to convert them?)
For a large degree polynomial, would something like this work?
double f(double x, double coeff[], int nCoeff)
{
double return_val = 0.0;
int exponent = nCoeff-1;
int i;
for(i=0; i<nCoeff-1; ++i, --exponent)
{
return_val = pow(coeff[i]*x, exponent) + return_val;
}
/* add on the final constant, 4, in our example */
return return_val + coeff[nCoeff-1];
}
In your example, you would call it like:
sampleCall()
{
double coefficients[] = {3.0, 2.5, -1.5, 0, 1.7, 4};
/* This expresses 3x^5 + 2.5x^4 + (-1.5x)^3 + 0x^2 + 1.7x + 4 */
my_integral = f(x, coefficients, 6);
}
By passing an array of coefficients (the exponents are assumed), you don't have to deal with variadic arguments. The hardest part is constructing the array, and that is pretty simple.
It should go without saying, if you put the coefficients array and number-of-coefficients into global variables, then the signature of f(x) doesn't need to change:
double f(double x)
{
// access glbl_coeff and glbl_NumOfCoeffs, instead of parameters
}
For you f() function consider making it variadic (varargs is another name)
http://www.gnu.org/s/libc/manual/html_node/Variadic-Functions.html
This way you could pass the function 1 arg telling it how many "pows" you want, with each susequent argument being a double value. Is this what you are asking for with the f() function part of your question?
Related
Consider my attempt to implement the Babylonian method in C:
int sqrt3(int x) {
double abs_err = 1.0;
double xold = x;
double xnew = 0;
while(abs_err > 1e-8) {
xnew = (2 * xold + x/(xold* xold))/3;
abs_err= xnew-xold;
if (abs_err < 0) abs_err = -abs_err;
xold=xnew;
}
return xnew;
}
int main() {
int a;
scanf("%d", &a);
printf(" Result is: %f",sqrt3(a));
return 0;
}
Result is for x=27: 0.0000?
Where is my mistake?
While the function returns an int, that value is printed with the wrong format specifier, %f instead of %d.
Change the signature (and the name, if I may) into something like this
double cube_root(double x) { ... }
Or change the format specifier, if you really want an int.
Following the explanation from tutorialspoint, which states, that the basic idea is to implement the Newton Raphson method for solving nonlinear equations, IMHO, the code below displays this fact more clearly. Since there is already an accepted answer, I add this answer just for future reference.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
double rootCube( double a)
{
double x = a;
double y = 1.0;
const double precision = 0.0000001;
while(fabs(x-y) > precision)
{
x = (x + y) / 2.0;
y = a / x / x;
}
return x;
}
int main(int argc, const char* argv[])
{
if(argc > 1)
{
double a =
strtod(argv[1],NULL);
printf("cubeRoot(%f) = %f\n", a, rootCube(a));
}
return 0;
}
Here, in contrast to the original code of the question, it is more obvious, that x and y are the bounds, which are being improved until a sufficiently accurate solution is found.
With modification of the line in the while block, where y is being updated, this code can also be used to solve similar equations. For finding the square root, for example, this line would look like this: y = a / x.
Firstly, i don't believe this is related to precision, I think the variable is losing scope somehow?
The function below, header file sorting.h:
#ifndef SORTING_H
#define SORTING_H
/*===========================================================================
Function find_median
Description: median values in a sorted array.
==========================================================*/
float find_median(float values[],int n );
#endif /* SORTING_H */
Implementation file sorting.c :
#include "sorting.h"
float find_median(float values[],int n)
{
float val = 0.0f;
// check for even case
if (n % 2 == 0)
{
val = (float)values[n/2];
}
else
{
int low_index = (n)/2;
int high_index= low_index + 1;
val = (values[low_index] + values[high_index])/2.0f;
}
return val;
}
Main entry, main.c:
int main(int argc, char** argv)
{
//unsorted
float output_array[] = { 3, 17, 13, 6, 9, -1, 10, 10 };
int row_length = sizeof(output_array) / sizeof(output_array[0]);
//sort
quicksort_iterative(output_array, row_length);
float median = 0.0f;
//get the median
median = find_median(output_array, row_length);
printf("median=%f", median);
}
Output:
sorted:,-1.000000,3.000000,6.000000,9.000000,10.000000,10.000000,13.000000,17.000000
median=6422100.000000
I'm attempted to assign the final median value from as a return value & also as tried passing median as a parameter but both attempts return incorrect values.
The median should be 11.
You seem to want to modify median in the calling function. In C++, all you simply do is:
float median(float values[],int n, float& median)
C is a little harder. For that you need a pointer:
float median(float values[],int n, float *median)
{
// ...
*median = val;
// ...
}
// ...
find_median(output_array, row_length, &median);
You are confused on a number of basic fronts. To begin with, look at your function find_median, and specifically at the parameters: (presuming you actually meant to name your function float_median instead of just median as written in sorting.c)
float float_median(float values[],int n, float median);
Your function takes an array of float as the first parameter, that's fine. (but could simply be written as float *values as an array is converted to a pointer on access, see: C11 Standard - 6.3.2.1 Other Operands - Lvalues, arrays, and function designators(p3) -- it works the same for C++)
Now your second parameter int n passing the number of elements in the array (also fine), but your third parameter float median, is effectively unused in float_median. Assigning median = val; has zero effect as in C parameters are passed by value so the assignment in float_median of median = val; simply changes the value of the copy of median used in the function and has zero effect on the original median in main(). You are returning the value of median from your function so simply drop the third parameter, e.g.
#include <math.h>
#include "sorting.h"
float find_median (float *values, int n)
{
float val = 0;
// check for even case
if (n % 2 == 0)
val = (float)values[n/2];
else {
int low_index = floor(n-1)/2;
int high_index = ceil(n-1)/2;
val = (values[low_index] + values[high_index]) / 2.;
}
return val;
}
(note: also the denominator is changed from 2 to 2.0 to eliminate the resulting cast to avoid integer division)
Good job on your use of header-guards to prevent multiple inclusion of sorting.h. You only need to update the function prototype to be consistent with dropping the third parameter, e.g.
#ifndef SORTING_H
#define SORTING_H
/*===========================================================================
Function find_median
Description: median values in a sorted array.
==========================================================*/
float find_median (float values[], int n);
#endif /* SORTING_H */
In your main() (I called it sort.c) you attempt to use a quicksort_iterative function that you do not provide. Forget it, just write a quick compare function for the elements in output_array and then use the standard qsort function to sort your array, e.g.
#include <stdio.h>
#include <stdlib.h>
#include "sorting.h"
int compare (const void *a, const void *b)
{
return (*(int*)a > *(int*)b) - (*(int*)a < *(int*)b);
}
int main (void) {
float output_array[] = { 3, 17, 13, 6, 9, -1, 10, 10 };
int row_length = sizeof output_array / sizeof *output_array;
//sort
qsort (output_array, row_length, sizeof *output_array, compare);
float median = find_median (output_array, row_length);
for (int i = 0; i < row_length; i++)
printf (i ? " %g" : "%g", output_array[i]);
putchar ('\n');
printf ("\nmedian = %.2f\n", median);
}
Now just compile:
gcc -Wall -Wextra -pedantic -std=c11 -Ofast sorting.c -o bin/sort sort.c
(note: I would also recommend including -Wshadow to catch any shadowed variables)
Example Use/Output
$ ./bin/sort
-1 3 6 9 10 10 13 17
median = 10.00
Look things over and let me know if you have further questions. If you are on windows or using another compiler than gcc/clang, let me know and I can post equivalent compile options for you.
I think there's problem in your formula. try this.
float median(float values[],int n) //, float& median) //note: notice the & here.
{
float val = 0.0f;
// check for even case
if (n % 2 == 0)
{
//get the average of the 2 mid values.
int high_index = n/2;
int low_index = high_index - 1;
val = (values[high_index] + values[low_index])/2.0f;
//note: 2 is integer, 2.0f is float. there might be problem if you use 2 speciall in division.
printf("even case: val=%f\n", val);
printf("values[%d]=%f\n",low_index);
printf("values[%d]=%f\n",high_index);
}
else
{
val = values[n/2];
printf("odd case: val=%f\n", val);
}
//median = val; //2 way output?
return val;
}
Update
I added logs on the code to trace what's the cause of the problem.
The function is called find_median in the header, but median in the implementation... how does it link?
Then, you are not assigning the result of find_median to the variable median
I'm trying to use the distance between points formula to calculate the perimeter of any geometric figure, but the function is not delivering the values it should. I have no clue of what I'm doing wrong
#include <math.h>
int perimeter(int flag, dot d[]){
float result, sum1, sum2, sum3, quad1, quad2, op[flag], sum;
for(int c=0;c<flag;c++){
sum1=d[c+1].x-d[c].x;
sum2=d[c+1].y-d[c].y;
quad1=pow(sum1, 2);
quad2=pow(sum2, 2);
sum3=quad1+quad2;
result=sqrt(sum3);
op[c]=result;
}
for(int c=0;c<flag;c++){
sum+=op[c];
}return sum;
}
Test values:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct dot{
float x,y;
}dot;
int main(){
int flag=4;
dot d[flag];
d[0].x=9;
d[0].y=10;
d[1].x=21;
d[1].y=10;
d[2].x=21;
d[2].y=16;
d[3].x=9;
d[4].y=16;
float result, sum1, sum2, sum3, quad1, quad2, op[flag], sum=0.0;
for(int c=0;c<flag;c++){
sum1=d[c+1%flag].x-d[c].x;
sum2=d[c+1%flag].y-d[c].y;
quad1=pow(sum1, 2);
quad2=pow(sum2, 2);
sum3=quad1+quad2;
result=sqrt(sum3);
printf("distance %d: %d\n", c, result);
sum+=result;
}
printf("final result: %d\n", result);
}
Console log(printing steps):
gcc version 4.6.3
distance 0: 0
distance 1: 1
distance 2: 2
distance 3: 3
final result: 26533904
You should look up the hypot() functions declared in the <math.h> header. You could end up with:
float perimeter(int n_dots, dot d[])
{
float sum = 0.0;
for (int i = 0; i < n_dots; i++)
{
int n = (i+1) % n_dots;
sum += hypotf(d[n].x - d[i].x, d[n].y - d[i].y);
}
return sum;
}
If you need to report on the values calculated, you can capture the result of hypotf() before you add it to sum.
Note, too, that you should return a float value. In my book, you should change float to double throughout (and use hypot() in place of hypotf()), but that's somewhat separate as an issue. Returning float (or double) rather than int is rather important, I think.
The MCVE (Minimal, Complete, Verifiable Example) version of your code might be:
#include <math.h>
#include <stdio.h>
typedef struct dot
{
float x, y;
} dot;
float perimeter(int n_dots, dot d[]);
int main(void)
{
enum { num_dots = 4 };
dot d[num_dots] =
{
{ .x = 9, .y = 10 },
{ .x = 21, .y = 10 },
{ .x = 21, .y = 16 },
{ .x = 9, .y = 16 },
};
printf("Perimeter: %.3f\n", perimeter(num_dots, d));
return 0;
}
float perimeter(int n_dots, dot d[])
{
float sum = 0.0;
for (int i = 0; i < n_dots; i++)
{
int n = (i + 1) % n_dots;
sum += hypotf(d[n].x - d[i].x, d[n].y - d[i].y);
}
return sum;
}
Using a VLA prevents you using an initializer for it, so I made the array into a regular fixed size array.
Output:
Perimeter: 36.000
For the given data, this is correct (the four sides are of length 12, 6, 12, 6).
Initialize sum with 0.0.
Then
Replace
op[c]=result;
with
sum+=result;
You don't need the other for loop.
Secondly, make sure the value of the variable flag passed to the perimeter function is 1 less than the size of the dots array d.
Lastly, you need to add the distance between the last point and the first point to the sum. (After the for loop).
sum1 = d[flag+1].x - d[0].x;
sum2 = d[flag+1].y - d[0].y;
quad1=pow(sum1, 2);
quad2=pow(sum2, 2);
sum3=quad1+quad2;
result=sqrt(sum3);
sum+=result;
Here is my version, with better variable names,
#include <math.h>
float perimeter(int flag, dot d[]){
float sum_x, sum_y, quad_x, quad_y, sum = 0;
for(int c=0;c<flag;c++){
sum_x=d[(c+1) % flag].x-d[c].x;
sum_y=d[(c+1) % flag].y-d[c].y;
quad_x=pow(sum_x, 2);
quad_y=pow(sum_y, 2);
sum += sqrt(quad_x + quad_y);
}
return sum;
}
I've been experimenting with SSE intrinsics and I seem to have run into a weird bug that I can't figure out. I am computing the inner product of two float arrays, 4 elements at a time.
For testing I've set each element of both arrays to 1, so the product should be == size.
It runs correctly, but whenever I run the code with size > ~68000000 the code using the sse intrinsics starts computing the wrong inner product. It seems to get stuck at a certain sum and never exceeds this number. Here is an example run:
joe:~$./test_sse 70000000
sequential inner product: 70000000.000000
sse inner product: 67108864.000000
sequential time: 0.417932
sse time: 0.274255
Compilation:
gcc -fopenmp test_sse.c -o test_sse -std=c99
This error seems to be consistent amongst the handful of computers I've tested it on. Here is the code, perhaps someone might be able to help me figure out what is going on:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <omp.h>
#include <math.h>
#include <assert.h>
#include <xmmintrin.h>
double inner_product_sequential(float * a, float * b, unsigned int size) {
double sum = 0;
for(unsigned int i = 0; i < size; i++) {
sum += a[i] * b[i];
}
return sum;
}
double inner_product_sse(float * a, float * b, unsigned int size) {
assert(size % 4 == 0);
__m128 X, Y, Z;
Z = _mm_set1_ps(0.0f);
float arr[4] __attribute__((aligned(sizeof(float) * 4)));
for(unsigned int i = 0; i < size; i += 4) {
X = _mm_load_ps(a+i);
Y = _mm_load_ps(b+i);
X = _mm_mul_ps(X, Y);
Z = _mm_add_ps(X, Z);
}
_mm_store_ps(arr, Z);
return arr[0] + arr[1] + arr[2] + arr[3];
}
int main(int argc, char ** argv) {
if(argc < 2) {
fprintf(stderr, "usage: ./test_sse <size>\n");
exit(EXIT_FAILURE);
}
unsigned int size = atoi(argv[1]);
srand(time(0));
float *a = (float *) _mm_malloc(size * sizeof(float), sizeof(float) * 4);
float *b = (float *) _mm_malloc(size * sizeof(float), sizeof(float) * 4);
for(int i = 0; i < size; i++) {
a[i] = b[i] = 1;
}
double start, time_seq, time_sse;
start = omp_get_wtime();
double inner_seq = inner_product_sequential(a, b, size);
time_seq = omp_get_wtime() - start;
start = omp_get_wtime();
double inner_sse = inner_product_sse(a, b, size);
time_sse = omp_get_wtime() - start;
printf("sequential inner product: %f\n", inner_seq);
printf("sse inner product: %f\n", inner_sse);
printf("sequential time: %f\n", time_seq);
printf("sse time: %f\n", time_sse);
_mm_free(a);
_mm_free(b);
}
You are running into the precision limit of single precision floating point numbers. The number 16777216 (2^24), which is the value of each component of the vector Z when reaching the "limit" inner product, is represented in 32-bit floating point as hexadecimal 0x4b800000 or binary 0 10010111 00000000000000000000000, i.e. the 23-bit mantissa is all zeros (implicit leading 1 bit), and the 8-bit exponent part is 151 representing the exponent 151 - 127 = 24. If you add a 1 to that value this would require to increase the exponent but then the added one cannot be represented in the mantissa any longer, so in single precision floating point arithmetic 2^24 + 1 = 2^24.
You do not see that in your sequential function because there you are using a 64-bit double precision value to store the result, and as we are working on a x86 platform, internally most probably an 80-bit excess precision register is used.
You can force to use single precision throughout in your sequential code by rewriting it as
float sum;
float inner_product_sequential(float * a, float * b, unsigned int size) {
sum = 0;
for(unsigned int i = 0; i < size; i++) {
sum += a[i] * b[i];
}
return sum;
}
and you will see 16777216.000000 as maximum computed value.
My aim is to calculate the numerical integral of a probability distribution function (PDF) of the distance of an electron from the nucleus of the hydrogen atom in C programming language. I have written a sample code however it fails to find the numerical value correctly due to the fact that I cannot increase the limit as much as its necessary in my opinion. I have also included the library but I cannot use the values stated in the following post as integral boundaries: min and max value of data type in C . What is the remedy in this case? Should switch to another programming language maybe? Any help and suggestion is appreciated, thanks in advance.
Edit: After some value I get the error segmentation fault. I have checked the actual result of the integral to be 0.0372193 with Wolframalpha. In addition to this if I increment k in smaller amounts I get zero as a result that is why I defined r[k]=k, I know it should be smaller for increased precision.
#include <stdio.h>
#include <math.h>
#include <limits.h>
#define a0 0.53
int N = 200000;
// This value of N is the highest possible number in long double
// data format. Change its value to adjust the precision of integration
// and computation time.
// The discrete integral may be defined as follows:
long double trapezoid(long double x[], long double f[]) {
int i;
long double dx = x[1]-x[0];
long double sum = 0.5*(f[0]+f[N]);
for (i = 1; i < N; i++)
sum+=f[i];
return sum*dx;
}
main() {
long double P[N], r[N], a;
// Declare and initialize the loop variable
int k = 0;
for (k = 0; k < N; k++)
{
r[k] = k ;
P[k] = r[k] * r[k] * exp( -2*r[k] / a0);
//printf("%.20Lf \n", r[k]);
//printf("%.20Lf \n", P[k]);
}
a = trapezoid(r, P);
printf("%.20Lf \n", a);
}
Last Code:
#include <stdio.h>
#include <math.h>
#include <limits.h>
#include <stdlib.h>
#define a0 0.53
#define N LLONG_MAX
// This value of N is the highest possible number in long double
// data format. Change its value to adjust the precision of integration
// and computation time.
// The discrete integral may be defined as follows:
long double trapezoid(long double x[],long double f[]) {
int i;
long double dx = x[1]-x[0];
long double sum = 0.5*(f[0]+f[N]);
for (i = 1; i < N; i++)
sum+=f[i];
return sum*dx;
}
main() {
printf("%Ld", LLONG_MAX);
long double * P = malloc(N * sizeof(long double));
long double * r = malloc(N * sizeof(long double));
// Declare and initialize the loop variable
int k = 0;
long double integral;
for (k = 1; k < N; k++)
{
P[k] = r[k] * r[k] * expl( -2*r[k] / a0);
}
integral = trapezoid(r, P);
printf("%Lf", integral);
}
Edit last code working:
#include <stdio.h>
#include <math.h>
#include <limits.h>
#include <stdlib.h>
#define a0 0.53
#define N LONG_MAX/100
// This value of N is the highest possible number in long double
// data format. Change its value to adjust the precision of integration
// and computation time.
// The discrete integral may be defined as follows:
long double trapezoid(long double x[],long double f[]) {
int i;
long double dx = x[1]-x[0];
long double sum = 0.5*(f[0]+f[N]);
for (i = 1; i < N; i++)
sum+=f[i];
return sum*dx;
}
main() {
printf("%Ld \n", LLONG_MAX);
long double * P = malloc(N * sizeof(long double));
long double * r = malloc(N * sizeof(long double));
// Declare and initialize the loop variable
int k = 0;
long double integral;
for (k = 1; k < N; k++)
{
r[k] = k / 100000.0;
P[k] = r[k] * r[k] * expl( -2*r[k] / a0);
}
integral = trapezoid(r, P);
printf("%.15Lf \n", integral);
free((void *)P);
free((void *)r);
}
In particular I have changed the definition for r[k] by using a floating point number in the division operation to get a long double as a result and also as I have stated in my last comment I cannot go for Ns larger than LONG_MAX/100 and I think I should investigate the code and malloc further to get the issue. I have found the exact value that is obtained analytically by taking the limits; I have confirmed the result with TI-89 Titanium and Wolframalpha (both numerically and analytically) apart from doing it myself. The trapezoid rule worked out pretty well when the interval size has been decreased. Many thanks for all the posters here for their ideas. Having a value of 2147483647 LONG_MAX is not that particularly large as I expected by the way, should the limit not be around ten to power 308?
Numerical point of view
The usual trapezoid method doesn't work with improper integrals. As such, Gaussian quadrature rules are much better, since they not only provide 2n-1 exactness (that is, for a polynomial of degree 2n-1 they will return the correct solution), but also manage improper integrals by using the right weight function.
If your integral is improper in both sides, you should try the Gauss-Hermite quadrature, otherwise use the Gauss-Laguerre quadrature.
The "overflow" error
long double P[N], r[N], a;
P has a size of roughly 3MB, and so does r. That's too much memory. Allocate the memory instead:
long double * P = malloc(N * sizeof(long double));
long double * r = malloc(N * sizeof(long double));
Don't forget to include <stdlib.h> and use free on both P and r if you don't need them any longer. Also, you may not access the N-th entry, so f[N] is wrong.
Using Gauss-Laguerre quadrature
Now Gauss-Laguerre uses exp(-x) as weight function. If you're not familiar with Gaussian quadrature: the result of E(f) is the integral of w * f, where w is the weight function.
Your f looks like this, and:
f x = x^2 * exp (-2 * x / a)
Wait a minute. f already contains exp(-term), so we can substitute x with t = x * a /2 and get
f' x = (t * a/2)^2 * exp(-t) * a/2
Since exp(-t) is already part of our weight function, your function fits now perfectly into the Gauss-Laguerre quadrature. The resulting code is
#include <stdio.h>
#include <math.h>
/* x[] and a[] taken from
* https://de.wikipedia.org/wiki/Gau%C3%9F-Quadratur#Gau.C3.9F-Laguerre-Integration
* Calculating them by hand is a little bit cumbersome
*/
const int gauss_rule_length = 3;
const double gauss_x[] = {0.415774556783, 2.29428036028, 6.28994508294};
const double gauss_a[] = {0.711093009929, 0.278517733569, 0.0103892565016};
double f(double x){
return x *.53/2 * x *.53/2 * .53/2;
}
int main(){
int i;
double sum = 0;
for(i = 0; i < gauss_rule_length; ++i){
sum += gauss_a[i] * f(gauss_x[i]);
}
printf("%.10lf\n",sum); /* 0.0372192500 */
return 0;
}