-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathejercicio1.c
More file actions
248 lines (211 loc) · 7.53 KB
/
ejercicio1.c
File metadata and controls
248 lines (211 loc) · 7.53 KB
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
/* File: histogram.c
* Purpose: Build a histogram from some random data
*
* Compile: gcc -g -Wall -o histogram histogram.c
* Run: ./histogram <bin_count> <min_meas> <max_meas> <data_count>
*
* Input: None
* Output: A histogram with X's showing the number of measurements
* in each bin
*
* Notes:
* 1. Actual measurements y are in the range min_meas <= y < max_meas
* 2. bin_counts[i] stores the number of measurements x in the range
* 3. bin_maxes[i-1] <= x < bin_maxes[i] (bin_maxes[-1] = min_meas)
* 4. DEBUG compile flag gives verbose output
* 5. The program will terminate if either the number of command line
* arguments is incorrect or if the search for a bin for a
* measurement fails.
*
* IPP: Section 2.7.1 (pp. 66 and ff.)
*/
#include <stdio.h>
#include <stdlib.h>
void Get_args(
char* argv[] /* in */,
int* bin_count_p /* out */,
float* min_meas_p /* out */,
float* max_meas_p /* out */,
int* data_count_p /* out */);
void Gen_data(
float min_meas /* in */,
float max_meas /* in */,
float data[] /* out */,
int data_count /* in */);
void Gen_bins(
float min_meas /* in */,
float max_meas /* in */,
float bin_maxes[] /* out */,
int bin_counts[] /* out */,
int bin_count /* in */);
int Which_bin(
float data /* in */,
float bin_maxes[] /* in */,
int bin_count /* in */,
float min_meas /* in */);
void Print_histo(
float bin_maxes[] /* in */,
int bin_counts[] /* in */,
int bin_count /* in */,
float min_meas /* in */);
int main(int argc, char* argv[]) {
int bin_count, i, bin;
float min_meas, max_meas;
float* bin_maxes;
int* bin_counts;
int data_count;
float* data;
int thread_count = omp_get_num_threads();
/* Check and get command line args */
Get_args(argv, &bin_count, &min_meas, &max_meas, &data_count);
/* Allocate arrays needed */
bin_maxes = malloc(bin_count*sizeof(float));
bin_counts = malloc(bin_count*sizeof(int));
data = malloc(data_count*sizeof(float));
/* Generate the data */
Gen_data(min_meas, max_meas, data, data_count);
/* Create bins for storing counts */
Gen_bins(min_meas, max_meas, bin_maxes, bin_counts, bin_count);
/* Count number of values in each bin */
#pragma omp parallel for num_threads(thread_count)
for (i = 0; i < data_count; i++) {
bin = Which_bin(data[i], bin_maxes, bin_count, min_meas);
bin_counts[bin]++;
}
/* Print the histogram */
Print_histo(bin_maxes, bin_counts, bin_count, min_meas);
free(data);
free(bin_maxes);
free(bin_counts);
return 0;
} /* main */
/*---------------------------------------------------------------------
* Function: Get_args
* Purpose: Get the command line arguments
* In arg: argv: strings from command line
* Out args: bin_count_p: number of bins
* min_meas_p: minimum measurement
* max_meas_p: maximum measurement
* data_count_p: number of measurements
*/
void Get_args(
char* argv[] /* in */,
int* bin_count_p /* out */,
float* min_meas_p /* out */,
float* max_meas_p /* out */,
int* data_count_p /* out */) {
*bin_count_p = strtol(argv[1], NULL, 10);
*min_meas_p = strtof(argv[2], NULL);
*max_meas_p = strtof(argv[3], NULL);
*data_count_p = strtol(argv[4], NULL, 10);
} /* Get_args */
/*---------------------------------------------------------------------
* Function: Gen_data
* Purpose: Generate random floats in the range min_meas <= x < max_meas
* In args: min_meas: the minimum possible value for the data
* max_meas: the maximum possible value for the data
* data_count: the number of measurements
* Out arg: data: the actual measurements
*/
void Gen_data(
float min_meas /* in */,
float max_meas /* in */,
float data[] /* out */,
int data_count /* in */) {
int i;
srandom(0);
#pragma omp parallel for
for (i = 0; i < data_count; i++)
data[i] = min_meas + (max_meas - min_meas)*random()/((double) RAND_MAX);
} /* Gen_data */
/*---------------------------------------------------------------------
* Function: Gen_bins
* Purpose: Compute max value for each bin, and store 0 as the
* number of values in each bin
* In args: min_meas: the minimum possible measurement
* max_meas: the maximum possible measurement
* bin_count: the number of bins
* Out args: bin_maxes: the maximum possible value for each bin
* bin_counts: the number of data values in each bin
*/
void Gen_bins(
float min_meas /* in */,
float max_meas /* in */,
float bin_maxes[] /* out */,
int bin_counts[] /* out */,
int bin_count /* in */) {
float bin_width;
int i;
bin_width = (max_meas - min_meas)/bin_count;
#pragma omp parallel for
for (i = 0; i < bin_count; i++) {
bin_maxes[i] = min_meas + (i+1)*bin_width;
bin_counts[i] = 0;
}
} /* Gen_bins */
/*---------------------------------------------------------------------
* Function: Which_bin
* Purpose: Use binary search to determine which bin a measurement
* belongs to
* In args: data: the current measurement
* bin_maxes: list of max bin values
* bin_count: number of bins
* min_meas: the minimum possible measurement
* Return: the number of the bin to which data belongs
* Notes:
* 1. The bin to which data belongs satisfies
*
* bin_maxes[i-1] <= data < bin_maxes[i]
*
* where, bin_maxes[-1] = min_meas
* 2. If the search fails, the function prints a message and exits
*/
int Which_bin(
float data /* in */,
float bin_maxes[] /* in */,
int bin_count /* in */,
float min_meas /* in */) {
int bottom = 0, top = bin_count-1;
int mid;
float bin_max, bin_min;
while (bottom <= top) {
mid = (bottom + top)/2;
bin_max = bin_maxes[mid];
bin_min = (mid == 0) ? min_meas: bin_maxes[mid-1];
if (data >= bin_max)
bottom = mid+1;
else if (data < bin_min)
top = mid-1;
else
return mid;
}
/* Whoops! */
fprintf(stderr, "Data = %f doesn't belong to a bin!\n", data);
fprintf(stderr, "Quitting\n");
exit(-1);
} /* Which_bin */
/*---------------------------------------------------------------------
* Function: Print_histo
* Purpose: Print a histogram. The number of elements in each
* bin is shown by an array of X's.
* In args: bin_maxes: the max value for each bin
* bin_counts: the number of elements in each bin
* bin_count: the number of bins
* min_meas: the minimum possible measurment
*/
void Print_histo(
float bin_maxes[] /* in */,
int bin_counts[] /* in */,
int bin_count /* in */,
float min_meas /* in */) {
int i, j;
float bin_max, bin_min;
for (i = 0; i < bin_count; i++) {
bin_max = bin_maxes[i];
bin_min = (i == 0) ? min_meas: bin_maxes[i-1];
printf("%.3f-%.3f:\t", bin_min, bin_max);
for (j = 0; j < bin_counts[i]; j++)
printf("X");
printf("\n");
}
} /* Print_histo */