numo-narray 0.9.0.1-x64-mingw32
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/Gemfile +4 -0
- data/README.md +47 -0
- data/Rakefile +41 -0
- data/ext/numo/narray/SFMT-params.h +97 -0
- data/ext/numo/narray/SFMT-params19937.h +46 -0
- data/ext/numo/narray/SFMT.c +620 -0
- data/ext/numo/narray/SFMT.h +157 -0
- data/ext/numo/narray/array.c +525 -0
- data/ext/numo/narray/data.c +901 -0
- data/ext/numo/narray/depend.erb +33 -0
- data/ext/numo/narray/extconf.rb +117 -0
- data/ext/numo/narray/gen/bit.erb.c +811 -0
- data/ext/numo/narray/gen/cogen.rb +18 -0
- data/ext/numo/narray/gen/def/dcomplex.rb +32 -0
- data/ext/numo/narray/gen/def/dfloat.rb +30 -0
- data/ext/numo/narray/gen/def/int16.rb +29 -0
- data/ext/numo/narray/gen/def/int32.rb +29 -0
- data/ext/numo/narray/gen/def/int64.rb +29 -0
- data/ext/numo/narray/gen/def/int8.rb +29 -0
- data/ext/numo/narray/gen/def/robject.rb +30 -0
- data/ext/numo/narray/gen/def/scomplex.rb +32 -0
- data/ext/numo/narray/gen/def/sfloat.rb +30 -0
- data/ext/numo/narray/gen/def/uint16.rb +29 -0
- data/ext/numo/narray/gen/def/uint32.rb +29 -0
- data/ext/numo/narray/gen/def/uint64.rb +29 -0
- data/ext/numo/narray/gen/def/uint8.rb +29 -0
- data/ext/numo/narray/gen/dtype.erb.c +328 -0
- data/ext/numo/narray/gen/tmpl/accum.c +36 -0
- data/ext/numo/narray/gen/tmpl/accum_binary.c +75 -0
- data/ext/numo/narray/gen/tmpl/accum_index.c +58 -0
- data/ext/numo/narray/gen/tmpl/allocate.c +35 -0
- data/ext/numo/narray/gen/tmpl/aref.c +51 -0
- data/ext/numo/narray/gen/tmpl/aset.c +61 -0
- data/ext/numo/narray/gen/tmpl/binary.c +53 -0
- data/ext/numo/narray/gen/tmpl/binary2.c +55 -0
- data/ext/numo/narray/gen/tmpl/binary_s.c +34 -0
- data/ext/numo/narray/gen/tmpl/bit_binary.c +94 -0
- data/ext/numo/narray/gen/tmpl/bit_count.c +82 -0
- data/ext/numo/narray/gen/tmpl/bit_unary.c +77 -0
- data/ext/numo/narray/gen/tmpl/cast.c +37 -0
- data/ext/numo/narray/gen/tmpl/cast_array.c +79 -0
- data/ext/numo/narray/gen/tmpl/cast_numeric.c +22 -0
- data/ext/numo/narray/gen/tmpl/coerce_cast.c +8 -0
- data/ext/numo/narray/gen/tmpl/cond_binary.c +51 -0
- data/ext/numo/narray/gen/tmpl/cond_unary.c +45 -0
- data/ext/numo/narray/gen/tmpl/cum.c +42 -0
- data/ext/numo/narray/gen/tmpl/each.c +43 -0
- data/ext/numo/narray/gen/tmpl/each_with_index.c +64 -0
- data/ext/numo/narray/gen/tmpl/extract.c +23 -0
- data/ext/numo/narray/gen/tmpl/eye.c +91 -0
- data/ext/numo/narray/gen/tmpl/fill.c +38 -0
- data/ext/numo/narray/gen/tmpl/format.c +60 -0
- data/ext/numo/narray/gen/tmpl/format_to_a.c +47 -0
- data/ext/numo/narray/gen/tmpl/head.c +25 -0
- data/ext/numo/narray/gen/tmpl/inspect.c +16 -0
- data/ext/numo/narray/gen/tmpl/map_with_index.c +94 -0
- data/ext/numo/narray/gen/tmpl/median.c +44 -0
- data/ext/numo/narray/gen/tmpl/minmax.c +47 -0
- data/ext/numo/narray/gen/tmpl/poly.c +49 -0
- data/ext/numo/narray/gen/tmpl/pow.c +74 -0
- data/ext/numo/narray/gen/tmpl/powint.c +17 -0
- data/ext/numo/narray/gen/tmpl/qsort.c +149 -0
- data/ext/numo/narray/gen/tmpl/rand.c +33 -0
- data/ext/numo/narray/gen/tmpl/rand_norm.c +46 -0
- data/ext/numo/narray/gen/tmpl/robj_allocate.c +32 -0
- data/ext/numo/narray/gen/tmpl/seq.c +61 -0
- data/ext/numo/narray/gen/tmpl/set2.c +56 -0
- data/ext/numo/narray/gen/tmpl/sort.c +36 -0
- data/ext/numo/narray/gen/tmpl/sort_index.c +86 -0
- data/ext/numo/narray/gen/tmpl/store.c +31 -0
- data/ext/numo/narray/gen/tmpl/store_array.c +5 -0
- data/ext/numo/narray/gen/tmpl/store_from.c +53 -0
- data/ext/numo/narray/gen/tmpl/store_numeric.c +22 -0
- data/ext/numo/narray/gen/tmpl/to_a.c +41 -0
- data/ext/numo/narray/gen/tmpl/unary.c +58 -0
- data/ext/numo/narray/gen/tmpl/unary2.c +58 -0
- data/ext/numo/narray/gen/tmpl/unary_s.c +57 -0
- data/ext/numo/narray/index.c +822 -0
- data/ext/numo/narray/kwarg.c +79 -0
- data/ext/numo/narray/math.c +140 -0
- data/ext/numo/narray/narray.c +1539 -0
- data/ext/numo/narray/ndloop.c +1928 -0
- data/ext/numo/narray/numo/compat.h +23 -0
- data/ext/numo/narray/numo/intern.h +112 -0
- data/ext/numo/narray/numo/narray.h +411 -0
- data/ext/numo/narray/numo/ndloop.h +99 -0
- data/ext/numo/narray/numo/template.h +140 -0
- data/ext/numo/narray/numo/types/bit.h +19 -0
- data/ext/numo/narray/numo/types/complex.h +410 -0
- data/ext/numo/narray/numo/types/complex_macro.h +205 -0
- data/ext/numo/narray/numo/types/dcomplex.h +11 -0
- data/ext/numo/narray/numo/types/dfloat.h +12 -0
- data/ext/numo/narray/numo/types/float_def.h +34 -0
- data/ext/numo/narray/numo/types/float_macro.h +277 -0
- data/ext/numo/narray/numo/types/int16.h +12 -0
- data/ext/numo/narray/numo/types/int32.h +12 -0
- data/ext/numo/narray/numo/types/int64.h +12 -0
- data/ext/numo/narray/numo/types/int8.h +12 -0
- data/ext/numo/narray/numo/types/int_macro.h +34 -0
- data/ext/numo/narray/numo/types/robj_macro.h +218 -0
- data/ext/numo/narray/numo/types/robject.h +21 -0
- data/ext/numo/narray/numo/types/scomplex.h +11 -0
- data/ext/numo/narray/numo/types/sfloat.h +13 -0
- data/ext/numo/narray/numo/types/uint16.h +12 -0
- data/ext/numo/narray/numo/types/uint32.h +12 -0
- data/ext/numo/narray/numo/types/uint64.h +12 -0
- data/ext/numo/narray/numo/types/uint8.h +12 -0
- data/ext/numo/narray/numo/types/uint_macro.h +31 -0
- data/ext/numo/narray/numo/types/xint_macro.h +133 -0
- data/ext/numo/narray/rand.c +87 -0
- data/ext/numo/narray/step.c +506 -0
- data/ext/numo/narray/struct.c +872 -0
- data/lib/2.1/numo/narray.so +0 -0
- data/lib/2.2/numo/narray.so +0 -0
- data/lib/2.3/numo/narray.so +0 -0
- data/lib/erbpp.rb +286 -0
- data/lib/erbpp/line_number.rb +126 -0
- data/lib/erbpp/narray_def.rb +338 -0
- data/lib/numo/narray.rb +6 -0
- data/numo-narray.gemspec +35 -0
- data/spec/bit_spec.rb +93 -0
- data/spec/narray_spec.rb +249 -0
- 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
data/README.md
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
# Numo::NArray - New NArray class library for Ruby/Numo (NUmerical MOdule)
|
2
|
+
|
3
|
+
[](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
|
+
}
|