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