Forum: Ruby 2D array strategies

Posted by Thomas Luedeke (tpl)
on 2012-10-02 20:49
I'm a relative Ruby Nuby, and am running into some difficulty
determining how to handle 2D arrays.  An extremely common task I am
using Ruby for is to post-process the output files of large engineering
codes, and extract scattered information into structured output for
visualization codes.  Frequently this amounts to pulling the same
information from multiple cases, and producing x vs. y1, y2, ..., yn
data.

It is easy to do this for a single array case, but the capacity for Ruby
to handle 2D array data is quite strange (and even awkward) to me.
Coming from a Fortran 90 type of background, multiple-dimension array
structures are very simple.

So getting to my question, what is a typical approach for a Ruby user to
solve a problem of this sort:

>  Set up a data structure to store at least one set of x versus y data.

>  Parse a file, looking to identify x versus y data for the first case out of an
indeterminant overall number of cases.

>  If I find a subsequent case, add on an x versus y1 set of data to the original
data structure

>  Repeat until EOF.

Since Ruby only does 1D arrays, is there a trick for an array of arrays?
Or is this hash territory?  How do I do the 2D equivalent of using the
.push array command to add on more data to the original array?  Are
there are any particular Ruby resources that I need to go read up on and
go practice in IRB?

Respectfully, TPL
Posted by 7stud -- (7stud)
on 2012-10-02 21:09
array2d = [
  ['a', 'b', 'c'],
  ['x', 'y', 'z']
]

puts array2d[1][0]

--output:--
x


array2d[0] << 'd'
p array2d

--output:--
[["a", "b", "c", "d"], ["x", "y", "z"]]



> Set up a data structure to store at least one set of x versus y data.

xy_data = [
  [1, 2],
  [3, 4]
]

> Parse a file, looking to identify x versus y data for the
> first case out of an indeterminant overall number of cases.

That is just pure gibberish.  Getting ready to debate Obama?

> If I find a subsequent case, add on an x versus y1 set of
> data to the original data structure

More gibberish.  How about a concrete example?
Posted by Thomas Luedeke (tpl)
on 2012-10-02 21:24
7stud -- wrote in post #1078413:
> array2d = [
>   ['a', 'b', 'c'],
>   ['x', 'y', 'z']
> ]
>
> puts array2d[1][0]
>
> --output:--
> x
>
>
> array2d[0] << 'd'
> p array2d
>
> --output:--
> [["a", "b", "c", "d"], ["x", "y", "z"]]
>
>
>
>> Set up a data structure to store at least one set of x versus y data.
>
> xy_data = [
>   [1, 2],
>   [3, 4]
> ]
>
>> Parse a file, looking to identify x versus y data for the
>> first case out of an indeterminant overall number of cases.
>
> That is just pure gibberish.  Getting ready to debate Obama?
>
>> If I find a subsequent case, add on an x versus y1 set of
>> data to the original data structure
>
> More gibberish.  How about a concrete example?





OK.  Try this as a file content:

============================================================= (BOF)
Gibberish

Gibberish

Gibberish

Case #1 Output
1    2
2    4
3    6
4    8
5    10
6    12
7    14

Gibberish

Gibberish

Gibberish

Case #2 Output
1    1
2    3
3    5
4    7
5    9
6    11
7    13

Gibberish

Gibberish

Gibberish
========================================================== (EOF)


I parse the file and identify the data associated with the first case, 
and load it up into an array.  I then parse through gibberish until I 
identify the data associated with the second case.  Now what?
Posted by Admin Tensor (tensor)
on 2012-10-02 21:45
Thomas Luedeke wrote in post #1078414:

> I parse the file and identify the data associated with the first case,
> and load it up into an array.  I then parse through gibberish until I
> identify the data associated with the second case.  Now what?

Hi,

It really depends on the actual data.  If you really want the most
efficient, you can try the NArray.  (Or, if you are using Windows, you
can try to use RTensor (http://tensor.heliohost.org) which I wrote a
while ago.)  At least the arrays will be 2D.  If all the cases have the
same amount of data, then you can make a single 3D array.

If on the other hand the amount of data is not much, then you can use a
combination of Ruby arrays and/or hashes.

Regards,

Bill
Posted by Ryan Davis (Guest)
on 2012-10-02 22:15
(Received via mailing list)
On Oct 2, 2012, at 11:49 , Thomas Luedeke <lists@ruby-forum.com> wrote:

> Since Ruby only does 1D arrays, is there a trick for an array of arrays?
> Or is this hash territory?  How do I do the 2D equivalent of using the
> .push array command to add on more data to the original array?  Are
> there are any particular Ruby resources that I need to go read up on and
> go practice in IRB?

Unless your dimensions are quite huge, you might want to try out Matrix:

% ri Matrix
= MMaattrriixx  <<  OObbjjeecctt

(from ruby core)
------------------------------------------------------------------------------
The Matrix class represents a mathematical matrix, and provides methods 
for
creating special-case matrices (zero, identity, diagonal, singular, 
vector),
operating on them arithmetically and algebraically, and determining 
their
mathematical properties (trace, rank, inverse, determinant).

Note that although matrices should theoretically be rectangular, this is 
not
enforced by the class.

Also note that the determinant of integer matrices may be incorrectly
calculated unless you also require 'mathn'.  This may be fixed in the 
future.

== MMeetthhoodd  CCaattaalloogguuee

To create a matrix:
*  Matrix[*rows]
*  Matrix.[](*rows)
*  Matrix.rows(rows, copy = true)
*  Matrix.columns(columns)
*  Matrix.diagonal(*values)
*  Matrix.scalar(n, value)
*  Matrix.scalar(n, value)
*  Matrix.identity(n)
*  Matrix.unit(n)
*  Matrix.I(n)
*  Matrix.zero(n)
*  Matrix.row_vector(row)
*  Matrix.column_vector(column)

To access Matrix elements/columns/rows/submatrices/properties:
*   [](i, j)
*  #row_size
*  #column_size
*  #row(i)
*  #column(j)
*  #collect
*  #map
*  #minor(*param)

Properties of a matrix:
*  #regular?
*  #singular?
*  #square?

Matrix arithmetic:
*   *(m)
*   +(m)
*   -(m)
*  #/(m)
*  #inverse
*  #inv
*   **

Matrix functions:
*  #determinant
*  #det
*  #rank
*  #trace
*  #tr
*  #transpose
*  #t

Conversion to other data types:
*  #coerce(other)
*  #row_vectors
*  #column_vectors
*  #to_a

String representations:
*  #to_s
*  #inspect
------------------------------------------------------------------------------
= CCllaassss  mmeetthhooddss::

  I
  []
  column_vector
  columns
  diagonal
  identity
  new
  row_vector
  rows
  scalar
  unit
  zero

= IInnssttaannccee  mmeetthhooddss::

  *
  **
  +
  -
  /
  ==
  []
  clone
  coerce
  collect
  column
  column_size
  column_vectors
  compare_by_row_vectors
  det
  determinant
  eql?
  hash
  init_rows
  inspect
  inv
  inverse
  inverse_from
  map
  minor
  rank
  regular?
  row
  row_size
  row_vectors
  singular?
  square?
  t
  to_a
  to_s
  tr
  trace
  transpose
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.