lib/statsample/factor/rotation.rb in statsample-0.13.1 vs lib/statsample/factor/rotation.rb in statsample-0.14.0

- old
+ new

@@ -1,12 +1,14 @@ module Statsample module Factor - # Base class for rotate matrixes - # References: + # Base class for component matrix rotation. + # + # == References: # * SPSS Manual - # * Johnny Lin code for IDL: http://www.johnny-lin.com/idl_code/varimax_k58.pro - # Use Varimax, Equimax or Quartimax for desired type of rotation + # * Johnny Lin code for IDL: [http://www.johnny-lin.com/idl_code/varimax_k58.pro] + # + # Use subclasses Varimax, Equimax or Quartimax for desired type of rotation # Use: # a = Matrix[ [ 0.4320, 0.8129, 0.3872] # , [ 0.7950, -0.5416, 0.2565] # , [ 0.5944, 0.7234, -0.3441] # , [ 0.8945, -0.3921, -0.1863] ] @@ -16,10 +18,11 @@ # p rotation.component_transformation_matrix # class Rotation EPSILON=1e-15 MAX_ITERATIONS=25 + include Summarizable include DirtyMemoize attr_reader :iterations, :rotated, :component_transformation_matrix, :h2 # Maximum number of iterations attr_accessor :max_iterations # Maximum precision @@ -27,10 +30,11 @@ dirty_writer :max_iterations, :epsilon dirty_memoize :iterations, :rotated, :component_transformation_matrix, :h2 def initialize(matrix, opts=Hash.new) + @name=_("%s rotation") % rotation_name @matrix=matrix @n=@matrix.row_size # Variables, p on original @m=@matrix.column_size # Factors, r on original @component_transformation_matrix=nil @max_iterations=MAX_ITERATIONS @@ -39,10 +43,16 @@ @h2=(@matrix.collect {|c| c**2} * Matrix.column_vector([1]*@m)).column(0).to_a opts.each{|k,v| self.send("#{k}=",v) if self.respond_to? k } end + def report_building(g) + g.section(:name=>@name) do |s| + s.parse_element(rotated) + s.parse_element(component_transformation_matrix) + end + end alias_method :communalities, :h2 alias_method :rotated_component_matrix, :rotated def compute iterate end @@ -109,11 +119,37 @@ end # if end #j end #i end # while @rotated=h*bh + @rotated.extend CovariateMatrix + @rotated.name=_("Rotated Component matrix") + + if @matrix.respond_to? :fields_x + @rotated.fields_x = @matrix.fields_x + else + @rotated.fields_x = @n.times.map {|i| "var_#{i+1}"} + end + if @matrix.respond_to? :fields_y + @rotated.fields_y = @matrix.fields_y + else + @rotated.fields_y = @m.times.map {|i| "var_#{i+1}"} + end + + + @component_transformation_matrix=t + @component_transformation_matrix.extend CovariateMatrix + @component_transformation_matrix.name=_("Component transformation matrix") + + if @matrix.respond_to? :fields_y + @component_transformation_matrix.fields = @matrix.fields_y + + else + @component_transformation_matrix.fields = @m.times.map {|i| "var_#{i+1}"} + end + @rotated end end class Varimax < Rotation @@ -121,24 +157,35 @@ d-(2*a*b / @n.to_f) end def y(a,b,c,d) c-((a**2-b**2) / @n.to_f) end + def rotation_name + "Varimax" + end end class Equimax < Rotation def x(a,b,c,d) d-(@m*a*b / @n.to_f) end def y(a,b,c,d) c-@m*((a**2-b**2) / (2*@n.to_f)) end + def rotation_name + "Equimax" + end + end class Quartimax < Rotation def x(a,b,c,d) d end def y(a,b,c,d) c end + def rotation_name + "Quartimax" + end + end end end