mr_prime 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,15 @@
1
+ begin
2
+ require 'jeweler'
3
+ Jeweler::Tasks.new do |s|
4
+ s.name = "mr_prime"
5
+ s.summary = "An Uber-fast primality testing library."
6
+ s.email = "burke@burkelibbey.org"
7
+ s.homepage = "http://github.com/rkneufeld/mr_prime"
8
+ s.description = "An Uber-fast primality testing library."
9
+ s.authors = ["Burke Libbey", "Ryan Neufeld"]
10
+ s.files = FileList["[A-Z]*", "{src,ext,lib}/**/*"]
11
+ s.extensions = ["ext/extconf.rb"]
12
+ end
13
+ rescue LoadError
14
+ puts "Jeweler, or one of its dependencies, is not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
15
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,157 @@
1
+
2
+ SHELL = /bin/sh
3
+
4
+ #### Start of system configuration section. ####
5
+
6
+ srcdir = .
7
+ topdir = /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/universal-darwin10.0
8
+ hdrdir = $(topdir)
9
+ VPATH = $(srcdir):$(topdir):$(hdrdir)
10
+ exec_prefix = $(prefix)
11
+ prefix = $(DESTDIR)/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr
12
+ sharedstatedir = $(prefix)/com
13
+ mandir = $(DESTDIR)/usr/share/man
14
+ psdir = $(docdir)
15
+ oldincludedir = $(DESTDIR)/usr/include
16
+ localedir = $(datarootdir)/locale
17
+ bindir = $(exec_prefix)/bin
18
+ libexecdir = $(exec_prefix)/libexec
19
+ sitedir = $(DESTDIR)/Library/Ruby/Site
20
+ htmldir = $(docdir)
21
+ vendorarchdir = $(vendorlibdir)/$(sitearch)
22
+ includedir = $(prefix)/include
23
+ infodir = $(DESTDIR)/usr/share/info
24
+ vendorlibdir = $(vendordir)/$(ruby_version)
25
+ sysconfdir = $(prefix)/etc
26
+ libdir = $(exec_prefix)/lib
27
+ sbindir = $(exec_prefix)/sbin
28
+ rubylibdir = $(libdir)/ruby/$(ruby_version)
29
+ docdir = $(datarootdir)/doc/$(PACKAGE)
30
+ dvidir = $(docdir)
31
+ vendordir = $(libdir)/ruby/vendor_ruby
32
+ datarootdir = $(prefix)/share
33
+ pdfdir = $(docdir)
34
+ archdir = $(rubylibdir)/$(arch)
35
+ sitearchdir = $(sitelibdir)/$(sitearch)
36
+ datadir = $(datarootdir)
37
+ localstatedir = $(prefix)/var
38
+ sitelibdir = $(sitedir)/$(ruby_version)
39
+
40
+ CC = gcc
41
+ LIBRUBY = $(LIBRUBY_SO)
42
+ LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a
43
+ LIBRUBYARG_SHARED = -l$(RUBY_SO_NAME)
44
+ LIBRUBYARG_STATIC = -l$(RUBY_SO_NAME)
45
+
46
+ RUBY_EXTCONF_H =
47
+ CFLAGS = -fno-common -arch i386 -arch x86_64 -g -Os -pipe -fno-common -DENABLE_DTRACE -fno-common -pipe -fno-common $(cflags)
48
+ INCFLAGS = -I. -I$(topdir) -I$(hdrdir) -I$(srcdir)
49
+ DEFS =
50
+ CPPFLAGS = -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE $(DEFS) $(cppflags)
51
+ CXXFLAGS = $(CFLAGS)
52
+ ldflags = -L. -arch i386 -arch x86_64
53
+ dldflags =
54
+ archflag =
55
+ DLDFLAGS = $(ldflags) $(dldflags) $(archflag)
56
+ LDSHARED = cc -arch i386 -arch x86_64 -pipe -bundle -undefined dynamic_lookup
57
+ AR = ar
58
+ EXEEXT =
59
+
60
+ RUBY_INSTALL_NAME = ruby
61
+ RUBY_SO_NAME = ruby
62
+ arch = universal-darwin10.0
63
+ sitearch = universal-darwin10.0
64
+ ruby_version = 1.8
65
+ ruby = /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby
66
+ RUBY = $(ruby)
67
+ RM = rm -f
68
+ MAKEDIRS = mkdir -p
69
+ INSTALL = /usr/bin/install -c
70
+ INSTALL_PROG = $(INSTALL) -m 0755
71
+ INSTALL_DATA = $(INSTALL) -m 644
72
+ COPY = cp
73
+
74
+ #### End of system configuration section. ####
75
+
76
+ preload =
77
+
78
+ libpath = . $(libdir)
79
+ LIBPATH = -L. -L$(libdir)
80
+ DEFFILE =
81
+
82
+ CLEANFILES = mkmf.log
83
+ DISTCLEANFILES =
84
+
85
+ extout =
86
+ extout_prefix =
87
+ target_prefix =
88
+ LOCAL_LIBS =
89
+ LIBS = $(LIBRUBYARG_SHARED) -lpthread -ldl
90
+ SRCS = prime.c
91
+ OBJS = prime.o
92
+ TARGET = better_prime
93
+ DLLIB = $(TARGET).bundle
94
+ EXTSTATIC =
95
+ STATIC_LIB =
96
+
97
+ BINDIR = $(bindir)
98
+ RUBYCOMMONDIR = $(sitedir)$(target_prefix)
99
+ RUBYLIBDIR = $(sitelibdir)$(target_prefix)
100
+ RUBYARCHDIR = $(sitearchdir)$(target_prefix)
101
+
102
+ TARGET_SO = $(DLLIB)
103
+ CLEANLIBS = $(TARGET).bundle $(TARGET).il? $(TARGET).tds $(TARGET).map
104
+ CLEANOBJS = *.o *.a *.s[ol] *.pdb *.exp *.bak
105
+
106
+ all: $(DLLIB)
107
+ static: $(STATIC_LIB)
108
+
109
+ clean:
110
+ @-$(RM) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES)
111
+
112
+ distclean: clean
113
+ @-$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log
114
+ @-$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES)
115
+
116
+ realclean: distclean
117
+ install: install-so install-rb
118
+
119
+ install-so: $(RUBYARCHDIR)
120
+ install-so: $(RUBYARCHDIR)/$(DLLIB)
121
+ $(RUBYARCHDIR)/$(DLLIB): $(DLLIB)
122
+ $(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR)
123
+ install-rb: pre-install-rb install-rb-default
124
+ install-rb-default: pre-install-rb-default
125
+ pre-install-rb: Makefile
126
+ pre-install-rb-default: Makefile
127
+ $(RUBYARCHDIR):
128
+ $(MAKEDIRS) $@
129
+
130
+ site-install: site-install-so site-install-rb
131
+ site-install-so: install-so
132
+ site-install-rb: install-rb
133
+
134
+ .SUFFIXES: .c .m .cc .cxx .cpp .C .o
135
+
136
+ .cc.o:
137
+ $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<
138
+
139
+ .cxx.o:
140
+ $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<
141
+
142
+ .cpp.o:
143
+ $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<
144
+
145
+ .C.o:
146
+ $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<
147
+
148
+ .c.o:
149
+ $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) -c $<
150
+
151
+ $(DLLIB): $(OBJS)
152
+ @-$(RM) $@
153
+ $(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS)
154
+
155
+
156
+
157
+ $(OBJS): ruby.h defines.h
@@ -0,0 +1,5 @@
1
+ require 'mkmf'
2
+
3
+ extension_name = 'mr_prime'
4
+ dir_config(extension_name)
5
+ create_makefile(extension_name, '.')
@@ -0,0 +1,115 @@
1
+ #include <stdbool.h>
2
+
3
+ #include "ruby.h"
4
+
5
+ typedef unsigned long long ullong;
6
+
7
+ ullong
8
+ expmod(ullong base, ullong exponent, ullong modulus)
9
+ {
10
+ ullong result = 1;
11
+ while(exponent > 0) {
12
+ if ((exponent & 1) == 1) {
13
+ result = (result * base) % modulus;
14
+ }
15
+ exponent >>= 1;
16
+ base = (base * base) % modulus;
17
+ }
18
+ return result;
19
+ }
20
+
21
+ VALUE
22
+ mrprime(VALUE obj)
23
+ {
24
+ rb_require("mr_prime/mr_prime_rb");
25
+ VALUE mrprime = rb_define_class("MR_Prime", rb_cObject);
26
+ return rb_funcall(mrprime, rb_intern("[]"), 1, obj);
27
+ }
28
+
29
+ /* Miller-Rabin algorithm to determine primality of a number.
30
+ * Uses values for a that guarantee correct results up to 314T.
31
+ * Above that, uses ryan@ryanneufeld.ca's Mr.Prime.
32
+ */
33
+ VALUE
34
+ integer_is_prime(VALUE self)
35
+ {
36
+ if (!FIXNUM_P(self)) {
37
+ return mrprime(self);
38
+ }
39
+
40
+ ullong n = NUM2ULL(self);
41
+
42
+ int *primes;
43
+ int nprimes;
44
+ int k, i, j;
45
+ ullong m, b;
46
+ bool prime;
47
+
48
+ static int primes_1[] = {2, 3};
49
+ static int primes_2[] = {31, 73};
50
+ static int primes_3[] = {2, 7, 61};
51
+ static int primes_4[] = {2, 3, 5, 7, 11};
52
+ static int primes_5[] = {2, 3, 5, 7, 11, 13};
53
+ static int primes_6[] = {2, 3, 5, 7, 11, 13, 17};
54
+
55
+ if (n < 2) {
56
+ return Qfalse;
57
+ } else if (n < 4) {
58
+ return Qtrue;
59
+ } else if (n < 1373653) {
60
+ primes = primes_1;
61
+ nprimes = 2;
62
+ } else if (n < 9080191) {
63
+ primes = primes_2;
64
+ nprimes = 2;
65
+ } else if (n < 4759123141ULL) {
66
+ primes = primes_3;
67
+ nprimes = 3;
68
+ } else if (n < 2152302989747ULL) {
69
+ primes = primes_4;
70
+ nprimes = 5;
71
+ } else if (n < 3474749660383ULL) {
72
+ primes = primes_5;
73
+ nprimes = 6;
74
+ } else if (n < 341550071728321ULL) {
75
+ primes = primes_6;
76
+ nprimes = 7;
77
+ } else {
78
+ // Quick, do something sensible!
79
+ return mrprime(self);
80
+ }
81
+
82
+ k = 0;
83
+ m = n - 1;
84
+ while (m & 1) {
85
+ m >>= 1;
86
+ k += 1;
87
+ }
88
+
89
+ for (i = 0; i < nprimes; i++) {
90
+ b = expmod(primes[i], m, n);
91
+
92
+ if (b != 1) {
93
+ prime = false;
94
+ for (j = 0; j < k; j++) {
95
+ if (b == n - 1) {
96
+ prime = true;
97
+ break;
98
+ }
99
+ b = expmod(b, 2, n);
100
+ }
101
+ if (!prime) {
102
+ return Qfalse;
103
+ }
104
+ }
105
+ }
106
+
107
+ return Qtrue;
108
+ }
109
+
110
+ void
111
+ Init_mr_prime()
112
+ {
113
+ VALUE cNumeric = rb_define_class("Numeric", rb_cObject);
114
+ rb_define_method(cNumeric, "prime?", integer_is_prime, 0);
115
+ }
@@ -0,0 +1,119 @@
1
+ # Thanks Bruce Schneier for this gem
2
+ def exponent_mod(base,exponent,modulus)
3
+ result = 1;
4
+ while(exponent > 0)
5
+ if ((exponent & 1) == 1)
6
+ result = (result * base) % modulus;
7
+ end
8
+ exponent >>= 1;
9
+ base = (base * base) % modulus;
10
+ end
11
+
12
+ return result;
13
+ end
14
+
15
+
16
+ # Test r&s can reconstitute n properly
17
+ class MR_Prime
18
+ attr_accessor :number
19
+ attr_reader :r,:s,:trials
20
+
21
+ # Allow for easier access to instance of class via MR_Prime[n]
22
+ def self.[](n,opts={})
23
+ MR_Prime.new(n,opts).prime?
24
+ end
25
+
26
+ def self.trials_for_precision(prec)
27
+ k = 1
28
+ while( 1.0 / (4.0 ** k) > prec)
29
+ k += 1
30
+ end
31
+ return k
32
+ end
33
+
34
+ def initialize(n,opts={})
35
+ self.number = n
36
+ set_trials(opts)
37
+ end
38
+
39
+ def witnessed_by?(a)
40
+ result = exponent_mod(a,@s,@number)
41
+ if result == 1
42
+ return true
43
+ else
44
+ 0.upto(@r-1) do |j|
45
+ result = exponent_mod(a,(2**j)*@s,@number)
46
+ if result == -1 or result == @number - 1
47
+ return true
48
+ end
49
+ end
50
+ end
51
+ return false
52
+ end
53
+
54
+ def number=(n)
55
+ @number = n
56
+ resolve_r_and_s
57
+ end
58
+
59
+ def prime?
60
+ witnesses.all? { |a| witnessed_by? a }
61
+ end
62
+
63
+ #private
64
+
65
+ # Set the number of trials to the max of num required for precision, witnesses opt, or 19 (giving at max 1.0e-10 chance of failure)
66
+ def set_trials(opts)
67
+ trials = [19] # default precision of 0.00000000036% chance of failure
68
+ if opts[:precision]
69
+ if opts[:precision] == 0 # Short circuit of absolute precision is required
70
+ @absolute = true
71
+ @trials = -1
72
+ return
73
+ else
74
+ trials.push(MR_Prime.trials_for_precision(opts[:precision]))
75
+ end
76
+ end
77
+ trials.push(opts[:witnesses]) if opts[:witnesses]
78
+ @trials = trials.max
79
+ end
80
+
81
+ # Find R and S such that 2^r * s + 1 == @number (as per MR def'n)
82
+ def resolve_r_and_s
83
+ @r,@s=0,@number-1
84
+ while(@s.even?)
85
+ @r += 1
86
+ @s /= 2
87
+ end
88
+ end
89
+
90
+ # Witnesses require for absoulte certainty for any number < key
91
+ # OR
92
+ # the number of trials specified by :witnesses or :precision arguments
93
+ # Source Wikipedia and "The Primes Page"
94
+ def witnesses
95
+ witnesses = []
96
+ if @number < 1_373_653
97
+ witnesses = [2,3]
98
+ elsif @number < 9_080_191
99
+ witnesses = [31,73]
100
+ elsif @number < 4_759_123_141
101
+ witnesses = [2,7,61]
102
+ elsif @number < 2_152_302_898_747
103
+ witnesses = [2,3,5,7,11]
104
+ elsif @number < 3_474_749_660_383
105
+ witnesses = [2, 3, 5, 7, 11, 13]
106
+ elsif @number < 341_550_071_728_321
107
+ witnesses = [2, 3, 5, 7, 11, 13, 17]
108
+ elsif @precision
109
+ witnesses = (2...@number)
110
+ else
111
+ witnesses = Array.new(@trials).map { rand(@number-1)+1 }
112
+ end
113
+ return witnesses
114
+ end
115
+ end
116
+
117
+ if __FILE__ == $0 and !ARGV.empty?
118
+ puts MR_Prime[ARGV.shift.to_i]
119
+ end
metadata ADDED
@@ -0,0 +1,61 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mr_prime
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Burke Libbey
8
+ - Ryan Neufeld
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2009-12-07 00:00:00 -06:00
14
+ default_executable:
15
+ dependencies: []
16
+
17
+ description: An Uber-fast primality testing library.
18
+ email: burke@burkelibbey.org
19
+ executables: []
20
+
21
+ extensions:
22
+ - ext/extconf.rb
23
+ extra_rdoc_files: []
24
+
25
+ files:
26
+ - Rakefile
27
+ - VERSION
28
+ - ext/Makefile
29
+ - ext/extconf.rb
30
+ - ext/prime.c
31
+ - lib/mr_prime/mr_prime_rb.rb
32
+ has_rdoc: true
33
+ homepage: http://github.com/rkneufeld/mr_prime
34
+ licenses: []
35
+
36
+ post_install_message:
37
+ rdoc_options:
38
+ - --charset=UTF-8
39
+ require_paths:
40
+ - lib
41
+ required_ruby_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: "0"
46
+ version:
47
+ required_rubygems_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: "0"
52
+ version:
53
+ requirements: []
54
+
55
+ rubyforge_project:
56
+ rubygems_version: 1.3.5
57
+ signing_key:
58
+ specification_version: 3
59
+ summary: An Uber-fast primality testing library.
60
+ test_files: []
61
+