-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathquadrature_cpu.c
126 lines (93 loc) · 2.73 KB
/
quadrature_cpu.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// -*- mode: C -*-
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <time.h> // clock() and clock_t
// Global data which defines f(x,y,z)
// Number of points P
#define P 500
// Array of points at which Gaussians are located
double *points;
// Gaussian height parameter A
double A = 0.1;
// Gaussian width parameter w
double w = 0.2;
// This function evaluates f(x,y,z)
double func(double x, double y,double z) {
double tot,arg;
int i;
tot = 0.0;
for (i=0;i<P;i++) {
arg = 0.0;
arg += (x-points[3*i+0])*(x-points[3*i+0]);
arg += (y-points[3*i+1])*(y-points[3*i+1]);
arg += (z-points[3*i+2])*(z-points[3*i+2]);
tot += A*expf(-w*arg);
}
return tot;
}
// This will, for a point on our two-dimension grid
// integrate over the function in the third dimension
void integrate1D(int i,int j, double Min, double Max, int Ngrid, double *g_host) {
int k;
double delta,x,y,z,p_old,p_new,g_loc;
// Compute grid spacing and current x and y value
delta = (Max-Min)/(double)(Ngrid-1);
x = Min+(double)i*delta;
y = Min+(double)j*delta;
// Integrate along z using trapezoidal rule
g_loc = 0.0;
z = Min;
p_old = expf(func(x,y,z));
for (k=1;k<Ngrid;k++) {
z += delta;
p_new = expf(func(x,y,z));
g_loc += delta*0.5f*(p_old+p_new);
p_old = p_new;
}
// Store at the appropriate location in g
g_host[i*Ngrid + j] = g_loc;
return;
}
/*================================================
This program uses the data and functions above
module above to compute the two-dimensional
function g(x,y). Note that we store the function
in a long vector of length Ngrid*Ngrid rather
than in a 2D matrix.
!===============================================*/
int main () {
// Extend of domain in each dimension
double gridMax = 10.0;
double gridMin = -10.0;
// Number of grid points in each dimension
int Ngrid = 128;
// Memory for g on the host
double *g_host;
int i,j;
double x;
// Allocate memory for points
points = (double *)malloc(3*P*sizeof(double));
// Populate points with random numbers between -10 and 10
for (i=0;i<P;i++) {
for (j=0;j<3;j++) {
x = rand()/(double)RAND_MAX;
points[3*i+j] = gridMin + (gridMax-gridMin)*x;
}
}
// Allocate memory for g on the host and zero it out
g_host = (double *)malloc(Ngrid*Ngrid*sizeof(double));
memset(g_host,0,Ngrid*Ngrid*sizeof(double));
clock_t t1 = clock();
// Compute g and store in g_host
for (i=0;i<Ngrid;i++) {
for (j=0;j<Ngrid;j++) {
integrate1D(i,j,gridMin,gridMax,Ngrid,g_host);
}
}
clock_t t2 = clock();
printf("Time taken on CPU = %f seconds\n",(double)(t2-t1)/(double)CLOCKS_PER_SEC);
free(g_host);
return 0;
}