lib/statsample/bivariate/polychoric.rb in statsample-0.9.0 vs lib/statsample/bivariate/polychoric.rb in statsample-0.10.0

- old
+ new

@@ -8,22 +8,33 @@ end # Polychoric correlation matrix. # Order of rows and columns depends on Dataset#fields order def self.polychoric_correlation_matrix(ds) - ds.collect_matrix do |row,col| + cache={} + matrix=ds.collect_matrix do |row,col| if row==col 1.0 else begin - polychoric(ds[row],ds[col]) + if cache[[col,row]].nil? + poly=polychoric(ds[row],ds[col]) + cache[[row,col]]=poly + poly + else + cache[[col,row]] + end rescue RuntimeError nil end end end + matrix.extend CovariateMatrix + matrix.fields=ds.fields + matrix end + # = Polychoric correlation. # # The <em>polychoric</em> correlation is a measure of # bivariate association arising when both observed variates # are ordered, categorical variables that result from polychotomizing @@ -81,10 +92,11 @@ # See http://rb-gsl.rubyforge.org/min.html for reference. attr_accessor :minimizer_type_joint # Method of calculation of polychoric series. + # <tt>:two_step</tt> used by default. # # :two_step:: two-step ML, based on code by Gegenfurtner(1992). # :polychoric_series:: polychoric series estimate, using # algorithm AS87 by Martinson and Hamdan (1975). # :joint:: one-step ML, based on R package 'polycor' @@ -105,11 +117,11 @@ METHOD=:two_step MAX_ITERATIONS=300 EPSILON=1e-6 MINIMIZER_TYPE_TWO_STEP="brent" MINIMIZER_TYPE_JOINT="nmsimplex" - def new_with_vectors(v1,v2) + def self.new_with_vectors(v1,v2) Polychoric.new(Crosstab.new(v1,v2).to_matrix) end # Params: # * matrix: Contingence table # * opts: Any attribute @@ -247,18 +259,19 @@ else a=(i==@nr-1) ? 100: alpha[i] b=(j==@nc-1) ? 100: beta[j] #puts "a:#{a} b:#{b}" pd[i][j]=Distribution::NormalBivariate.cdf(a, b, rho) + end pc[i][j] = pd[i][j] pd[i][j] = pd[i][j] - pc[i-1][j] if i>0 pd[i][j] = pd[i][j] - pc[i][j-1] if j>0 pd[i][j] = pd[i][j] + pc[i-1][j-1] if (i>0 and j>0) res= pd[i][j] #puts "i:#{i} | j:#{j} | ac: #{sprintf("%0.4f", pc[i][j])} | pd: #{sprintf("%0.4f", pd[i][j])} | res:#{sprintf("%0.4f", res)}" - if (res==0) + if (res<=0) # puts "Correccion" res=1e-16 end loglike+= @matrix[i,j] * Math::log( res ) } @@ -326,10 +339,10 @@ @log="Minimizing using GSL Brent method\n" min=Minimization::Brent.new(-0.9999,0.9999,f) min.epsilon=@epsilon min.expected=0 min.iterate - @log+=min.log + @log+=min.log.to_table.to_s @r=min.x_minimum @loglike_model=-min.f_minimum puts @log if @debug end