Home   Archive   Permalink



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