numo-narray 0.9.0.1-x64-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (124) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +4 -0
  3. data/README.md +47 -0
  4. data/Rakefile +41 -0
  5. data/ext/numo/narray/SFMT-params.h +97 -0
  6. data/ext/numo/narray/SFMT-params19937.h +46 -0
  7. data/ext/numo/narray/SFMT.c +620 -0
  8. data/ext/numo/narray/SFMT.h +157 -0
  9. data/ext/numo/narray/array.c +525 -0
  10. data/ext/numo/narray/data.c +901 -0
  11. data/ext/numo/narray/depend.erb +33 -0
  12. data/ext/numo/narray/extconf.rb +117 -0
  13. data/ext/numo/narray/gen/bit.erb.c +811 -0
  14. data/ext/numo/narray/gen/cogen.rb +18 -0
  15. data/ext/numo/narray/gen/def/dcomplex.rb +32 -0
  16. data/ext/numo/narray/gen/def/dfloat.rb +30 -0
  17. data/ext/numo/narray/gen/def/int16.rb +29 -0
  18. data/ext/numo/narray/gen/def/int32.rb +29 -0
  19. data/ext/numo/narray/gen/def/int64.rb +29 -0
  20. data/ext/numo/narray/gen/def/int8.rb +29 -0
  21. data/ext/numo/narray/gen/def/robject.rb +30 -0
  22. data/ext/numo/narray/gen/def/scomplex.rb +32 -0
  23. data/ext/numo/narray/gen/def/sfloat.rb +30 -0
  24. data/ext/numo/narray/gen/def/uint16.rb +29 -0
  25. data/ext/numo/narray/gen/def/uint32.rb +29 -0
  26. data/ext/numo/narray/gen/def/uint64.rb +29 -0
  27. data/ext/numo/narray/gen/def/uint8.rb +29 -0
  28. data/ext/numo/narray/gen/dtype.erb.c +328 -0
  29. data/ext/numo/narray/gen/tmpl/accum.c +36 -0
  30. data/ext/numo/narray/gen/tmpl/accum_binary.c +75 -0
  31. data/ext/numo/narray/gen/tmpl/accum_index.c +58 -0
  32. data/ext/numo/narray/gen/tmpl/allocate.c +35 -0
  33. data/ext/numo/narray/gen/tmpl/aref.c +51 -0
  34. data/ext/numo/narray/gen/tmpl/aset.c +61 -0
  35. data/ext/numo/narray/gen/tmpl/binary.c +53 -0
  36. data/ext/numo/narray/gen/tmpl/binary2.c +55 -0
  37. data/ext/numo/narray/gen/tmpl/binary_s.c +34 -0
  38. data/ext/numo/narray/gen/tmpl/bit_binary.c +94 -0
  39. data/ext/numo/narray/gen/tmpl/bit_count.c +82 -0
  40. data/ext/numo/narray/gen/tmpl/bit_unary.c +77 -0
  41. data/ext/numo/narray/gen/tmpl/cast.c +37 -0
  42. data/ext/numo/narray/gen/tmpl/cast_array.c +79 -0
  43. data/ext/numo/narray/gen/tmpl/cast_numeric.c +22 -0
  44. data/ext/numo/narray/gen/tmpl/coerce_cast.c +8 -0
  45. data/ext/numo/narray/gen/tmpl/cond_binary.c +51 -0
  46. data/ext/numo/narray/gen/tmpl/cond_unary.c +45 -0
  47. data/ext/numo/narray/gen/tmpl/cum.c +42 -0
  48. data/ext/numo/narray/gen/tmpl/each.c +43 -0
  49. data/ext/numo/narray/gen/tmpl/each_with_index.c +64 -0
  50. data/ext/numo/narray/gen/tmpl/extract.c +23 -0
  51. data/ext/numo/narray/gen/tmpl/eye.c +91 -0
  52. data/ext/numo/narray/gen/tmpl/fill.c +38 -0
  53. data/ext/numo/narray/gen/tmpl/format.c +60 -0
  54. data/ext/numo/narray/gen/tmpl/format_to_a.c +47 -0
  55. data/ext/numo/narray/gen/tmpl/head.c +25 -0
  56. data/ext/numo/narray/gen/tmpl/inspect.c +16 -0
  57. data/ext/numo/narray/gen/tmpl/map_with_index.c +94 -0
  58. data/ext/numo/narray/gen/tmpl/median.c +44 -0
  59. data/ext/numo/narray/gen/tmpl/minmax.c +47 -0
  60. data/ext/numo/narray/gen/tmpl/poly.c +49 -0
  61. data/ext/numo/narray/gen/tmpl/pow.c +74 -0
  62. data/ext/numo/narray/gen/tmpl/powint.c +17 -0
  63. data/ext/numo/narray/gen/tmpl/qsort.c +149 -0
  64. data/ext/numo/narray/gen/tmpl/rand.c +33 -0
  65. data/ext/numo/narray/gen/tmpl/rand_norm.c +46 -0
  66. data/ext/numo/narray/gen/tmpl/robj_allocate.c +32 -0
  67. data/ext/numo/narray/gen/tmpl/seq.c +61 -0
  68. data/ext/numo/narray/gen/tmpl/set2.c +56 -0
  69. data/ext/numo/narray/gen/tmpl/sort.c +36 -0
  70. data/ext/numo/narray/gen/tmpl/sort_index.c +86 -0
  71. data/ext/numo/narray/gen/tmpl/store.c +31 -0
  72. data/ext/numo/narray/gen/tmpl/store_array.c +5 -0
  73. data/ext/numo/narray/gen/tmpl/store_from.c +53 -0
  74. data/ext/numo/narray/gen/tmpl/store_numeric.c +22 -0
  75. data/ext/numo/narray/gen/tmpl/to_a.c +41 -0
  76. data/ext/numo/narray/gen/tmpl/unary.c +58 -0
  77. data/ext/numo/narray/gen/tmpl/unary2.c +58 -0
  78. data/ext/numo/narray/gen/tmpl/unary_s.c +57 -0
  79. data/ext/numo/narray/index.c +822 -0
  80. data/ext/numo/narray/kwarg.c +79 -0
  81. data/ext/numo/narray/math.c +140 -0
  82. data/ext/numo/narray/narray.c +1539 -0
  83. data/ext/numo/narray/ndloop.c +1928 -0
  84. data/ext/numo/narray/numo/compat.h +23 -0
  85. data/ext/numo/narray/numo/intern.h +112 -0
  86. data/ext/numo/narray/numo/narray.h +411 -0
  87. data/ext/numo/narray/numo/ndloop.h +99 -0
  88. data/ext/numo/narray/numo/template.h +140 -0
  89. data/ext/numo/narray/numo/types/bit.h +19 -0
  90. data/ext/numo/narray/numo/types/complex.h +410 -0
  91. data/ext/numo/narray/numo/types/complex_macro.h +205 -0
  92. data/ext/numo/narray/numo/types/dcomplex.h +11 -0
  93. data/ext/numo/narray/numo/types/dfloat.h +12 -0
  94. data/ext/numo/narray/numo/types/float_def.h +34 -0
  95. data/ext/numo/narray/numo/types/float_macro.h +277 -0
  96. data/ext/numo/narray/numo/types/int16.h +12 -0
  97. data/ext/numo/narray/numo/types/int32.h +12 -0
  98. data/ext/numo/narray/numo/types/int64.h +12 -0
  99. data/ext/numo/narray/numo/types/int8.h +12 -0
  100. data/ext/numo/narray/numo/types/int_macro.h +34 -0
  101. data/ext/numo/narray/numo/types/robj_macro.h +218 -0
  102. data/ext/numo/narray/numo/types/robject.h +21 -0
  103. data/ext/numo/narray/numo/types/scomplex.h +11 -0
  104. data/ext/numo/narray/numo/types/sfloat.h +13 -0
  105. data/ext/numo/narray/numo/types/uint16.h +12 -0
  106. data/ext/numo/narray/numo/types/uint32.h +12 -0
  107. data/ext/numo/narray/numo/types/uint64.h +12 -0
  108. data/ext/numo/narray/numo/types/uint8.h +12 -0
  109. data/ext/numo/narray/numo/types/uint_macro.h +31 -0
  110. data/ext/numo/narray/numo/types/xint_macro.h +133 -0
  111. data/ext/numo/narray/rand.c +87 -0
  112. data/ext/numo/narray/step.c +506 -0
  113. data/ext/numo/narray/struct.c +872 -0
  114. data/lib/2.1/numo/narray.so +0 -0
  115. data/lib/2.2/numo/narray.so +0 -0
  116. data/lib/2.3/numo/narray.so +0 -0
  117. data/lib/erbpp.rb +286 -0
  118. data/lib/erbpp/line_number.rb +126 -0
  119. data/lib/erbpp/narray_def.rb +338 -0
  120. data/lib/numo/narray.rb +6 -0
  121. data/numo-narray.gemspec +35 -0
  122. data/spec/bit_spec.rb +93 -0
  123. data/spec/narray_spec.rb +249 -0
  124. metadata +238 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6ba9387322df645be933895e871e8cfc22405fbb
4
+ data.tar.gz: 6aa7706cac725c3daec4dc417189fe364a37bb82
5
+ SHA512:
6
+ metadata.gz: bdb2934fa9249928968f35cf6eb437995281f32180d482f36960422bd1b79d2e1cd55f9481c1d7cbeb7592ffd8ea407fa5cc3bd4386c3f276f5994a364d5038b
7
+ data.tar.gz: 956176ac05733f08f251cb5ff177b20f393ac159d129e7b59daf2e6c9ec2e12f3ee134037b834d6e6cfe539ffbf204e29c0149f9a97b8476b18314a17ad213a1
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in narray-devel.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,47 @@
1
+ # Numo::NArray - New NArray class library for Ruby/Numo (NUmerical MOdule)
2
+
3
+ [![Build Status](https://travis-ci.org/ruby-numo/narray.svg?branch=master)](https://travis-ci.org/ruby-numo/narray)
4
+
5
+ under development
6
+
7
+ ## Related Projects
8
+ * [Numo::Linalg](https://github.com/ruby-numo/linalg): Linear Algebra library with [LAPACK](http://www.netlib.org/lapack/).
9
+ * [Numo::GSL](https://github.com/ruby-numo/gsl): Ruby interface for [GSL (GNU Scientific Library)](http://www.gnu.org/software/gsl/).
10
+ * [Numo::FFTE](https://github.com/ruby-numo/ffte): Ruby interface for [FFTE (A Fast Fourier Transform library with radix-2,3,5)](http://www.ffte.jp/).
11
+
12
+ ## Installation
13
+ ### Ubuntu, Debian
14
+ ```shell
15
+ apt install -y git ruby gcc ruby-dev rake make
16
+ git clone git://github.com/ruby-numo/narray
17
+ cd narray
18
+ gem build numo-narray.gemspec
19
+ gem install numo-narray-0.9.0.1.gem
20
+ ```
21
+
22
+ ## Quick start
23
+ An example
24
+ ```ruby
25
+ [1] pry(main)> require "numo/narray"
26
+ => true
27
+ [2] pry(main)> a = Numo::DFloat.new(3,5).seq
28
+ => Numo::DFloat#shape=[3,5]
29
+ [[0, 1, 2, 3, 4],
30
+ [5, 6, 7, 8, 9],
31
+ [10, 11, 12, 13, 14]]
32
+ [3] pry(main)> a.shape
33
+ => [3, 5]
34
+ [4] pry(main)> a.ndim
35
+ => 2
36
+ [5] pry(main)> a.class
37
+ => Numo::DFloat
38
+ [6] pry(main)> a.size
39
+ => 15
40
+ ```
41
+ For more examples, check out this [narray version of 100 numpy exercises](https://github.com/ruby-numo/narray/wiki/100-narray-exercises).
42
+
43
+ ## numo-array status compared to numpy
44
+
45
+ https://github.com/ruby-numo/narray/wiki/Numo-vs-numpy
46
+
47
+ ## [NArray Tentative API Document](http://ruby-numo.github.io/narray/narray/frames.html)
data/Rakefile ADDED
@@ -0,0 +1,41 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/extensiontask"
3
+ require "rake_compiler_dock"
4
+ require "shellwords"
5
+
6
+ spec = Bundler::GemHelper.gemspec
7
+
8
+ Rake::ExtensionTask.new("numo/narray", spec) do |ext|
9
+ ext.cross_compile = true
10
+ ext.cross_platform = ["x86-mingw32", "x64-mingw32"]
11
+ end
12
+
13
+ namespace :build do
14
+ pkg_dir = "pkg"
15
+ directory pkg_dir
16
+
17
+ desc "Build gems for Windows into the pkg directory"
18
+ task :windows => pkg_dir do
19
+ ruby_versions = "2.1.6:2.2.2:2.3.0"
20
+
21
+ build_dir = "tmp/windows"
22
+ rm_rf build_dir
23
+ mkdir_p build_dir
24
+
25
+ commands = [
26
+ ["git", "clone", "file://#{Dir.pwd}/.git", build_dir],
27
+ ["cd", build_dir],
28
+ ["bundle"],
29
+ ["rake", "cross", "native", "gem", "RUBY_CC_VERSION=#{ruby_versions}"],
30
+ ]
31
+ raw_commands = commands.collect do |command|
32
+ Shellwords.join(command)
33
+ end
34
+ raw_command_line = raw_commands.join(" && ")
35
+
36
+ RakeCompilerDock.sh(raw_command_line)
37
+
38
+ cp(Dir.glob("#{build_dir}/#{pkg_dir}/*.gem"),
39
+ "#{pkg_dir}/")
40
+ end
41
+ end
@@ -0,0 +1,97 @@
1
+ #ifndef SFMT_PARAMS_H
2
+ #define SFMT_PARAMS_H
3
+
4
+ #if !defined(MEXP)
5
+ //#ifdef __GNUC__
6
+ // #warning "MEXP is not defined. I assume MEXP is 19937."
7
+ //#endif
8
+ #define MEXP 19937
9
+ #endif
10
+ /*-----------------
11
+ BASIC DEFINITIONS
12
+ -----------------*/
13
+ /** Mersenne Exponent. The period of the sequence
14
+ * is a multiple of 2^MEXP-1.
15
+ * #define MEXP 19937 */
16
+ /** SFMT generator has an internal state array of 128-bit integers,
17
+ * and N is its size. */
18
+ #define N (MEXP / 128 + 1)
19
+ /** N32 is the size of internal state array when regarded as an array
20
+ * of 32-bit integers.*/
21
+ #define N32 (N * 4)
22
+ /** N64 is the size of internal state array when regarded as an array
23
+ * of 64-bit integers.*/
24
+ #define N64 (N * 2)
25
+
26
+ /*----------------------
27
+ the parameters of SFMT
28
+ following definitions are in paramsXXXX.h file.
29
+ ----------------------*/
30
+ /** the pick up position of the array.
31
+ #define POS1 122
32
+ */
33
+
34
+ /** the parameter of shift left as four 32-bit registers.
35
+ #define SL1 18
36
+ */
37
+
38
+ /** the parameter of shift left as one 128-bit register.
39
+ * The 128-bit integer is shifted by (SL2 * 8) bits.
40
+ #define SL2 1
41
+ */
42
+
43
+ /** the parameter of shift right as four 32-bit registers.
44
+ #define SR1 11
45
+ */
46
+
47
+ /** the parameter of shift right as one 128-bit register.
48
+ * The 128-bit integer is shifted by (SL2 * 8) bits.
49
+ #define SR2 1
50
+ */
51
+
52
+ /** A bitmask, used in the recursion. These parameters are introduced
53
+ * to break symmetry of SIMD.
54
+ #define MSK1 0xdfffffefU
55
+ #define MSK2 0xddfecb7fU
56
+ #define MSK3 0xbffaffffU
57
+ #define MSK4 0xbffffff6U
58
+ */
59
+
60
+ /** These definitions are part of a 128-bit period certification vector.
61
+ #define PARITY1 0x00000001U
62
+ #define PARITY2 0x00000000U
63
+ #define PARITY3 0x00000000U
64
+ #define PARITY4 0xc98e126aU
65
+ */
66
+
67
+ #if MEXP == 607
68
+ #include "SFMT-params607.h"
69
+ #elif MEXP == 1279
70
+ #include "SFMT-params1279.h"
71
+ #elif MEXP == 2281
72
+ #include "SFMT-params2281.h"
73
+ #elif MEXP == 4253
74
+ #include "SFMT-params4253.h"
75
+ #elif MEXP == 11213
76
+ #include "SFMT-params11213.h"
77
+ #elif MEXP == 19937
78
+ #include "SFMT-params19937.h"
79
+ #elif MEXP == 44497
80
+ #include "SFMT-params44497.h"
81
+ #elif MEXP == 86243
82
+ #include "SFMT-params86243.h"
83
+ #elif MEXP == 132049
84
+ #include "SFMT-params132049.h"
85
+ #elif MEXP == 216091
86
+ #include "SFMT-params216091.h"
87
+ #else
88
+ #ifdef __GNUC__
89
+ #error "MEXP is not valid."
90
+ #undef MEXP
91
+ #else
92
+ #undef MEXP
93
+ #endif
94
+
95
+ #endif
96
+
97
+ #endif /* SFMT_PARAMS_H */
@@ -0,0 +1,46 @@
1
+ #ifndef SFMT_PARAMS19937_H
2
+ #define SFMT_PARAMS19937_H
3
+
4
+ #define POS1 122
5
+ #define SL1 18
6
+ #define SL2 1
7
+ #define SR1 11
8
+ #define SR2 1
9
+ #define MSK1 0xdfffffefU
10
+ #define MSK2 0xddfecb7fU
11
+ #define MSK3 0xbffaffffU
12
+ #define MSK4 0xbffffff6U
13
+ #define PARITY1 0x00000001U
14
+ #define PARITY2 0x00000000U
15
+ #define PARITY3 0x00000000U
16
+ #define PARITY4 0x13c9e684U
17
+
18
+
19
+ /* PARAMETERS FOR ALTIVEC */
20
+ #if defined(__APPLE__) /* For OSX */
21
+ #define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1)
22
+ #define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1)
23
+ #define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4)
24
+ #define ALTI_MSK64 \
25
+ (vector unsigned int)(MSK2, MSK1, MSK4, MSK3)
26
+ #define ALTI_SL2_PERM \
27
+ (vector unsigned char)(1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8)
28
+ #define ALTI_SL2_PERM64 \
29
+ (vector unsigned char)(1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0)
30
+ #define ALTI_SR2_PERM \
31
+ (vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14)
32
+ #define ALTI_SR2_PERM64 \
33
+ (vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14)
34
+ #else /* For OTHER OSs(Linux?) */
35
+ #define ALTI_SL1 {SL1, SL1, SL1, SL1}
36
+ #define ALTI_SR1 {SR1, SR1, SR1, SR1}
37
+ #define ALTI_MSK {MSK1, MSK2, MSK3, MSK4}
38
+ #define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3}
39
+ #define ALTI_SL2_PERM {1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8}
40
+ #define ALTI_SL2_PERM64 {1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0}
41
+ #define ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14}
42
+ #define ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14}
43
+ #endif /* For OSX */
44
+ #define IDSTR "SFMT-19937:122-18-1-11-1:dfffffef-ddfecb7f-bffaffff-bffffff6"
45
+
46
+ #endif /* SFMT_PARAMS19937_H */
@@ -0,0 +1,620 @@
1
+ /**
2
+ * @file SFMT.c
3
+ * @brief SIMD oriented Fast Mersenne Twister(SFMT)
4
+ *
5
+ * @author Mutsuo Saito (Hiroshima University)
6
+ * @author Makoto Matsumoto (Hiroshima University)
7
+ *
8
+ * Copyright (C) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
9
+ * University. All rights reserved.
10
+ *
11
+ * The new BSD License is applied to this software, see LICENSE.txt
12
+ */
13
+ #include <string.h>
14
+ #include <assert.h>
15
+ #include "SFMT.h"
16
+ #include "SFMT-params.h"
17
+
18
+ #if defined(__BIG_ENDIAN__) && !defined(__amd64) && !defined(BIG_ENDIAN64)
19
+ #define BIG_ENDIAN64 1
20
+ #endif
21
+ #if defined(HAVE_ALTIVEC) && !defined(BIG_ENDIAN64)
22
+ #define BIG_ENDIAN64 1
23
+ #endif
24
+ #if defined(ONLY64) && !defined(BIG_ENDIAN64)
25
+ #if defined(__GNUC__)
26
+ #error "-DONLY64 must be specified with -DBIG_ENDIAN64"
27
+ #endif
28
+ #undef ONLY64
29
+ #endif
30
+ /*------------------------------------------------------
31
+ 128-bit SIMD data type for Altivec, SSE2 or standard C
32
+ ------------------------------------------------------*/
33
+ #if defined(HAVE_ALTIVEC)
34
+ #if !defined(__APPLE__)
35
+ #include <altivec.h>
36
+ #endif
37
+ /** 128-bit data structure */
38
+ union W128_T {
39
+ vector unsigned int s;
40
+ uint32_t u[4];
41
+ };
42
+ /** 128-bit data type */
43
+ typedef union W128_T w128_t;
44
+
45
+ #elif defined(HAVE_SSE2)
46
+ #include <emmintrin.h>
47
+
48
+ /** 128-bit data structure */
49
+ union W128_T {
50
+ __m128i si;
51
+ uint32_t u[4];
52
+ };
53
+ /** 128-bit data type */
54
+ typedef union W128_T w128_t;
55
+
56
+ #else
57
+
58
+ /** 128-bit data structure */
59
+ struct W128_T {
60
+ uint32_t u[4];
61
+ };
62
+ /** 128-bit data type */
63
+ typedef struct W128_T w128_t;
64
+
65
+ #endif
66
+
67
+ /*--------------------------------------
68
+ FILE GLOBAL VARIABLES
69
+ internal state, index counter and flag
70
+ --------------------------------------*/
71
+ /** the 128-bit internal state array */
72
+ static w128_t sfmt[N];
73
+ /** the 32bit integer pointer to the 128-bit internal state array */
74
+ static uint32_t *psfmt32 = &sfmt[0].u[0];
75
+ #if !defined(BIG_ENDIAN64) || defined(ONLY64)
76
+ /** the 64bit integer pointer to the 128-bit internal state array */
77
+ static uint64_t *psfmt64 = (uint64_t *)&sfmt[0].u[0];
78
+ #endif
79
+ /** index counter to the 32-bit internal state array */
80
+ static int idx;
81
+ /** a flag: it is 0 if and only if the internal state is not yet
82
+ * initialized. */
83
+ static int initialized = 0;
84
+ /** a parity check vector which certificate the period of 2^{MEXP} */
85
+ static uint32_t parity[4] = {PARITY1, PARITY2, PARITY3, PARITY4};
86
+
87
+ /*----------------
88
+ STATIC FUNCTIONS
89
+ ----------------*/
90
+ inline static int idxof(int i);
91
+ inline static void rshift128(w128_t *out, w128_t const *in, int shift);
92
+ inline static void lshift128(w128_t *out, w128_t const *in, int shift);
93
+ inline static void gen_rand_all(void);
94
+ inline static void gen_rand_array(w128_t *array, int size);
95
+ inline static uint32_t func1(uint32_t x);
96
+ inline static uint32_t func2(uint32_t x);
97
+ static void period_certification(void);
98
+ #if defined(BIG_ENDIAN64) && !defined(ONLY64)
99
+ inline static void swap(w128_t *array, int size);
100
+ #endif
101
+
102
+ #if defined(HAVE_ALTIVEC)
103
+ #include "SFMT-alti.h"
104
+ #elif defined(HAVE_SSE2)
105
+ #include "SFMT-sse2.h"
106
+ #endif
107
+
108
+ /**
109
+ * This function simulate a 64-bit index of LITTLE ENDIAN
110
+ * in BIG ENDIAN machine.
111
+ */
112
+ #ifdef ONLY64
113
+ inline static int idxof(int i) {
114
+ return i ^ 1;
115
+ }
116
+ #else
117
+ inline static int idxof(int i) {
118
+ return i;
119
+ }
120
+ #endif
121
+ /**
122
+ * This function simulates SIMD 128-bit right shift by the standard C.
123
+ * The 128-bit integer given in in is shifted by (shift * 8) bits.
124
+ * This function simulates the LITTLE ENDIAN SIMD.
125
+ * @param out the output of this function
126
+ * @param in the 128-bit data to be shifted
127
+ * @param shift the shift value
128
+ */
129
+ #ifdef ONLY64
130
+ inline static void rshift128(w128_t *out, w128_t const *in, int shift) {
131
+ uint64_t th, tl, oh, ol;
132
+
133
+ th = ((uint64_t)in->u[2] << 32) | ((uint64_t)in->u[3]);
134
+ tl = ((uint64_t)in->u[0] << 32) | ((uint64_t)in->u[1]);
135
+
136
+ oh = th >> (shift * 8);
137
+ ol = tl >> (shift * 8);
138
+ ol |= th << (64 - shift * 8);
139
+ out->u[0] = (uint32_t)(ol >> 32);
140
+ out->u[1] = (uint32_t)ol;
141
+ out->u[2] = (uint32_t)(oh >> 32);
142
+ out->u[3] = (uint32_t)oh;
143
+ }
144
+ #else
145
+ inline static void rshift128(w128_t *out, w128_t const *in, int shift) {
146
+ uint64_t th, tl, oh, ol;
147
+
148
+ th = ((uint64_t)in->u[3] << 32) | ((uint64_t)in->u[2]);
149
+ tl = ((uint64_t)in->u[1] << 32) | ((uint64_t)in->u[0]);
150
+
151
+ oh = th >> (shift * 8);
152
+ ol = tl >> (shift * 8);
153
+ ol |= th << (64 - shift * 8);
154
+ out->u[1] = (uint32_t)(ol >> 32);
155
+ out->u[0] = (uint32_t)ol;
156
+ out->u[3] = (uint32_t)(oh >> 32);
157
+ out->u[2] = (uint32_t)oh;
158
+ }
159
+ #endif
160
+ /**
161
+ * This function simulates SIMD 128-bit left shift by the standard C.
162
+ * The 128-bit integer given in in is shifted by (shift * 8) bits.
163
+ * This function simulates the LITTLE ENDIAN SIMD.
164
+ * @param out the output of this function
165
+ * @param in the 128-bit data to be shifted
166
+ * @param shift the shift value
167
+ */
168
+ #ifdef ONLY64
169
+ inline static void lshift128(w128_t *out, w128_t const *in, int shift) {
170
+ uint64_t th, tl, oh, ol;
171
+
172
+ th = ((uint64_t)in->u[2] << 32) | ((uint64_t)in->u[3]);
173
+ tl = ((uint64_t)in->u[0] << 32) | ((uint64_t)in->u[1]);
174
+
175
+ oh = th << (shift * 8);
176
+ ol = tl << (shift * 8);
177
+ oh |= tl >> (64 - shift * 8);
178
+ out->u[0] = (uint32_t)(ol >> 32);
179
+ out->u[1] = (uint32_t)ol;
180
+ out->u[2] = (uint32_t)(oh >> 32);
181
+ out->u[3] = (uint32_t)oh;
182
+ }
183
+ #else
184
+ inline static void lshift128(w128_t *out, w128_t const *in, int shift) {
185
+ uint64_t th, tl, oh, ol;
186
+
187
+ th = ((uint64_t)in->u[3] << 32) | ((uint64_t)in->u[2]);
188
+ tl = ((uint64_t)in->u[1] << 32) | ((uint64_t)in->u[0]);
189
+
190
+ oh = th << (shift * 8);
191
+ ol = tl << (shift * 8);
192
+ oh |= tl >> (64 - shift * 8);
193
+ out->u[1] = (uint32_t)(ol >> 32);
194
+ out->u[0] = (uint32_t)ol;
195
+ out->u[3] = (uint32_t)(oh >> 32);
196
+ out->u[2] = (uint32_t)oh;
197
+ }
198
+ #endif
199
+
200
+ /**
201
+ * This function represents the recursion formula.
202
+ * @param r output
203
+ * @param a a 128-bit part of the internal state array
204
+ * @param b a 128-bit part of the internal state array
205
+ * @param c a 128-bit part of the internal state array
206
+ * @param d a 128-bit part of the internal state array
207
+ */
208
+ #if (!defined(HAVE_ALTIVEC)) && (!defined(HAVE_SSE2))
209
+ #ifdef ONLY64
210
+ inline static void do_recursion(w128_t *r, w128_t *a, w128_t *b, w128_t *c,
211
+ w128_t *d) {
212
+ w128_t x;
213
+ w128_t y;
214
+
215
+ lshift128(&x, a, SL2);
216
+ rshift128(&y, c, SR2);
217
+ r->u[0] = a->u[0] ^ x.u[0] ^ ((b->u[0] >> SR1) & MSK2) ^ y.u[0]
218
+ ^ (d->u[0] << SL1);
219
+ r->u[1] = a->u[1] ^ x.u[1] ^ ((b->u[1] >> SR1) & MSK1) ^ y.u[1]
220
+ ^ (d->u[1] << SL1);
221
+ r->u[2] = a->u[2] ^ x.u[2] ^ ((b->u[2] >> SR1) & MSK4) ^ y.u[2]
222
+ ^ (d->u[2] << SL1);
223
+ r->u[3] = a->u[3] ^ x.u[3] ^ ((b->u[3] >> SR1) & MSK3) ^ y.u[3]
224
+ ^ (d->u[3] << SL1);
225
+ }
226
+ #else
227
+ inline static void do_recursion(w128_t *r, w128_t *a, w128_t *b, w128_t *c,
228
+ w128_t *d) {
229
+ w128_t x;
230
+ w128_t y;
231
+
232
+ lshift128(&x, a, SL2);
233
+ rshift128(&y, c, SR2);
234
+ r->u[0] = a->u[0] ^ x.u[0] ^ ((b->u[0] >> SR1) & MSK1) ^ y.u[0]
235
+ ^ (d->u[0] << SL1);
236
+ r->u[1] = a->u[1] ^ x.u[1] ^ ((b->u[1] >> SR1) & MSK2) ^ y.u[1]
237
+ ^ (d->u[1] << SL1);
238
+ r->u[2] = a->u[2] ^ x.u[2] ^ ((b->u[2] >> SR1) & MSK3) ^ y.u[2]
239
+ ^ (d->u[2] << SL1);
240
+ r->u[3] = a->u[3] ^ x.u[3] ^ ((b->u[3] >> SR1) & MSK4) ^ y.u[3]
241
+ ^ (d->u[3] << SL1);
242
+ }
243
+ #endif
244
+ #endif
245
+
246
+ #if (!defined(HAVE_ALTIVEC)) && (!defined(HAVE_SSE2))
247
+ /**
248
+ * This function fills the internal state array with pseudorandom
249
+ * integers.
250
+ */
251
+ inline static void gen_rand_all(void) {
252
+ int i;
253
+ w128_t *r1, *r2;
254
+
255
+ r1 = &sfmt[N - 2];
256
+ r2 = &sfmt[N - 1];
257
+ for (i = 0; i < N - POS1; i++) {
258
+ do_recursion(&sfmt[i], &sfmt[i], &sfmt[i + POS1], r1, r2);
259
+ r1 = r2;
260
+ r2 = &sfmt[i];
261
+ }
262
+ for (; i < N; i++) {
263
+ do_recursion(&sfmt[i], &sfmt[i], &sfmt[i + POS1 - N], r1, r2);
264
+ r1 = r2;
265
+ r2 = &sfmt[i];
266
+ }
267
+ }
268
+
269
+ /**
270
+ * This function fills the user-specified array with pseudorandom
271
+ * integers.
272
+ *
273
+ * @param array an 128-bit array to be filled by pseudorandom numbers.
274
+ * @param size number of 128-bit pseudorandom numbers to be generated.
275
+ */
276
+ inline static void gen_rand_array(w128_t *array, int size) {
277
+ int i, j;
278
+ w128_t *r1, *r2;
279
+
280
+ r1 = &sfmt[N - 2];
281
+ r2 = &sfmt[N - 1];
282
+ for (i = 0; i < N - POS1; i++) {
283
+ do_recursion(&array[i], &sfmt[i], &sfmt[i + POS1], r1, r2);
284
+ r1 = r2;
285
+ r2 = &array[i];
286
+ }
287
+ for (; i < N; i++) {
288
+ do_recursion(&array[i], &sfmt[i], &array[i + POS1 - N], r1, r2);
289
+ r1 = r2;
290
+ r2 = &array[i];
291
+ }
292
+ for (; i < size - N; i++) {
293
+ do_recursion(&array[i], &array[i - N], &array[i + POS1 - N], r1, r2);
294
+ r1 = r2;
295
+ r2 = &array[i];
296
+ }
297
+ for (j = 0; j < 2 * N - size; j++) {
298
+ sfmt[j] = array[j + size - N];
299
+ }
300
+ for (; i < size; i++, j++) {
301
+ do_recursion(&array[i], &array[i - N], &array[i + POS1 - N], r1, r2);
302
+ r1 = r2;
303
+ r2 = &array[i];
304
+ sfmt[j] = array[i];
305
+ }
306
+ }
307
+ #endif
308
+
309
+ #if defined(BIG_ENDIAN64) && !defined(ONLY64) && !defined(HAVE_ALTIVEC)
310
+ inline static void swap(w128_t *array, int size) {
311
+ int i;
312
+ uint32_t x, y;
313
+
314
+ for (i = 0; i < size; i++) {
315
+ x = array[i].u[0];
316
+ y = array[i].u[2];
317
+ array[i].u[0] = array[i].u[1];
318
+ array[i].u[2] = array[i].u[3];
319
+ array[i].u[1] = x;
320
+ array[i].u[3] = y;
321
+ }
322
+ }
323
+ #endif
324
+ /**
325
+ * This function represents a function used in the initialization
326
+ * by init_by_array
327
+ * @param x 32-bit integer
328
+ * @return 32-bit integer
329
+ */
330
+ static uint32_t func1(uint32_t x) {
331
+ return (x ^ (x >> 27)) * (uint32_t)1664525UL;
332
+ }
333
+
334
+ /**
335
+ * This function represents a function used in the initialization
336
+ * by init_by_array
337
+ * @param x 32-bit integer
338
+ * @return 32-bit integer
339
+ */
340
+ static uint32_t func2(uint32_t x) {
341
+ return (x ^ (x >> 27)) * (uint32_t)1566083941UL;
342
+ }
343
+
344
+ /**
345
+ * This function certificate the period of 2^{MEXP}
346
+ */
347
+ static void period_certification(void) {
348
+ int inner = 0;
349
+ int i, j;
350
+ uint32_t work;
351
+
352
+ for (i = 0; i < 4; i++)
353
+ inner ^= psfmt32[idxof(i)] & parity[i];
354
+ for (i = 16; i > 0; i >>= 1)
355
+ inner ^= inner >> i;
356
+ inner &= 1;
357
+ /* check OK */
358
+ if (inner == 1) {
359
+ return;
360
+ }
361
+ /* check NG, and modification */
362
+ for (i = 0; i < 4; i++) {
363
+ work = 1;
364
+ for (j = 0; j < 32; j++) {
365
+ if ((work & parity[i]) != 0) {
366
+ psfmt32[idxof(i)] ^= work;
367
+ return;
368
+ }
369
+ work = work << 1;
370
+ }
371
+ }
372
+ }
373
+
374
+ /*----------------
375
+ PUBLIC FUNCTIONS
376
+ ----------------*/
377
+ /**
378
+ * This function returns the identification string.
379
+ * The string shows the word size, the Mersenne exponent,
380
+ * and all parameters of this generator.
381
+ */
382
+ const char *get_idstring(void) {
383
+ return IDSTR;
384
+ }
385
+
386
+ /**
387
+ * This function returns the minimum size of array used for \b
388
+ * fill_array32() function.
389
+ * @return minimum size of array used for fill_array32() function.
390
+ */
391
+ int get_min_array_size32(void) {
392
+ return N32;
393
+ }
394
+
395
+ /**
396
+ * This function returns the minimum size of array used for \b
397
+ * fill_array64() function.
398
+ * @return minimum size of array used for fill_array64() function.
399
+ */
400
+ int get_min_array_size64(void) {
401
+ return N64;
402
+ }
403
+
404
+ #ifndef ONLY64
405
+ /**
406
+ * This function generates and returns 32-bit pseudorandom number.
407
+ * init_gen_rand or init_by_array must be called before this function.
408
+ * @return 32-bit pseudorandom number
409
+ */
410
+ uint32_t gen_rand32(void) {
411
+ uint32_t r;
412
+
413
+ assert(initialized);
414
+ if (idx >= N32) {
415
+ gen_rand_all();
416
+ idx = 0;
417
+ }
418
+ r = psfmt32[idx++];
419
+ return r;
420
+ }
421
+ #endif
422
+ /**
423
+ * This function generates and returns 64-bit pseudorandom number.
424
+ * init_gen_rand or init_by_array must be called before this function.
425
+ * The function gen_rand64 should not be called after gen_rand32,
426
+ * unless an initialization is again executed.
427
+ * @return 64-bit pseudorandom number
428
+ */
429
+ uint64_t gen_rand64(void) {
430
+ #if defined(BIG_ENDIAN64) && !defined(ONLY64)
431
+ uint32_t r1, r2;
432
+ #else
433
+ uint64_t r;
434
+ #endif
435
+
436
+ assert(initialized);
437
+ assert(idx % 2 == 0);
438
+
439
+ if (idx >= N32) {
440
+ gen_rand_all();
441
+ idx = 0;
442
+ }
443
+ #if defined(BIG_ENDIAN64) && !defined(ONLY64)
444
+ r1 = psfmt32[idx];
445
+ r2 = psfmt32[idx + 1];
446
+ idx += 2;
447
+ return ((uint64_t)r2 << 32) | r1;
448
+ #else
449
+ r = psfmt64[idx / 2];
450
+ idx += 2;
451
+ return r;
452
+ #endif
453
+ }
454
+
455
+ #ifndef ONLY64
456
+ /**
457
+ * This function generates pseudorandom 32-bit integers in the
458
+ * specified array[] by one call. The number of pseudorandom integers
459
+ * is specified by the argument size, which must be at least 624 and a
460
+ * multiple of four. The generation by this function is much faster
461
+ * than the following gen_rand function.
462
+ *
463
+ * For initialization, init_gen_rand or init_by_array must be called
464
+ * before the first call of this function. This function can not be
465
+ * used after calling gen_rand function, without initialization.
466
+ *
467
+ * @param array an array where pseudorandom 32-bit integers are filled
468
+ * by this function. The pointer to the array must be \b "aligned"
469
+ * (namely, must be a multiple of 16) in the SIMD version, since it
470
+ * refers to the address of a 128-bit integer. In the standard C
471
+ * version, the pointer is arbitrary.
472
+ *
473
+ * @param size the number of 32-bit pseudorandom integers to be
474
+ * generated. size must be a multiple of 4, and greater than or equal
475
+ * to (MEXP / 128 + 1) * 4.
476
+ *
477
+ * @note \b memalign or \b posix_memalign is available to get aligned
478
+ * memory. Mac OSX doesn't have these functions, but \b malloc of OSX
479
+ * returns the pointer to the aligned memory block.
480
+ */
481
+ void fill_array32(uint32_t *array, int size) {
482
+ assert(initialized);
483
+ assert(idx == N32);
484
+ assert(size % 4 == 0);
485
+ assert(size >= N32);
486
+
487
+ gen_rand_array((w128_t *)array, size / 4);
488
+ idx = N32;
489
+ }
490
+ #endif
491
+
492
+ /**
493
+ * This function generates pseudorandom 64-bit integers in the
494
+ * specified array[] by one call. The number of pseudorandom integers
495
+ * is specified by the argument size, which must be at least 312 and a
496
+ * multiple of two. The generation by this function is much faster
497
+ * than the following gen_rand function.
498
+ *
499
+ * For initialization, init_gen_rand or init_by_array must be called
500
+ * before the first call of this function. This function can not be
501
+ * used after calling gen_rand function, without initialization.
502
+ *
503
+ * @param array an array where pseudorandom 64-bit integers are filled
504
+ * by this function. The pointer to the array must be "aligned"
505
+ * (namely, must be a multiple of 16) in the SIMD version, since it
506
+ * refers to the address of a 128-bit integer. In the standard C
507
+ * version, the pointer is arbitrary.
508
+ *
509
+ * @param size the number of 64-bit pseudorandom integers to be
510
+ * generated. size must be a multiple of 2, and greater than or equal
511
+ * to (MEXP / 128 + 1) * 2
512
+ *
513
+ * @note \b memalign or \b posix_memalign is available to get aligned
514
+ * memory. Mac OSX doesn't have these functions, but \b malloc of OSX
515
+ * returns the pointer to the aligned memory block.
516
+ */
517
+ void fill_array64(uint64_t *array, int size) {
518
+ assert(initialized);
519
+ assert(idx == N32);
520
+ assert(size % 2 == 0);
521
+ assert(size >= N64);
522
+
523
+ gen_rand_array((w128_t *)array, size / 2);
524
+ idx = N32;
525
+
526
+ #if defined(BIG_ENDIAN64) && !defined(ONLY64)
527
+ swap((w128_t *)array, size /2);
528
+ #endif
529
+ }
530
+
531
+ /**
532
+ * This function initializes the internal state array with a 32-bit
533
+ * integer seed.
534
+ *
535
+ * @param seed a 32-bit integer used as the seed.
536
+ */
537
+ void init_gen_rand(uint32_t seed) {
538
+ int i;
539
+
540
+ psfmt32[idxof(0)] = seed;
541
+ for (i = 1; i < N32; i++) {
542
+ psfmt32[idxof(i)] = 1812433253UL * (psfmt32[idxof(i - 1)]
543
+ ^ (psfmt32[idxof(i - 1)] >> 30))
544
+ + i;
545
+ }
546
+ idx = N32;
547
+ period_certification();
548
+ initialized = 1;
549
+ }
550
+
551
+ /**
552
+ * This function initializes the internal state array,
553
+ * with an array of 32-bit integers used as the seeds
554
+ * @param init_key the array of 32-bit integers, used as a seed.
555
+ * @param key_length the length of init_key.
556
+ */
557
+ void init_by_array(uint32_t *init_key, int key_length) {
558
+ int i, j, count;
559
+ uint32_t r;
560
+ int lag;
561
+ int mid;
562
+ int size = N * 4;
563
+
564
+ if (size >= 623) {
565
+ lag = 11;
566
+ } else if (size >= 68) {
567
+ lag = 7;
568
+ } else if (size >= 39) {
569
+ lag = 5;
570
+ } else {
571
+ lag = 3;
572
+ }
573
+ mid = (size - lag) / 2;
574
+
575
+ memset(sfmt, 0x8b, sizeof(sfmt));
576
+ if (key_length + 1 > N32) {
577
+ count = key_length + 1;
578
+ } else {
579
+ count = N32;
580
+ }
581
+ r = func1(psfmt32[idxof(0)] ^ psfmt32[idxof(mid)]
582
+ ^ psfmt32[idxof(N32 - 1)]);
583
+ psfmt32[idxof(mid)] += r;
584
+ r += key_length;
585
+ psfmt32[idxof(mid + lag)] += r;
586
+ psfmt32[idxof(0)] = r;
587
+
588
+ count--;
589
+ for (i = 1, j = 0; (j < count) && (j < key_length); j++) {
590
+ r = func1(psfmt32[idxof(i)] ^ psfmt32[idxof((i + mid) % N32)]
591
+ ^ psfmt32[idxof((i + N32 - 1) % N32)]);
592
+ psfmt32[idxof((i + mid) % N32)] += r;
593
+ r += init_key[j] + i;
594
+ psfmt32[idxof((i + mid + lag) % N32)] += r;
595
+ psfmt32[idxof(i)] = r;
596
+ i = (i + 1) % N32;
597
+ }
598
+ for (; j < count; j++) {
599
+ r = func1(psfmt32[idxof(i)] ^ psfmt32[idxof((i + mid) % N32)]
600
+ ^ psfmt32[idxof((i + N32 - 1) % N32)]);
601
+ psfmt32[idxof((i + mid) % N32)] += r;
602
+ r += i;
603
+ psfmt32[idxof((i + mid + lag) % N32)] += r;
604
+ psfmt32[idxof(i)] = r;
605
+ i = (i + 1) % N32;
606
+ }
607
+ for (j = 0; j < N32; j++) {
608
+ r = func2(psfmt32[idxof(i)] + psfmt32[idxof((i + mid) % N32)]
609
+ + psfmt32[idxof((i + N32 - 1) % N32)]);
610
+ psfmt32[idxof((i + mid) % N32)] ^= r;
611
+ r -= i;
612
+ psfmt32[idxof((i + mid + lag) % N32)] ^= r;
613
+ psfmt32[idxof(i)] = r;
614
+ i = (i + 1) % N32;
615
+ }
616
+
617
+ idx = N32;
618
+ period_certification();
619
+ initialized = 1;
620
+ }