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