class Statsample::Factor::Rotation
Base class for component matrix rotation.
Reference:¶ ↑
-
SPSS Manual
-
Lin, J. (2007). VARIMAX_K58 [Source code]. [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] ] rotation = Statsample::Factor::Varimax(a) rotation.iterate p rotation.rotated p rotation.component_transformation_matrix
Base class for component matrix rotation.
Reference:¶ ↑
-
SPSS Manual
-
Lin, J. (2007). VARIMAX_K58 [Source code]. [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] ] rotation = Statsample::Factor::Varimax(a) rotation.iterate p rotation.rotated p rotation.component_transformation_matrix
Constants
- EPSILON
- MAX_ITERATIONS
Attributes
communalities[R]
component_transformation_matrix[R]
epsilon[RW]
Maximum precision
h2[R]
iterations[R]
max_iterations[RW]
Maximum number of iterations
rotated[R]
rotated_component_matrix[R]
use_gsl[RW]
Public Class Methods
new(matrix, opts=Hash.new)
click to toggle source
# File lib/statsample/factor/rotation.rb, line 34 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 @epsilon=EPSILON @rotated=nil @h2=(@matrix.collect {|c| c**2} * Matrix.column_vector([1]*@m)).column(0).to_a @use_gsl=Statsample.has_gsl? opts.each{|k,v| self.send("#{k}=",v) if self.respond_to? k } end
Public Instance Methods
compute()
click to toggle source
# File lib/statsample/factor/rotation.rb, line 57 def compute iterate end
iterate()
click to toggle source
Start iteration
# File lib/statsample/factor/rotation.rb, line 61 def iterate k_matrix=@use_gsl ? GSL::Matrix : ::Matrix t=k_matrix.identity(@m) b=(@use_gsl ? @matrix.to_gsl : @matrix.dup) h=k_matrix.diagonal(*@h2).collect {|c| Math::sqrt(c)} h_inverse=h.collect {|c| c!=0 ? 1/c : 0 } bh=h_inverse * b @not_converged=true @iterations=0 while @not_converged break if @iterations>@max_iterations @iterations+=1 #puts "Iteration #{iterations}" num_pairs=@m*(@m-1).quo(2) (0..(@m-2)).each do |i| #+ go through factor index 0:r-1-1 (begin) ((i+1)..(@m-1)).each do |j| #+ pair i to "rest" of factors (begin) xx = bh.column(i) yy = bh.column(j) tx = t.column(i) ty = t.column(j) uu = @n.times.collect {|var_i| xx[var_i]**2-yy[var_i]**2} vv = @n.times.collect {|var_i| 2*xx[var_i]*yy[var_i]} a = @n.times.inject(0) {|ac,var_i| ac+ uu[var_i] } b = @n.times.inject(0) {|ac,var_i| ac+ vv[var_i] } c = @n.times.inject(0) {|ac,var_i| ac+ (uu[var_i]**2 - vv[var_i]**2) } d = @n.times.inject(0) {|ac,var_i| ac+ (2*uu[var_i]*vv[var_i]) } num=x(a,b,c,d) den=y(a,b,c,d) phi=Math::atan2(num,den) / 4.0 # puts "#{i}-#{j}: #{phi}" if(Math::sin(phi.abs) >= @epsilon) xx_rot=( Math::cos(phi)*xx)+(Math::sin(phi)*yy) yy_rot=((-Math::sin(phi))*xx)+(Math::cos(phi)*yy) tx_rot=( Math::cos(phi)*tx)+(Math::sin(phi)*ty) ty_rot=((-Math::sin(phi))*tx)+(Math::cos(phi)*ty) bh=bh.to_a @n.times {|row_i| bh[row_i][i] = xx_rot[row_i] bh[row_i][j] = yy_rot[row_i] } t=t.to_a @m.times {|row_i| t[row_i][i]=tx_rot[row_i] t[row_i][j]=ty_rot[row_i] } #if @use_gsl bh=k_matrix.[](*bh) t=k_matrix.[](*t) #else # bh=Matrix.rows(bh) # t=Matrix.rows(t) #end else num_pairs=num_pairs-1 @not_converged=false if num_pairs==0 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
report_building(g)
click to toggle source
# File lib/statsample/factor/rotation.rb, line 49 def report_building(g) g.section(:name=>@name) do |s| s.parse_element(rotated) s.parse_element(component_transformation_matrix) end end