Multiplying large blocks of data?
what would be a good way of multiplying a block of numbers 1 - 1,000,000 by 2? test: [1 2 3...1000000] test2: [] foreach num test [append test2 num * 2] that seems to do the trick, but I'm sure there must be another way.
posted by: Andrew 17-Jun-2017/0:19:38-7:00
You can do this: t: [1 2 3 4 5 6] repeat x length? t [t/(x): t/(x) * 2]
posted by: Nick 17-Jun-2017/1:17:46-7:00
and BTW, to test it with an actually large block: t: copy [] insert/dup t 1 1000000 repeat x length? t [t/(x): t/(x) * 2]
posted by: Nick 17-Jun-2017/1:21:09-7:00
and also BTW, to create a list of numbers 1-10million, the first option below is much faster: t: copy [] repeat i 10000000 [insert tail t i] t: copy [] repeat i 10000000 [append t i]
posted by: Nick 17-Jun-2017/1:27:21-7:00
Why not use `map-each`, which is designed for it: t: [1 2 3 4 5 6] map-each i t [i * 2] Well, the times are a bit different: 0:00:11 map-each 0:00:06 foreach Andrew 0:00:04 repeat Nick
posted by: Geekyi 18-Jun-2017/8:43:48-7:00
Yes, and for 10 million+ values, for example, the delay makes a dramatic difference (seconds rather than minutes).
posted by: Nick 18-Jun-2017/9:55:56-7:00
This worked a bit faster on my PC t: copy [] insert/dup t 1 1000000 i: 1 until [t/:i: t/:i * 2 tail? t: next t]
posted by: Endo 19-Jun-2017/5:11:04-7:00
Interesting, running on a little Windows 8 tablet with Z3735G 1.33 GHz CPU and 1 GB RAM (w/ Rebol 2.7.8.3.1), my results are the opposite in every case: >> t: copy [] repeat i 10000000 [insert tail t i] == [] >> delta-time [i: 1 until [t/:i: t/:i * 2 tail? t: next t]] == 0:00:21.236 >> t: copy [] repeat i 10000000 [insert tail t i] == [] >> delta-time [repeat x length? t [t/(x): t/(x) * 2]] == 0:00:16.228 >> t: copy [] insert/dup t 1 10000000 == [] >> delta-time [i: 1 until [t/:i: t/:i * 2 tail? t: next t]] == 0:00:22.194 >> t: copy [] insert/dup t 1 10000000 == [] >> delta-time [repeat x length? t [t/(x): t/(x) * 2]] == 0:00:15.447 What system are you running Endo? I'm really curious about the difference in performance.
posted by: Nick 19-Jun-2017/8:41:57-7:00
Here's the cleaned up copy of the tests - curious to hear results on other platforms: t: copy [] repeat i 10000000 [insert tail t i] delta-time [i: 1 until [t/:i: t/:i * 2 tail? t: next t]] t: copy [] repeat i 10000000 [insert tail t i] delta-time [repeat x length? t [t/(x): t/(x) * 2]] t: copy [] insert/dup t 1 10000000 delta-time [i: 1 until [t/:i: t/:i * 2 tail? t: next t]] t: copy [] insert/dup t 1 10000000 delta-time [repeat x length? t [t/(x): t/(x) * 2]]
posted by: Nick 19-Jun-2017/8:51:20-7:00
t1 14.433255 14.375567 14.562163 t2 10.988527 10.948129 10.986415 t3 14.513004 14.739353 14.632172 t4 11.097424 10.935371 10.952677 linux 3.14.20 (i686) Inspiron 1501 tahrpup 6.0 (Puppy Linux) Mobile AMD Sempron 3500+ 800 mhz Memory: Total: 14166616 kB Free: 714000 kB Available: 101500 kB
posted by: Howard 19-Jun-2017/19:16:53-7:00
t1 18.689 18.720 18.844 t2 13.876 13.813 13.819 t3 18.454 18.532 18.610 t4 13.829 13.844 13.860 Windows 8 64bit Ausus S200E Celeron 847 1.1 Ghz 2 GB memory, 1.89 GB usable hmnnn....
posted by: Howard 19-Jun-2017/23:13:13-7:00
>> t: copy [] repeat i 10000000 [insert tail t i] == [] >> delta-time [i: 1 until [t/:i: t/:i * 2 tail? t: next t]] == 0:00:10.66 >> t: copy [] repeat i 10000000 [insert tail t i] == [] >> delta-time [repeat x length? t [t/(x): t/(x) * 2]] == 0:00:08.004 >> t: copy [] insert/dup t 1 10000000 == [] >> delta-time [i: 1 until [t/:i: t/:i * 2 tail? t: next t]] == 0:00:10.386 >> t: copy [] insert/dup t 1 10000000 == [] >> delta-time [repeat x length? t [t/(x): t/(x) * 2]] == 0:00:08.03
posted by: Nick 20-Jun-2017/23:11:17-7:00
My friend had an assignment in college for a program called MatLab. He mentioned that MatLab can multiply arrays together, like [2 3 4 5 6] * [3 4 5 6 7] to make one which is [6 12 20 30 42]. What would be an easy way to do this? R E B O L [] lol1: [2 3 4 5 6] lol2: [3 4 5 6 7] lol3: [] foreach lol lol1 [append lol3 (lol * first lol2) remove lol2]
posted by: Andrew 22-Jun-2017/19:15:21-7:00
repeat i length? lol1 [insert tail lol3 lol1/:i * lol2/:i]
posted by: Nick 23-Jun-2017/1:23:57-7:00
If you'll perform this operation often, create a function and put it in your rebol.r file: multiply-blocks: func [bl1 bl2] [ bl3: copy [] repeat i length? bl1 [insert tail bl3 bl1/:i * bl2/:i] bl3 ] multiply-blocks [2 3 4 5 6] [3 4 5 6 7] lol1: [2 3 4 5 6] lol2: [3 4 5 6 7] multiply-blocks lol1 lol2 You can choose how to handle blocks of different length, how to handle a arbitrary number of blocks, etc.: multiply-all: func [bl] [ result: copy [] lens: copy [] foreach b bl [append lens length? b] len: first minimum-of lens repeat i len [ total: 1 foreach b bl [total: total * b/:i] append result total ] result ] multiply-all [ [1 2 3 4 5 6] [2 3 4 5] [3 4 5 6 7] ]
posted by: Nick 23-Jun-2017/10:36:41-7:00
Here's the function above using 'map-each to find the shortest input block: multiply-all: func [bl] [ result: copy [] repeat i first minimum-of map-each b bl [length? b] [ total: 1 foreach b bl [total: total * b/:i] append result total ] ] multiply-all [[1 2 3 4 5 6][2 3 4 5][3 4 5 6 7]]
posted by: Nick 23-Jun-2017/10:59:03-7:00
(try that function with any number of blocks, each containing any arbitrary number of values)
posted by: Nick 23-Jun-2017/11:04:50-7:00
Could you explain what lol1/:i means, or give me a link to an explanation ?
posted by: Andrew 23-Jun-2017/16:48:45-7:00
> lol1/:i It's an equivalent to pick lol1 i. In addition, you can use the notation for assigning values too. Example with different word names: blk: copy [a b c d e f] ind: 4 blk/:ind ;; equivalent to pick blk ind == d blk/:ind: 88 ;; equivalent to poke blk ind 88 blk == [a b c 88 e f]
posted by: Sunanda 23-Jun-2017/17:00:57-7:00
Thank you so much !
posted by: Andrew 23-Jun-2017/17:13:41-7:00
Why do you do blk: copy [a b c d e f] instead of blk: [a b c d e f]?
posted by: Andrew 23-Jun-2017/17:32:30-7:00
'Copy ensures that any previous values in the block are erased.
posted by: Nick 24-Jun-2017/6:36:11-7:00
|