Menu

#494 real numbers in for loop iterator

open
nobody
loop (1) for (1)
5
2019-10-02
2019-09-17
cipper
No

Presently only integers are accepted in 'for' iterator, while often real numbers are needed, es.:
p for [i = 0.1 : 1.0 : 0.1] "mydata".i

Such generalization would be very appreciated.

Discussion

  • cipper

    cipper - 2019-09-30

    any feedback?

     
  • Ethan Merritt

    Ethan Merritt - 2019-10-01

    There has been discussion about this before. I don't think a solid case has been made that it gains enough to be worth the added complexity. The example you give wouldn't actually work anyway because autopromotion of a floating point value to a string is not well defined. And as soon as you bring a format into it, you might as well use the integer equivalent:

    plot for [i=1:10] sprintf("mydata.%.1f", i/10.)

     
  • cipper

    cipper - 2019-10-01

    The promotion to string can always be done by "".i
    i.e. by concatenating with an empty string.

    Your sprintf() solution is indeed a workaround, but it could actually make the script quite more complex and messy than it should be. Take for example an apparently simple case like:

    p for [i = 8.562 : 12.137 : 0.065] "data_".i
    

    This format would be clear and straight, and does not require one to work it around by something like:

    end=int((12.137-8.562)/0.065)
    plot for [i=0:end] sprintf("data_%.3f", 8.562+i*0.065)
    

    which is a quite unreadable way to get a simple iteration.

     

    Last edit: cipper 2019-10-01
    • Ethan Merritt

      Ethan Merritt - 2019-10-01

      You are missing the point. What string is produced by

      foo = 1./3.
      filename = "data_".foo
      
      "data_.3" ? "data_0.3"? "data_0.333333333333333333"?
      

      Without a format specifier the result of the automatic conversion is undefined.

       
      • cipper

        cipper - 2019-10-02

        You are right. I thought that the "".i trick worked also for floats...

         
  • cipper

    cipper - 2019-10-01

    rather, one could use the system() call (as you teach):

    p for [i in system("seq 8.562 0.065 12.137")] (i+0) t i
    

    which is clean enough. However, if it wasn't a big change, the direct iteration (without workarounds) would be best. There's really so much to change to get this?

    Thank you,
    Roberto

     
    • Ethan Merritt

      Ethan Merritt - 2019-10-01

      No need to jump outside gnuplot and invoke the system shell.
      There are multiple ways on doing this in gnuplot itself:

      array FOO = [ 8.562, 0.065, 12.137]
      
      do for [i=1:|FOO|] {
            ... something using FOO[i]
       }
      
       BAZ = "8.562 0.065 12.137"
       do for [i=1:words(BAZ)] {
          ... something using word(BAZ,i)
       }
      
       
      • cipper

        cipper - 2019-10-02

        What you write is totally different from my case. You are just iterating among the 3 elements of an array, not among 55 elements of a sequence from 8.562 to 12.13 in steps of 0.065, as I would get from the system() call above.

         
        • Ethan Merritt

          Ethan Merritt - 2019-10-02

          Ah, sorry. I was not familiar with the "seq" command so I misinterpreted your example.

           

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.