File: test-primes-script.pl

package info (click to toggle)
libmath-prime-util-perl 0.73-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 2,796 kB
  • sloc: perl: 24,676; ansic: 11,471; makefile: 26; python: 24
file content (144 lines) | stat: -rwxr-xr-x 4,150 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#!/usr/bin/env perl
use strict;
use warnings;
use File::Spec::Functions;
use FindBin;
use Time::HiRes qw(gettimeofday tv_interval);
use bigint try => 'GMP';
use Data::BitStream::XS;
$|++; #flush the output buffer after every write() or print() function

# Maps between oeis name and number, filled in as we read sequences.
my %oeis_number; # short-name -> no
my %oeis_data;   # no -> ref to info+data

# returned array contains elements of:
#   [$oeis_no, $name, $script_arg, $num_entries, \@ref_data];
my $test_data = read_script_data('script-test-data.bs');

# Verify additional filters
my @additional_filters;
foreach my $name (@ARGV) {
  $name =~ s/^--//;
  my $oeis_no = $oeis_number{$name};
  die "Unknown filter: $name\n" unless defined $oeis_no;
  push @additional_filters, $oeis_no;
}
if (@additional_filters > 0) {
  print "Additional Filters: ",
        join(" ", map { $oeis_data{$_}->[2] } @additional_filters), "\n";
}

foreach my $test (@$test_data) {
  test_oeis(@$test);
}




sub read_script_data {
  my ($filename) = @_;

  die "Can't find test file: $filename\nRun make-script-test-data.pl\n"
      unless -r $filename;

  my $stream = Data::BitStream::XS->new( file => $filename, mode => 'ro' );
  my @data;

  while (!$stream->exhausted) {
    my $script_arg = get_text_string($stream);
    my $name       = get_text_string($stream);
    my ($oeis_no, $is_bigint, $num_entries, @ref) = $stream->get_gamma(5);
    printf "%12s primes (OEIS A%06d): reading %7d entries..", $name, $oeis_no, $num_entries;
    if ($is_bigint) {
      print ",";
      my $k = 2;
      my @deltas = $stream->get_arice($k, $num_entries-2);
      print ".";
      # Check to see if we have any giant deltas
      foreach my $d (@deltas) {
        if ( $d >= '18446744073709551614' ) {
          my $len = $stream->get_gamma;
          my $binstr = $stream->read_string($len);
          $d = Math::BigInt->new('0b' . $binstr);
        }
      }
      print ".";
      my $prev = $ref[1];
      push @ref, map { $prev = $_*2+$prev+2; } @deltas;
      print ".\n";
    } else {
      no bigint;
      print ".";
      my $k = 2;
      my @deltas = $stream->get_arice($k, $num_entries-2);
      print ".";
      my $prev = $ref[1];
      push @ref, map { $prev = $_*2+$prev+2; } @deltas;
      print ".\n";
    }
    my $row = [$oeis_no, $name, $script_arg, $num_entries, \@ref];
    push @data, $row;
    $oeis_data{$oeis_no} = $row;
    $oeis_number{$script_arg} = $oeis_no;
  }
  \@data;
}

sub test_oeis {
  my($oeis_no, $name, $script_arg, $num_entries, $ref_data) = @_;

  my @ref = @$ref_data;
  my $end = $ref[-1];
  $script_arg = '--' . $script_arg;

  foreach my $filter_no (@additional_filters) {
    #my $row = [$oeis_no, $name, $script_arg, $num_entries, \@ref];
    my $filter_name = $oeis_data{$filter_no}->[2];
    my $filter_data_ref = $oeis_data{$filter_no}->[4];
    my %filter_data_hash;
    undef @filter_data_hash{ @$filter_data_ref };
    my $filter_end = $filter_data_ref->[-1];
    @ref = grep { exists $filter_data_hash{$_} } @ref;
    $script_arg .= " --$filter_name";
    $end = $filter_end if $end > $filter_end;  # bring endpoint down
  }

  printf "%12s primes (OEIS A%06d): generating..", $name, $oeis_no;

  my $start = [gettimeofday];
  my @scr = split /\s+/, qx+$FindBin::Bin/../bin/primes.pl $script_arg 1 $end+;
  {
    no bigint;
    my $num_generated = scalar @scr || 0.1;
    my $seconds = tv_interval($start);
    my $msperprime = ($seconds * 1000.0) / $num_generated;
    printf " %7d. %7.2f ms/prime\n", $num_generated, $msperprime;
  }

  if (scalar @ref != scalar @scr) {
    warn "  $FindBin::Bin/../bin/primes.pl $script_arg 1 $end\n";
    die "Not equal numbers:  ", scalar @ref, " - ", scalar @scr, "\n";
  }

  foreach my $i (0 .. $#ref) {
    die "$name prime $i not equal:  $ref[$i] - $scr[$i]\n"
        if $ref[$i] != $scr[$i];
  }
}

sub put_text_string {
  my ($stream, $str) = @_;
  $stream->put_gamma(ord($_)) for (split "", $str);
  $stream->put_gamma(0);
  1;
}

sub get_text_string {
  my ($stream) = @_;
  my $str = '';
  while (my $c = $stream->get_gamma) {
    $str .= chr($c);
  }
  $str;
}