int 0.0.1.interval
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.
- checksums.yaml +7 -0
- data/README.md +41 -0
- data/Rakefile +10 -0
- data/lib/int/version.rb +3 -0
- data/lib/int.rb +139 -0
- data/sig/int.rbs +4 -0
- metadata +105 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 949f5639815b1a5a2655f7e1db7982baf19d8d60e1029d2cb88fb246dc2c64f8
|
4
|
+
data.tar.gz: 98b7c7df5ade14a9dca26cfb3fce1271b1eeede5950f36c8765f8b3917f76c9d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 450dd42f73818e5dd8561cf7ac081b8c8a6d095586f8473febe1a57a397a534ff59d2ee1ff0eee22078e8133a1f8706402da8a8a7eee1969b8848db283d5145d
|
7
|
+
data.tar.gz: 119b66a9ccb05c68ab503688b9a0d7813d9d9f4fac638d6303cef07a2e7c186c0601196f2764f1c7eb03084cb8d2abc0844da12dd98b3081e948b77c75a849db
|
data/README.md
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
# Int
|
2
|
+
|
3
|
+
An interval-arithmetic-ish library (with a terrible name).
|
4
|
+
|
5
|
+
## Introduction
|
6
|
+
|
7
|
+
Welcome to my new gem! In this directory, I'll find the files I need to be able to package
|
8
|
+
up my Ruby library into a gem. Put my Ruby code in the file `lib/int`. To experiment with
|
9
|
+
that code, run `bin/console` for an interactive prompt.
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
Install the gem and add to the application's Gemfile by executing:
|
14
|
+
|
15
|
+
$ bundle add int
|
16
|
+
|
17
|
+
If bundler is not being used to manage dependencies, install the gem by executing:
|
18
|
+
|
19
|
+
$ gem install int
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
pp Int(1, 2) + Int(3, 4) #=> Int(4..(5.0)..6)
|
25
|
+
```
|
26
|
+
|
27
|
+
## Development
|
28
|
+
|
29
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake
|
30
|
+
test-unit` to run the tests. You can also run `bin/console` for an interactive prompt that
|
31
|
+
will allow you to experiment.
|
32
|
+
|
33
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a
|
34
|
+
new version, update the version number in `version.rb`, and then run `bundle exec rake
|
35
|
+
release`, which will create a git tag for the version, push git commits and the created
|
36
|
+
tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
37
|
+
|
38
|
+
## Contributing
|
39
|
+
|
40
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/tadd/int
|
41
|
+
except for name change proposals.
|
data/Rakefile
ADDED
data/lib/int/version.rb
ADDED
data/lib/int.rb
ADDED
@@ -0,0 +1,139 @@
|
|
1
|
+
# Interval arithmetics
|
2
|
+
|
3
|
+
require_relative "int/version"
|
4
|
+
|
5
|
+
class Int < Numeric
|
6
|
+
attr_reader :begin, :end, :median
|
7
|
+
protected attr_reader :values
|
8
|
+
|
9
|
+
def initialize(beg, encl = nil, error: nil)
|
10
|
+
if error
|
11
|
+
raise ArgumentError, 'do not specify 2nd arg when `error:`' if encl
|
12
|
+
raise ArgumentError, 'error value should be non-negtative' if error.negative?
|
13
|
+
med = beg
|
14
|
+
beg, encl = med-error, med+error
|
15
|
+
else
|
16
|
+
raise ArgumentError, 'specify 2nd arg when no `error:`' unless encl
|
17
|
+
raise ArgumentError, "needs begin <= end: #{beg} <=> #{encl}" unless beg <= encl
|
18
|
+
end
|
19
|
+
@begin, @end = beg, encl
|
20
|
+
@values = [beg, encl]
|
21
|
+
@median = (beg + encl) / 2.0
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def new(...) = self.class.new(...)
|
27
|
+
def scala?(other) = [Integer, Float, Rational].include?(other.class)
|
28
|
+
def ensure_coerced(other) = other.kind_of?(self.class) ? other : coerce(other).first
|
29
|
+
|
30
|
+
protected
|
31
|
+
|
32
|
+
def round_median(n) = (@median = @median.round(n)).then { self }
|
33
|
+
def invert
|
34
|
+
one = @end.zero? ? -1.0 : 1.0
|
35
|
+
new(one / @end, 1.0 / @begin)
|
36
|
+
end
|
37
|
+
|
38
|
+
public
|
39
|
+
|
40
|
+
def self.error(error)
|
41
|
+
new(1, error:)
|
42
|
+
end
|
43
|
+
|
44
|
+
def coerce(other)
|
45
|
+
if scala?(other)
|
46
|
+
other = new(*[other]*2)
|
47
|
+
else
|
48
|
+
raise "Unknown class #{other.class}: #{other}"
|
49
|
+
end
|
50
|
+
[other, self]
|
51
|
+
end
|
52
|
+
|
53
|
+
def +(other)
|
54
|
+
other = ensure_coerced(other)
|
55
|
+
new(@begin + other.begin, @end + other.end)
|
56
|
+
end
|
57
|
+
|
58
|
+
def -(other)
|
59
|
+
other = ensure_coerced(other)
|
60
|
+
new(@begin - other.end, @end - other.begin)
|
61
|
+
end
|
62
|
+
|
63
|
+
def *(other)
|
64
|
+
other = ensure_coerced(other)
|
65
|
+
mul = values.product(other.values).map{_1.inject(:*)}
|
66
|
+
raise "got a NaN; I don't know what to do" if mul.any?{|x| x.respond_to?(:nan?) && x.nan?}
|
67
|
+
new(*mul.minmax)
|
68
|
+
end
|
69
|
+
|
70
|
+
def /(other)
|
71
|
+
self * ensure_coerced(other).invert
|
72
|
+
end
|
73
|
+
|
74
|
+
def <=>(other)
|
75
|
+
other = ensure_coerced(other)
|
76
|
+
return 0 if @begin == @end && @begin == other.begin && @begin == other.end
|
77
|
+
return 1 if @begin > other.end
|
78
|
+
return -1 if @end < other.begin
|
79
|
+
nil
|
80
|
+
end
|
81
|
+
|
82
|
+
def <=(other)
|
83
|
+
other = ensure_coerced(other)
|
84
|
+
@end <= other.begin
|
85
|
+
end
|
86
|
+
|
87
|
+
def >=(other)
|
88
|
+
other = ensure_coerced(other)
|
89
|
+
@begin >= other.end
|
90
|
+
end
|
91
|
+
|
92
|
+
def comparable?(other)
|
93
|
+
other = ensure_coerced(other) rescue (return false)
|
94
|
+
!!(self <=> other) || @end == other.begin || @begin == other.end
|
95
|
+
end
|
96
|
+
|
97
|
+
def round(n)
|
98
|
+
new(*[self.begin,self.end].map{_1.round(n)}).round_median(n)
|
99
|
+
end
|
100
|
+
|
101
|
+
def with_error(e) = self * self.class.error(e)
|
102
|
+
def with_error_percent(e) = with_error(e * 0.01)
|
103
|
+
|
104
|
+
def to_s = "(#{self.begin}..#{self.end})"
|
105
|
+
def inspect = self.class.name + to_s.sub('..', "..(#{median})..")
|
106
|
+
end
|
107
|
+
|
108
|
+
def Int(...) = Int.new(...)
|
109
|
+
|
110
|
+
if $0 == __FILE__
|
111
|
+
x, y = Int(1, 2), Int(2, 3)
|
112
|
+
pp(x:, y:)
|
113
|
+
|
114
|
+
pp [x == y, x != y]
|
115
|
+
pp [x >= y, x <= y]
|
116
|
+
pp [y >= x, y <= x]
|
117
|
+
pp [x.comparable?(y), y.comparable?(x)]
|
118
|
+
|
119
|
+
z = Int(1.1, 1.4)
|
120
|
+
pp z
|
121
|
+
pp [x.comparable?(z), z.comparable?(x)]
|
122
|
+
pp z.comparable?(:foo)
|
123
|
+
pp z.round(1)
|
124
|
+
pp Int.error(0.2)
|
125
|
+
|
126
|
+
pp [x.with_error(0.01), x.with_error_percent(1)].map{_1.round(2)}
|
127
|
+
|
128
|
+
pp [z / 2, z / z].map{_1.round(2)}
|
129
|
+
|
130
|
+
i = Int(0, 1.2)
|
131
|
+
j = Int(-1.2, 0)
|
132
|
+
pp [x/i, x/j]
|
133
|
+
ji = j.send(:invert)
|
134
|
+
pp ji
|
135
|
+
pp [i, ji]
|
136
|
+
#pp i*ji
|
137
|
+
#pp i/j
|
138
|
+
#pp j/i
|
139
|
+
end
|
data/sig/int.rbs
ADDED
metadata
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: int
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1.interval
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Tadashi Saito
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-01-18 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: test-unit
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: debug
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: steep
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description:
|
70
|
+
email:
|
71
|
+
- tad.a.digger@gmail.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- README.md
|
77
|
+
- Rakefile
|
78
|
+
- lib/int.rb
|
79
|
+
- lib/int/version.rb
|
80
|
+
- sig/int.rbs
|
81
|
+
homepage: https://github.com/tadd/int
|
82
|
+
licenses: []
|
83
|
+
metadata:
|
84
|
+
homepage_uri: https://github.com/tadd/int
|
85
|
+
source_code_uri: https://github.com/tadd/int
|
86
|
+
post_install_message:
|
87
|
+
rdoc_options: []
|
88
|
+
require_paths:
|
89
|
+
- lib
|
90
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
91
|
+
requirements:
|
92
|
+
- - ">="
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '0'
|
95
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
96
|
+
requirements:
|
97
|
+
- - ">="
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '0'
|
100
|
+
requirements: []
|
101
|
+
rubygems_version: 3.5.4
|
102
|
+
signing_key:
|
103
|
+
specification_version: 4
|
104
|
+
summary: Interval-arithmetic-ish library with a terrible name.
|
105
|
+
test_files: []
|