public function rank($info, $weights)
    {
        if (!empty($weights)) {
            $weights = explode(',', $weights);
        }
        $score = (float) 0.0; // the value to return
        $isize = 4; // the amount of string we need to collect for each integer
        $phrases = (int) ord(substr($info, 0, $isize));
        $columns = (int) ord(substr($info, $isize, $isize));
        $string = $phrases.' '.$columns.' ';
        for ($p = 0; $p < $phrases; ++$p) {
            $term = substr($info, (2 + $p * $columns * 3) * $isize); // the start of $info for current phrase
            for ($c = 0; $c < $columns; ++$c) {
                $here = (float) ord(substr($term, (3 * $c * $isize), 1)); // total occurrences in this row and column
                $total = (float) ord(substr($term, (3 * $c + 1) * $isize, 1)); // total occurrences for all rows in this column
                $rows = (float) ord(substr($term, (3 * $c + 2) * $isize, 1)); // total rows with at least one occurence in this column
                $relevance = (!empty($total)) ? ($rows / $total) * $here : 0;
                $weight = (isset($weights[$c])) ? (float) $weights[$c] : 1;
                $score += $relevance * $weight;
                $string .= $here.$total.$rows.' ('.round($relevance, 2).'*'.$weight.') ';
            }
        }
        // return $string . '- ' . $score; // to debug
        return $score;
    }