Nooby question : multidimensional arrays.

L

Larry Evans

Is this an okay job of implementing a multidimensional array?

https://github.com/kedarmhaswade/datacube/blob/master/data_cube.rb

Thank you for any feedback.

-Kedar
There's a book:

http://web.engr.oregonstate.edu/~budd/Books/aplc/

which describes an expansion vector which is a scan of
the array sizes. IOW, for:

arr = Array.new(s0,s1,...sn)

the expansion vector for this arr is:

arr.ev = [1, s0, s0*s1, s0*s1*s3,..., s0*s1*...*sn]
The expansion vector for DataCube.new(n,m) would be:

[m**0,m**1,m**2,...,m**n]

IOW, the length of this expansion vector is n+1.

[snip]
arr[i0,i1,..., ij, ... in]

is located:

i0*arr.ev[0]+i1*arr.ev[1]+...+in*arr.ev[n]

elements from the 1st element:

arr[0,0,...,0]

Thus, given the sizes, you can create a member variable
which is the expansion vector, then use that to access the
elements by calculating the offset from the initial element
using the dot product:

i0*arr.ev[0]+i1*arr.ev[1]+...+in*arr.ev[n]
However, after looking at:

https://github.com/kedarmhaswade/datacube/blob/master/data_cube.rb#L48

it's not clear that to_index calculates the same offset because
coefficients corresponds to one of the i0,i1,...,in-1 in the
above formulat, and coefficients is not multiplied by anything.
It's only added to mega_index*n, and mega_index*n involves
multiplication by the dimension, n, instead of ths uniform size, m.


HTH

-Larry
 
K

Kedar Mhaswade

Larry,

Thanks for references and detailed review. I will go over them to
understand them better. Just to reiterate, my implementation is pretty
rudimentary at this point and more importantly, it caters for the cases
where the number of elements in *every dimension* is assumed to be the
same (IOW, you can't simply represent a 2x3 matrix is it).

-Kedar
 
R

Robert Klemme

Thanks for references and detailed review. I will go over them to
understand them better. Just to reiterate, my implementation is pretty
rudimentary at this point and more importantly, it caters for the cases
where the number of elements in *every dimension* is assumed to be the
same (IOW, you can't simply represent a 2x3 matrix is it).

If you need that you could do something like https://gist.github.com/772827

Cheers

robert
 
K

Kedar Mhaswade

If you need that you could do something like

Interesting. Thanks, Robert.
But using hash internally to represent arrays is slightly
counterintuitive. But I agree, it will work well for "sparse"
multi-dimensional arrays. I realize that I could do something similar
and still retain the one-dimensional flattening, in my implementation.
And yes, expanding it to do non-cube entities is on my list.

-Kedar
 
R

Robert Klemme

Interesting. Thanks, Robert.
But using hash internally to represent arrays is slightly
counterintuitive.

Well, you don't see it from the outside. For users of the class it
doesn't really matter how it internally works (unless they hit some
limitations).
But I agree, it will work well for "sparse"
multi-dimensional arrays.

Exactly that was the use case I had in mind.
I realize that I could do something similar
and still retain the one-dimensional flattening, in my implementation.

How exactly do you want to do that?
And yes, expanding it to do non-cube entities is on my list.

:) Actually "cube" is just a special case of the more general one.
I'd rather implement the special case and add a custom constructor for
the cube case:

https://gist.github.com/772827

Cheers

robert
 
L

Larry Evans

On 01/10/11 08:33, Robert Klemme wrote:
[snip]
If you need that you could do something like https://gist.github.com/772827
[snip]
Are you using a ruby newer than 1.8.7. I'm getting an error as shown here:

~/prog_dev/ruby/gist772827-61376303a967918b698bc0ddb50af26d6368438c $
ruby mda.rb
mda.rb:20: syntax error, unexpected tIDENTIFIER, expecting tAMPER or '&'
def []=(*idx, val)
^
mda.rb:41: syntax error, unexpected kEND, expecting $end
~/prog_dev/ruby/gist772827-61376303a967918b698bc0ddb50af26d6368438c $
ruby -v
ruby 1.8.7 (2010-01-10 patchlevel 249) [x86_64-linux]
 
K

Kedar Mhaswade

Robert Klemme wrote in post #973678:
Well, you don't see it from the outside. For users of the class it
doesn't really matter how it internally works (unless they hit some
limitations).

I meant for a programmer to implement it. And yes, it is a damn good
idea.
Exactly that was the use case I had in mind.


How exactly do you want to do that?

Grrr. I was not thinking enough. I could make the current implementation
better in that I can lazily expand the array which will fill the
intervening elements with nil's but yeah, it's nowhere near the fast
lookup of hashtables.
 
R

Robert Klemme

On 01/10/11 08:33, Robert Klemme wrote:
[snip]
If you need that you could do something like https://gist.github.com/772= 827
[snip]
Are you using a ruby newer than 1.8.7. I'm getting an error as shown here= :

~/prog_dev/ruby/gist772827-61376303a967918b698bc0ddb50af26d6368438c $
ruby mda.rb
mda.rb:20: syntax error, unexpected tIDENTIFIER, expecting tAMPER or '&'
=A0def []=3D(*idx, val)
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ^
mda.rb:41: syntax error, unexpected kEND, expecting $end
~/prog_dev/ruby/gist772827-61376303a967918b698bc0ddb50af26d6368438c $
ruby -v
ruby 1.8.7 (2010-01-10 patchlevel 249) [x86_64-linux]

Yes, you need 1.9ish Ruby for this to work. Reason is that 1.9 has
extended pattern matching. With 1.8 you need to do it yourself:

09:14:49 ~$ irb
Ruby version 1.8.7
irb(main):001:0> class X
irb(main):002:1> def []=3D(*a)
irb(main):003:2> v =3D a.pop
irb(main):004:2> p a, v
irb(main):005:2> end
irb(main):006:1> end
=3D> nil
irb(main):007:0> X.new[1,2,3]=3D4
[1, 2, 3]
4
=3D> 4
irb(main):008:0>

Sorry for not mentioning it.

Kind regards

robert


--=20
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
 
L

Larry Evans

Larry,

Thanks for references and detailed review. I will go over them to
understand them better. Just to reiterate, my implementation is pretty
rudimentary at this point and more importantly, it caters for the cases
where the number of elements in *every dimension* is assumed to be the
same (IOW, you can't simply represent a 2x3 matrix is it).

-Kedar
Kadar,

I was looking through my computers ruby packages and found one:

libnarray-ruby1.9.1

claiming it:

has numerical n-dimensional array class

Googling found:

https://github.com/princelab/narray/wiki/Tentative-NArray-Tutorial

So, I tried it and, it works:

/home/evansl/prog_dev/ruby $ irb1.9.1
irb(main):001:0> require 'narray'
=> true
irb(main):002:0> a = NArray.int(2,3,4)
=> NArray.int(2,3,4):
[ [ [ 0, 0 ],
[ 0, 0 ],
[ 0, 0 ] ],
[ [ 0, 0 ],
[ 0, 0 ],
[ 0, 0 ] ],
[ [ 0, 0 ],
[ 0, 0 ],
[ 0, 0 ] ],
[ [ 0, 0 ],
...
irb(main):003:0>

HTH.

-Larry
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,143
Latest member
SterlingLa
Top