Jef! Posted August 3, 2018 Share Posted August 3, 2018 Note: In BricsCAD the max function does not have the 'int to float' issue Jef! has mentioned. Good to know that. Another reason to avoid using it in a situation like this one, especially for people targeting portability of their code. @Roy, as noted in my earlier posts, I avoid methods such as used in your 'PosOfMax' function as I find these unreliable when used with doubles. Roy_043 was right too, and his demonstration clearly shows that using a fuzz factor can have unpredictable result as well with floats in that situation. Even if it looks slightly less elegant, your max-idx is 3 times faster (actually the fastest) and reliable. I like my vl-sort-i approach, both fast and elegant! Here is a benchmark of only the ones that has the same output as input. Even if some might have unwanted results in some circumstances, I've included them in the comparison. pizi is pbe's version of ziele's. Elapsed milliseconds / relative speed for 32768 iteration(s): (MAX-IDX L).................2465 / 11.82 (PBEFOO L)..................2496 / 11.67 (JEFFOO L)..................2699 / 10.79 (PIZIFOO L).................6973 / 4.18 (LMFOO L)...................7285 / 4.00 (MAXNUMWITHPOSITION L).....13104 / 2.22 ; see note below (GRRRFOO L)................29125 / 1.00 Grrr grrfoo is crawling behind due to your abusive relationship towards lambdas... hahahaha ...and your maxnumwithposition is reverse (shows (value . position)) and has a side effect that I would have had if I used (car (vl-sort-i l '>)) instead of (last (vl-sort-i l ' Command: !L (5.2 8 2 1.03 8 7) Command: (JEFFOO L) (8 . 1) Command: (MAX-IDX L) (8 . 1) Command: (GRRRFOO L) (8 . 1) Command: (PBEFOO L) (8 . 1) (MAXNUMWITHPOSITION L) (4 . A lot can be learned in this topic. This topic is fun Special thanks to Lee and Roy_043 for the academic value of your replies. Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted August 3, 2018 Share Posted August 3, 2018 OK, so the min and max functions in AutoCAD have this unexpected behavior (as Jef! already mentioned). But for a list containing only doubles or only integers PosOfMax would work just fine. Or is there also some AutoCAD issue with vl-position? _$ (setq l (list pi 4)) (3.14159 4) _$ (vl-position (apply 'max l) l) nil Quote Link to comment Share on other sites More sharing options...
Grrr Posted August 3, 2018 Share Posted August 3, 2018 Grrr grrfoo is crawling behind due to your abusive relationship towards lambdas... hahahaha That was the first subfoo in my mind that blinked for a solution, but in the end I'd prefer your suggestion with vl-sort-i ...and your maxnumwithposition is reverse (shows (value . position)) shouldn't be a big deal.. just change (if num (cons idx num)) to (if num (cons num idx)) and has a side effect that I would have had if I used (car (vl-sort-i l '>)) instead of (last (vl-sort-i l ' Didn't concider duplicate value(s), if the first max was required - I'd just probably reverse the input list for the MaxNumWithPosition But I wrote it for fun, it should be the slowest due alot of reasons, such as redefining 'fixif' subfoo on every item processing. If talking about speed, how about: (defun fmax ( L / n i m ) (setq n (car L) i 0 m 0) (foreach x (cdr L) (setq i (1+ i)) (or (> n x) (setq n x m i)) ) (cons m n) ) Quote Link to comment Share on other sites More sharing options...
Roy_043 Posted August 3, 2018 Share Posted August 3, 2018 @Lee: You have misread my previous message. OK, so the min and max functions in AutoCAD have this unexpected behavior (as Jef! already mentioned). But for a list containing only doubles or only integers PosOfMax would work just fine. Or is there also some AutoCAD issue with vl-position? Quote Link to comment Share on other sites More sharing options...
Jef! Posted August 3, 2018 Share Posted August 3, 2018 On one hand, one cannot arbitrarily check using a fuzz because 2 values can have a difference of the said fuzz, and also "hardcoding" a fuzz value will have unpredictable results as the minimum fuzz will differ depending on the value of the checked double. Also, the problem is not with vl-position (or member) per se. The problem is with the combination of Max&vl-position, or Max&member. The guilty party here is Max. As a proof pBe's example returns the correct value because he relies on vl-sort rather than max. (defun pbefoo ( l / m) (cons (Setq m (car (vl-sort l '>))) (vl-position m l) ) ) Whenever reals or a combination of reals and integers are manipulated, by using functions such as member or vl-position have to be used with a lot of caution, and the user have to be on the lookout for any other functions such as min/max (is there any other?) that modify/ might modify the nature of the data being manipulated. It might not be a bad idea to remain on the safe side... I did more benchmarks keeping only the functions that returned the same format and the correct value using a list with 2 occurrences of the highest value, preceded by the highest minus the smallest fuzz possible distinguishable for the max value which here is 8. (= 8 (- 8 4.44e-16)) returns T (= 8 (- 8 4.45e-16)) returns nil, so I used (setq l (list 5.2 (- 8 4.45e-16) 8 2 1.03 8 7)) which returns (5.2 8.0 8 2 1.03 8 7). Elapsed milliseconds / relative speed for 32768 iteration(s): (PBEFOO L)......1513 / 2.73 (MAX-IDX L).....1528 / 2.71 (JEFFOO L)......1763 / 2.34 (PIZIFOO L).....4134 / 1.00 Elapsed milliseconds / relative speed for 32768 iteration(s): (MAX-IDX L).....1732 / 2.74 (PBEFOO L)......1763 / 2.69 (JEFFOO L)......1981 / 2.39 (PIZIFOO L).....4743 / 1.00 Foo made by pBe and max-idx by LM are pretty alike speed-wise, max-idx seems to be fastest most of the time. Didn't concider duplicate value(s), if the first max was required - I'd just probably reverse the input list for the MaxNumWithPosition fot the (cons idx num) > (cons num idx)You are right. For the other point, still no joy. A list of (5 5 0 0 0 0) needs to return pos 0. Yours returned pos 1. If you just reverse the input list, you end up pointing from the end, which would be pos 4 here! If talking about speed, how about:(defun fmax Speed wise it is good! Elapsed milliseconds / relative speed for 32768 iteration(s): (FMAX L)........1326 / 1.19 (PBEFOO L)......1357 / 1.16 (MAX-IDX L).....1357 / 1.16 (JEFFOO L)......1575 / 1.00 Ah. Here, exactly what I meant Grrrfoo: (8 . 2)pbefoo: (8 . 2) pizifoo: (8 . 2) jeffoo: (8 . 2) Max-idx: (8 . 2) fmax: (5 . 8 ) hahaha. Let's benchmark the following. Who can grab a cold one faster... Have a nice week end guys Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.