Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.graphics.apps.gnuplot > #4541

Re: How to: Assign an array[7] variable (with scope local to just one plot command) the array[7] value returned by a function block

Newsgroups comp.graphics.apps.gnuplot
Date 2023-09-27 04:17 -0700
References <e8824da3-8b68-4598-b374-a1f582d6ff14n@googlegroups.com>
Message-ID <01876985-e443-42e8-bdf3-ef3af7b10aa4n@googlegroups.com> (permalink)
Subject Re: How to: Assign an array[7] variable (with scope local to just one plot command) the array[7] value returned by a function block
From najevi <najevi@gmail.com>

Show all headers | View raw


On Tuesday, September 26, 2023 at 11:54:51 PM UTC+10, najevi wrote:
> I am using gnuplot v6 rc1 as I am relying on a function block to implement a non-trivial algorithm. 
> 
> I have a function block returning a 7 element array based on each data point in a dataset. The function, $f(), consumes just one data point ($1) and returns an array[7] value. So something like: 
> 
> local array x[7] = $f($1) 
> 
> The data set is not complex - being just one value per line in a file. The length of a dataset can be very large. Currently ~20,000,000 data points is the longest dataset but I test with datasets of fewer than 600 data points. 
> 
> Ideally I'd assign the return value of the function to an array variable and then use references to that local array variable within a single plot command however I cannot see how to achieve such a local array variable assignment within the syntax of a plot command. 
> 
> As you can see from the pseudo-code below, I use 5 elements of the returned array in a plot command and since I currently do so by calling the function 5 times I think it is terribly wasteful of CPU cycles. (NOTE: I currently use the other 2 elements of the returned array to dramatically skip over function block code whenever ARGV[1] and ARGC have not changed since the last time the function was called.) 
> 
> I'd appreciate learning how to achieve the same result more efficiently. 
> 
> pseudo code to illustrate:- 
> 
> = = = start of pseudo code = = = 
> array lastFNvalue[7] = [0,0,0,0,0,0,0] 
> 
> function $f << _EOFD 
> if ( (lastFNvalue[2] == ARGC) && (lastFNvalue[1] == ARGV[1]) ) { return lastFNvalue } 
> : 
> : # algorithm yielding 5 values from one input value 
> : 
> local array s[7] = [ ARGV[1], ARGC, azimuth, r, delTheta, delR, density ] 
> lastFNvalue = s 
> return s 
> _EOFD 
> 
> : 
> : 
> 
> plot @inFile \ 
> using ($f($1)[3]) : ($f($1)[4]) : ($f($1)[5]) : ($f($1)[6]) : ($f($1)[7]) \ 
> with sectors linecolor palette \ 
> , @inFile \ 
> using ($f($1)[3]+$f($1)[5]/2) : ($f($1)[4]-0.4) : 1 : (-fixT*( ($f($1)[3]+$f($1)[5]/3) + pi/2 ) ) : ($f($1)[7]) \ 
> with labels nopoint center rotate variable textcolor palette font "Times,8" \ 
> , '-' using 1:2:3:4:5 with sectors linecolor variable 
> 0 0 2 @N 0 
> EOD 
> = = = end of pseudo code = = = 
> 
> So you can see that elements 3,4,5,6 of the array are used to plot (annular) sectors and element 7 (the density) indexes a color palette to yield a meaningful color for each radius of this plot .. which clearly uses polar coordinates. 
> 
> I'd imagined I could use one comma-delimited: 
> <plot-element>, 
> to assign the returned value of $f($1) to an array variable and thereby avoid calling $f() multiple times within the one plot command. When I could not discover a suitable syntax for doing so I capitulated and settled for calling $f() multiple times and simply inserted a conditional test (as shown above) to bypass the complex algorithm whenever the $1 data value being passed to $f() has not changed since the last time $f() was called. 
> 
> ** Do you know of a legitimate syntax that enables (what hopefully the reader will agree is) intuitive/expected behaviour from the pseudo-code I describe below:- 
> 
> specifically that plot-element: 
> local array x[7] = $f($1) , 
> 
> = = = 
> plot @inFile \ 
> local array x[7] = $f($1) \ 
> , using (x[3]) : (x[4]) : (x[5]) : (x[6]) : (x[7]) \ 
> with sectors linecolor palette \ 
> , using (x[3]+x[5]/2) : (x[4]-0.4) : 1 : (-fixT*( (x[3]+x[5]/3) + pi/2 ) ) : (x[7]) \ 
> with labels nopoint center rotate variable textcolor palette font "Times,8" \ 
> , '-' using 1:2:3:4:5 with sectors linecolor variable 
> 0 0 2 @N 0 
> EOD 
> = = = 
> 
> The intent being that array x[7] has scope local to just that one plot command and therefore $f($1) is called only the once per data point in any data set. 
> 
> Thank you for considering this specific application of gnuplot. 
> 
> FWIW: 
> I did toy with having $f() return a string resembling the "using" syntax: 
> 
> "using (azimuth) : (r) : (delTheta) : (delR) : (density) " 
> 
> with a view to substitution of that string variable as a macro via: 
> @$f($1) 
> style of dereferencing but that was frustratingly unsuccessful.

One satisfactory solution I have found is to use the so-called "comma operator" within the parenthesized 1st-term of a using-clause:

using (x = $f($1), x[3]) : (x[4]) : (x[5]) : (x[6]) : (x[7]) 

and

using (x = $f($1), x[3] + x[5]/2) : (x[4]-0.4) : 1 : (-fixT * (x[3] + x[5]/2 + pi/2))  : (x[7]) 

reduces the number of times $f() is called to just once per using-clause .. so this can still mean multiple times per plot command but this is nonetheless a significant improvement compared to the prior method I was using.

Parentheses are important because without parentheses the enclosed expressions will not evaluate each time plot reads a data point/data record. So this helps me to better understand what 'triggers' plot to call $f($1). This solution seems robust viz a viz running replot - so that is an added benefit. 

Back to comp.graphics.apps.gnuplot | Previous | NextPrevious in thread | Find similar


Thread

How to: Assign an array[7] variable (with scope local to just one plot command) the array[7] value returned by a function block najevi <najevi@gmail.com> - 2023-09-26 06:54 -0700
  Re: How to: Assign an array[7] variable (with scope local to just one plot command) the array[7] value returned by a function block najevi <najevi@gmail.com> - 2023-09-27 04:17 -0700

csiph-web