Author Topic: Range Function  (Read 9931 times)

0 Members and 1 Guest are viewing this topic.

ymg

  • Guest
Range Function
« on: November 17, 2013, 12:51:33 AM »
Would there be any merit ?  to a range function like they have in Python.

Say we define the following:

Code - Auto/Visual Lisp: [Select]
  1. (defun in_range ( i j step / l)
  2.    (setq l (list i))
  3.    (while (< (setq i (+ i step)) j)
  4.       (setq l (cons i l))
  5.    )
  6.    (reverse l)
  7. )
  8.  

Now we could have construct like this and get away from updating the index:

Code - Auto/Visual Lisp: [Select]
  1. (foreach i (in_range 0 10 1)
  2.     ;;;
  3.    ;Do something here
  4. )
  5.  

ymg
« Last Edit: November 17, 2013, 01:52:27 AM by ymg »

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Range Function
« Reply #1 on: November 17, 2013, 02:14:03 AM »
There are quite a few functions in Python and Javascript that would be handy in Lisp.


I recall that Tony T wrote a case() and let() function (similar to common lisp)  back in the day. I still use it regularly now.
« Last Edit: November 17, 2013, 03:11:31 AM by Kerry »
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

ymg

  • Guest
Re: Range Function
« Reply #2 on: November 17, 2013, 02:19:49 AM »
Kerry,

Then maybe it would be worth to optimize it a little.

Too bad we don't really have the luxury of optional arguments.

Don't really know what is the speed impact as compared to incrementing an index.

ymg

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Range Function
« Reply #3 on: November 17, 2013, 03:10:36 AM »
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

ymg

  • Guest
Re: Range Function
« Reply #4 on: November 17, 2013, 03:31:37 AM »
Kerry,

The let function is quite powerful.

Could use it I believe in that Levenberg-Marquardt solver.

Thanks, for sharing.

ymg

ymg

  • Guest
Re: Range Function
« Reply #5 on: November 17, 2013, 05:18:54 AM »
If we define in_range as follow, it would work both ways

Code - Auto/Visual Lisp: [Select]
  1. (defun in_range ( i j step / l)
  2.   (setq l (list i))
  3.   (repeat (- (fix (/ (- j i) step)) 1)    
  4.      (setq l (cons (setq i (+ i step)) l))
  5.   )
  6.   (reverse l)
  7. )
  8.  

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: Range Function
« Reply #6 on: November 17, 2013, 05:48:40 AM »
Note:
Code: [Select]
(ymg_in_range_1 0 10.5 1) => (0 1 2 3 4 5 6 7 8 9 10)
(ymg_in_range_1 0 3 2) => (0 2)

(ymg_in_range_2 0 10.5 1) => (0 1 2 3 4 5 6 7 8 9)
(ymg_in_range_2 0 3 2) => (0)

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: Range Function
« Reply #7 on: November 17, 2013, 06:03:16 AM »
For index ranges I have been using these two functions:

Code - Auto/Visual Lisp: [Select]
  1. ; Make a zero based list of integers.
  2. ; With speed improvement based on Reini Urban's (std-%setnth).
  3. ; (KGA_List_IndexSeqMakeLength 7) => (0 1 2 3 4 5 6)
  4. (defun KGA_List_IndexSeqMakeLength (len / ret)
  5.   (repeat (rem len 8)
  6.     (setq ret (cons (setq len (1- len)) ret))
  7.   )
  8.   (repeat (/ len 8)
  9.     (setq ret
  10.       (vl-list*
  11.         (- len 8)
  12.         (- len 7)
  13.         (- len 6)
  14.         (- len 5)
  15.         (- len 4)
  16.         (- len 3)
  17.         (- len 2)
  18.         (- len 1)
  19.         ret
  20.       )
  21.     )
  22.     (setq len (- len 8))
  23.   )
  24.   ret
  25. )
  26.  
  27. ; Make a list of integers from start index to end index.
  28. ; The Sequence always ends before the end index and the length of the result is: (abs (- end start)).
  29. ; This also applies if start is bigger than end. Input values can also be 'integers as reals'.
  30. ; With speed improvement based on Reini Urban's (std-%setnth).
  31. ; (KGA_List_IndexSeqMakeStartEnd 3 6) => (3 4 5)
  32. ; (KGA_List_IndexSeqMakeStartEnd 6 3) => (6 5 4)
  33. ; (KGA_List_IndexSeqMakeStartEnd -3.0 -8.0) => (-3.0 -4.0 -5.0 -6.0 -7.0)
  34. (defun KGA_List_IndexSeqMakeStartEnd (start end / len ret step)
  35.   (setq step (if (< start end) -1 1))
  36.   (repeat (rem (setq len (fix (abs (- end start)))) 8)
  37.     (setq ret (cons (setq end (+ end step)) ret))
  38.   )
  39.   (repeat (/ len 8)
  40.     (setq ret
  41.       (vl-list*
  42.         (+ end (* 8 step))
  43.         (+ end (* 7 step))
  44.         (+ end (* 6 step))
  45.         (+ end (* 5 step))
  46.         (+ end (* 4 step))
  47.         (+ end (* 3 step))
  48.         (+ end (* 2 step))
  49.         (+ end step)
  50.         ret
  51.       )
  52.     )
  53.     (setq end (+ end (* 8 step)))
  54.   )
  55.   ret
  56. )

ymg

  • Guest
Re: Range Function
« Reply #8 on: November 17, 2013, 06:34:55 AM »
roy_043,

Your function certainly work to give a range.

What I am really interested in is in using a construct of
the type python use,  for i in range(n):

and having something similar in Autolisp,  foreach i (in_range 0 n 1).

Would there be any advantage ?

Are we getting a hit speedwise ?

The in_range function as I gave it could certainly be optimized.

ymg

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: Range Function
« Reply #9 on: November 17, 2013, 09:15:17 AM »
Using an index range can make the life of a Lisp programmer a little easier. But there are some speed concerns. I have tried to optimize my functions for speed by reducing the number of calls to (setq) and avoiding the use or (reverse). As mentioned this optimization is based on Reini Urban's (std-%setnth). But I have not compared the speed of functions that use a range to functions that do not. My guess is that using a range will generally be slower.

Below is an example of how I use (KGA_List_IndexSeqMakeLength):
Code - Auto/Visual Lisp: [Select]
  1. (setq pointList (KGA_List_Divide (vlax-get object 'coordinates) 2))
  2. (setq len (length pointList))
  3. (setq bulgeList
  4.   (mapcar
  5.     '(lambda (i)
  6.       (vlax-invoke object 'getbulge i)
  7.     )
  8.     (KGA_List_IndexSeqMakeLength len)
  9.   )
  10. )

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Range Function
« Reply #10 on: November 17, 2013, 09:18:10 AM »
Another offering:
Code - Auto/Visual Lisp: [Select]
  1. ;;  from start to end using step return the values
  2. ;;  integers only
  3. (defun in_range (start end step / value)
  4.   (setq value (list start))
  5.     (repeat (fix (/ (- end start) step))
  6.       (setq value (cons (setq start (+ step start)) value))
  7.     )
  8.   )
  9. )
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: Range Function
« Reply #11 on: November 17, 2013, 09:34:35 AM »
@ CAB:
I am not sure but judging by ymg's first post all values in the return value should be smaller than the 'end' argument.
Code: [Select]
(cab_in_range_1 0 10 1) => (0 1 2 3 4 5 6 7 8 9 10)

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: Range Function
« Reply #12 on: November 17, 2013, 09:37:29 AM »
@ ymg:
In the Python implementation is 'start' always smaller than 'end'?

ymg

  • Guest
Re: Range Function
« Reply #13 on: November 17, 2013, 11:40:49 AM »
Quote
In the Python implementation is 'start' always smaller than 'end'?

Not sure, I am actually quite Green in Python.

The whole idea would be to get rid of having to keep a separate index in for loop.

Mind you, it still would not be equivalent to a For... Next  as the range is compute beforehand
and you cannot modify it while the loop is running.

It does have the advantage of being quite readable.  But again would there be a hit on speed ?
We certainly are using more memory but this get freed eventually.

I like!!! Cab's offering, the only problem with it is that it includes end,
(in_range 0 5 1) should return (0 1 2 3 4), but is easy to fix.

ymg

Here from:    docs.python.org
Code - Python: [Select]
  1. range(start, stop[, step])
  2. This is a versatile function to create lists containing arithmetic progressions. It is most often used in for loops. The arguments must be plain integers. If the step argument is omitted, it defaults to 1. If the start argument is omitted, it defaults to 0. The full form returns a list of plain integers [start, start + step, start + 2 * step, ...]. If step is positive, the last element is the largest start + i * step less than stop; if step is negative, the last element is the smallest start + i * step greater than stop. step must not be zero (or else ValueError is raised). Example:
  3.  
  4. >>>
  5. >>> range(10)
  6. [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
  7. >>> range(1, 11)
  8. [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
  9. >>> range(0, 30, 5)
  10. [0, 5, 10, 15, 20, 25]
  11. >>> range(0, 10, 3)
  12. [0, 3, 6, 9]
  13. >>> range(0, -10, -1)
  14. [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
  15. >>> range(0)
  16. []
  17. >>> range(1, 0)
  18. []
  19.  
« Last Edit: November 17, 2013, 12:01:50 PM by ymg »

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Range Function
« Reply #14 on: November 17, 2013, 11:55:07 AM »
I posted something similar to Python's range function here - might be of interest.

LE3

  • Guest
Re: Range Function
« Reply #15 on: November 17, 2013, 12:06:42 PM »
Have you seen the work of Sergey Bochkanov ALGLIB Project --- for the LMA - give it a read/try:

http://www.alglib.net/optimization/levenbergmarquardt.php

ymg

  • Guest
Re: Range Function
« Reply #16 on: November 17, 2013, 12:19:56 PM »
Quote
Have you seen the work of Sergey Bochkanov ALGLIB Project --- for the LMA - give it a read/try:


Thanks Luis,

Yes I did see it and it is well done.

Right now concentrating to get something going, so I am translating that Python implementation.

After that with help from the gurus here maybe optimize it and then includes those nice to have like
so called  geodesic acceleration etc.

But we are in the wrong thread.

ymg

ymg

  • Guest
Re: Range Function
« Reply #17 on: November 18, 2013, 01:51:36 AM »
Here is the latest, using Cab's offering with a little modification.

Mind you we still have a divide by zero error if step is set at zero,
may be we should wrap the function with a cond.

Also get a bad return at (in_range 0 10 3), so maybe the logic behind subtracting 1 from (fix (/ (- end start) step))
is not correct.

ymg

Code - Auto/Visual Lisp: [Select]
  1. (defun in_range (start end step / value)
  2.   (setq value (list start))
  3.     (repeat (- (fix (/ (- end start) step)) 1)
  4.       (setq value (cons (setq start (+ step start)) value))
  5.     )
  6.   )
  7. )
  8.  

So we modify like so:

Code - Auto/Visual Lisp: [Select]
  1. (defun in_range (start end step / value)
  2.   (setq value (list start))
  3.   (repeat (fix (/ (- end start) step))
  4.      (setq value (cons (setq start (+ step start)) value))
  5.   )
  6.   (reverse (if (= (car value) end) (cdr value) value))
  7. )
  8.  

Returns from autolisp/ python:

Code - Auto/Visual Lisp: [Select]
  1. $ (in_range 0 10 1)
  2.    (0 1 2 3 4 5 6 7 8 9)
  3. >>> range(10)
  4. [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
  5.  
  6. $ (in_range 1 11 1)
  7. (1 2 3 4 5 6 7 8 9 10)
  8. >>> range(1, 11)
  9. [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
  10.  
  11. $ (in_range 0 30 5)
  12. (0 5 10 15 20 25)
  13. >>> range(0, 30, 5)
  14. [0, 5, 10, 15, 20, 25]
  15.  
  16. $ (in_range 0 10 3)
  17. (0 3 6 9)        
  18. >>> range(0, 10, 3)
  19. [0, 3, 6, 9]
  20.  
  21. $ (in_range 0 -10 -1)
  22. (0 -1 -2 -3 -4 -5 -6 -7 -8 -9)
  23. >>> range(0, -10, -1)
  24. [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
  25.  
  26. $ (in_range 0 0 1)
  27. nil
  28. >>> range(0)
  29. []
  30. >>> range(1, 0)
  31. []
  32.  
  33.  
« Last Edit: November 18, 2013, 03:06:35 AM by ymg »

ElpanovEvgeniy

  • Water Moccasin
  • Posts: 1569
  • Moscow (Russia)
Re: Range Function
« Reply #18 on: November 18, 2013, 02:58:58 AM »
recursion way

Code - Auto/Visual Lisp: [Select]
  1. (defun range (s e i)
  2.   (if (< s e)
  3.     (cons s (range (+ i s) e i))
  4.   )
  5. )
:-)

ymg

  • Guest
Re: Range Function
« Reply #19 on: November 18, 2013, 03:12:21 AM »
Quote
recursion way

Best one!!! by a tall margin.

ymg

ElpanovEvgeniy

  • Water Moccasin
  • Posts: 1569
  • Moscow (Russia)
Re: Range Function
« Reply #20 on: November 18, 2013, 03:16:31 AM »
Quote
recursion way

Best one!!! by a tall margin.

ymg

Thank you!

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: Range Function
« Reply #21 on: November 18, 2013, 04:24:31 AM »
@ ElpanovEvgeniy:
Your function is nice and short but:
Code: [Select]
(EE_range 0 -10 -1) => nil

ymg

  • Guest
Re: Range Function
« Reply #22 on: November 18, 2013, 04:44:13 AM »
Quote
@ ElpanovEvgeniy:
Your function is nice and short but:
Code: [Select]
(EE_range 0 -10 -1) => nil

Ooops! ,  So then we have:

Code - Auto/Visual Lisp: [Select]
  1. ;;  By Cab      (iterative)                                                   ;
  2. ;;                                                                            ;
  3. (defun in_range (start end step / value)
  4.   (setq value (list start))
  5.   (repeat (fix (/ (- end start) step))
  6.      (setq value (cons (setq start (+ step start)) value))
  7.   )
  8.   (reverse (if (= (car value) end) (cdr value) value))
  9. )
  10.  

But we  still haven't addressed if there is any merit to such construct as
  (foreach  i  (in_range 0 10 1) ....

ymg

ElpanovEvgeniy

  • Water Moccasin
  • Posts: 1569
  • Moscow (Russia)
Re: Range Function
« Reply #23 on: November 18, 2013, 05:34:24 AM »
@ ElpanovEvgeniy:
Your function is nice and short but:
Code: [Select]
(EE_range 0 -10 -1) => nil

Thank you, I corrected!

Code - Auto/Visual Lisp: [Select]
  1. (defun range (s e i)
  2.   (if (or (and (> i 0) (< s e)) (and (< i 0) (> s e)))
  3.     (cons s (range (+ i s) e i))
  4.   )
  5. )
:-)

ymg

  • Guest
Re: Range Function
« Reply #24 on: November 18, 2013, 06:22:04 AM »
No matter how I try, I don't have the recursive bone in me.

Haven't figured how the first one work, now need to wrap my head around the corrected one.

Still the Best One!!

But, Evgeniy what do you think of construct like the one proposed???

Quote
But we  still haven't addressed if there is any merit to such construct as
  (foreach  i  (in_range 0 10 1) ....

ymg

ElpanovEvgeniy

  • Water Moccasin
  • Posts: 1569
  • Moscow (Russia)
Re: Range Function
« Reply #25 on: November 18, 2013, 06:36:27 AM »
(foreach i (in_range 0 10 1) [I do not understand what needs to be here] ....

give any example...

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Range Function
« Reply #26 on: November 18, 2013, 06:47:12 AM »
An iterative solution perhaps:
Code - Auto/Visual Lisp: [Select]
  1. (defun range ( s e i / l )
  2.     (repeat (fix (abs (/ (- e s) i)))
  3.         (setq e (- e i) l (cons e l))
  4.     )
  5. )

EDIT: spoke too soon...
Code - Auto/Visual Lisp: [Select]
  1. _$ (range 0 10 3)
  2. (1 4 7)

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Range Function
« Reply #27 on: November 18, 2013, 06:55:37 AM »
A quick fix, but not great  :-(

Code - Auto/Visual Lisp: [Select]
  1. (defun range ( s e i / l )
  2.     (if (< 0 (abs (rem e i)))
  3.         (setq e (+ e (- i (rem e i))))
  4.     )
  5.     (repeat (fix (abs (/ (- e s) i)))
  6.         (setq e (- e i) l (cons e l))
  7.     )
  8. )

ymg

  • Guest
Re: Range Function
« Reply #28 on: November 18, 2013, 07:01:45 AM »
Quote
(foreach i (in_range 0 10 1) [I do not understand what needs to be here] ....

Here is a stupid one:

Code: [Select]
(foreach i (in_range 0 10 1)
    (setq tot (+ tot i))
)

In other word we do not need to increment the index to the loop.

The python boys use it at every sauce.

ymg
« Last Edit: November 18, 2013, 07:11:10 AM by ymg »

ElpanovEvgeniy

  • Water Moccasin
  • Posts: 1569
  • Moscow (Russia)
Re: Range Function
« Reply #29 on: November 18, 2013, 09:11:00 AM »
Here is a stupid one:

Code: [Select]
(foreach i (in_range 0 10 1)
    (setq tot (+ tot i))
)

In other word we do not need to increment the index to the loop.

The python boys use it at every sauce.

ymg

Code - Auto/Visual Lisp: [Select]
  1. (defun range (s e i f)
  2.   (if (or (and (> i 0) (< s e)) (and (< i 0) (> s e)))
  3.     (progn (f s) (range (+ i s) e i f))
  4.   )
  5. )

test:  corrected  (test 0 10 1 0) >> (test 0 10 1 55)
Code - Auto/Visual Lisp: [Select]
  1. (defun test (s e i tot)
  2.    (range s e i (lambda (a) (setq tot (+ tot a))))
  3.    tot
  4. )
  5.  
  6. (test 0 10 1 0) ; >> 45
  7. (test 0 10 1 55) ; >> 100
« Last Edit: November 18, 2013, 10:47:54 AM by ElpanovEvgeniy »

ribarm

  • Gator
  • Posts: 3274
  • Marko Ribar, architect
Re: Range Function
« Reply #30 on: November 18, 2013, 10:09:40 AM »
Code - Auto/Visual Lisp: [Select]
  1. (defun range (s e i f)
  2.   (if (or (and (> i 0) (< s e)) (and (< i 0) (> s e)))
  3.     (progn (f s) (range (+ i s) e i f))
  4.   )
  5. )
  6.  
  7. (defun test (s e i / tot)
  8.   (setq tot 0)
  9.   (range s e i (lambda (a) (setq tot (+ tot a))))
  10.   tot
  11. )
  12.  
  13. (test 0 10 1) >> 45
  14. (test 0 10 1) >> 45
  15.  
« Last Edit: November 18, 2013, 10:29:22 AM by ribarm »
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

ElpanovEvgeniy

  • Water Moccasin
  • Posts: 1569
  • Moscow (Russia)
Re: Range Function
« Reply #31 on: November 18, 2013, 10:14:29 AM »
Code - Auto/Visual Lisp: [Select]
  1. (defun test (s e i a / tot)
  2.   (range s e i (lambda (a) (setq tot (+ tot a))))
  3.   tot
  4. )
  5.  
  6. (test 0 10 1 0) >> 45
  7. (test 0 10 1 0) >> 45
  8.  


 :-D
Code - Auto/Visual Lisp: [Select]
  1. (test 0 10 1 0) ; >> 45
  2. (test 0 10 1 55) ; >> 100

ribarm

  • Gator
  • Posts: 3274
  • Marko Ribar, architect
Re: Range Function
« Reply #32 on: November 18, 2013, 10:37:29 AM »
So what, little testings where I was wrong...

Code - Auto/Visual Lisp: [Select]
  1. (defun range (s e i f)
  2.   (if (or (and (> i 0) (< s e)) (and (< i 0) (> s e)))
  3.     (progn (f s) (range (+ i s) e i f))
  4.   )
  5. )
  6.  
  7. (defun test (s e i tot)
  8.   (range s e i (lambda (a) (setq tot (+ tot a))))
  9.   tot
  10. )
  11.  
  12. (test 0 10 1 0) >> 45
  13. (test 0 10 1 0) >> 45
  14. (test 0 10 1 55) >> 100
  15.  
« Last Edit: November 18, 2013, 11:18:22 AM by ribarm »
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

ElpanovEvgeniy

  • Water Moccasin
  • Posts: 1569
  • Moscow (Russia)
Re: Range Function
« Reply #33 on: November 18, 2013, 10:41:43 AM »
So what, little testings where I was wrong...

it was my bug...

ymg

  • Guest
Re: Range Function
« Reply #34 on: November 18, 2013, 11:47:08 AM »
Code - Auto/Visual Lisp: [Select]
  1. ;;  By Cab      (iterative)                                                   ;
  2. ;;                                                                            ;
  3.  
  4. (defun in_rangec (start end step / value)
  5.   (setq value (list start))
  6.   (repeat (fix (/ (- end start) step))
  7.      (setq value (cons (setq start (+ step start)) value))
  8.   )
  9.   (reverse (if (= (car value) end) (cdr value) value))
  10. )
  11. ;; By ElpanovEvgeniy       (recursive)                                        ;
  12. (defun in_range (s e i)
  13.   (if (or (and (> i 0) (< s e)) (and (< i 0) (> s e)))
  14.     (cons s (in_range (+ i s) e i))
  15.   )
  16. )
  17.  
  18.  
  19. (defun c:test ()
  20.   (setq ti (car (_vl-times)))
  21.   (repeat 5000
  22.      (setq tot 0)
  23.      (foreach i (in_range 0 10 1)
  24.         (setq tot (+ tot i))
  25.      )
  26.   )
  27.   (princ (strcat "\nRecursive in_range(): " (rtos (/ (- (car (_VL-TIMES)) ti) 1000.) 2 4) " secs"))
  28.   (princ)
  29. )
  30.  
  31. (defun c:test1 ()
  32.   (setq ti (car (_vl-times)))
  33.   (repeat 5000
  34.      (setq tot 0)
  35.      (foreach i (in_rangec 0 10 1)
  36.         (setq tot (+ tot i))
  37.      )
  38.   )
  39.   (princ (strcat "\nIterative in_range(): " (rtos (/ (- (car (_VL-TIMES)) ti) 1000.) 2 4) " secs"))
  40.   (princ)
  41. )
  42.  
  43. (defun c:test2 ()
  44.   (setq ti (car (_vl-times)))
  45.   (repeat 5000
  46.      (setq tot 0 i 0)
  47.      (repeat 9
  48.         (setq tot (+ tot (setq i (1+ i))))
  49.      )
  50.   )
  51.   (princ (strcat "\nTraditionnal Index: " (rtos (/ (- (car (_VL-TIMES)) ti) 1000.) 2 4) " secs"))
  52.   (princ)
  53. )
  54.  

Quote
_$ (c:test)
Recursive in_range(): 0.109 secs

_$ (c:test1)
Iterative inrange(): 0.109 secs

_$ (c:test2)
Traditionnal Index: 0.047 secs
_$

ribarm

  • Gator
  • Posts: 3274
  • Marko Ribar, architect
Re: Range Function
« Reply #35 on: November 18, 2013, 01:02:15 PM »
It should be almost like (c:test2)...

Code - Auto/Visual Lisp: [Select]
  1. (defun c:test3 ()
  2.  (setq ti (car (_vl-times)))
  3.  (setq n (- (length (in_range 0 10 1)) 1)) ;;; or (setq n (- (length (in_rangec 0 10 1)) 1))
  4.  (repeat 5000
  5.     (setq tot 0 i 0)
  6.     (repeat n
  7.        (setq tot (+ tot (setq i (1+ i))))
  8.     )
  9.  )
  10.  (princ (strcat "\nTraditionnal combined Index: " (rtos (/ (- (car (_VL-TIMES)) ti) 1000.) 2 4) " secs"))
  11.  (princ)
  12. )
  13.  
  14. (defun c:test4 ()
  15.  (setq ti (car (_vl-times)))
  16.  (setq l (in_range 0 10 1)) ;; or (setq l (in_rangec 0 10 1))
  17.  (repeat 5000
  18.     (setq tot 0)
  19.     (foreach i l
  20.        (setq tot (+ tot i))
  21.     )
  22.  )
  23.  (princ (strcat "\nForeach in_range(): " (rtos (/ (- (car (_VL-TIMES)) ti) 1000.) 2 4) " secs"))
  24.  (princ)
  25. )
  26.  
« Last Edit: November 18, 2013, 01:24:19 PM by ribarm »
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

ymg

  • Guest
Re: Range Function
« Reply #36 on: November 18, 2013, 09:53:16 PM »
Quote
It should be almost like (c:test2)...

Marko,

You are right test4 is more like the real situation and comes out at
exactly the same time as the traditional index.

Quote
_$ (c:test4)
Foreach in_range(): 0.047 secs

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: Range Function
« Reply #37 on: November 19, 2013, 03:49:58 AM »
@ ymg & ribarm
Benchmarking is not a 'real situation'. If you are trying to benchmark the range functions you should keep it inside the (repeat 5000 ...) loop.

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: Range Function
« Reply #38 on: November 19, 2013, 04:15:19 AM »
Code: [Select]
Benchmarking .......... elapsed milliseconds / relative timing <5000 iterations>

  (KGA_LIST_INDEXSEQMAKESTARTEND 0 100) ..... 125 / 4.62 <fastest>
  (CAB_IN_RANGE 0 100 1) .................... 235 / 2.46
  (EE_IN_RANGE 0 100 1) ..................... 578 / 1.00 <slowest>

My function (KGA_List_IndexSeqMakeStartEnd) is not a true range function, but I think the numbers confirm the effectiveness of the speed improvement method for large ranges (0-100).
For the (CAB_in_range) and (EE_in_range) functions see reply #34 by ymg.

ymg

  • Guest
Re: Range Function
« Reply #39 on: November 19, 2013, 04:56:42 AM »
Quote
@ ymg & ribarm
Benchmarking is not a 'real situation'. If you are trying to benchmark the range functions you should keep it inside the (repeat 5000 ...) loop.

roy_043,

What we are trying to assess is How it compares to a traditionnal incrementing of a separate index
in a loop.

That means that Marko's logic is right for the case at hand.

In other word using this method or the traditional one is essentially equivalent time-wise.

And yes we could use your code and maybe gain a little.

ymg

To be complete:

Code: [Select]
;; By roy_043                                                                 ;
(defun in_ranger (start end / len ret step)
  (setq step (if (< start end) -1 1))
  (repeat (rem (setq len (fix (abs (- end start)))) 8)
    (setq ret (cons (setq end (+ end step)) ret))
  )
  (repeat (/ len 8)
    (setq ret
      (vl-list*
        (+ end (* 8 step))
        (+ end (* 7 step))
        (+ end (* 6 step))
        (+ end (* 5 step))
        (+ end (* 4 step))
        (+ end (* 3 step))
        (+ end (* 2 step))
        (+ end step)
        ret
      )
    )
    (setq end (+ end (* 8 step)))
  )
  ret
)

(defun c:testr ()
 (setq ti (car (_vl-times)))
 (setq l (in_ranger 0 10)) ;; or (setq l (in_rangec 0 10 1))
 (repeat 5000
    (setq tot 0)
    (foreach i l
       (setq tot (+ tot i))
    )
 )
 (princ (strcat "\nForeach in_ranger(): " (rtos (/ (- (car (_VL-TIMES)) ti) 1000.) 2 4) " secs"))
 (princ)
)

Quote
(c:testr)
Foreach in_ranger(): 0.0470 secs
« Last Edit: November 19, 2013, 05:39:17 AM by ymg »

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Range Function
« Reply #40 on: November 19, 2013, 07:20:11 AM »
@roy: Just curious, why 8? Why not more (or less)?

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: Range Function
« Reply #41 on: November 19, 2013, 08:50:58 AM »
@roy: Just curious, why 8? Why not more (or less)?
From my test file:
Code: [Select]
;;; 20111115
;;; Conclusions:
;;; The (repeat) loop with (setq) is very time consuming.
;;; Using serial (cons) is usually slower than using (vl-list*).
;;; Using (append) is of course bad for speed.
;;; (KGA_LIST_INDEXSEQMAKELENGTH_08) has an acceptable balance between speed gain and program length.
 
; Benchmarking .......... elapsed milliseconds / relative timing <1000 iterations>

  ; (KGA_LIST_INDEXSEQMAKELENGTH_32 1000) ...... 125 / 2.88 <fastest>
  ; (KGA_LIST_INDEXSEQMAKELENGTH_16 1000) ...... 140 / 2.57
  ; (KGA_LIST_INDEXSEQMAKELENGTH_08 1000) ...... 172 / 2.09
  ; (KGA_LIST_INDEXSEQMAKELENGTH_04 1000) ...... 234 / 1.54
  ; (KGA_LIST_INDEXSEQMAKELENGTH_01 1000) ...... 360 / 1.00 <slowest>

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Range Function
« Reply #42 on: November 19, 2013, 09:55:53 AM »
Very thorough roy  :-)

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: Range Function
« Reply #43 on: November 20, 2013, 06:48:51 AM »