Skip to content

Instantly share code, notes, and snippets.

@jeromepl
Created August 10, 2021 16:30
Show Gist options
  • Save jeromepl/6818445f4980ed78b85195307b0d7734 to your computer and use it in GitHub Desktop.
Save jeromepl/6818445f4980ed78b85195307b0d7734 to your computer and use it in GitHub Desktop.
Raked Weighting in Ruby
require "numo/narray"
require "numo/linalg"
def raking_inverse(x)
Numo::NMath.exp(x)
end
def d_raking_inverse(x)
Numo::NMath.exp(x)
end
def graking(X, T, max_steps: 500, tolerance: 1e-6)
# Based on algo in (Deville et al., 1992) explained in detail on page 37 in
# https://orca.cf.ac.uk/109727/1/2018daviesgpphd.pdf
# Initialize variables - Step 1
n, m = X.shape
L = Numo::DFloat.zeros(m)
w = Numo::DFloat.ones(n)
H_diag = Numo::DFloat.ones(n)
success = false
max_steps.times do
L += Numo::Linalg.pinv((X.transpose * H_diag).dot(X)).dot(T - X.transpose.dot(w)) # Step 2.1
w = raking_inverse(X.dot(L)) # Step 2.2
H_diag = d_raking_inverse(X.dot(L)) # Step 2.3
# Termination condition:
loss = ((T - X.transpose.dot(w)).abs / T).max
if loss < tolerance
success = true
break
end
end
raise StandardError, "Did not converged" unless success
w
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment