From: David M. <da...@as...> - 2010-01-06 08:11:37
|
As I said in an earlier message, I'm working on Ruby bindings to PLplot that are analogous to the Ruby bindings to PGPLOT. Like the PGPLOT Ruby bindings, I've chosen to use/support the Ruby "NArray" extension (http://narray.rubyforge.org/) for data arrays. I just implemented the plsurf3d function and it works great, but... NArray stores 2D data (like the z data for plsurf3d) in a nx*ny element 1D array in (I think) FORTRAN ordering (I think it's known as "column major" ordering, but I always seem to suffer from row/column dyslexia when it comes to remembering which is which). So to get the plots in example 8 to look right, I have to index the NArray z data as z[j,i] rather than z[i,j] (where i is the index in the "x dimension" and j is the index in the "y dimension"). I also have to dimension the z array "backwards" (so I can use the indexes "backwards"). To interface NArray's 2D data with plsurf3d, I have to allocate and populate an array of nx pointers to arrays of ny values. Since the y values have to be contiguous in memory for plsurf3d, using the "backwards" indexing scheme (perhaps "pre-transposed" is a more apt term?) with NArray's 2D data saves a lot of memory copying. While this is a little odd feeling, I don't think this will be a "problem" per se, so the following is a low priority feature request: It would be nice if plsurf3d (and presumably other 3D functions that I haven't gotten to yet) supported an option (e.g. "TRANSPOSED_Z") that would indicate z is being given as an array of ny pointers to arrays of nx values rather than the other way around. Is there some existing way to accomplish the same thing? How does the FORTRAN interface to plsurf3d work? Thanks, Dave |
From: Arjen M. <arj...@de...> - 2010-01-06 08:31:47
|
Hi David, while I suffer from the same type of dyslexia (even after all these years I still have trouble getting the indices right and frequently have to sketch what the layout of the data is and what it should be, using Fortran, C and a couple of other languages), I must point out that plsurf3d uses the _C_ ordering. You can see this for yourself in bindings/f(77|95)/sc3d.c which contains the Fortran-callable wrapper for that function. There the array z is transposed to fill the temporary array temp. (I hope I do remember this correctly: the Fortran ordering is called column-major and C ordering is called row-major.) Regards, Arjen On 2010-01-06 09:11, David MacMahon wrote: > As I said in an earlier message, I'm working on Ruby bindings to > PLplot that are analogous to the Ruby bindings to PGPLOT. Like the > PGPLOT Ruby bindings, I've chosen to use/support the Ruby "NArray" > extension (http://narray.rubyforge.org/) for data arrays. I just > implemented the plsurf3d function and it works great, but... > > NArray stores 2D data (like the z data for plsurf3d) in a nx*ny > element 1D array in (I think) FORTRAN ordering (I think it's known as > "column major" ordering, but I always seem to suffer from row/column > dyslexia when it comes to remembering which is which). So to get the > plots in example 8 to look right, I have to index the NArray z data > as z[j,i] rather than z[i,j] (where i is the index in the "x > dimension" and j is the index in the "y dimension"). I also have to > dimension the z array "backwards" (so I can use the indexes > "backwards"). > > To interface NArray's 2D data with plsurf3d, I have to allocate and > populate an array of nx pointers to arrays of ny values. Since the y > values have to be contiguous in memory for plsurf3d, using the > "backwards" indexing scheme (perhaps "pre-transposed" is a more apt > term?) with NArray's 2D data saves a lot of memory copying. > > While this is a little odd feeling, I don't think this will be a > "problem" per se, so the following is a low priority feature > request: It would be nice if plsurf3d (and presumably other 3D > functions that I haven't gotten to yet) supported an option (e.g. > "TRANSPOSED_Z") that would indicate z is being given as an array of > ny pointers to arrays of nx values rather than the other way around. > > Is there some existing way to accomplish the same thing? How does > the FORTRAN interface to plsurf3d work? > > Thanks, > Dave > > > ------------------------------------------------------------------------------ > This SF.Net email is sponsored by the Verizon Developer Community > Take advantage of Verizon's best-in-class app development support > A streamlined, 14 day to market process makes app distribution fast and easy > Join now and get one step closer to millions of Verizon customers > http://p.sf.net/sfu/verizon-dev2dev > _______________________________________________ > Plplot-devel mailing list > Plp...@li... > https://lists.sourceforge.net/lists/listinfo/plplot-devel > |
From: David M. <da...@as...> - 2010-01-06 16:32:06
|
Hi, Arjen, On Jan 6, 2010, at 0:31 , Arjen Markus wrote: > while I suffer from the same type of dyslexia (even after all these > years I still have trouble getting the indices right and frequently > have to sketch what the layout of the data is and what it should be, > using Fortran, C and a couple of other languages) :-) (-:, or should I say :-( )-: ? :-) > I must point out > that plsurf3d uses the _C_ ordering. You can see this for yourself > in bindings/f(77|95)/sc3d.c which contains the Fortran-callable > wrapper > for that function. There the array z is transposed to fill the > temporary > array temp. Thanks, it sounds like the FORTRAN bindings would also benefit from something like a "TRANSPOSED_Z" option. > (I hope I do remember this correctly: the Fortran ordering is called > column-major and C ordering is called row-major.) You got it right! http://en.wikipedia.org/wiki/Row-major_order Dave |
From: Alan W. I. <ir...@be...> - 2010-01-06 17:03:51
|
On 2010-01-06 09:31+0100 Arjen Markus wrote: > Hi David, > > while I suffer from the same type of dyslexia (even after all these > years I still have trouble getting the indices right and frequently > have to sketch what the layout of the data is and what it should be, > using Fortran, C and a couple of other languages), I must point out > that plsurf3d uses the _C_ ordering. You can see this for yourself > in bindings/f(77|95)/sc3d.c which contains the Fortran-callable wrapper > for that function. There the array z is transposed to fill the temporary > array temp. Arjen, from the fortran wrappers do we use the C order for all our two-dimensional arrays or just for the plsurf3d related functions? If we have a mixture of C and Fortran ordering for the two-dimensional arrays in our API, we should decide which convention we should use in our API and convert to it if/when we decide to do other major API breakage we have been discussing. Alan __________________________ Alan W. Irwin Astronomical research affiliation with Department of Physics and Astronomy, University of Victoria (astrowww.phys.uvic.ca). Programming affiliations with the FreeEOS equation-of-state implementation for stellar interiors (freeeos.sf.net); PLplot scientific plotting software package (plplot.org); the libLASi project (unifont.org/lasi); the Loads of Linux Links project (loll.sf.net); and the Linux Brochure Project (lbproject.sf.net). __________________________ Linux-powered Science __________________________ |
From: Arjen M. <arj...@de...> - 2010-01-06 17:29:32
|
On Wed, 6 Jan 2010 09:03:42 -0800 (PST) "Alan W. Irwin" <ir...@be...> wrote: > > Arjen, from the fortran wrappers do we use the C order >for all our > two-dimensional arrays or just for the plsurf3d related >functions? > > If we have a mixture of C and Fortran ordering for the >two-dimensional > arrays in our API, we should decide which convention we >should use in our > API and convert to it if/when we decide to do other >major API breakage we > have been discussing. > Hi Alan, I will have to check, but I think the ordering is leaning consistently to row-major, uh, the C way. Regards, Arjen |
From: David M. <da...@as...> - 2010-01-07 01:00:51
|
Hi, Alan, On Jan 6, 2010, at 9:03 , Alan W. Irwin wrote: > If we have a mixture of C and Fortran ordering for the two-dimensional > arrays in our API, we should decide which convention we should use > in our > API and convert to it if/when we decide to do other major API > breakage we > have been discussing. I guess I joined the list after that discussion, but I think it would be great if the API supported the following four ways of passing in 2D data... 1) 1D array of nx pointers to 1D arrays of ny values 2) 1D array of ny pointers to 1D arrays of nx values 3) Pointer to 1D array of nx*ny values in row major order 4) Pointer to 1D array of nx*ny values in column major order This may be somewhat of a grandiose, idealistic wish, but it would support the most common ways of specifying 2D data without requiring (potentially expensive) transposition of the data. I haven't gotten too far into the other 3D-ish functions yet, but some (e.g. plcont) accept a "transformation" function pointer through which lookups occur. Perhaps this mechanism (or something similar) could be used to provide the level of flexibility I'm suggesting (and beyond!). Just an idea, Dave |
From: Maurice L. <mj...@br...> - 2010-01-07 01:55:21
|
On Wednesday, January 6, 2010 at 17:00:40 (-0800) David MacMahon writes: > Hi, Alan, > > On Jan 6, 2010, at 9:03 , Alan W. Irwin wrote: > > > If we have a mixture of C and Fortran ordering for the two-dimensional > > arrays in our API, we should decide which convention we should use > > in our > > API and convert to it if/when we decide to do other major API > > breakage we > > have been discussing. > > I guess I joined the list after that discussion, but I think it would > be great if the API supported the following four ways of passing in > 2D data... > > 1) 1D array of nx pointers to 1D arrays of ny values > 2) 1D array of ny pointers to 1D arrays of nx values > 3) Pointer to 1D array of nx*ny values in row major order > 4) Pointer to 1D array of nx*ny values in column major order > > This may be somewhat of a grandiose, idealistic wish, but it would > support the most common ways of specifying 2D data without requiring > (potentially expensive) transposition of the data. I haven't gotten > too far into the other 3D-ish functions yet, but some (e.g. plcont) > accept a "transformation" function pointer through which lookups > occur. Perhaps this mechanism (or something similar) could be used > to provide the level of flexibility I'm suggesting (and beyond!). Some centuries ago I did endow the contourer with the function evaluator technique to deal with the issue of C vs Fortran vs whatever array storage. Worked out nicely IMO. Would've liked to upgrade all array-handling functions in like fashion but so far I think it's only been done for the plshadexx family. -- Maurice LeBrun |
From: Arjen M. <arj...@de...> - 2010-01-07 07:51:15
|
Hi David, Alan, On 2010-01-07 07:43, David MacMahon wrote: > > I'm willing to try my hand at adapting some other functions to use > this technique. As far as I can tell, the list of functions that > could benefit from this are... > > c_plgriddata (*) > c_plmesh (**) > c_plmeshc (**) > c_plot3d (**) > c_plot3dc (**) > c_plot3dcl > c_plimagefr (***) > c_plimage (***) > c_plsurf3d (****) > c_plsurf3dl > c_plvect (*****) > I can confirm that the Fortran bindings transpose the data arrays for all of these functions with the exception of c_plvect. This function uses plfvect and plf2evalr in its implementation which together take care of the storage differences. David, you should probably use these two as a starting point for your work. Regards, Arjen |
From: David M. <da...@as...> - 2010-01-07 23:39:57
|
On Jan 6, 2010, at 23:51 , Arjen Markus wrote: > David, you should probably use these two as a starting point for your > work. Thanks, Arjen, I agree. Dave |
From: David M. <da...@as...> - 2010-01-07 06:43:57
|
On Jan 6, 2010, at 17:14 , Maurice LeBrun wrote: > Some centuries ago I did endow the contourer with the function > evaluator > technique to deal with the issue of C vs Fortran vs whatever array > storage. > Worked out nicely IMO. Would've liked to upgrade all array- > handling functions > in like fashion but so far I think it's only been done for the > plshadexx > family. Thanks, Maurice, I see that now in plfcont and plfshade. I think that's just the kind of thing that would be great to have for every function that deals with >1-D data. I'm willing to try my hand at adapting some other functions to use this technique. As far as I can tell, the list of functions that could benefit from this are... c_plgriddata (*) c_plmesh (**) c_plmeshc (**) c_plot3d (**) c_plot3dc (**) c_plot3dcl c_plimagefr (***) c_plimage (***) c_plsurf3d (****) c_plsurf3dl c_plvect (*****) (*) c_plgriddata might need both a "getter" and a "setter" version of this technique. (**) calls through to c_plot3dcl (***) might need a "plf..." version of plMinMax2dGrid (****) calls through to c_plsurf3dl (*****) already has a plfvect in plvect.c, but not plplot.h! My plan would be to rename the existing functions from "c_pl..." to "plf..." (or "c_plf..."?) and create new versions of the old functions that call the "plf" variant "with a particular choice for f2eval and f2eval_data" (as the c_plcont comments say). The only downside to doing this, AFAICT, is that the current behavior of these functions will be somewhat slower since they will be getting data via the evaluator function and not directly from the "z[nx][ny]" array (at least for z arrays that don't need to be "pre-un- transposed" into that format). If anyone thinks that (or anything else about this idea) is a show- stopper, please let me know ASAP so I don't spend time implementing something that won't be incorporated. Thanks, Dave |
From: Maurice L. <mj...@br...> - 2010-01-07 07:17:00
|
On Wednesday, January 6, 2010 at 22:43:44 (-0800) David MacMahon writes: > On Jan 6, 2010, at 17:14 , Maurice LeBrun wrote: > > > Some centuries ago I did endow the contourer with the function > > evaluator > > technique to deal with the issue of C vs Fortran vs whatever array > > storage. > > Worked out nicely IMO. Would've liked to upgrade all array- > > handling functions > > in like fashion but so far I think it's only been done for the > > plshadexx > > family. > > Thanks, Maurice, I see that now in plfcont and plfshade. I think > that's just the kind of thing that would be great to have for every > function that deals with >1-D data. > > I'm willing to try my hand at adapting some other functions to use > this technique. As far as I can tell, the list of functions that > could benefit from this are... > > c_plgriddata (*) > c_plmesh (**) > c_plmeshc (**) > c_plot3d (**) > c_plot3dc (**) > c_plot3dcl > c_plimagefr (***) > c_plimage (***) > c_plsurf3d (****) > c_plsurf3dl > c_plvect (*****) > > (*) c_plgriddata might need both a "getter" and a "setter" version of > this technique. > (**) calls through to c_plot3dcl > (***) might need a "plf..." version of plMinMax2dGrid > (****) calls through to c_plsurf3dl > (*****) already has a plfvect in plvect.c, but not plplot.h! > > My plan would be to rename the existing functions from "c_pl..." to > "plf..." (or "c_plf..."?) and create new versions of the old > functions that call the "plf" variant "with a particular choice for > f2eval and f2eval_data" (as the c_plcont comments say). > > The only downside to doing this, AFAICT, is that the current behavior > of these functions will be somewhat slower since they will be getting > data via the evaluator function and not directly from the "z[nx][ny]" > array (at least for z arrays that don't need to be "pre-un- > transposed" into that format). My only suggestion is to not worry about the performance issues in function evaluation.. after all you've got a system call somewhere down the line to actually draw something. In my experience that's usually where the worst (and most intractable) bottleneck occurs. -- Maurice LeBrun |
From: David M. <da...@as...> - 2010-01-07 23:41:23
|
On Jan 6, 2010, at 23:14 , Maurice LeBrun wrote: > My only suggestion is to not worry about the performance issues in > function > evaluation.. after all you've got a system call somewhere down the > line to > actually draw something. In my experience that's usually where the > worst (and > most intractable) bottleneck occurs. Thanks for putting my mind at ease about this, Maurice! Dave |
From: David M. <da...@as...> - 2010-02-01 20:53:13
|
I think I have accomplished the changes described in the thread quoted below. I still have some testing to do, but I'd appreciate any comments on my approach. Preliminary testing shows negligible (i.e. undetectable) effect on performance. Here is a summary of what I did (a patch is available if desired, but I'd prefer to hold off sending it out until my testing is completed)... Support arbitrary storage of 2D user data Adds support for arbitrary storage of 2D user data. This is very similar to the technique employed by some existing functions (e.g. plfcont and plfshade) that use "evaluator" functions to access 2D user data that is stored in an arbtrary format. The new approach extends the concept of a user-supplied (or predefined) "evaluator" function to a group of user-supplied (or predefined) "operator" functions. The operator functions provide for various operations on the arbitrarily stored 2D data including: get, set, +=, -=, *=, /=, isnan, and minmax. To facilitate the passing of an entire family of operator functions (via function pointers), a plf2ops_t structure is defined to contain a pointer to each type of operator function. Predefined operator functions are defined for several common 2D data storage techniques. Variables (of type plf2ops_t) containing function pointers for these operator functions are also defined. New variants of functions that accept 2D data are created. The new variants accept the 2D data as two parameters: a pointer to a plf2ops_t structure containing (pointers to) suitable operator functions and a PLPointer to the actual 2D data store. Existing functions that accept 2D data are modified to simply pass their parameters to the corresponding new variant of the function, along with a pointer to the suitable predefined plf2ops_t stucture of operator function pointers. The list of functions for which new variants are created is: c_plimagefr, c_plmesh, c_plmeshc, c_plot3d, c_plot3dc, c_plot3dcl, c_plsurf3d, and c_plsurf3dl, and c_plgriddata. The new variants are named the same as their corresponding existing function except that the "c_" prefix is changed to "plf" (e.g. the new variant of c_plmesh is called plfmesh). Adds plfvect declaration to plplot.h and changes the names (and only the names) of some plfvect arguments to make them slightly clearer. In order to maintain backwards API compatibility, this function and the other existing functions that use "evaluator" functions are NOT changed to use the new operator functions. Thanks for any feedback, Dave On Jan 6, 2010, at 22:43 , David MacMahon wrote: > On Jan 6, 2010, at 17:14 , Maurice LeBrun wrote: > >> Some centuries ago I did endow the contourer with the function >> evaluator >> technique to deal with the issue of C vs Fortran vs whatever array >> storage. >> Worked out nicely IMO. Would've liked to upgrade all array- >> handling functions >> in like fashion but so far I think it's only been done for the >> plshadexx >> family. > > Thanks, Maurice, I see that now in plfcont and plfshade. I think > that's just the kind of thing that would be great to have for every > function that deals with >1-D data. > > I'm willing to try my hand at adapting some other functions to use > this technique. As far as I can tell, the list of functions that > could benefit from this are... > > c_plgriddata (*) > c_plmesh (**) > c_plmeshc (**) > c_plot3d (**) > c_plot3dc (**) > c_plot3dcl > c_plimagefr (***) > c_plimage (***) > c_plsurf3d (****) > c_plsurf3dl > c_plvect (*****) > > (*) c_plgriddata might need both a "getter" and a "setter" version of > this technique. > (**) calls through to c_plot3dcl > (***) might need a "plf..." version of plMinMax2dGrid > (****) calls through to c_plsurf3dl > (*****) already has a plfvect in plvect.c, but not plplot.h! > > My plan would be to rename the existing functions from "c_pl..." to > "plf..." (or "c_plf..."?) and create new versions of the old > functions that call the "plf" variant "with a particular choice for > f2eval and f2eval_data" (as the c_plcont comments say). > > The only downside to doing this, AFAICT, is that the current behavior > of these functions will be somewhat slower since they will be getting > data via the evaluator function and not directly from the "z[nx][ny]" > array (at least for z arrays that don't need to be "pre-un- > transposed" into that format). > > If anyone thinks that (or anything else about this idea) is a show- > stopper, please let me know ASAP so I don't spend time implementing > something that won't be incorporated. > > Thanks, > Dave > > > ---------------------------------------------------------------------- > -------- > This SF.Net email is sponsored by the Verizon Developer Community > Take advantage of Verizon's best-in-class app development support > A streamlined, 14 day to market process makes app distribution fast > and easy > Join now and get one step closer to millions of Verizon customers > http://p.sf.net/sfu/verizon-dev2dev > _______________________________________________ > Plplot-devel mailing list > Plp...@li... > https://lists.sourceforge.net/lists/listinfo/plplot-devel |
From: David M. <da...@as...> - 2010-02-03 21:15:14
|
On Feb 1, 2010, at 12:53 , David MacMahon wrote: > I think I have accomplished the changes described in the thread > quoted below. I still have some testing to do, but I'd appreciate > any comments on my approach. Preliminary testing shows negligible > (i.e. undetectable) effect on performance. Not to toot my own horn, but I thought I'd add some more comments about this. I think the ability to use arbitrary storage of user data has many benefits, including: 1. FORTRAN arrays need not be transposed before passing to C functions. 2. It allow for not only the arbitrary of arrangement of the data, but also for arbitrary types of data since each element is returned by a user-defined function which can cast each element as needed to type PLFLT. This provides a path towards supporting both single and double precision user data in the same library, as well as integer user data, half precision user data, etc. More generally, the user defined function can transform each point for plotting. For example, the user data could be complex, but user-defined operator functions could be used to treat the data as just the real component, just the imaginary component, magnitudes, or phases. Another potential use of transformation operator functions would be to facilitate log plots. And, of course, the user data need not even be stored; it could be computed (e.g. fractals). 3. Simplifying interfaces with other libraries. For example, the GSL library has its own two dimensional data type (i.e. matrix). It also supports "views" into existing matrices (i.e. submatrix) with various stride options. By providing a small set of GSL-aware operator functions, pointers to GSL matrices and even GSL matrix "views" could be passed directly to the PLplot functions that accept operator functions. IMHO, the benefits are compelling enough and the apparent performance hit negligible enough that it could be argued that providing similar behavior for 1D data would be worthwhile! Dave |