Forum: Ruby Nooby question : multidimensional arrays.

5744873599d8e8c52731468da38e52b9?d=identicon&s=25 marinho.tobolla@syncity.de (Guest)
on 2006-08-16 11:37
(Received via mailing list)
Well am I right, that in Ruby there are only one dimensional arrays, and
that i have to add an array into an array to get multidimensional
arrays, or is there a simpler more ruby like way to create them ?
2630db3069f8c7d8445567fafe36b0e7?d=identicon&s=25 Chris Gehlker (Guest)
on 2006-08-16 12:52
(Received via mailing list)
On Aug 16, 2006, at 2:37 AM, marinho.tobolla@syncity.de wrote:

> Well am I right, that in Ruby there are only one dimensional
> arrays, and that i have to add an array into an array to get
> multidimensional arrays, or is there a simpler more ruby like way
> to create them ?

Yep. You create them by just making arrays of arrays and you
reference them just like C arrays
irb(main):001:0> ary = []
=> []
irb(main):002:0> ary << [1, 2, 3] << %w{dog cat bird} << [8, 10, 17]
=> [[1, 2, 3], ["dog", "cat", "bird"], [8, 10, 17]]
irb(main):003:0> ary[1][2]
=> "bird"


--
The folly of mistaking a paradox for a discovery, a metaphor for a
proof, a torrent of verbiage for a spring of capital truths, and
oneself for an oracle, is inborn in us.
-Paul Valery, poet and philosopher (1871-1945)
Cf6d0868b2b4c69bac3e6f265a32b6a7?d=identicon&s=25 Daniel Martin (Guest)
on 2006-08-16 14:11
(Received via mailing list)
"marinho.tobolla@syncity.de" <marinho.tobolla@syncity.de> writes:

> Well am I right, that in Ruby there are only one dimensional arrays,
> and that i have to add an array into an array to get
> multidimensional arrays, or is there a simpler more ruby like way to
> create them ?

Well, there's also the block that Array.new takes to give its initial
value:

a = Array.new(8) {Array.new(8) {0}}

This creates an 8 by 8 two-dimensional array initialized with all 0.

(Technically, you don't need that second block and could do the inner
bit as Array.new(8,0))
B81659fa35f4cf2da37bca8664ffc7d0?d=identicon&s=25 Craig Kim (Guest)
on 2006-08-16 14:11
(Received via mailing list)
One would have to think in Ruby. For a C programmer, it can be a hard
transition but once one gets used to the Ruby way, you will find the C
way
bit inflexible and rigid. For example, in C, you might write:

#define NUM_COLS 20
#define NUM_ROWS 10
int ary[NUM_ROWS][NUM_COLS];
...
int i, j;
for (i = 0; i < NUM_ROWS; i++) {
    for (j = 0; i < NUM_COLS; j++) {
        ary[i][j] = some_code....
   }
}

In Ruby, you don't need to worry about setting up iterator variables
since
arrays know how to iterate themselves, e.g.

ary.each {|r|
    r.each {|c|
        ...
    }
}

If you need to access a specific element, you can still use the C-like
notation, i.e. ary[r][c].


----- Original Message -----
From: "Chris Gehlker" <canyonrat@mac.com>
4299e35bacef054df40583da2d51edea?d=identicon&s=25 James Gray (bbazzarrakk)
on 2006-08-16 15:11
(Received via mailing list)
On Aug 16, 2006, at 4:37 AM, marinho.tobolla@syncity.de wrote:

> Well am I right, that in Ruby there are only one dimensional
> arrays, and that i have to add an array into an array to get
> multidimensional arrays, or is there a simpler more ruby like way
> to create them ?

Others have given you great answers, but it's also worth pointing out
that you can make a multidimensional Array, if you like:

 >> class Array2D
 >>   def initialize(width, height)
 >>     @data = Array.new(width) { Array.new(height) }
 >>   end
 >>   def [](x, y)
 >>     @data[x][y]
 >>   end
 >>   def []=(x, y, value)
 >>     @data[x][y] = value
 >>   end
 >> end
=> nil
 >> arr = Array2D.new(3, 2)
=> #<Array2D:0x31d0b0 @data=[[nil, nil], [nil, nil], [nil, nil]]>
 >> arr[1, 1] = "Hello"
=> "Hello"
 >> arr
=> #<Array2D:0x31d0b0 @data=[[nil, nil], [nil, "Hello"], [nil, nil]]>
 >> arr[1, 1]
=> "Hello"

James Edward Gray II
430ea1cba106cc65b7687d66e9df4f06?d=identicon&s=25 David Vallner (Guest)
on 2006-08-17 16:29
(Received via mailing list)
On Wed, 2006-08-16 at 18:37 +0900, marinho.tobolla@syncity.de wrote:
> Well am I right, that in Ruby there are only one dimensional arrays, and that i have to 
add an array into an array to get multidimensional arrays, or is there a simpler more ruby 
like way to create them ?

Or, if you need a speed burst, NArray [http://narray.rubyforge.org/]
could help. Never used it myself yet though.

David Vallner
Eb6513063ed2380cb6f561d295d925e9?d=identicon&s=25 b1_ __ (b1_)
on 2009-09-12 06:06
01 class Array2D
02
03   def initialize(width, height)
04   @data = Array.new(width) { Array.new(height) }
05   end
06
07  def [](x, y)
08    @data[x][y]
09  end
10
11  def []=(x, y, value)
12    @data[x][y] = value
13  end
14
15 end

Can someone explain what's going on in this code for a newbie.

I'm getting lost in the looping logic of the second def; and the 3rd def
I'm guessing has something do do with hashes?

I'm using this code in a simple 2d array. It was working but then I
changed all of my ranges from (0...value) to (1..value) [I used ranges
to populate my 2D array with hashes] I now get the error message:

11:in `[]=': undefined method `[]=' for nil:NilClass (NoMethodError)
E066a7a97381665935273b2471fc9bc6?d=identicon&s=25 Simon Hicks (Guest)
on 2009-09-12 06:51
(Received via mailing list)
The first method simply creates an Array of size width and places an
Array of size height in each index, so

Array.new(2){Array.new(3)}
=>  [ [ nil , nil , nil ] , [ nil , nil , nil] ]

The second method is merely a way of accessing a coordinate within the
2d array, so for
a = Array2D.new 2, 2
a[0,1]

it would first find @data[0]  which would return the object in index 0
which is an array [ nil, nil ] and then @data[0][1] would return the
object in index 1 of the sub-array which in this case is nil. In fact
the logic here is no more complex than the logic for a simple Array...
it only looks more complex, because we are using the same method
twice... perhaps it'd help to think about it like this

def [](x, y)
   sub_array = @data[x]
   return sub_array[y]
end

The third def is exactly the same as the second def, except instead of
simply looking to see what's stored at a coordinate, you're changing
the object that's stored at that coordinate. Again the logic is the
same as with simple arrays, except the object in each index is also an
array.

I don't know exactly what's causing the error you're seeing, but it
looks like you're calling [x,y]= using a value of x that is higher
than the maximum index in the outer array, so instead of returning a
sub_array it returns nil, and then tries to call [y]= on nil...

hth...
46ec10622045f5671a1067865566f13c?d=identicon&s=25 Ben Giddings (Guest)
on 2009-09-12 07:00
(Received via mailing list)
On Sep 12, 2009, at 00:06, Shawn W_ wrote:
> 04   @data = Array.new(width) { Array.new(height) }

Create an Array named @data initially with 'width' rows.  Set the
value of each element of the array to a new array with 'height' rows.

If 'width' is 3 and 'height' is 2, @data initially looks like:

[[nil, nil], [nil, nil], [nil, nil]]


> 07  def [](x, y)
> 08    @data[x][y]
> 09  end

Create a method to access the elements like so:

obj[2,0] returns the value of @data[2][0] (here it would be nil)

> 11  def []=(x, y, value)
> 12    @data[x][y] = value
> 13  end

Create a method to set the values:

obj[1,1] = 4 assigns 5 to the array element at of @data[1][1]

After which, @data would look like:

[[nil, nil], [nil, 5], [nil, nil]]


I'm not sure what looping logic you're talking about.  There are no
loops here, nor any hashes.  Array access syntax looks the same as
hashes.  If you think there are hashes because of the block braces
{ }, it's an unfortunate thing that they share the same syntax, but
generally whether it's a block or an array is pretty clear from the
context.

Basically all that's going on is that this class is creating a way of
doing 2d arrays with a subscript that looks like [x, y], and hiding
the fact that the underlying implementation is actually a 1
dimensional array containing at each element another one-dimensional
array.

> I'm using this code in a simple 2d array. It was working but then I
> changed all of my ranges from (0...value) to (1..value) [I used ranges
> to populate my 2D array with hashes] I now get the error message:


What's probably happening is that you're going beyond the initial size
of the array (width, height).  If your array is 2 by 3 and you try to
do:

x[10, 20] = 5

Internally it tries to do @data[10][20] = 5.  @data[10] is past the
end of the array, so its value is nil, so @data[10][20] = 5 becomes
nil[20] = 5.

Giving the error message:

11:in `[]=': undefined method `[]=' for nil:NilClass (NoMethodError)

You could probably fix that by changing the []= method to something
like:

def []=(x, y, value)
   # If @data[x] is nil, create it as an empty array
   @data[x] ||= Array.new
   @data[x][y] = value
end

If you do that, you should also fix [] to create missing values too:

def [](x, y)
   # If @data[x] is nil, create it as an empty array
   @data[x] ||= Array.new
   @data[x][y]
end

Ben
Eb6513063ed2380cb6f561d295d925e9?d=identicon&s=25 b1_ __ (b1_)
on 2009-09-12 13:28
Ben Giddings wrote:
> On Sep 12, 2009, at 00:06, Shawn W_ wrote:
>> 04   @data = Array.new(width) { Array.new(height) }
>
> Create an Array named @data initially with 'width' rows.  Set the
> value of each element of the array to a new array with 'height' rows.
>
> If 'width' is 3 and 'height' is 2, @data initially looks like:
>
> [[nil, nil], [nil, nil], [nil, nil]]

I have no problem understanding this bit. An instance variable has been
created called "data". The value of this variable is unique for each
object created in this class. This variable is equal to an array inside
an array; the {} are used to pass the Array.new(height) into each part
of the Array.new(width).

>
>> 07  def [](x, y)
>> 08    @data[x][y]
>> 09  end
>
> Create a method to access the elements like so:
>
> obj[2,0] returns the value of @data[2][0] (here it would be nil)

I understand what this is doing but not how it works. As far as I can
see it's creating a class Array2D method named [], with parameters x and
y. So when you call this method it should look like:

2D_array_obj = Array2D.new(3,8)
puts 2D_array_obj.[](1,1) <-- should put whatever is in row 1, column 1.
puts 2D_array_obj[1,1] <-- but this is what works to display row 1,
column 1.

How can you name a method [] when such syntax is used so often
elsewhere? How do those 1's get inside the square brackets?

Then there is the line:
>> 08    @data[x][y]
Which is actually:
>> 08    a 2D array [x][y]
Is the [][] syntax a way of accessing an array inside an array normally?
I know you can access a hash inside array using this method. I am even
using such code to substitute values into a hash inside my Array2D
object like so:
2D_array_obj[x,y]["hash_key"] = new value

>
>> 11  def []=(x, y, value)
>> 12    @data[x][y] = value
>> 13  end
>
> Create a method to set the values:
>
> obj[1,1] = 4 assigns 5 to the array element at of @data[1][1]
>
> After which, @data would look like:
>
> [[nil, nil], [nil, 5], [nil, nil]]

I assume "obj[1,1] = 4 assigns 5..." is a typo and should be "obj[1,1] =
5 assigns 5..."?

Here we have a different syntax with []= being used. Is []= the name of
the method? Now you've explained it I know what this is doing but it's
still not clear how it works.
>
>
> I'm not sure what looping logic you're talking about.  There are no
> loops here, nor any hashes.  Array access syntax looks the same as
> hashes.  If you think there are hashes because of the block braces
> { }, it's an unfortunate thing that they share the same syntax, but
> generally whether it's a block or an array is pretty clear from the
> context.

I thought because of the [][] that it was accessing a hash. Isn't this
how you access a hash inside an array?


>> I'm using this code in a simple 2d array. It was working but then I
>> changed all of my ranges from (0...value) to (1..value) [I used ranges
>> to populate my 2D array with hashes] I now get the error message:
>
>
> What's probably happening is that you're going beyond the initial size
> of the array (width, height).  If your array is 2 by 3 and you try to
> do:
>
> x[10, 20] = 5
>
> Internally it tries to do @data[10][20] = 5.  @data[10] is past the
> end of the array, so its value is nil, so @data[10][20] = 5 becomes
> nil[20] = 5.
>
> Giving the error message:
>
> 11:in `[]=': undefined method `[]=' for nil:NilClass (NoMethodError)
>
> You could probably fix that by changing the []= method to something
> like:
>
> def []=(x, y, value)
>    # If @data[x] is nil, create it as an empty array
>    @data[x] ||= Array.new
>    @data[x][y] = value
> end
>
> If you do that, you should also fix [] to create missing values too:
>
> def [](x, y)
>    # If @data[x] is nil, create it as an empty array
>    @data[x] ||= Array.new
>    @data[x][y]
> end

I think I know what's going wrong. The size of the array hasn't changed,
but where I start entering values into the array has, which means
there's no room for the last row and column. Basically what I've done is
change (0...5), which is 0 1 2 3 4, to (1..5), which is 1 2 3 4 5 - both
the same size. But when I use this new range to iterate through my array
the first position addressed is now 1; so I'm trying to fit 5 units into
a 5 unit box without filling up the space in the box allocated to unit
1.
Eb6513063ed2380cb6f561d295d925e9?d=identicon&s=25 b1_ __ (b1_)
on 2009-09-12 13:34
A better way to put it:

was:
[0,1,2,3,4]

now:
[nil,1,2,3,4]5
F53b05cdbdf561cfe141f69b421244f3?d=identicon&s=25 David A. Black (Guest)
on 2009-09-12 13:40
(Received via mailing list)
Hi --

On Sat, 12 Sep 2009, Shawn W_ wrote:

>
>>
> puts 2D_array_obj[1,1] <-- but this is what works to display row 1,
> column 1.
>
> How can you name a method [] when such syntax is used so often
> elsewhere? How do those 1's get inside the square brackets?

You can name it [] because the parser knows what it means in a given
context. This:

   identifier[]

always means the [] method.

As for the 1's inside the brackets: that's syntactic sugar. When Ruby
sees this:

   x[y]

it automatically converts it to:

   x.[](y)

> Then there is the line:
>>> 08    @data[x][y]
> Which is actually:
>>> 08    a 2D array [x][y]
> Is the [][] syntax a way of accessing an array inside an array normally?

It really means this:

   @data.[](x).[](y)

In other words, it's calling the [] method first on @data, then on the
return value of @data[x].

>> Create a method to set the values:
> Here we have a different syntax with []= being used. Is []= the name of
> the method? Now you've explained it I know what this is doing but it's
> still not clear how it works.

Yes, []= is the name of the method.

> I thought because of the [][] that it was accessing a hash. Isn't this
> how you access a hash inside an array?

It's all about method calls. [][] by itself doesn't mean array or hash
or any other class of object. If you do this:

   x[y][z]

then you're calling the [] method on x, with the argument y -- which
can return an array, a hash, a string, a Person instance, anything at
all -- and then you're calling [] on whatever you got back, with the
argument z.


David
D7e150e675abb80df7659fe14e7ac0a0?d=identicon&s=25 Kedar Mhaswade (kedarmhaswade)
on 2011-01-08 00:56
Is this an okay job of implementing a multidimensional array?

https://github.com/kedarmhaswade/datacube/blob/mas...

Thank you for any feedback.

-Kedar
70e4d6be1fe97f8ef830802933d616aa?d=identicon&s=25 .serialhex .. (serialhex)
on 2011-01-08 01:55
(Received via mailing list)
uhm...i'm not sure what your trying to do with this, but what if i
wanted to
get the 5th element in the 4th dimension?

i'd write the generator method something like this:

while i < @n
j = 0
while j < @m
@array[[i]] << 0
j += 1
end
i += 1
end

(i havnt tested it, so it may not work)

then you'd need to define the other accessor methods & such...  but
thats a
start

hex
D7e150e675abb80df7659fe14e7ac0a0?d=identicon&s=25 Kedar Mhaswade (kedarmhaswade)
on 2011-01-08 02:00
Thanks for the feedback!

I simply thought it would be nice if you can address elements simply as:
A[i, j, k ...]

> uhm...i'm not sure what your trying to do with this, but what if i
> wanted to
> get the 5th element in the 4th dimension?

Wouldn't that simply be dc[0,0,0,5]?

>
> i'd write the generator method something like this:
>
> while i < @n
> j = 0
> while j < @m
> @array[[i]] << 0
> j += 1
> end
> i += 1
> end
>
> (i havnt tested it, so it may not work)
>
> then you'd need to define the other accessor methods & such...  but
> thats a
> start
>
> hex
70e4d6be1fe97f8ef830802933d616aa?d=identicon&s=25 .serialhex .. (serialhex)
on 2011-01-08 02:27
(Received via mailing list)
Thanks for the feedback!
>

np

>
> I simply thought it would be nice if you can address elements simply as:
> A[i, j, k ...]
>

true, it'd be nice but it kinda wont work... (see next)


>
> > uhm...i'm not sure what your trying to do with this, but what if i
> > wanted to
> > get the 5th element in the 4th dimension?
>
> Wouldn't that simply be dc[0,0,0,5]?
>

no, that wont work.  try your code in irb, with your 3x5 data cube...

irb(main):055:0* dc = DataCube.new(3, 5)
=> [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0,
0, 0]
irb(main):056:0> dc[0,1,2]=44
=> 44
irb(main):057:0> puts dc[0, 1, 2]
44
=> nil
irb(main):058:0> puts dc.size
125
=> nil
irb(main):059:0> dc
=> [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0,
0]

thats the actual representation of the data cube in your computer.  i'm
not
sure that's exactly what you want, but it dosnt really look right to me.

i dunno, mabye you are right and this is just a funky way to do this,
i'll
take a longer look a little later, but now PIZZA!!

hex


(yes, pizza is more important than you :P)
70e4d6be1fe97f8ef830802933d616aa?d=identicon&s=25 .serialhex .. (serialhex)
on 2011-01-08 03:47
(Received via mailing list)
alright, so i've played around with it a bit more, and i kind of like
your
implementation... though if your trying to do what i think you are there
are
a few bugs in the implementation you should fix.

from what i can see you want someone to be able to use a call like:
dc[0,1]
and get the second element of the second dimension of the data cube
right?
 i think it's kinda cool, but the way it's currently implemented calling
dc[3] does the same thing.  in fact, check out this little irb session i
just did:

irb(main):100:0> dc = DataCube.new(1, 1)
=> [0]
irb(main):101:0> dc[1,1]=1
=> 1
irb(main):102:0> dc
=> [0, nil, nil, 1]
irb(main):103:0> dc[1,0]=2
=> 2
irb(main):104:0> dc
=> [0, 2, nil, 1]
irb(main):105:0> dc[3]=7
=> 7
irb(main):106:0> dc
=> [0, 2, nil, 7]

i dont think that's the behavior you want.  that aside, if you can get
it
working the way you want it to i think it'd be a pretty cool way to
access
everything.

though how would i get all the elements in dimension 3?  reading up on
data
cubes real quick one may want to do that... but overall it looks good
and
your implementation - though to my best knowledge unorthodox - will
probably
work fine if done right.

hex

(oh, and pizza rox sox!!)
D7e150e675abb80df7659fe14e7ac0a0?d=identicon&s=25 Kedar Mhaswade (kedarmhaswade)
on 2011-01-08 04:16
Thank you for your feedback, again!

I simply started with flattening out the elements into a one-dimensional
array internally (which is quite obvious). I am not sure about its
applications yet. Also, dc[3] does not make sense for this
implementation, unless the DataCube itself is one-dimensional (in which
case it just degenerates to normal array).

So, if you have p dimensions, then the array has to be accessed (or
indexed) using an index like: [x, y, z, ...] where the length of this
array itself is p.

That said, I haven't yet considering "expanding the array" dynamically.
It's like, you fix the # and size of dimensions upfront and freeze them.
I will address that officially, as you suggest.

I will admit, I haven't checked the current literature of Data Cube when
implementing it. Maybe I should do that.

My modest expectation was that to address a point in multidimensional
space A[d1,d2,d3 ... dn] was a more natural notation than
A[d1][d2][d3]...[dn], because the former is how we would represent it on
paper. And Ruby's flexibility allowed me to do just that!

Regards,
Kedar
588f37a40705b449b92d7705a9c7be18?d=identicon&s=25 Larry Evans (Guest)
on 2011-01-08 05:01
(Received via mailing list)
On 01/07/11 17:56, Kedar Mhaswade wrote:
> Is this an okay job of implementing a multidimensional array?
>
> https://github.com/kedarmhaswade/datacube/blob/mas...
>
> 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 i-th element of arr.ev is the distance between successive
elements in the i-th dimension.  IOW:

  the locatoin of:
    arr[i0,i1,..., ij, ... in]
  is located arr.ev[j] elements from:
    arr[i0,i1,..., ij+1, ... in]

IOW:

    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]

HTH.

Good luck.
588f37a40705b449b92d7705a9c7be18?d=identicon&s=25 Larry Evans (Guest)
on 2011-01-08 15:40
(Received via mailing list)
On 01/07/11 21:57, Larry Evans wrote:
[snip]
> 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]
>

Also, if you're interested in transposing the vector,
IIRC, that just invovles permuting the expansion vector.
IOW, if the original expansion vector was:

  evo = [e1,e2,e3,...,en-1,en]

then simply reversing it:

  evt = [en,en-1,....,e3,e2,e1]

and using the same vector of values for elements,
would result in a transposed array.  I guess you
could try that for just 2 dimensional array
to see if that works.

  -Larry
588f37a40705b449b92d7705a9c7be18?d=identicon&s=25 Larry Evans (Guest)
on 2011-01-08 20:36
(Received via mailing list)
On 01/07/11 21:57, Larry Evans wrote:
>
>
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]
>
> 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/mas...

it's not clear that to_index calculates the same offset because
coefficients[i] corresponds to one of the i0,i1,...,in-1 in the
above formulat, and coefficients[i] 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
588f37a40705b449b92d7705a9c7be18?d=identicon&s=25 Larry Evans (Guest)
on 2011-01-10 06:11
(Received via mailing list)
Attachment: ArrayEv.rb (2 KB)
On 01/08/11 13:33, Larry Evans wrote:
>> There's a book:
>>   arr.ev = [1, s0, s0*s1, s0*s1*s3,..., s0*s1*...*sn]
>>
>> 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]
>>
[snip]

To illustrate, the attached produces output:

44
12
[0,0,0]
0
[1,0,0]
1
[0,1,0]
2
[1,1,0]
3
[1,1,2]
11
[ [ [0, 1]
  , [2, 3]
  ]
, [ [4, 5]
  , [6, 7]
  ]
, [ [8, 9]
  , [44, 11]
  ]
]

The last several lines (starting with [ [ [)
show the output to the to_s and were designed
to show (hopefully) the nested subarray's.

-regards,
Larry
D7e150e675abb80df7659fe14e7ac0a0?d=identicon&s=25 Kedar Mhaswade (kedarmhaswade)
on 2011-01-10 14:03
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
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (Guest)
on 2011-01-10 15:36
(Received via mailing list)
On Mon, Jan 10, 2011 at 2:06 PM, Kedar Mhaswade
<kedar.mhaswade@gmail.com> wrote:
> 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
D7e150e675abb80df7659fe14e7ac0a0?d=identicon&s=25 Kedar Mhaswade (kedarmhaswade)
on 2011-01-10 16:14
> If you need that you could do something like
> https://gist.github.com/772827
>
> Cheers
>
> robert

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
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (Guest)
on 2011-01-10 17:05
(Received via mailing list)
On Mon, Jan 10, 2011 at 4:14 PM, Kedar Mhaswade
<kedar.mhaswade@gmail.com> wrote:
>> If you need that you could do something like
>> https://gist.github.com/772827

> 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
588f37a40705b449b92d7705a9c7be18?d=identicon&s=25 Larry Evans (Guest)
on 2011-01-10 21:17
(Received via mailing list)
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]
D7e150e675abb80df7659fe14e7ac0a0?d=identicon&s=25 Kedar Mhaswade (kedarmhaswade)
on 2011-01-10 21:27
Robert Klemme wrote in post #973678:
> On Mon, Jan 10, 2011 at 4:14 PM, Kedar Mhaswade
> <kedar.mhaswade@gmail.com> wrote:
>>> If you need that you could do something like
>>> https://gist.github.com/772827
>
>> 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).

I meant for a programmer to implement it. And yes, it is a damn good
idea.

>
>> 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?

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.

>
>> 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
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (Guest)
on 2011-01-11 09:16
(Received via mailing list)
On Mon, Jan 10, 2011 at 9:15 PM, Larry Evans <cppljevans@suddenlink.net>
wrote:
> 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]

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 []=(*a)
irb(main):003:2> v = a.pop
irb(main):004:2> p a, v
irb(main):005:2> end
irb(main):006:1> end
=> nil
irb(main):007:0> X.new[1,2,3]=4
[1, 2, 3]
4
=> 4
irb(main):008:0>

Sorry for not mentioning it.

Kind regards

robert
588f37a40705b449b92d7705a9c7be18?d=identicon&s=25 Larry Evans (Guest)
on 2011-01-11 17:36
(Received via mailing list)
On 01/10/11 07:06, Kedar Mhaswade wrote:
> 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...

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
9d5c65ab3dc76a098d61f18346b6c92e?d=identicon&s=25 Dreamr O. (dreamr_o)
on 2011-07-30 22:11
I know this is an old thread, but I have to respond since the venerable
JEGII didn't point out the obvious to you guys.

Matrix.build(row_count, col_count) do |row, col|

end

See
http://www.ruby-doc.org/stdlib/libdoc/matrix/rdoc/...
Please log in before posting. Registration is free and takes only a minute.
Existing account

NEW: Do you have a Google/GoogleMail, Yahoo or Facebook account? No registration required!
Log in with Google account | Log in with Yahoo account | Log in with Facebook account
No account? Register here.