flt 1.2.1 → 1.3.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/History.txt +10 -0
- data/Manifest.txt +5 -0
- data/README.txt +16 -10
- data/lib/flt/bin_num.rb +4 -0
- data/lib/flt/complex.rb +312 -0
- data/lib/flt/dec_num.rb +0 -21
- data/lib/flt/math.rb +47 -567
- data/lib/flt/num.rb +249 -20
- data/lib/flt/trigonometry.rb +746 -0
- data/lib/flt/version.rb +2 -2
- data/test/generate_trig_data.rb +169 -0
- data/test/test_basic.rb +5 -0
- metadata +11 -4
    
        data/lib/flt/version.rb
    CHANGED
    
    
| @@ -0,0 +1,169 @@ | |
| 1 | 
            +
            # Generate test data for trigonometry tests (test_trig.rbG)
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require File.expand_path(File.join(File.dirname(__FILE__),'helper.rb'))
         | 
| 4 | 
            +
            require File.dirname(__FILE__) + '/../lib/flt/math'
         | 
| 5 | 
            +
            include Flt
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            def around(x)
         | 
| 8 | 
            +
              [x,x.next_plus,x.next_minus,x.next_plus.next_plus,x.next_minus.next_minus]
         | 
| 9 | 
            +
            end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            def near(x)
         | 
| 12 | 
            +
              ulp = x.ulp
         | 
| 13 | 
            +
              prec = x.num_class.context.precision
         | 
| 14 | 
            +
              xs = around(x)
         | 
| 15 | 
            +
              [2,3,4].each do |k|
         | 
| 16 | 
            +
                d = (prec/k)*ulp
         | 
| 17 | 
            +
                xs += around(x-d)
         | 
| 18 | 
            +
                xs += around(x+d)
         | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
              xs.uniq
         | 
| 21 | 
            +
            end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
            # random angles in radians for sin,cos,tan
         | 
| 24 | 
            +
            def angle_data(num_class)
         | 
| 25 | 
            +
              xs = []
         | 
| 26 | 
            +
              pi = num_class::Math.send(:half_cycle)
         | 
| 27 | 
            +
              (-8..8).each do |k|
         | 
| 28 | 
            +
                x = k*pi/4
         | 
| 29 | 
            +
                xs += near(x)
         | 
| 30 | 
            +
              end
         | 
| 31 | 
            +
              pi2 = num_class::Math.send(:quarter_cycle)
         | 
| 32 | 
            +
              50.times{ xs << random_num_one(num_class)*pi2}
         | 
| 33 | 
            +
              base = xs.dup
         | 
| 34 | 
            +
              (2...10).each do |k|
         | 
| 35 | 
            +
                xs += base.map{|x| x+num_class.int_radix_power(k)}
         | 
| 36 | 
            +
              end
         | 
| 37 | 
            +
              xs.uniq
         | 
| 38 | 
            +
            end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
            # random data in [-1,-1] for asin, acos
         | 
| 41 | 
            +
            def one_data(num_class)
         | 
| 42 | 
            +
              half = num_class.Num(1)/2
         | 
| 43 | 
            +
              zero = num_class.Num(0)
         | 
| 44 | 
            +
              one = num_class.Num(1)
         | 
| 45 | 
            +
              xs = [-one, -half, zero, half, one].map{|x| near(x)}.flatten
         | 
| 46 | 
            +
              50.times{ xs << random_num_one(num_class)}
         | 
| 47 | 
            +
              xs.uniq.reject{|x| x<-1 || x>1}
         | 
| 48 | 
            +
            end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
            def random_num_one(num_class=DecNum)
         | 
| 51 | 
            +
              context = num_class.context
         | 
| 52 | 
            +
              if false # rand(20)==0
         | 
| 53 | 
            +
                # generate 5% of subnormals
         | 
| 54 | 
            +
                f = rand(context.radix**(context.precision-1))
         | 
| 55 | 
            +
                e = context.etiny
         | 
| 56 | 
            +
              elsif rand(20)==0
         | 
| 57 | 
            +
                # and some singular values too
         | 
| 58 | 
            +
                if rand(1) == 0
         | 
| 59 | 
            +
                  f = context.radix**context.precision - 1
         | 
| 60 | 
            +
                  f -= rand(3)
         | 
| 61 | 
            +
                else
         | 
| 62 | 
            +
                  f = context.radix**(context.precision - 1)
         | 
| 63 | 
            +
                  f += rand(3)
         | 
| 64 | 
            +
                end
         | 
| 65 | 
            +
                # e = random_integer(context.etiny, context.etop)
         | 
| 66 | 
            +
                if rand(1)==0
         | 
| 67 | 
            +
                  e = random_integer(-context.precision-1,-context.precision)
         | 
| 68 | 
            +
                 else
         | 
| 69 | 
            +
                  e = random_integer(-context.precision-10,-context.precision)
         | 
| 70 | 
            +
                end
         | 
| 71 | 
            +
              else
         | 
| 72 | 
            +
                f = rand(context.radix**context.precision)
         | 
| 73 | 
            +
                # e = random_integer(context.etiny, context.etop)
         | 
| 74 | 
            +
                if rand(1)==0
         | 
| 75 | 
            +
                  e = random_integer(-context.precision-1,-context.precision)
         | 
| 76 | 
            +
                 else
         | 
| 77 | 
            +
                  e = random_integer(-context.precision-10,-context.precision)
         | 
| 78 | 
            +
                end
         | 
| 79 | 
            +
              end
         | 
| 80 | 
            +
              # f = -f if rand(1)==0
         | 
| 81 | 
            +
              context.Num(f, e)
         | 
| 82 | 
            +
            end
         | 
| 83 | 
            +
             | 
| 84 | 
            +
             | 
| 85 | 
            +
            def gen_test_data(num_class, prec, angle_units=:rad)
         | 
| 86 | 
            +
              dir = File.dirname(__FILE__)+'/trigtest'
         | 
| 87 | 
            +
              num_class.context(:precision=>prec) do
         | 
| 88 | 
            +
                num_class.context.angle = angle_units
         | 
| 89 | 
            +
                DecNum.context.traps[DecNum::DivisionByZero] = false
         | 
| 90 | 
            +
                radix = "#{num_class.context.radix}_"
         | 
| 91 | 
            +
                units = "_#{num_class.context.angle}"
         | 
| 92 | 
            +
                angles = angle_data(num_class)
         | 
| 93 | 
            +
                extra_prec = prec + 100
         | 
| 94 | 
            +
                extra_elimit = [10000, num_class.context.emax.abs, num_class.context.emin.abs].max
         | 
| 95 | 
            +
                File.open("#{dir}/sin#{radix}#{prec}#{units}.txt","w") do |out|
         | 
| 96 | 
            +
                  angles.each do |angle|
         | 
| 97 | 
            +
                    result = +num_class.context(:precision=>extra_prec, :elimit=>extra_elimit) {
         | 
| 98 | 
            +
                      num_class::Math.sin(angle)
         | 
| 99 | 
            +
                    }
         | 
| 100 | 
            +
                    out.puts "#{angle.to_s(:base=>num_class.radix)}\t#{result.to_s(:base=>num_class.radix)}"
         | 
| 101 | 
            +
                  end
         | 
| 102 | 
            +
                end
         | 
| 103 | 
            +
                File.open("#{dir}/cos#{radix}#{prec}#{units}.txt","w") do |out|
         | 
| 104 | 
            +
                  angles.each do |angle|
         | 
| 105 | 
            +
                    result = +num_class.context(:precision=>extra_prec, :elimit=>extra_elimit) {
         | 
| 106 | 
            +
                      num_class::Math.cos(angle)
         | 
| 107 | 
            +
                    }
         | 
| 108 | 
            +
                    out.puts "#{angle.to_s(:base=>num_class.radix)}\t#{result.to_s(:base=>num_class.radix)}"
         | 
| 109 | 
            +
                  end
         | 
| 110 | 
            +
                end
         | 
| 111 | 
            +
                File.open("#{dir}/tan#{radix}#{prec}#{units}.txt","w") do |out|
         | 
| 112 | 
            +
                  angles.each do |angle|
         | 
| 113 | 
            +
                    result = +num_class.context(:precision=>extra_prec, :elimit=>extra_elimit) {
         | 
| 114 | 
            +
                      num_class::Math.tan(angle)
         | 
| 115 | 
            +
                    }
         | 
| 116 | 
            +
                    out.puts "#{angle.to_s(:base=>num_class.radix)}\t#{result.to_s(:base=>num_class.radix)}"
         | 
| 117 | 
            +
                  end
         | 
| 118 | 
            +
                end
         | 
| 119 | 
            +
                xs = one_data(num_class)
         | 
| 120 | 
            +
                File.open("#{dir}/asin#{radix}#{prec}#{units}.txt","w") do |out|
         | 
| 121 | 
            +
                  xs.each do |x|
         | 
| 122 | 
            +
                    result = +num_class.context(:precision=>extra_prec, :elimit=>extra_elimit) {
         | 
| 123 | 
            +
                      num_class::Math.asin(x)
         | 
| 124 | 
            +
                    }
         | 
| 125 | 
            +
                    out.puts "#{x.to_s(:base=>num_class.radix)}\t#{result.to_s(:base=>num_class.radix)}"
         | 
| 126 | 
            +
                  end
         | 
| 127 | 
            +
                end
         | 
| 128 | 
            +
                File.open("#{dir}/acos#{radix}#{prec}#{units}.txt","w") do |out|
         | 
| 129 | 
            +
                  xs.each do |x|
         | 
| 130 | 
            +
                    result = +num_class.context(:precision=>extra_prec, :elimit=>extra_elimit) {
         | 
| 131 | 
            +
                      num_class::Math.acos(x)
         | 
| 132 | 
            +
                    }
         | 
| 133 | 
            +
                    out.puts "#{x.to_s(:base=>num_class.radix)}\t#{result.to_s(:base=>num_class.radix)}"
         | 
| 134 | 
            +
                  end
         | 
| 135 | 
            +
                end
         | 
| 136 | 
            +
                xs += Array.new(100){random_num(num_class)}
         | 
| 137 | 
            +
                File.open("#{dir}/atan#{radix}#{prec}#{units}.txt","w") do |out|
         | 
| 138 | 
            +
                  xs.each do |x|
         | 
| 139 | 
            +
                    result = +num_class.context(:precision=>extra_prec, :elimit=>extra_elimit) {
         | 
| 140 | 
            +
                      num_class::Math.atan(x)
         | 
| 141 | 
            +
                    }
         | 
| 142 | 
            +
                    out.puts "#{x.to_s(:base=>num_class.radix)}\t#{result.to_s(:base=>num_class.radix)}"
         | 
| 143 | 
            +
                  end
         | 
| 144 | 
            +
                end
         | 
| 145 | 
            +
              end
         | 
| 146 | 
            +
            end
         | 
| 147 | 
            +
             | 
| 148 | 
            +
            srand 12322
         | 
| 149 | 
            +
            gen_test_data DecNum, 12, :rad
         | 
| 150 | 
            +
             | 
| 151 | 
            +
            srand 12322
         | 
| 152 | 
            +
            gen_test_data DecNum, 12, :deg
         | 
| 153 | 
            +
             | 
| 154 | 
            +
            srand 12322
         | 
| 155 | 
            +
            BinNum.context = BinNum::IEEEDoubleContext
         | 
| 156 | 
            +
            gen_test_data BinNum, 53, :rad
         | 
| 157 | 
            +
             | 
| 158 | 
            +
             | 
| 159 | 
            +
            # TODO:
         | 
| 160 | 
            +
            # 1. prepare test data for 12, 15, 25, 50 digits with gen_test_data
         | 
| 161 | 
            +
            # 2. check with RPL, Mathematica:
         | 
| 162 | 
            +
            #    programs that process test data and prepare RPL/Mathematica programs that yield results
         | 
| 163 | 
            +
            #    then check results
         | 
| 164 | 
            +
            #    RPL: (to be executed in emulator for speed/ease of I/O)
         | 
| 165 | 
            +
            #     \<< [angle1, angle2, angle3, ...] N \-> D N \<< 1 N FOR I D I GET SIN NEXT N \->LIST \>> |>>
         | 
| 166 | 
            +
            #    Mathematica:
         | 
| 167 | 
            +
            #      F[x_]:=N[Sin[x],prec]
         | 
| 168 | 
            +
            #      Map[F, {angle1.to_r.to_s, angle2.to_r.to_s, ...}]
         | 
| 169 | 
            +
            # 3. add special number tests (nans, infinities)
         | 
    
        data/test/test_basic.rb
    CHANGED
    
    | @@ -101,6 +101,11 @@ class TestBasic < Test::Unit::TestCase | |
| 101 101 | 
             
                }
         | 
| 102 102 | 
             
                assert_equal 10, DecNum.context.precision
         | 
| 103 103 |  | 
| 104 | 
            +
                DecNum.context(:extra_precision=>4) {
         | 
| 105 | 
            +
                  assert_equal 14, DecNum.context.precision
         | 
| 106 | 
            +
                }
         | 
| 107 | 
            +
                assert_equal 10, DecNum.context.precision
         | 
| 108 | 
            +
             | 
| 104 109 | 
             
                DecNum.local_context(DecNum::BasicContext) {
         | 
| 105 110 | 
             
                  assert_equal :half_up, DecNum.context.rounding
         | 
| 106 111 | 
             
                  assert_equal 9, DecNum.context.precision
         | 
    
        metadata
    CHANGED
    
    | @@ -1,12 +1,13 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification 
         | 
| 2 2 | 
             
            name: flt
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version 
         | 
| 4 | 
            +
              hash: 27
         | 
| 4 5 | 
             
              prerelease: false
         | 
| 5 6 | 
             
              segments: 
         | 
| 6 7 | 
             
              - 1
         | 
| 7 | 
            -
              -  | 
| 8 | 
            -
              -  | 
| 9 | 
            -
              version: 1. | 
| 8 | 
            +
              - 3
         | 
| 9 | 
            +
              - 0
         | 
| 10 | 
            +
              version: 1.3.0
         | 
| 10 11 | 
             
            platform: ruby
         | 
| 11 12 | 
             
            authors: 
         | 
| 12 13 | 
             
            - Javier Goizueta
         | 
| @@ -14,7 +15,7 @@ autorequire: | |
| 14 15 | 
             
            bindir: bin
         | 
| 15 16 | 
             
            cert_chain: []
         | 
| 16 17 |  | 
| 17 | 
            -
            date: 2010-06- | 
| 18 | 
            +
            date: 2010-06-22 00:00:00 +02:00
         | 
| 18 19 | 
             
            default_executable: 
         | 
| 19 20 | 
             
            dependencies: 
         | 
| 20 21 | 
             
            - !ruby/object:Gem::Dependency 
         | 
| @@ -25,6 +26,7 @@ dependencies: | |
| 25 26 | 
             
                requirements: 
         | 
| 26 27 | 
             
                - - ">="
         | 
| 27 28 | 
             
                  - !ruby/object:Gem::Version 
         | 
| 29 | 
            +
                    hash: 9
         | 
| 28 30 | 
             
                    segments: 
         | 
| 29 31 | 
             
                    - 2
         | 
| 30 32 | 
             
                    - 1
         | 
| @@ -52,6 +54,7 @@ files: | |
| 52 54 | 
             
            - lib/flt/b.rb
         | 
| 53 55 | 
             
            - lib/flt/bigdecimal.rb
         | 
| 54 56 | 
             
            - lib/flt/bin_num.rb
         | 
| 57 | 
            +
            - lib/flt/complex.rb
         | 
| 55 58 | 
             
            - lib/flt/d.rb
         | 
| 56 59 | 
             
            - lib/flt/dec_num.rb
         | 
| 57 60 | 
             
            - lib/flt/float.rb
         | 
| @@ -61,6 +64,7 @@ files: | |
| 61 64 | 
             
            - lib/flt/support.rb
         | 
| 62 65 | 
             
            - lib/flt/tolerance.rb
         | 
| 63 66 | 
             
            - lib/flt/tolerance/sugar.rb
         | 
| 67 | 
            +
            - lib/flt/trigonometry.rb
         | 
| 64 68 | 
             
            - lib/flt/version.rb
         | 
| 65 69 | 
             
            - setup.rb
         | 
| 66 70 | 
             
            - tasks/ann.rake
         | 
| @@ -77,6 +81,7 @@ files: | |
| 77 81 | 
             
            - tasks/svn.rake
         | 
| 78 82 | 
             
            - tasks/test.rake
         | 
| 79 83 | 
             
            - test/all_tests.rb
         | 
| 84 | 
            +
            - test/generate_trig_data.rb
         | 
| 80 85 | 
             
            - test/helper.rb
         | 
| 81 86 | 
             
            - test/reader.rb
         | 
| 82 87 | 
             
            - test/test_basic.rb
         | 
| @@ -123,6 +128,7 @@ required_ruby_version: !ruby/object:Gem::Requirement | |
| 123 128 | 
             
              requirements: 
         | 
| 124 129 | 
             
              - - ">="
         | 
| 125 130 | 
             
                - !ruby/object:Gem::Version 
         | 
| 131 | 
            +
                  hash: 3
         | 
| 126 132 | 
             
                  segments: 
         | 
| 127 133 | 
             
                  - 0
         | 
| 128 134 | 
             
                  version: "0"
         | 
| @@ -131,6 +137,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 131 137 | 
             
              requirements: 
         | 
| 132 138 | 
             
              - - ">="
         | 
| 133 139 | 
             
                - !ruby/object:Gem::Version 
         | 
| 140 | 
            +
                  hash: 3
         | 
| 134 141 | 
             
                  segments: 
         | 
| 135 142 | 
             
                  - 0
         | 
| 136 143 | 
             
                  version: "0"
         |