frac 0.9.0
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.
- data/ext/extconf.rb +4 -0
- data/ext/frac_ext.c +83 -0
- data/lib/frac.rb +10 -0
- metadata +64 -0
data/ext/extconf.rb
ADDED
data/ext/frac_ext.c
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
// http://www.ics.uci.edu/~eppstein/numth/frap.c
|
2
|
+
/*
|
3
|
+
** find rational approximation to given real number
|
4
|
+
** David Eppstein / UC Irvine / 8 Aug 1993
|
5
|
+
**
|
6
|
+
** With corrections from Arno Formella, May 2008
|
7
|
+
**
|
8
|
+
** usage: a.out r d
|
9
|
+
** r is real number to approx
|
10
|
+
** d is the maximum denominator allowed
|
11
|
+
**
|
12
|
+
** based on the theory of continued fractions
|
13
|
+
** if x = a1 + 1/(a2 + 1/(a3 + 1/(a4 + ...)))
|
14
|
+
** then best approximation is found by truncating this series
|
15
|
+
** (with some adjustments in the last term).
|
16
|
+
**
|
17
|
+
** Note the fraction can be recovered as the first column of the matrix
|
18
|
+
** ( a1 1 ) ( a2 1 ) ( a3 1 ) ...
|
19
|
+
** ( 1 0 ) ( 1 0 ) ( 1 0 )
|
20
|
+
** Instead of keeping the sequence of continued fraction terms,
|
21
|
+
** we just keep the last partial product of these matrices.
|
22
|
+
*/
|
23
|
+
|
24
|
+
#include <stdio.h>
|
25
|
+
#include <ruby.h>
|
26
|
+
|
27
|
+
static VALUE find_fracs(VALUE mod, VALUE rv, VALUE dv)
|
28
|
+
{
|
29
|
+
VALUE ret;
|
30
|
+
long m[2][2];
|
31
|
+
double startx, x = RFLOAT_VALUE(rv);
|
32
|
+
long ai, maxden = NUM2LONG(dv);
|
33
|
+
|
34
|
+
startx = x;
|
35
|
+
|
36
|
+
/* initialize matrix */
|
37
|
+
m[0][0] = m[1][1] = 1;
|
38
|
+
m[0][1] = m[1][0] = 0;
|
39
|
+
|
40
|
+
/* loop finding terms until denom gets too big */
|
41
|
+
while (m[1][0] * ( ai = (long)x ) + m[1][1] <= maxden) {
|
42
|
+
long t;
|
43
|
+
t = m[0][0] * ai + m[0][1];
|
44
|
+
m[0][1] = m[0][0];
|
45
|
+
m[0][0] = t;
|
46
|
+
t = m[1][0] * ai + m[1][1];
|
47
|
+
m[1][1] = m[1][0];
|
48
|
+
m[1][0] = t;
|
49
|
+
if(x==(double)ai) break; // AF: division by zero
|
50
|
+
x = 1/(x - (double) ai);
|
51
|
+
if(x>(double)0x7FFFFFFF) break; // AF: representation failure
|
52
|
+
}
|
53
|
+
|
54
|
+
{
|
55
|
+
/* now remaining x is between 0 and 1/ai */
|
56
|
+
/* approx as either 0 or 1/m where m is max that will fit in maxden */
|
57
|
+
/* first try zero */
|
58
|
+
VALUE num1, den1, err1, num2, den2, err2;
|
59
|
+
|
60
|
+
num1 = LONG2NUM(m[0][0]);
|
61
|
+
den1 = LONG2NUM(m[1][0]);
|
62
|
+
err1 = rb_float_new(startx - ((double) m[0][0] / (double) m[1][0]));
|
63
|
+
|
64
|
+
/* now try other possibility */
|
65
|
+
ai = (maxden - m[1][1]) / m[1][0];
|
66
|
+
m[0][0] = m[0][0] * ai + m[0][1];
|
67
|
+
m[1][0] = m[1][0] * ai + m[1][1];
|
68
|
+
|
69
|
+
num2 = LONG2NUM(m[0][0]);
|
70
|
+
den2 = LONG2NUM(m[1][0]);
|
71
|
+
err2 = rb_float_new(startx - ((double) m[0][0] / (double) m[1][0]));
|
72
|
+
|
73
|
+
return rb_ary_new3(6, num1, den1, err1, num2, den2, err2);
|
74
|
+
}
|
75
|
+
}
|
76
|
+
|
77
|
+
|
78
|
+
void Init_frac_ext()
|
79
|
+
{
|
80
|
+
rb_define_module_function(rb_mMath, "find_fracs", find_fracs, 2);
|
81
|
+
}
|
82
|
+
|
83
|
+
|
data/lib/frac.rb
ADDED
metadata
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: frac
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 9
|
8
|
+
- 0
|
9
|
+
version: 0.9.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Pavel Valodzka
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-05-25 00:00:00 +03:00
|
18
|
+
default_executable:
|
19
|
+
dependencies: []
|
20
|
+
|
21
|
+
description: Find rational approximation to given real number
|
22
|
+
email: pavel@valodzka.name
|
23
|
+
executables: []
|
24
|
+
|
25
|
+
extensions:
|
26
|
+
- ext/extconf.rb
|
27
|
+
extra_rdoc_files: []
|
28
|
+
|
29
|
+
files:
|
30
|
+
- ext/frac_ext.c
|
31
|
+
- ext/extconf.rb
|
32
|
+
- lib/frac.rb
|
33
|
+
has_rdoc: true
|
34
|
+
homepage: http://github.com/valodzka/frac
|
35
|
+
licenses: []
|
36
|
+
|
37
|
+
post_install_message:
|
38
|
+
rdoc_options: []
|
39
|
+
|
40
|
+
require_paths:
|
41
|
+
- lib
|
42
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
segments:
|
47
|
+
- 0
|
48
|
+
version: "0"
|
49
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
segments:
|
54
|
+
- 0
|
55
|
+
version: "0"
|
56
|
+
requirements: []
|
57
|
+
|
58
|
+
rubyforge_project:
|
59
|
+
rubygems_version: 1.3.6
|
60
|
+
signing_key:
|
61
|
+
specification_version: 2
|
62
|
+
summary: Find rational approximation to given real number. based on the theory of continued fractions if x = a1 + 1/(a2 + 1/(a3 + 1/(a4 + ...))) then best approximation is found by truncating this series (with some adjustments in the last term). Note the fraction can be recovered as the first column of the matrix ( a1 1 ) ( a2 1 ) ( a3 1 ) ... ( 1 0 ) ( 1 0 ) ( 1 0 ) Instead of keeping the sequence of continued fraction terms, we just keep the last partial product of these matrices.
|
63
|
+
test_files: []
|
64
|
+
|