Returning a column vector from a 2D array

I have a @data_array variable, which is a 2 dimensional array. If I
run a @data_array.inspect, I get the entire 2D array in string form
reporting back to me.

But I want to pick off a specific column, ie., create a column vector
from one of the columns on the array. If I do something like
@data_array.length, I get an undefined method length, probably because
@data_array simply reference the Array ID?? If I do an
@data_array.inspect.length, this appears to give me the number of
elements in the complete array versus the actual length of the array.
I need to know the length, to read back a vector (I believe).

Is there already a method existing to do this, or do I need to go down
the road of determining 2d array length, to read back a specific column
of a 2d array through a looping structure?

Thanks

On Tue, Feb 1, 2011 at 8:53 PM, Jim C. [email protected] wrote:

I need to know the length, to read back a vector (I believe).

Is there already a method existing to do this, or do I need to go down
the road of determining 2d array length, to read back a specific column
of a 2d array through a looping structure?

Can you show some code? Are you using a specific 2d array from a
library or are you using an array of arrays?
If @data_array is referencing an object and not nil, can you show us
the ouput of puts @data_array.class ?
If the error you are getting mentions NilClass, you are probably not
assigning anything to @data_array.

Jesus.

Hope this isn’t too fragmentary and of no use

Here is where I create class for generating 2D arrays


class Array2D

require ‘matrix’

def initialize(row, column) #this creates the 2D array structure
@data = Array.new(row) { Array.new(column) {0}} #initialize
array with
#0’s
end

def [](x, y) #this allows one read access to cells within 2D array
@data[x][y]
end

def []=(x, y, value) #this allows one write access to cells within 2D
array
@data[x][y] = value
end

end


In a separate class, ExteriorBallistics, in its method “calculate,” I
create a new array component


nrows = ((los_rng - start_rng)/rng_incr).round

initialize arrays

e = Array2D.new(nrows+1, 14)

Later I assign to the matrix e. Putting puts in front of any of these
assignments yields correct column values


Store Values at appropriate intervals (integral numbers of RangeInc)

    if ((range_ctr % rng_incr == 0)||(range_ctr == los_rng ))

      @index = (((rng_incr + range2 - start_rng)/rng_incr) - 1).ceil

      e[@index,RANGE] = range2
      e[@index,VELOCITY] = vel
      e[@index,TIME] = time1
      e[@index,PATH] = height1 * 12      # %path, converted to 

inches
e[@index,DEFLECTION] = deflection1 * 12 # %convert to inches
e[@index,ENERGY] = energy
e[@index,DROP] = drop
e[@index,MOA] = moa
e[@index,ADJ_PATH] = adj_path
e[@index,EQV_DROP] = eqv_drop
e[@index,MOMENTUM] = momentum
e[@index,TAYLOR_KO] = taylor_ko
e[@index,OGW] = optimal_game_weight

    end  #  if (range_ctr % rng_incr == 0)

@index gives me the column length once the entire routine is complete.
Towards the end of the “calculate” method, once all elements have been
assigned to the matrix, I make the following association


@data_array = e


Furthermore, under the same class ExteriorBallistics, I declare an
attr_accessor :data_array

Then I want to run calculate via

ExteriorBallistics.new do

{a bunch of assignments here}

calculate

ary_length = @index #returns the correct column length
puts @data_array

This returns the Array ID.

I can do a .inspect to have the entire matrix printed out in string
format, but I really want column numeric values.

Strangely, if I do either this @data_array[0…ary_length,0] or this
@data_array[0,0…ary_length], I get the exact same result, which is the
first ROW spanning all columns that I created.

Using Matrix.rb does not work in this application, because I have to
assign matrix values dynamically, and it appears that Matrix class
requires static assignment of the matrix. That’s why I created my own
Array2D class. I was able to take and modify a method from Matrix.rb to
solve this problem however. It is the column method (see below)

class Array2D

require ‘matrix’

def initialize(row, column) #this creates the 2D array structure
@data = Array.new(row) { Array.new(column) {0}} #initialize
array with
#0’s
end

def [](x, y) #this allows one read access

# to cells within 2D array
  @data[x][y]

end

def []=(x, y, value) #this allows one write access to cells within 2D
array
@data[x][y] = value
end

Returns column vector number +j+ of the matrix as a Vector (starting

at 0

like an array). When a block is given, the elements of that vector

are

iterated.

def column(j,row_size) # :yield: e
if block_given?
row_size.times do |i|
yield @data[i][j]
end
else
col = (0 … row_size).collect {|i|
@data[i][j]
}
#Vector.elements(col, false)
end
end #column

end

This is the call

puts ary_length = @index
puts @data_array.column(0,ary_length)