Skip to content

Instantly share code, notes, and snippets.

@MollsReis
Last active January 17, 2019 18:13
Show Gist options
  • Save MollsReis/3b15ed47a078d56674570c60c0fbf1da to your computer and use it in GitHub Desktop.
Save MollsReis/3b15ed47a078d56674570c60c0fbf1da to your computer and use it in GitHub Desktop.
Rank Biased Overlap (Base) implementation (plpgsql)
DROP FUNCTION IF EXISTS f_intersect;
CREATE OR REPLACE FUNCTION f_intersect(a ANYARRAY, b ANYARRAY)
RETURNS ANYARRAY AS $$
BEGIN
-- TODO ensure a and b are the same length
RETURN ARRAY(SELECT UNNEST(a) INTERSECT SELECT UNNEST(b));
END;
$$ LANGUAGE plpgsql;
DROP FUNCTION IF EXISTS f_overlap;
CREATE OR REPLACE FUNCTION f_overlap(a ANYARRAY, b ANYARRAY)
RETURNS INTEGER AS $$
BEGIN
RETURN CARDINALITY(f_intersect(a, b));
END;
$$ LANGUAGE plpgsql;
DROP FUNCTION IF EXISTS f_agreement;
CREATE OR REPLACE FUNCTION f_agreement(a ANYARRAY, b ANYARRAY)
RETURNS NUMERIC AS $$
BEGIN
RETURN (f_overlap(a, b) / CARDINALITY(a)::NUMERIC)::NUMERIC(5,4);
END;
$$ LANGUAGE plpgsql;
DROP FUNCTION IF EXISTS f_rank_biased_overlap;
CREATE OR REPLACE FUNCTION f_rank_biased_overlap(a ANYARRAY, b ANYARRAY, p NUMERIC DEFAULT 0.8)
RETURNS NUMERIC AS $$
DECLARE
sum NUMERIC;
BEGIN
sum := 0;
FOR d IN 1 .. CARDINALITY(a) LOOP
sum = sum + ((p ^ (d - 1)) * f_agreement(a[1:d], b[1:d]));
END LOOP;
RETURN (sum * (1 - p))::NUMERIC(5,4);
END;
$$ LANGUAGE plpgsql;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment