1 // Predefined 2-D data access functions.
2 //
3 // Copyright (C) 2010 David H. E. MacMahon
4 //
5 // This file is part of PLplot.
6 //
7 // PLplot is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU Library General Public License as published
9 // by the Free Software Foundation; either version 2 of the License, or
10 // (at your option) any later version.
11 //
12 // PLplot is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Library General Public License for more details.
16 //
17 // You should have received a copy of the GNU Library General Public License
18 // along with PLplot; if not, write to the Free Software
19 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 //
21
22 #include "plplotP.h"
23
24 //
25 // 2-D data access functions for data stored in (PLFLT **), such as the C
26 // variable z declared as...
27 //
28 // PLFLT z[nx][ny];
29 //
30 // These functions are named plf2OP1, where OP is "get", "set", etc. The
31 // plf2ops_t instance named "plf2ops1" is also defined below.
32 //
33
34 static PLFLT
plf2ops_c_get(PLPointer p,PLINT ix,PLINT iy)35 plf2ops_c_get( PLPointer p, PLINT ix, PLINT iy )
36 {
37 return ( (PLFLT **) p )[ix][iy];
38 }
39
40 static PLFLT
plf2ops_c_f2eval(PLINT ix,PLINT iy,PLPointer p)41 plf2ops_c_f2eval( PLINT ix, PLINT iy, PLPointer p )
42 {
43 return ( (PLFLT **) p )[ix][iy];
44 }
45
46 static PLFLT
plf2ops_c_set(PLPointer p,PLINT ix,PLINT iy,PLFLT z)47 plf2ops_c_set( PLPointer p, PLINT ix, PLINT iy, PLFLT z )
48 {
49 return ( ( (PLFLT **) p )[ix][iy] = z );
50 }
51
52 static PLFLT
plf2ops_c_add(PLPointer p,PLINT ix,PLINT iy,PLFLT z)53 plf2ops_c_add( PLPointer p, PLINT ix, PLINT iy, PLFLT z )
54 {
55 return ( ( (PLFLT **) p )[ix][iy] += z );
56 }
57
58 static PLFLT
plf2ops_c_sub(PLPointer p,PLINT ix,PLINT iy,PLFLT z)59 plf2ops_c_sub( PLPointer p, PLINT ix, PLINT iy, PLFLT z )
60 {
61 return ( ( (PLFLT **) p )[ix][iy] -= z );
62 }
63
64 static PLFLT
plf2ops_c_mul(PLPointer p,PLINT ix,PLINT iy,PLFLT z)65 plf2ops_c_mul( PLPointer p, PLINT ix, PLINT iy, PLFLT z )
66 {
67 return ( ( (PLFLT **) p )[ix][iy] *= z );
68 }
69
70 static PLFLT
plf2ops_c_div(PLPointer p,PLINT ix,PLINT iy,PLFLT z)71 plf2ops_c_div( PLPointer p, PLINT ix, PLINT iy, PLFLT z )
72 {
73 return ( ( (PLFLT **) p )[ix][iy] /= z );
74 }
75
76 static PLINT
plf2ops_c_isnan(PLPointer p,PLINT ix,PLINT iy)77 plf2ops_c_isnan( PLPointer p, PLINT ix, PLINT iy )
78 {
79 return isnan( ( (PLFLT **) p )[ix][iy] );
80 }
81
82 static void
plf2ops_c_minmax(PLPointer p,PLINT nx,PLINT ny,PLFLT * zmin,PLFLT * zmax)83 plf2ops_c_minmax( PLPointer p, PLINT nx, PLINT ny, PLFLT *zmin, PLFLT *zmax )
84 {
85 int i, j;
86 PLFLT min, max;
87 PLFLT **z = (PLFLT **) p;
88
89 if ( !isfinite( z[0][0] ) )
90 {
91 max = -HUGE_VAL;
92 min = HUGE_VAL;
93 }
94 else
95 min = max = z[0][0];
96
97 for ( i = 0; i < nx; i++ )
98 {
99 for ( j = 0; j < ny; j++ )
100 {
101 if ( !isfinite( z[i][j] ) )
102 continue;
103 if ( z[i][j] < min )
104 min = z[i][j];
105 if ( z[i][j] > max )
106 max = z[i][j];
107 }
108 }
109 *zmin = min;
110 *zmax = max;
111 }
112
113 static plf2ops_t s_plf2ops_c = {
114 plf2ops_c_get,
115 plf2ops_c_set,
116 plf2ops_c_add,
117 plf2ops_c_sub,
118 plf2ops_c_mul,
119 plf2ops_c_div,
120 plf2ops_c_isnan,
121 plf2ops_c_minmax,
122 plf2ops_c_f2eval
123 };
124
125 PLF2OPS
plf2ops_c()126 plf2ops_c()
127 {
128 return &s_plf2ops_c;
129 }
130
131 //
132 // 2-D data access functions for data stored in (PLfGrid2 *), with the
133 // PLfGrid2's "f" field treated as type (PLFLT **).
134 //
135
136 static PLFLT
plf2ops_grid_c_get(PLPointer p,PLINT ix,PLINT iy)137 plf2ops_grid_c_get( PLPointer p, PLINT ix, PLINT iy )
138 {
139 return ( ( (PLfGrid2 *) p )->f )[ix][iy];
140 }
141
142 static PLFLT
plf2ops_grid_c_f2eval(PLINT ix,PLINT iy,PLPointer p)143 plf2ops_grid_c_f2eval( PLINT ix, PLINT iy, PLPointer p )
144 {
145 return ( ( (PLfGrid2 *) p )->f )[ix][iy];
146 }
147
148 static PLFLT
plf2ops_grid_c_set(PLPointer p,PLINT ix,PLINT iy,PLFLT z)149 plf2ops_grid_c_set( PLPointer p, PLINT ix, PLINT iy, PLFLT z )
150 {
151 return ( ( ( (PLfGrid2 *) p )->f )[ix][iy] = z );
152 }
153
154 static PLFLT
plf2ops_grid_c_add(PLPointer p,PLINT ix,PLINT iy,PLFLT z)155 plf2ops_grid_c_add( PLPointer p, PLINT ix, PLINT iy, PLFLT z )
156 {
157 return ( ( ( (PLfGrid2 *) p )->f )[ix][iy] += z );
158 }
159
160 static PLFLT
plf2ops_grid_c_sub(PLPointer p,PLINT ix,PLINT iy,PLFLT z)161 plf2ops_grid_c_sub( PLPointer p, PLINT ix, PLINT iy, PLFLT z )
162 {
163 return ( ( ( (PLfGrid2 *) p )->f )[ix][iy] -= z );
164 }
165
166 static PLFLT
plf2ops_grid_c_mul(PLPointer p,PLINT ix,PLINT iy,PLFLT z)167 plf2ops_grid_c_mul( PLPointer p, PLINT ix, PLINT iy, PLFLT z )
168 {
169 return ( ( ( (PLfGrid2 *) p )->f )[ix][iy] *= z );
170 }
171
172 static PLFLT
plf2ops_grid_c_div(PLPointer p,PLINT ix,PLINT iy,PLFLT z)173 plf2ops_grid_c_div( PLPointer p, PLINT ix, PLINT iy, PLFLT z )
174 {
175 return ( ( ( (PLfGrid2 *) p )->f )[ix][iy] /= z );
176 }
177
178 static PLINT
plf2ops_grid_c_isnan(PLPointer p,PLINT ix,PLINT iy)179 plf2ops_grid_c_isnan( PLPointer p, PLINT ix, PLINT iy )
180 {
181 return isnan( ( ( (PLfGrid2 *) p )->f )[ix][iy] );
182 }
183
184 static void
plf2ops_grid_c_minmax(PLPointer p,PLINT nx,PLINT ny,PLFLT * zmin,PLFLT * zmax)185 plf2ops_grid_c_minmax( PLPointer p, PLINT nx, PLINT ny, PLFLT *zmin, PLFLT *zmax )
186 {
187 int i, j;
188 PLFLT min, max;
189 PLfGrid2 *g = (PLfGrid2 *) p;
190 PLFLT **z = g->f;
191
192 // Ignore passed in parameters
193 nx = g->nx;
194 ny = g->ny;
195
196 if ( !isfinite( z[0][0] ) )
197 {
198 max = -HUGE_VAL;
199 min = HUGE_VAL;
200 }
201 else
202 min = max = z[0][0];
203
204 for ( i = 0; i < nx; i++ )
205 {
206 for ( j = 0; j < ny; j++ )
207 {
208 if ( !isfinite( z[i][j] ) )
209 continue;
210 if ( z[i][j] < min )
211 min = z[i][j];
212 if ( z[i][j] > max )
213 max = z[i][j];
214 }
215 }
216 *zmin = min;
217 *zmax = max;
218 }
219
220 static plf2ops_t s_plf2ops_grid_c = {
221 plf2ops_grid_c_get,
222 plf2ops_grid_c_set,
223 plf2ops_grid_c_add,
224 plf2ops_grid_c_sub,
225 plf2ops_grid_c_mul,
226 plf2ops_grid_c_div,
227 plf2ops_grid_c_isnan,
228 plf2ops_grid_c_minmax,
229 plf2ops_grid_c_f2eval
230 };
231
232 PLF2OPS
plf2ops_grid_c()233 plf2ops_grid_c()
234 {
235 return &s_plf2ops_grid_c;
236 }
237
238 //
239 // 2-D data access functions for data stored in (PLfGrid2 *), with the
240 // PLfGrid2's "f" field treated as type (PLFLT *) pointing to 2-D data stored
241 // in row-major order. In the context of plotting, it might be easier to think
242 // of it as "X-major" order. In this ordering, values for a single X index are
243 // stored in consecutive memory locations.
244 //
245
246 static PLFLT
plf2ops_grid_row_major_get(PLPointer p,PLINT ix,PLINT iy)247 plf2ops_grid_row_major_get( PLPointer p, PLINT ix, PLINT iy )
248 {
249 PLfGrid2 *g = (PLfGrid2 *) p;
250 return ( (PLFLT *) g->f )[ix * g->ny + iy];
251 }
252
253 static PLFLT
plf2ops_grid_row_major_f2eval(PLINT ix,PLINT iy,PLPointer p)254 plf2ops_grid_row_major_f2eval( PLINT ix, PLINT iy, PLPointer p )
255 {
256 PLfGrid2 *g = (PLfGrid2 *) p;
257 return ( (PLFLT *) g->f )[ix * g->ny + iy];
258 }
259
260 static PLFLT
plf2ops_grid_row_major_set(PLPointer p,PLINT ix,PLINT iy,PLFLT z)261 plf2ops_grid_row_major_set( PLPointer p, PLINT ix, PLINT iy, PLFLT z )
262 {
263 PLfGrid2 *g = (PLfGrid2 *) p;
264 return ( ( (PLFLT *) g->f )[ix * g->ny + iy] = z );
265 }
266
267 static PLFLT
plf2ops_grid_row_major_add(PLPointer p,PLINT ix,PLINT iy,PLFLT z)268 plf2ops_grid_row_major_add( PLPointer p, PLINT ix, PLINT iy, PLFLT z )
269 {
270 PLfGrid2 *g = (PLfGrid2 *) p;
271 return ( ( (PLFLT *) g->f )[ix * g->ny + iy] += z );
272 }
273
274 static PLFLT
plf2ops_grid_row_major_sub(PLPointer p,PLINT ix,PLINT iy,PLFLT z)275 plf2ops_grid_row_major_sub( PLPointer p, PLINT ix, PLINT iy, PLFLT z )
276 {
277 PLfGrid2 *g = (PLfGrid2 *) p;
278 return ( ( (PLFLT *) g->f )[ix * g->ny + iy] -= z );
279 }
280
281 static PLFLT
plf2ops_grid_row_major_mul(PLPointer p,PLINT ix,PLINT iy,PLFLT z)282 plf2ops_grid_row_major_mul( PLPointer p, PLINT ix, PLINT iy, PLFLT z )
283 {
284 PLfGrid2 *g = (PLfGrid2 *) p;
285 return ( ( (PLFLT *) g->f )[ix * g->ny + iy] *= z );
286 }
287
288 static PLFLT
plf2ops_grid_row_major_div(PLPointer p,PLINT ix,PLINT iy,PLFLT z)289 plf2ops_grid_row_major_div( PLPointer p, PLINT ix, PLINT iy, PLFLT z )
290 {
291 PLfGrid2 *g = (PLfGrid2 *) p;
292 return ( ( (PLFLT *) g->f )[ix * g->ny + iy] /= z );
293 }
294
295 static PLINT
plf2ops_grid_row_major_isnan(PLPointer p,PLINT ix,PLINT iy)296 plf2ops_grid_row_major_isnan( PLPointer p, PLINT ix, PLINT iy )
297 {
298 PLfGrid2 *g = (PLfGrid2 *) p;
299 return isnan( ( (PLFLT *) g->f )[ix * g->ny + iy] );
300 }
301
302 static void
plf2ops_grid_xxx_major_minmax(PLPointer p,PLINT nx,PLINT ny,PLFLT * zmin,PLFLT * zmax)303 plf2ops_grid_xxx_major_minmax( PLPointer p, PLINT nx, PLINT ny, PLFLT *zmin, PLFLT *zmax )
304 {
305 int i;
306 PLFLT min, max;
307 PLfGrid2 *g = (PLfGrid2 *) p;
308 PLFLT *z = (PLFLT *) ( (PLFLT *) g->f );
309
310 // Ignore passed in parameters
311 nx = g->nx;
312 ny = g->ny;
313
314 if ( !isfinite( z[0] ) )
315 {
316 max = -HUGE_VAL;
317 min = HUGE_VAL;
318 }
319 else
320 min = max = z[0];
321
322 for ( i = 0; i < nx * ny; i++ )
323 {
324 if ( !isfinite( z[i] ) )
325 continue;
326 if ( z[i] < min )
327 min = z[i];
328 if ( z[i] > max )
329 max = z[i];
330 }
331 *zmin = min;
332 *zmax = max;
333 }
334
335 static plf2ops_t s_plf2ops_grid_row_major = {
336 plf2ops_grid_row_major_get,
337 plf2ops_grid_row_major_set,
338 plf2ops_grid_row_major_add,
339 plf2ops_grid_row_major_sub,
340 plf2ops_grid_row_major_mul,
341 plf2ops_grid_row_major_div,
342 plf2ops_grid_row_major_isnan,
343 plf2ops_grid_xxx_major_minmax,
344 plf2ops_grid_row_major_f2eval
345 };
346
347 PLF2OPS
plf2ops_grid_row_major()348 plf2ops_grid_row_major()
349 {
350 return &s_plf2ops_grid_row_major;
351 }
352
353 //
354 // 2-D data access functions for data stored in (PLfGrid2 *), with the
355 // PLfGrid2's "f" field treated as type (PLFLT *) pointing to 2-D data stored
356 // in column-major order. In the context of plotting, it might be easier to
357 // think of it as "Y-major" order. In this ordering, values for a single Y
358 // index are stored in consecutive memory locations.
359 //
360
361 static PLFLT
plf2ops_grid_col_major_get(PLPointer p,PLINT ix,PLINT iy)362 plf2ops_grid_col_major_get( PLPointer p, PLINT ix, PLINT iy )
363 {
364 PLfGrid2 *g = (PLfGrid2 *) p;
365 return ( (PLFLT *) g->f )[ix + g->nx * iy];
366 }
367
368 static PLFLT
plf2ops_grid_col_major_f2eval(PLINT ix,PLINT iy,PLPointer p)369 plf2ops_grid_col_major_f2eval( PLINT ix, PLINT iy, PLPointer p )
370 {
371 PLfGrid2 *g = (PLfGrid2 *) p;
372 return ( (PLFLT *) g->f )[ix + g->nx * iy];
373 }
374
375 static PLFLT
plf2ops_grid_col_major_set(PLPointer p,PLINT ix,PLINT iy,PLFLT z)376 plf2ops_grid_col_major_set( PLPointer p, PLINT ix, PLINT iy, PLFLT z )
377 {
378 PLfGrid2 *g = (PLfGrid2 *) p;
379 return ( ( (PLFLT *) g->f )[ix + g->nx * iy] = z );
380 }
381
382 static PLFLT
plf2ops_grid_col_major_add(PLPointer p,PLINT ix,PLINT iy,PLFLT z)383 plf2ops_grid_col_major_add( PLPointer p, PLINT ix, PLINT iy, PLFLT z )
384 {
385 PLfGrid2 *g = (PLfGrid2 *) p;
386 return ( ( (PLFLT *) g->f )[ix + g->nx * iy] += z );
387 }
388
389 static PLFLT
plf2ops_grid_col_major_sub(PLPointer p,PLINT ix,PLINT iy,PLFLT z)390 plf2ops_grid_col_major_sub( PLPointer p, PLINT ix, PLINT iy, PLFLT z )
391 {
392 PLfGrid2 *g = (PLfGrid2 *) p;
393 return ( ( (PLFLT *) g->f )[ix + g->nx * iy] -= z );
394 }
395
396 static PLFLT
plf2ops_grid_col_major_mul(PLPointer p,PLINT ix,PLINT iy,PLFLT z)397 plf2ops_grid_col_major_mul( PLPointer p, PLINT ix, PLINT iy, PLFLT z )
398 {
399 PLfGrid2 *g = (PLfGrid2 *) p;
400 return ( ( (PLFLT *) g->f )[ix + g->nx * iy] *= z );
401 }
402
403 static PLFLT
plf2ops_grid_col_major_div(PLPointer p,PLINT ix,PLINT iy,PLFLT z)404 plf2ops_grid_col_major_div( PLPointer p, PLINT ix, PLINT iy, PLFLT z )
405 {
406 PLfGrid2 *g = (PLfGrid2 *) p;
407 return ( ( (PLFLT *) g->f )[ix + g->nx * iy] /= z );
408 }
409
410 static PLINT
plf2ops_grid_col_major_isnan(PLPointer p,PLINT ix,PLINT iy)411 plf2ops_grid_col_major_isnan( PLPointer p, PLINT ix, PLINT iy )
412 {
413 PLfGrid2 *g = (PLfGrid2 *) p;
414 return isnan( ( (PLFLT *) g->f )[ix + g->nx * iy] );
415 }
416
417 plf2ops_t s_plf2ops_grid_col_major = {
418 plf2ops_grid_col_major_get,
419 plf2ops_grid_col_major_set,
420 plf2ops_grid_col_major_add,
421 plf2ops_grid_col_major_sub,
422 plf2ops_grid_col_major_mul,
423 plf2ops_grid_col_major_div,
424 plf2ops_grid_col_major_isnan,
425 plf2ops_grid_xxx_major_minmax,
426 plf2ops_grid_col_major_f2eval
427 };
428
429 PLF2OPS
plf2ops_grid_col_major()430 plf2ops_grid_col_major()
431 {
432 return &s_plf2ops_grid_col_major;
433 }
434