Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.graphics.apps.gnuplot > #4541
| 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> |
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 | Next — Previous in thread | Find similar
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