=begin rdoc
Row: iCookware row class for vector matrix

Author: Jan-Ole Esleben (esleben@cl.uni-heidelberg.de), Stephanie Schuldes (schuldes@cl.uni-heidelberg.de), Nicola Kaiser (kaiser@cl.uni-heidelberg.de)
Project:: iCookWare
Copyright:: iCookWare Team 2005 (Nicola Kaiser, Ana Kovatcheva, Olga Mordvinova, Stephanie Schuldes)
Embedded Documentation Tool:: rdoc
=end

require "taxo"

include TAXO


# Changes by NK:
# * Row does contain values as floats, row does no longer contain name
# * additional method for building matrix from data instead of file
# * weighting vectors
module ICW
  # ICW::Row works like an array but provides added convenience for ingredient rows
  class Row < Array
    attr_reader :name, :column_names
    
    # +name+:: the name of the ingredient described by this row
    # +column_names+:: the names of all columns
    # +initarray+:: initial array to fill the row
    def initialize name, column_names, initarray=nil
      raise TypeError, "column array" unless column_names.class == Array
      @column_names = column_names[1..-1] # ugly: columnname for name should not be included
      @name = name
      @w=computeWeight
      @w = [1.0]*initarray.length unless @w
      
      if initarray then initarray.each_with_index { |el, i| push el*@w[i] } end
    end
    
    def computeWeight
    	ingred=Ingredient.new()
    	return ingred.getClassVector(@name)
    end
 
    # Iterate over array, yielding each element and its feature name    
    def each_with_key
      each_with_index do | el, idx |
        yield el, @column_names[idx]
      end
    end
  end
  
  # ICW::IngredientMatrix contains objects of class Row and basically works
  # like an array
  class IngredientMatrix < Array
        
    def initialize
        @col_names = Array.new	# container for ingredient column names (e.g. 'bratbar')
    end
	# Build matrix rows (Row objects) and extract column names (i.e. feature names)
	# +filename+:: ingredient features file with format:
	# 			   ingredientName + values for features
    def buildMatrix(filename)
        featurefile = File.new(filename, "r")
        
        # get first line from file, split feature names
        @col_names = featurefile.gets.split
        
        # split each line and create one Row object per line
        featurefile.each_line do |line| 
            val = line.split
            newRow = ICW::Row.new(val[0], @col_names)
            for i in 1...val.length do 
                newRow.push val[i].to_f
            end
            push newRow
        end
        featurefile.close
        
        #normalize data points (each component 0...1), actually not needed now - AK
				#for some reason we have a reference problem here -> double clusters etc
=begin
        for i in 1...self[0].length do
	         min=99999.9 
	         max=-99999.9
           each { |x|
	            if x[i] < min
		             min=x[i]
		          end
		          if x[i] > max
		             max=x[i]
		          end 
 				 }
 					 each { |x|
	            if(max==min) # avoid div by zero
		            x[i]=0
		          else
                x[i]=(x[i]-min)/(max-min)
							end
 				}
        end
=end
     end

    def buildMatrixFromData data, colnames=nil
      if colnames
        @col_names=colnames
      else
        @col_names=Array.new(data[0].length, "x")
      end
      data.each do |el|
        newRow=ICW::Row.new el[0], @col_names
        for i in 1...el.length do
          newRow.push el[i].to_f
        end
        push newRow
      end
    end
  end
end


