nsphere 0.1.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.
Files changed (2) hide show
  1. data/lib/nsphere.rb +105 -0
  2. metadata +46 -0
data/lib/nsphere.rb ADDED
@@ -0,0 +1,105 @@
1
+ # encoding: utf-8
2
+
3
+ class NSphere
4
+ attr_reader :radius, :thetas, :coordinates
5
+
6
+ def initialize(args)
7
+ if not (args[:radius].nil? or args[:thetas].nil?)
8
+ if check_argument(args[:radius], args[:thetas])
9
+ build_by_radius_thetas(args[:radius], args[:thetas])
10
+ else
11
+ raise "Argument range error, please make sure you initialize" +
12
+ " proper n-dimensional sphere."
13
+ end
14
+ elsif not args[:coord].nil?
15
+ build_by_coordinate(args[:coord])
16
+ else
17
+ raise ArgumentError, "Arguments must contain :radius and :thetas field" +
18
+ " or :coord field"
19
+ end
20
+ end
21
+
22
+ def check_argument(radius, thetas)
23
+ radius >= 0.0 and thetas[0..-2].all? { |x| x >= 0 and x <= Math::PI} and
24
+ thetas[-1] >= 0 and thetas[-1] <= 2 * Math::PI
25
+ end
26
+
27
+ def build_by_radius_thetas(radius, thetas)
28
+ @radius = radius
29
+ @thetas = thetas
30
+ dim = @thetas.size + 1
31
+ @coordinates = [0.0] * dim
32
+ (0..(dim - 2)).to_a.each do |idx|
33
+ tmp = @radius
34
+ (0..(idx - 1)).to_a { |j| tmp = tmp * Math.sin(@thetas[j])}
35
+ @coordinates[idx] = tmp * Math.cos(@thetas[idx])
36
+ end
37
+ @coordinates[-1] = @thetas.map { |x| Math.sin(x)}.inject(@radius, :*)
38
+ end
39
+
40
+ def build_by_coordinate(coordinates)
41
+ @coordinates = coordinates
42
+ dim = @coordinates.size
43
+ coord_square = coordinates.map { |x| x ** 2}
44
+ @radius = Math.sqrt(coord_square.inject(:+))
45
+ sum = [0] * (dim + 1)
46
+ coord_square.each_with_index do |elem, idx|
47
+ sum[idx + 1] = sum[idx] + elem
48
+ end
49
+ @thetas = [0.0] * (dim - 1)
50
+ @thetas[dim - 2] = Math.atan2(coordinates[dim - 1], coordinates[dim - 2])
51
+ (0..(dim - 3)).to_a.reverse.each do |idx|
52
+ @thetas[idx] = atan((sum[dim - 1] - sum[idx]) , coordinates[idx])
53
+ end
54
+ end
55
+
56
+ def atan(y, x)
57
+ if x.abs <= 10e-6 && y.abs <= 10e-6
58
+ return 0.0
59
+ else
60
+ return Math.atan(y / x)
61
+ end
62
+ end
63
+
64
+ def negate
65
+ NSphere.new(radius: -self.radius,
66
+ thetas: self.thetas.map { |x| -x})
67
+ end
68
+
69
+ def +(a)
70
+ tmp = self.coordinates.zip(a.coordinates).map { |x|
71
+ x.inject(:+)
72
+ }
73
+ NSphere.new(coord: tmp)
74
+ end
75
+
76
+ def -(a)
77
+ self + a.negate
78
+ end
79
+
80
+ def *(a)
81
+ tmp = self.coordinates.zip(a.coordinates).map { |x|
82
+ x.inject(:+)
83
+ }
84
+ NSphere.new(radius: self.radius * a.radius,
85
+ thetas: tmp)
86
+ end
87
+
88
+ def /(a)
89
+ tmp = self.coordinates.zip(a.coordinates).map { |x|
90
+ x[0] - x[1]
91
+ }
92
+ NSphere.new(radius: self.radius / a.radius,
93
+ thetas: tmp)
94
+ end
95
+
96
+ def self.random_vector(dim, radius = 1.0)
97
+ thetas = [0.0] * (dim - 1)
98
+ thetas[-1] = Random.rand(0..(2 * Math::PI))
99
+ (0..(dim - 3)).to_a.each do |idx|
100
+ thetas[idx] = Random.rand(0..Math::PI)
101
+ end
102
+ NSphere.new(radius: radius,
103
+ thetas: thetas)
104
+ end
105
+ end
metadata ADDED
@@ -0,0 +1,46 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nsphere
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - m00nlight
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-09-16 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: ruby implementation of n-sphere
15
+ email: dot_wangyushi@yeah.net
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/nsphere.rb
21
+ homepage: https://github.com/m00nlight/nsphere
22
+ licenses:
23
+ - MIT
24
+ post_install_message:
25
+ rdoc_options: []
26
+ require_paths:
27
+ - lib
28
+ required_ruby_version: !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ required_rubygems_version: !ruby/object:Gem::Requirement
35
+ none: false
36
+ requirements:
37
+ - - ! '>='
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ requirements: []
41
+ rubyforge_project:
42
+ rubygems_version: 1.8.23
43
+ signing_key:
44
+ specification_version: 3
45
+ summary: NSphere
46
+ test_files: []