├── .github └── workflows │ └── build.yml ├── .gitignore ├── 100-narray-exercises.ipynb ├── Gemfile ├── LICENSE ├── README.md ├── Rakefile ├── ToDo.md ├── binder ├── apt.txt └── postBuild ├── doc ├── api.ja.md ├── memo.ja.md ├── memo2.ja.md └── note.md ├── ext └── numo │ └── narray │ ├── SFMT-params.h │ ├── SFMT-params19937.h │ ├── SFMT.c │ ├── SFMT.h │ ├── array.c │ ├── data.c │ ├── depend.erb │ ├── extconf.rb │ ├── gen │ ├── cogen.rb │ ├── def │ │ ├── bit.rb │ │ ├── dcomplex.rb │ │ ├── dfloat.rb │ │ ├── int16.rb │ │ ├── int32.rb │ │ ├── int64.rb │ │ ├── int8.rb │ │ ├── robject.rb │ │ ├── scomplex.rb │ │ ├── sfloat.rb │ │ ├── uint16.rb │ │ ├── uint32.rb │ │ ├── uint64.rb │ │ └── uint8.rb │ ├── erbln.rb │ ├── erbpp2.rb │ ├── narray_def.rb │ ├── spec.rb │ ├── tmpl │ │ ├── accum.c │ │ ├── accum_arg.c │ │ ├── accum_binary.c │ │ ├── accum_index.c │ │ ├── alloc_func.c │ │ ├── allocate.c │ │ ├── aref.c │ │ ├── aset.c │ │ ├── binary.c │ │ ├── binary2.c │ │ ├── binary_s.c │ │ ├── bincount.c │ │ ├── cast.c │ │ ├── cast_array.c │ │ ├── class.c │ │ ├── clip.c │ │ ├── coerce_cast.c │ │ ├── cond_binary.c │ │ ├── cond_unary.c │ │ ├── cum.c │ │ ├── each.c │ │ ├── each_with_index.c │ │ ├── ewcomp.c │ │ ├── extract.c │ │ ├── extract_data.c │ │ ├── eye.c │ │ ├── fill.c │ │ ├── format.c │ │ ├── format_to_a.c │ │ ├── frexp.c │ │ ├── init_class.c │ │ ├── init_module.c │ │ ├── inspect.c │ │ ├── lib.c │ │ ├── logseq.c │ │ ├── map_with_index.c │ │ ├── median.c │ │ ├── minmax.c │ │ ├── module.c │ │ ├── new_dim0.c │ │ ├── poly.c │ │ ├── pow.c │ │ ├── powint.c │ │ ├── qsort.c │ │ ├── rand.c │ │ ├── rand_norm.c │ │ ├── seq.c │ │ ├── set2.c │ │ ├── sort.c │ │ ├── sort_index.c │ │ ├── store.c │ │ ├── store_array.c │ │ ├── store_bit.c │ │ ├── store_from.c │ │ ├── store_numeric.c │ │ ├── to_a.c │ │ ├── unary.c │ │ ├── unary2.c │ │ ├── unary_ret2.c │ │ └── unary_s.c │ └── tmpl_bit │ │ ├── allocate.c │ │ ├── aref.c │ │ ├── aset.c │ │ ├── binary.c │ │ ├── bit_count.c │ │ ├── bit_reduce.c │ │ ├── each.c │ │ ├── each_with_index.c │ │ ├── extract.c │ │ ├── fill.c │ │ ├── format.c │ │ ├── format_to_a.c │ │ ├── inspect.c │ │ ├── mask.c │ │ ├── none_p.c │ │ ├── store_array.c │ │ ├── store_bit.c │ │ ├── store_from.c │ │ ├── to_a.c │ │ ├── unary.c │ │ ├── where.c │ │ └── where2.c │ ├── index.c │ ├── kwargs.c │ ├── math.c │ ├── narray.c │ ├── narray.def │ ├── ndloop.c │ ├── numo │ ├── compat.h │ ├── intern.h │ ├── narray.h │ ├── ndloop.h │ ├── template.h │ └── types │ │ ├── bit.h │ │ ├── complex.h │ │ ├── complex_macro.h │ │ ├── dcomplex.h │ │ ├── dfloat.h │ │ ├── float_def.h │ │ ├── float_macro.h │ │ ├── int16.h │ │ ├── int32.h │ │ ├── int64.h │ │ ├── int8.h │ │ ├── int_macro.h │ │ ├── real_accum.h │ │ ├── robj_macro.h │ │ ├── robject.h │ │ ├── scomplex.h │ │ ├── sfloat.h │ │ ├── uint16.h │ │ ├── uint32.h │ │ ├── uint64.h │ │ ├── uint8.h │ │ ├── uint_macro.h │ │ └── xint_macro.h │ ├── rand.c │ ├── step.c │ └── struct.c ├── fft ├── README.md ├── depend ├── extconf.rb ├── fft.c ├── fft.erb.c ├── fft_tmpl.rb ├── fftsg.c └── t.rb ├── lib └── numo │ ├── narray.rb │ └── narray │ └── extra.rb ├── numo-narray.gemspec └── test ├── bit_test.rb ├── narray_test.rb ├── ractor_test.rb └── test_helper.rb /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | MRI: 7 | name: ${{ matrix.os }} ruby-${{ matrix.ruby }} 8 | runs-on: ${{ matrix.os }}-latest 9 | strategy: 10 | fail-fast: false 11 | matrix: 12 | os: ['ubuntu', 'macos', 'windows'] 13 | ruby: ['2.6', '2.7', '3.0', '3.1', '3.2', '3.3', '3.4', head] 14 | steps: 15 | - uses: actions/checkout@v4 16 | - name: Set up Ruby ${{ matrix.ruby }} 17 | uses: ruby/setup-ruby@v1 18 | with: 19 | ruby-version: ${{ matrix.ruby }} 20 | - name: Build and Install 21 | run: | 22 | gem build numo-narray.gemspec 23 | gem install numo-narray-*.gem 24 | bundle install 25 | - name: Tests 26 | run: rake test 27 | 28 | ruby-head-debug: 29 | name: Build on ruby-head-debug 30 | runs-on: ubuntu-latest 31 | continue-on-error: true 32 | strategy: 33 | fail-fast: false 34 | matrix: 35 | ruby: [ 'debug' ] 36 | steps: 37 | - uses: actions/checkout@v4 38 | - name: Set up Ruby ${{ matrix.ruby }} 39 | uses: ruby/setup-ruby@v1 40 | with: 41 | ruby-version: ${{ matrix.ruby }} 42 | - name: Build and Install 43 | run: | 44 | gem build numo-narray.gemspec 45 | gem install numo-narray-*.gem 46 | bundle install 47 | - name: Tests 48 | run: rake test 49 | 50 | Fedora: 51 | name: fedora 52 | runs-on: ubuntu-latest 53 | steps: 54 | - name: Setup Podman 55 | run: | 56 | sudo apt update 57 | sudo apt-get -y install podman 58 | podman pull fedora:rawhide 59 | - name: Get source 60 | uses: actions/checkout@v4 61 | with: 62 | path: 'numo-narray' 63 | - name: Create container and run tests 64 | run: | 65 | { 66 | echo 'FROM fedora:rawhide' 67 | echo 'RUN dnf -y update' 68 | echo 'RUN dnf -y install gcc-c++ git ruby-devel' 69 | echo 'RUN dnf clean all' 70 | echo 'COPY numo-narray numo-narray' 71 | echo 'WORKDIR /numo-narray' 72 | echo 'RUN gem install --no-document bundler' 73 | echo 'RUN gem build numo-narray.gemspec' 74 | echo 'RUN gem install numo-narray-*.gem' 75 | echo 'RUN bundle install' 76 | echo 'RUN bundle exec rake compile' 77 | echo 'RUN bundle exec rake test' 78 | } > podmanfile 79 | podman build --tag fedora_test -f ./podmanfile 80 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | *.rbc 3 | .bundle 4 | .config 5 | .yardoc 6 | yard 7 | api 8 | Gemfile.lock 9 | InstalledFiles 10 | _yardoc 11 | coverage 12 | lib/bundler/man 13 | pkg 14 | rdoc 15 | spec/reports 16 | test/tmp 17 | test/version_tmp 18 | tmp 19 | *~ 20 | *.o 21 | *.so 22 | *.bundle 23 | mkmf.log 24 | ext/numo/narray/t_*.c 25 | ext/numo/narray/numo/extconf.h 26 | ext/numo/narray/Makefile 27 | ext/numo/narray/depend 28 | lib/numo/numo/extconf.h 29 | TAGS 30 | t.rb 31 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # Specify your gem's dependencies in narray-devel.gemspec 4 | gemspec 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 1999-2020, Masahiro TANAKA 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Numo::NArray 2 | [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/ruby-numo/numo-narray/HEAD?filepath=100-narray-exercises.ipynb) 3 | [![Build Status](https://github.com/ruby-numo/numo-narray/workflows/build/badge.svg)](https://github.com/ruby-numo/numo-narray/actions) 4 | 5 | [GitHub](https://github.com/ruby-numo/numo-narray) 6 | | [RubyGems](https://rubygems.org/gems/numo-narray) 7 | 8 | Numo::NArray is an Numerical N-dimensional Array class 9 | for fast processing and easy manipulation of multi-dimensional numerical data, 10 | similar to numpy.ndarray. 11 | This project is the successor to [Ruby/NArray](http://masa16.github.io/narray/). 12 | 13 | ## Documentation 14 | 15 | All documents are primitive. 16 | 17 | * [Numo::NArray API Doc](http://ruby-numo.github.io/numo-narray/yard/index.html) 18 | * [Numo::NArray vs numpy](https://github.com/ruby-numo/numo-narray/wiki/Numo-vs-numpy) 19 | * [Numo::NArray vs ndarray](https://github.com/ruby-numo/numo-narray/wiki/Numo-vs-ndarray) 20 | * [Numo::NArray Overview](https://github.com/ruby-numo/numo-narray/wiki/Numo::NArray-Overview-(Japanese)) (in Japanese) 21 | 22 | ## Related Projects 23 | 24 | * [Numo::Linalg](https://github.com/ruby-numo/numo-linalg) - Linear Algebra library with [LAPACK](http://www.netlib.org/lapack/). 25 | * [Numo::GSL](https://github.com/ruby-numo/numo-gsl) - Ruby interface for [GSL (GNU Scientific Library)](http://www.gnu.org/software/gsl/). 26 | * [Numo::FFTW](https://github.com/ruby-numo/numo-fftw) - Ruby/Numo interface to [FFTW (A Discrete Fourier Transform library](http://www.fftw.org/). 27 | * [Numo::FFTE](https://github.com/ruby-numo/numo-ffte) - Ruby interface for [FFTE (A Fast Fourier Transform library with radix-2,3,5)](http://www.ffte.jp/). 28 | * [Numo::Gnuplot](https://github.com/ruby-numo/numo-gnuplot) - Simple and easy-to-use Gnuplot interface. 29 | 30 | ## Installation 31 | 32 | ### Requirement 33 | 34 | Ruby ver 2.2 and later. 35 | 36 | ### Ubuntu, Debian, Bash on Windows 37 | 38 | ```shell 39 | apt install -y git ruby gcc ruby-dev rake make 40 | gem install specific_install 41 | gem specific_install https://github.com/ruby-numo/numo-narray.git 42 | ``` 43 | 44 | ## Quick start 45 | 46 | An example 47 | 48 | ```ruby 49 | [1] pry(main)> require "numo/narray" 50 | => true 51 | [2] pry(main)> a = Numo::DFloat.new(3,5).seq 52 | => Numo::DFloat#shape=[3,5] 53 | [[0, 1, 2, 3, 4], 54 | [5, 6, 7, 8, 9], 55 | [10, 11, 12, 13, 14]] 56 | [3] pry(main)> a.shape 57 | => [3, 5] 58 | [4] pry(main)> a.ndim 59 | => 2 60 | [5] pry(main)> a.class 61 | => Numo::DFloat 62 | [6] pry(main)> a.size 63 | => 15 64 | ``` 65 | 66 | For more examples, check out the **narray version of 100 numpy exercises**. 67 | - [Wiki version](https://github.com/ruby-numo/numo-narray/wiki/100-narray-exercises) of the 100 exercises 68 | - [Reproducible version](https://mybinder.org/v2/gh/ruby-numo/numo-narray/HEAD?filepath=100-narray-exercises.ipynb) of the 100 exercises (With this, you can try narray without creating an environment locally.) 69 | 70 | ## Development 71 | 72 | ### Build 73 | 74 | ```shell 75 | git clone https://github.com/ruby-numo/numo-narray 76 | cd numo-narray 77 | bundle install 78 | bundle exec rake compile 79 | ``` 80 | 81 | ### Run tests 82 | 83 | ```shell 84 | bundle exec rake test 85 | ``` 86 | 87 | Tips: You may run tests defined in a specified line as: 88 | 89 | ```shell 90 | bundle exec ruby test/bit_test.rb --location 27 91 | ``` 92 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require "bundler/gem_tasks" 2 | 3 | task :doc do 4 | dir = "ext/numo/narray" 5 | src = %w[array.c data.c index.c math.c narray.c rand.c struct.c]. 6 | map{|s| File.join(dir,s)} + 7 | [File.join(dir,"t_*.c"), "lib/numo/narray/extra.rb"] 8 | sh "cd ext/numo/narray; ruby extconf.rb; make src" 9 | sh "rm -rf yard .yardoc; yard doc -o yard -m markdown -r README.md #{src.join(' ')}" 10 | end 11 | 12 | require 'rake/testtask' 13 | Rake::TestTask.new(:test) do |t| 14 | t.libs << "test" 15 | t.libs << "lib" 16 | t.verbose = false 17 | t.warning = false 18 | t.test_files = FileList['test/**/*_test.rb'] 19 | end 20 | 21 | require 'rake/extensiontask' 22 | Rake::ExtensionTask.new('numo/narray') 23 | -------------------------------------------------------------------------------- /ToDo.md: -------------------------------------------------------------------------------- 1 | 2 | - [x] copy to buffer if non-contiguous.gc 3 | - [x] contract contiguous dimensions.gc 4 | 5 | - [ ] transpose and flatten reduce dimeinsion to last user dimension. -- almost done. 6 | 7 | - [ ] NArray with 1-d index and md-shape?? 8 | - [ ] enable a[a.sort_index] == a.sort for multi-dimensional array -- perhaps done. 9 | 10 | - [ ] specify Input/Overwrite array -- already has OVERWRITE 11 | 12 | - [x] accept int-array as index argument of aref.gc 13 | 14 | - [x] convert binary from/to Stringgc 15 | 16 | - [x] Complex#seq allows complex stepgc 17 | 18 | - [ ] Frozen array -- checking OBJ_FROZEN. 19 | 20 | - [ ] Marshaling -- perhaps done except Bit, Struct. 21 | 22 | - [x] inspect Enumerable#step objectgc 23 | 24 | - [x] contiguous checkgc 25 | 26 | - [x] propagate_nan for min,max,sum,...gc 27 | 28 | - [ ] parsing keyword arguments -- use ruby api. 29 | 30 | - [x] use erbpp2gc 31 | 32 | - [x] switch to TypedData.gc 33 | 34 | - [x] how to get the element size value effectivelygc 35 | 36 | - [x] introduce keyword :keepdims (keep dimension/axis) for reduce_dimension.gc 37 | 38 | - [x] refactoring array.c: avoid using na_compose_t and na_ary_composition.gc 39 | 40 | - [x] reshape!gc 41 | 42 | 43 | - [ ] flatten_dim 44 | 45 | - [ ] name of new_zeros, zeros_like etc. 46 | 47 | - [ ] NMath.sin => DFloat.sin ?? 48 | 49 | - [ ] contiguous if na_view->stridx == NULL ? 50 | 51 | - [ ] store_binary with bite_swap. 52 | 53 | - [ ] write barrier? 54 | 55 | - [ ] move "reduce" field from RNArray to RNArrayView? 56 | 57 | - [ ] unify RNArrayBase and RNArrayView structure?? 58 | 59 | 60 | - [ ] Thread-locked array?? 61 | 62 | - [ ] use rb_thread_call_without_gvl?? 63 | 64 | 65 | - [ ] alignment 66 | 67 | - [ ] force buffering option 68 | 69 | - [ ] update MT Random Number Generator 70 | 71 | - [ ] GVL release 72 | - [ ] Ctrl-C stop during method 73 | 74 | - [ ] floor method should be same as Ruby floor or C99 floor ?? 75 | 76 | # constants 77 | 78 | - [ ] NAN 79 | - [ ] INF 80 | - [ ] EPS 81 | 82 | # Matlab method 83 | 84 | - [x] logspace 85 | - [ ] meshgrid 86 | - [x] rot90 87 | - [x] rad2deg 88 | - [x] deg2rad 89 | - [x] expm1 90 | - [ ] histcount 91 | 92 | # from numpy 93 | 94 | - [x] <<,>> 95 | - [x] swapaxis 96 | - [ ] squeeze 97 | - [x] trace 98 | - [x] ptp 99 | - [x] clip 100 | - [ ] ravel 101 | - [ ] take 102 | - [ ] put 103 | - [ ] choose choise 104 | - [ ] select 105 | - [ ] partition 106 | - [ ] searchsorted / bsearch 107 | - [ ] compress 108 | - [ ] pad 109 | - [x] tile 110 | - [x] copysign 111 | - [x] bincount 112 | - [ ] unique 113 | - [ ] roll 114 | - [x] repeat 115 | - [ ] logical_and/or/not - Bit & | ^ 116 | - [ ] minimum,maximum 117 | - [ ] shuffle 118 | - [ ] interp 119 | - [ ] intersect1d 120 | - [ ] asarray - cast 121 | - [ ] persentile 122 | 123 | # Math 124 | 125 | - [ ] csc,sec,cot 126 | - [ ] csch,sech,coth 127 | - [ ] acsc,asec,acot 128 | - [ ] acsch,asech,acoth 129 | -------------------------------------------------------------------------------- /binder/apt.txt: -------------------------------------------------------------------------------- 1 | libtool 2 | libffi-dev 3 | ruby 4 | ruby-dev 5 | make 6 | git 7 | gcc 8 | rake 9 | libczmq-dev 10 | libzmq3-dev 11 | -------------------------------------------------------------------------------- /binder/postBuild: -------------------------------------------------------------------------------- 1 | gem install --user-install bundler rake rake-compiler iruby 2 | git clone https://github.com/ruby-numo/numo-narray 3 | cd numo-narray 4 | /home/jovyan/.gem/ruby/2.5.0/bin/bundle install 5 | /home/jovyan/.gem/ruby/2.5.0/bin/bundle exec rake compile 6 | /home/jovyan/.gem/ruby/2.5.0/bin/iruby register --force 7 | -------------------------------------------------------------------------------- /doc/memo.ja.md: -------------------------------------------------------------------------------- 1 | - 処理の途中で raise された場合、処理が戻ってこない場合がある。 2 | - その場合、 malloc で確保したメモリーが開放されない可能性があり、メモリーリークになる。 3 | - メモリーリークを防ぐには、次のいずれかの方法を採る。 4 | - スタックにメモリを確保する 5 | - ruby object としてラップする => これで対処完了 6 | 7 | 現状のコード 8 | 9 | // Rubyメソッドに対応するC関数を定義 10 | static VALUE 11 | nary_dfloat_s_add(VALUE mod, VALUE a1, VALUE a2) 12 | { 13 | ndfunc_t *func; 14 | VALUE v; 15 | 16 | func = ndfunc_alloc(iter_dfloat_add, NDF_CONTIGUOUS_LOOP, 17 | 2, 1, cT, cT, cT); 18 | v = ndloop_do(func, 2, a1, a2); 19 | ndfunc_free(func); 20 | return v; 21 | } 22 | 23 | typedef struct NDFUNCTION { 24 | na_iter_func_t func; // user function 25 | unsigned int flag; // what kind of loop user function supports 26 | int narg; // # of arguments 27 | int nopt; // # of options 28 | int nres; // # of results 29 | ndfunc_arg_t *args; // spec of arguments 30 | VALUE *opt_types; // option types 31 | } ndfunc_t; 32 | 33 | typedef struct NDFUNC_ARG { 34 | VALUE type; // argument types 35 | VALUE init; // initial value 36 | int dim; // # of dimension of argument handled by user function 37 | union { 38 | size_t shape[1]; 39 | size_t *shape_p; 40 | } aux; // shape 41 | } ndfunc_arg_t; 42 | 43 | 44 | ndfunc_t をスタックで確保するには 45 | 46 | // Rubyメソッドに対応するC関数を定義 47 | static VALUE 48 | nary_dfloat_s_add(VALUE mod, VALUE a1, VALUE a2) 49 | { 50 | ndfunc_t nf; 51 | VALUE v; 52 | VALUE inp[2] = {cT,cT}; 53 | VALUE out[1] = {cT}; 54 | option_t option; 55 | 56 | ndfunc_arg_t inp[2] = {{cT,0,NULL},{cT,0,NULL}}; 57 | ndfunc_arg_t out[1] = {{cT,0,NULL}}; 58 | 59 | ndfunc_set( nf, itr, flag, inp, 2, out, 1 ); 60 | nf.func = itr_func; 61 | nf.flag = flag; 62 | nf.inp = inp; 63 | nf.ninp = 2; 64 | nf.out = out; 65 | nf.nout = 1; 66 | nf.option = &option; 67 | 68 | func = ndfunc_alloc(iter_dfloat_add, NDF_CONTIGUOUS_LOOP, 69 | 2, 1, cT, cT, cT); 70 | v = ndloop_do(func, 2, a1, a2); 71 | ndfunc_free(func); 72 | return v; 73 | } 74 | 75 | こうしたい: 76 | 77 | // Rubyメソッドに対応するC関数を定義 78 | static VALUE 79 | nary_dfloat_s_add(VALUE mod, int argc, VALUE *argv) 80 | { 81 | nanika_t opts; 82 | ndfunc_arg_t args[3] = {{cT,0,NULL},{cT,0,NULL},{INT2FIX(3),0,NULL}}; 83 | ndfunc_t ndf = { init_func, itr_func, flags, 2, 1, args, &opts }; 84 | 85 | return na_ndloop(&ndf, argc, argv); 86 | } 87 | 88 | 89 | 90 | // Rubyメソッドに対応するC関数を定義 91 | static VALUE 92 | nary_dfloat_s_add(VALUE mod, int argc, VALUE *argv) 93 | { 94 | nanika_t opts; 95 | ndfunc_arg_t argt[3] = {{cT,0,NULL},{cT,0,NULL},{INT2FIX(3),0,NULL}}; 96 | ndfunc_t ndf = { init_func, itr_func, flags, 2, 1, argt, &opts }; 97 | 98 | return na_vndloop(&ndf, argc, argv); 99 | } 100 | 101 | -------------------------------------------------------------------------------- /doc/memo2.ja.md: -------------------------------------------------------------------------------- 1 | # memo2 2 | - とりあえずロック機構はあきらめる? 3 | - 出力配列が2つ以上のとき、入力配列に inplace がある場合 4 | - 第1番目の出力配列が inplace 配列とする 5 | - inplace の強度 6 | - cast された配列は、 inplace が無効になる 7 | - cast された場合でも writeback したいときは? 8 | - inplace 配列がアクセスタイプによってコピーされた場合は、結果が writeback される 9 | - 入力配列がキャストまたはコピーされた場合、その配列が 一時的に inplace となる。 10 | - 一時的inplace は、writepack 回避 11 | 12 | - 入力配列がキャスト・コピーされたかどうか判別する方法 13 | - writeback するか否か判別する方法 14 | 15 | ------- 16 | 17 | # na_ndloop_main 18 | ## ndloop_cast_args 19 | - 入力配列をキャスト 20 | - 型の比較 21 | - (ループタイプ) 22 | 23 | ## ndloop_alloc 24 | - max_nd を得る 25 | - lp イテレータをアロケート 26 | 27 | - (入力配列のアクセスタイプを得る) 28 | - (ループ関数のループタイプを得る) 29 | - (次の条件のとき、入力配列をキャスト・コピーする 30 | - 配列データタイプが、ループ関数指定のデータ型とマッチしないとき。 31 | - ループ関数が HAS_LOOP であり、配列アクセスタイプをサポートしないとき。 32 | - ループ関数が NO_LOOP で、user_ndim が1以上であり、配列アクセスタイプをサポートしないとき。 33 | - ) 34 | 35 | # ndloop_run 36 | ## ndloop_init_args 37 | 38 | ### (ndloop_set_input_iter) 39 | - 各入力配列について 40 | - LITER.ptr をセット 41 | - 各次元について 42 | - LITER pos step idx をセット 43 | 44 | ### (ndloop_set_output_iter) 45 | - 各出力配列について 46 | - ndloop_get_arg_type 配列dataタイプを得る 47 | - ndloop_set_narray_result (prepare_output_narray) 48 | - 入力配列に inplace またはコピー配列がある場合: 49 | - データタイプ、(アクセスタイプ)、shape が合い、ループ関数がinplaceサポートならば、出力配列として用いる 50 | - ない場合: 51 | - inplace がなければ、出力配列を作る 52 | - LITER にセット 53 | 54 | ### (ndloop_init_output) 55 | - 初期化データがある場合 56 | - na_store 57 | 58 | ## ndfunc_set_user_loop 59 | ### ndfunc_check_user_loop 60 | - ループ関数内でループするかどうかの検出 61 | - user.ndim の調整 62 | 63 | ## (次元の縮約) 64 | 65 | ## loop_narray 66 | 演算 operate_narray 67 | 68 | ## (inplaceに書き戻し!) 69 | ndloop_return_output 70 | 条件: 入力配列に inplace があり、shape が合うのに、出力配列にセットされなかったとき 71 | 72 | - 入力配列が inplace でなく、キャストして inplace になり、出力配列にセットされたものは 73 | inplace フラグをはずす。 74 | -------------------------------------------------------------------------------- /doc/note.md: -------------------------------------------------------------------------------- 1 | # Miscellaneous notes for Numo::NArray 2 | 3 | ## Running RSpec 4 | 5 | (in advance, install gem with --development option) 6 | 7 | ```shell 8 | $ "${HOME}/.gem/ruby/2.?/bin/rspec" "${HOME}/.gem/ruby/2.?/gems/numo-narray-0.9.?.?/spec/bit_spec.rb" 9 | $ "${HOME}/.gem/ruby/2.?/bin/rspec" "${HOME}/.gem/ruby/2.?/gems/numo-narray-0.9.?.?/spec/narray_spec.rb" 10 | ``` 11 | 12 | ## YARD documents generation 13 | 14 | (in advance, install yard gem) 15 | 16 | ```shell 17 | $ cd "${HOME}/.gem/ruby/2.?/gems/numo-narray-0.9.?.?/ext/numo/narray" 18 | $ make doc 19 | yard doc *.c types/*.c 20 | ... 21 | ``` 22 | -------------------------------------------------------------------------------- /ext/numo/narray/SFMT-params.h: -------------------------------------------------------------------------------- 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 */ 98 | -------------------------------------------------------------------------------- /ext/numo/narray/SFMT-params19937.h: -------------------------------------------------------------------------------- 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 */ 47 | -------------------------------------------------------------------------------- /ext/numo/narray/depend.erb: -------------------------------------------------------------------------------- 1 | TAGSRC = \ 2 | numo/types/*.h \ 3 | *.c 4 | 5 | tags : TAGS 6 | TAGS : $(TAGSRC) 7 | etags $(TAGSRC) 8 | 9 | doc : 10 | yard doc *.c 11 | 12 | C_TMPL = <%=Dir.glob("#{__dir__}/gen/tmpl*/*.c").join(" ")%> 13 | 14 | COGEN = <%= __dir__ %>/gen/cogen.rb 15 | DEPENDS = $(C_TMPL) <%= __dir__ %>/gen/*.rb 16 | 17 | <% 18 | type_c = [] 19 | type_rb = Dir.glob("#{__dir__}/gen/def/*.rb") 20 | type_rb.each do |s| 21 | type_c << c = "t_"+File.basename(s,".rb")+".c" 22 | %> 23 | <%=c%>: <%=s%> $(DEPENDS) 24 | ruby $(COGEN) -l -o $@ <%=s%> 25 | <% end %> 26 | 27 | src : <%= type_c.join(" ") %> 28 | 29 | CLEANOBJS = *.o t_*.c *.bak 30 | DISTCLEANFILES = depend TAGS 31 | -------------------------------------------------------------------------------- /ext/numo/narray/extconf.rb: -------------------------------------------------------------------------------- 1 | require 'rbconfig.rb' 2 | require 'mkmf' 3 | require "erb" 4 | 5 | if RUBY_VERSION < "2.1.0" 6 | puts "Numo::NArray requires Ruby version 2.1 or later." 7 | exit(1) 8 | end 9 | 10 | def d(file) 11 | File.join(__dir__,file) 12 | end 13 | 14 | rm_f d('numo/extconf.h') 15 | 16 | #$CFLAGS="-g3 -O0 -Wall" 17 | #$CFLAGS=" $(cflags) -O3 -m64 -msse2 -funroll-loops" 18 | #$CFLAGS=" $(cflags) -O3" 19 | $INCFLAGS = "-Itypes #$INCFLAGS" 20 | 21 | $INSTALLFILES = Dir.glob(%w[numo/*.h numo/types/*.h]).map{|x| [x,'$(archdir)'] } 22 | $INSTALLFILES << ['numo/extconf.h','$(archdir)'] 23 | if /cygwin|mingw/ =~ RUBY_PLATFORM 24 | $DLDFLAGS << " -Wl,--export-all,--out-implib=libnarray.a" 25 | $INSTALLFILES << ['./libnarray.a', '$(archdir)'] 26 | end 27 | 28 | srcs = %w( 29 | narray 30 | array 31 | step 32 | index 33 | ndloop 34 | data 35 | t_bit 36 | t_int8 37 | t_int16 38 | t_int32 39 | t_int64 40 | t_uint8 41 | t_uint16 42 | t_uint32 43 | t_uint64 44 | t_sfloat 45 | t_dfloat 46 | t_scomplex 47 | t_dcomplex 48 | t_robject 49 | math 50 | SFMT 51 | struct 52 | rand 53 | ) 54 | 55 | if RUBY_VERSION[0..3] == "2.1." 56 | puts "add kwargs" 57 | srcs << "kwargs" 58 | end 59 | 60 | if have_header("stdbool.h") 61 | stdbool = "stdbool.h" 62 | else 63 | stdbool = nil 64 | end 65 | 66 | if have_header("stdint.h") 67 | stdint = "stdint.h" 68 | elsif have_header("sys/types.h") 69 | stdint = "sys/types.h" 70 | else 71 | stdint = nil 72 | end 73 | 74 | have_type("bool", stdbool) 75 | unless have_type("u_int8_t", stdint) 76 | have_type("uint8_t",stdint) 77 | end 78 | unless have_type("u_int16_t", stdint) 79 | have_type("uint16_t",stdint) 80 | end 81 | have_type("int32_t", stdint) 82 | unless have_type("u_int32_t", stdint) 83 | have_type("uint32_t",stdint) 84 | end 85 | have_type("int64_t", stdint) 86 | unless have_type("u_int64_t", stdint) 87 | have_type("uint64_t", stdint) 88 | end 89 | have_func("exp10") 90 | have_func("rb_arithmetic_sequence_extract") 91 | have_func("RTYPEDDATA_GET_DATA") 92 | 93 | have_var("rb_cComplex") 94 | 95 | $objs = srcs.collect{|i| i+".o"} 96 | 97 | create_header d('numo/extconf.h') 98 | 99 | File.open(d('depend'), "w") do |depend| 100 | File.open(d('depend.erb'), "r") do |depend_erb| 101 | erb = ERB.new(depend_erb.read) 102 | erb.filename = d('depend.erb') 103 | depend.print(erb.result) 104 | end 105 | end 106 | 107 | create_makefile('numo/narray') 108 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/cogen.rb: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env ruby 2 | 3 | # Build gems for Windows by using fake RbConfig::CONFIG by rake-compiler. 4 | fake_path = File.join(Dir.pwd, 'fake.rb') 5 | if File.exist? fake_path 6 | $:.unshift(Dir.pwd) 7 | require 'fake' 8 | end 9 | 10 | thisdir = File.dirname(__FILE__) 11 | libpath = File.absolute_path(File.dirname(__FILE__))+"/../../../../lib" 12 | $LOAD_PATH.unshift libpath 13 | 14 | require_relative "narray_def" 15 | 16 | $line_number = false 17 | 18 | while true 19 | if ARGV[0] == "-l" 20 | $line_number = true 21 | ARGV.shift 22 | elsif ARGV[0] == "-o" 23 | ARGV.shift 24 | $output = ARGV.shift 25 | require "fileutils" 26 | FileUtils.rm_f($output) 27 | else 28 | break 29 | end 30 | end 31 | 32 | if ARGV.size != 1 33 | puts "usage:\n ruby #{$0} [-l] erb_base [type_file]" 34 | exit 1 35 | end 36 | 37 | type_file, = ARGV 38 | type_name = File.basename(type_file,".rb") 39 | 40 | erb_dir = ["tmpl"] 41 | erb_dir.unshift("tmpl_bit") if (type_name == "bit") 42 | erb_dir.map!{|d| File.join(thisdir,d)} 43 | 44 | code = DefLib.new do 45 | set line_number: $line_number 46 | set erb_dir: erb_dir 47 | set erb_suffix: ".c" 48 | set ns_var: "mNumo" 49 | 50 | set file_name: $output||"" 51 | set include_files: ["numo/types/#{type_name}.h"] 52 | set lib_name: "numo_"+type_name 53 | 54 | if (::RbConfig::CONFIG['target_cpu'] == 'x86_64') or (::RbConfig::CONFIG['target_cpu'] == 'x64') 55 | set is_simd: true 56 | else 57 | set is_simd: false 58 | end 59 | 60 | def_class do 61 | extend NArrayMethod 62 | extend NArrayType 63 | eval File.read(type_file), binding, type_file 64 | eval File.read(File.join(thisdir,"spec.rb")), binding, "spec.rb" 65 | end 66 | end.result 67 | 68 | if $output 69 | File.write($output, code) 70 | else 71 | $stdout.write(code) 72 | end 73 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/def/bit.rb: -------------------------------------------------------------------------------- 1 | set name: "bit" 2 | set type_name: "bit" 3 | set full_class_name: "Numo::Bit" 4 | set class_name: "Bit" 5 | set class_alias: nil 6 | set class_var: "cT" 7 | set ctype: "BIT_DIGIT" 8 | 9 | set has_math: false 10 | set is_bit: true 11 | set is_int: false 12 | set is_unsigned: true 13 | set is_float: false 14 | set is_complex: false 15 | set is_object: false 16 | set is_real: false 17 | set is_comparable: false 18 | set is_double_precision: false 19 | set need_align: false 20 | 21 | upcast_rb "Integer" 22 | upcast_rb "Float", "DFloat" 23 | upcast_rb "Complex", "DComplex" 24 | 25 | upcast "RObject", "RObject" 26 | upcast "DComplex", "DComplex" 27 | upcast "SComplex", "SComplex" 28 | upcast "DFloat", "DFloat" 29 | upcast "SFloat", "SFloat" 30 | upcast "Int64", "Int64" 31 | upcast "Int32", "Int32" 32 | upcast "Int16", "Int16" 33 | upcast "Int8", "Int8" 34 | upcast "UInt64", "UInt64" 35 | upcast "UInt32", "UInt32" 36 | upcast "UInt16", "UInt16" 37 | upcast "UInt8", "UInt8" 38 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/def/dcomplex.rb: -------------------------------------------------------------------------------- 1 | set name: "dcomplex" 2 | set type_name: "dcomplex" 3 | set full_class_name: "Numo::DComplex" 4 | set class_name: "DComplex" 5 | set class_alias: "Complex64" 6 | set class_var: "cT" 7 | set ctype: "dcomplex" 8 | set real_class_name: "DFloat" 9 | set real_ctype: "double" 10 | 11 | set has_math: true 12 | set is_bit: false 13 | set is_int: false 14 | set is_unsigned: false 15 | set is_float: true 16 | set is_real: false 17 | set is_complex: true 18 | set is_object: false 19 | set is_comparable: false 20 | set is_double_precision: true 21 | set need_align: true 22 | 23 | upcast_rb "Integer" 24 | upcast_rb "Float" 25 | upcast_rb "Complex" 26 | 27 | upcast "RObject", "RObject" 28 | upcast "DComplex", "DComplex" 29 | upcast "SComplex", "DComplex" 30 | upcast "DFloat", "DComplex" 31 | upcast "SFloat", "DComplex" 32 | upcast "Int64", "DComplex" 33 | upcast "Int32", "DComplex" 34 | upcast "Int16", "DComplex" 35 | upcast "Int8", "DComplex" 36 | upcast "UInt64", "DComplex" 37 | upcast "UInt32", "DComplex" 38 | upcast "UInt16", "DComplex" 39 | upcast "UInt8", "DComplex" 40 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/def/dfloat.rb: -------------------------------------------------------------------------------- 1 | set name: "dfloat" 2 | set type_name: "dfloat" 3 | set full_class_name: "Numo::DFloat" 4 | set class_name: "DFloat" 5 | set class_alias: "Float64" 6 | set class_var: "cT" 7 | set ctype: "double" 8 | set simd_type: "pd" 9 | 10 | set has_math: true 11 | set is_bit: false 12 | set is_int: false 13 | set is_unsigned: false 14 | set is_float: true 15 | set is_complex: false 16 | set is_object: false 17 | set is_real: true 18 | set is_comparable: true 19 | set is_double_precision: true 20 | set need_align: true 21 | 22 | upcast_rb "Integer" 23 | upcast_rb "Float" 24 | upcast_rb "Complex", "DComplex" 25 | 26 | upcast "RObject", "RObject" 27 | upcast "DComplex", "DComplex" 28 | upcast "SComplex", "DComplex" 29 | upcast "DFloat", "DFloat" 30 | upcast "SFloat", "DFloat" 31 | upcast "Int64", "DFloat" 32 | upcast "Int32", "DFloat" 33 | upcast "Int16", "DFloat" 34 | upcast "Int8", "DFloat" 35 | upcast "UInt64", "DFloat" 36 | upcast "UInt32", "DFloat" 37 | upcast "UInt16", "DFloat" 38 | upcast "UInt8", "DFloat" 39 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/def/int16.rb: -------------------------------------------------------------------------------- 1 | set name: "int16" 2 | set type_name: "int16" 3 | set full_class_name: "Numo::Int16" 4 | set class_name: "Int16" 5 | set class_var: "cT" 6 | set ctype: "int16_t" 7 | 8 | set has_math: false 9 | set is_bit: false 10 | set is_int: true 11 | set is_unsigned: false 12 | set is_float: false 13 | set is_complex: false 14 | set is_object: false 15 | set is_real: true 16 | set is_comparable: true 17 | set is_double_precision: false 18 | set need_align: true 19 | 20 | upcast_rb "Integer" 21 | upcast_rb "Float", "DFloat" 22 | upcast_rb "Complex", "DComplex" 23 | 24 | upcast "RObject", "RObject" 25 | upcast "DComplex", "DComplex" 26 | upcast "SComplex", "SComplex" 27 | upcast "DFloat", "DFloat" 28 | upcast "SFloat", "SFloat" 29 | upcast "Int64", "Int64" 30 | upcast "Int32", "Int32" 31 | upcast "Int16" 32 | upcast "Int8" 33 | upcast "UInt64", "Int64" 34 | upcast "UInt32", "Int32" 35 | upcast "UInt16" 36 | upcast "UInt8" 37 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/def/int32.rb: -------------------------------------------------------------------------------- 1 | set name: "int32" 2 | set type_name: "int32" 3 | set full_class_name: "Numo::Int32" 4 | set class_name: "Int32" 5 | set class_var: "cT" 6 | set ctype: "int32_t" 7 | 8 | set has_math: false 9 | set is_bit: false 10 | set is_int: true 11 | set is_unsigned: false 12 | set is_float: false 13 | set is_complex: false 14 | set is_object: false 15 | set is_real: true 16 | set is_comparable: true 17 | set is_double_precision: false 18 | set need_align: true 19 | 20 | upcast_rb "Integer" 21 | upcast_rb "Float", "DFloat" 22 | upcast_rb "Complex", "DComplex" 23 | 24 | upcast "RObject", "RObject" 25 | upcast "DComplex", "DComplex" 26 | upcast "SComplex", "SComplex" 27 | upcast "DFloat", "DFloat" 28 | upcast "SFloat", "SFloat" 29 | upcast "Int64", "Int64" 30 | upcast "Int32" 31 | upcast "Int16" 32 | upcast "Int8" 33 | upcast "UInt64", "Int64" 34 | upcast "UInt32" 35 | upcast "UInt16" 36 | upcast "UInt8" 37 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/def/int64.rb: -------------------------------------------------------------------------------- 1 | set name: "int64" 2 | set type_name: "int64" 3 | set full_class_name: "Numo::Int64" 4 | set class_name: "Int64" 5 | set class_var: "cT" 6 | set ctype: "int64_t" 7 | 8 | set has_math: false 9 | set is_bit: false 10 | set is_int: true 11 | set is_unsigned: false 12 | set is_float: false 13 | set is_complex: false 14 | set is_object: false 15 | set is_real: true 16 | set is_comparable: true 17 | set is_double_precision: false 18 | set need_align: true 19 | 20 | upcast_rb "Integer" 21 | upcast_rb "Float", "DFloat" 22 | upcast_rb "Complex", "DComplex" 23 | 24 | upcast "RObject", "RObject" 25 | upcast "DComplex", "DComplex" 26 | upcast "SComplex", "SComplex" 27 | upcast "DFloat", "DFloat" 28 | upcast "SFloat", "SFloat" 29 | upcast "Int64" 30 | upcast "Int32" 31 | upcast "Int16" 32 | upcast "Int8" 33 | upcast "UInt64" 34 | upcast "UInt32" 35 | upcast "UInt16" 36 | upcast "UInt8" 37 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/def/int8.rb: -------------------------------------------------------------------------------- 1 | set name: "int8" 2 | set type_name: "int8" 3 | set full_class_name: "Numo::Int8" 4 | set class_name: "Int8" 5 | set class_var: "cT" 6 | set ctype: "int8_t" 7 | 8 | set has_math: false 9 | set is_bit: false 10 | set is_int: true 11 | set is_unsigned: false 12 | set is_float: false 13 | set is_complex: false 14 | set is_object: false 15 | set is_real: true 16 | set is_comparable: true 17 | set is_double_precision: false 18 | set need_align: false 19 | 20 | upcast_rb "Integer" 21 | upcast_rb "Float", "DFloat" 22 | upcast_rb "Complex", "DComplex" 23 | 24 | upcast "RObject", "RObject" 25 | upcast "DComplex", "DComplex" 26 | upcast "SComplex", "SComplex" 27 | upcast "DFloat", "DFloat" 28 | upcast "SFloat", "SFloat" 29 | upcast "Int64", "Int64" 30 | upcast "Int32", "Int32" 31 | upcast "Int16", "Int16" 32 | upcast "Int8", "Int8" 33 | upcast "UInt64", "Int64" 34 | upcast "UInt32", "Int64" 35 | upcast "UInt16", "Int32" 36 | upcast "UInt8", "Int16" 37 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/def/robject.rb: -------------------------------------------------------------------------------- 1 | set name: "robject" 2 | set type_name: "robject" 3 | set full_class_name: "Numo::RObject" 4 | set class_name: "RObject" 5 | set class_var: "cT" 6 | set ctype: "VALUE" 7 | set real_class_name: "RObject" 8 | set real_ctype: "VALUE" 9 | 10 | set has_math: false 11 | set is_bit: false 12 | set is_int: true 13 | set is_unsigned: false 14 | set is_float: true 15 | set is_real: true 16 | set is_complex: false 17 | set is_object: true 18 | set is_comparable: true 19 | set is_double_precision: false 20 | set need_align: false 21 | 22 | upcast_rb "Integer" 23 | upcast_rb "Float" 24 | upcast_rb "Complex" 25 | 26 | upcast "DComplex", "RObject" 27 | upcast "SComplex", "RObject" 28 | upcast "DFloat", "RObject" 29 | upcast "SFloat", "RObject" 30 | upcast "Int64", "RObject" 31 | upcast "Int32", "RObject" 32 | upcast "Int16", "RObject" 33 | upcast "Int8", "RObject" 34 | upcast "UInt64", "RObject" 35 | upcast "UInt32", "RObject" 36 | upcast "UInt16", "RObject" 37 | upcast "UInt8", "RObject" 38 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/def/scomplex.rb: -------------------------------------------------------------------------------- 1 | set name: "scomplex" 2 | set type_name: "scomplex" 3 | set full_class_name: "Numo::SComplex" 4 | set class_name: "SComplex" 5 | set class_alias: "Complex32" 6 | set class_var: "cT" 7 | set ctype: "Scomplex" 8 | set real_class_name: "SFloat" 9 | set real_ctype: "float" 10 | 11 | set has_math: true 12 | set is_bit: false 13 | set is_int: false 14 | set is_unsigned: false 15 | set is_float: true 16 | set is_real: false 17 | set is_complex: true 18 | set is_object: false 19 | set is_comparable: false 20 | set is_double_precision: false 21 | set need_align: true 22 | 23 | upcast_rb "Integer" 24 | upcast_rb "Float" 25 | upcast_rb "Complex" 26 | 27 | upcast "RObject", "RObject" 28 | upcast "DComplex", "DComplex" 29 | upcast "SComplex", "SComplex" 30 | upcast "DFloat", "DComplex" 31 | upcast "SFloat", "SComplex" 32 | upcast "Int64", "SComplex" 33 | upcast "Int32", "SComplex" 34 | upcast "Int16", "SComplex" 35 | upcast "Int8", "SComplex" 36 | upcast "UInt64", "SComplex" 37 | upcast "UInt32", "SComplex" 38 | upcast "UInt16", "SComplex" 39 | upcast "UInt8", "SComplex" 40 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/def/sfloat.rb: -------------------------------------------------------------------------------- 1 | set name: "sfloat" 2 | set type_name: "sfloat" 3 | set full_class_name: "Numo::SFloat" 4 | set class_name: "SFloat" 5 | set class_alias: "Float32" 6 | set class_var: "cT" 7 | set ctype: "float" 8 | set simd_type: "ps" 9 | 10 | set has_math: true 11 | set is_bit: false 12 | set is_int: false 13 | set is_unsigned: false 14 | set is_float: true 15 | set is_complex: false 16 | set is_object: false 17 | set is_real: true 18 | set is_comparable: true 19 | set is_double_precision: false 20 | set need_align: true 21 | 22 | upcast_rb "Integer" 23 | upcast_rb "Float" 24 | upcast_rb "Complex", "SComplex" 25 | 26 | upcast "RObject", "RObject" 27 | upcast "DComplex", "DComplex" 28 | upcast "SComplex", "SComplex" 29 | upcast "DFloat", "DFloat" 30 | upcast "SFloat", "SFloat" 31 | upcast "Int64", "SFloat" 32 | upcast "Int32", "SFloat" 33 | upcast "Int16", "SFloat" 34 | upcast "Int8", "SFloat" 35 | upcast "UInt64", "SFloat" 36 | upcast "UInt32", "SFloat" 37 | upcast "UInt16", "SFloat" 38 | upcast "UInt8", "SFloat" 39 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/def/uint16.rb: -------------------------------------------------------------------------------- 1 | set name: "uint16" 2 | set type_name: "uint16" 3 | set full_class_name: "Numo::UInt16" 4 | set class_name: "UInt16" 5 | set class_var: "cT" 6 | set ctype: "u_int16_t" 7 | 8 | set has_math: false 9 | set is_bit: false 10 | set is_int: true 11 | set is_unsigned: true 12 | set is_float: false 13 | set is_complex: false 14 | set is_object: false 15 | set is_real: true 16 | set is_comparable: true 17 | set is_double_precision: false 18 | set need_align: true 19 | 20 | upcast_rb "Integer" 21 | upcast_rb "Float", "DFloat" 22 | upcast_rb "Complex", "DComplex" 23 | 24 | upcast "RObject", "RObject" 25 | upcast "DComplex", "DComplex" 26 | upcast "SComplex", "SComplex" 27 | upcast "DFloat", "DFloat" 28 | upcast "SFloat", "SFloat" 29 | upcast "Int64", "Int64" 30 | upcast "Int32", "Int32" 31 | upcast "Int16", "Int16" 32 | upcast "Int8", "Int16" 33 | upcast "UInt64", "UInt64" 34 | upcast "UInt32", "UInt32" 35 | upcast "UInt16" 36 | upcast "UInt8" 37 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/def/uint32.rb: -------------------------------------------------------------------------------- 1 | set name: "uint32" 2 | set type_name: "uint32" 3 | set full_class_name: "Numo::UInt32" 4 | set class_name: "UInt32" 5 | set class_var: "cT" 6 | set ctype: "u_int32_t" 7 | 8 | set has_math: false 9 | set is_bit: false 10 | set is_int: true 11 | set is_unsigned: true 12 | set is_float: false 13 | set is_complex: false 14 | set is_object: false 15 | set is_real: true 16 | set is_comparable: true 17 | set is_double_precision: false 18 | set need_align: true 19 | 20 | upcast_rb "Integer" 21 | upcast_rb "Float", "DFloat" 22 | upcast_rb "Complex", "DComplex" 23 | 24 | upcast "RObject", "RObject" 25 | upcast "DComplex", "DComplex" 26 | upcast "SComplex", "SComplex" 27 | upcast "DFloat", "DFloat" 28 | upcast "SFloat", "SFloat" 29 | upcast "Int64", "Int64" 30 | upcast "Int32", "Int32" 31 | upcast "Int16", "Int32" 32 | upcast "Int8", "Int32" 33 | upcast "UInt64", "UInt64" 34 | upcast "UInt32" 35 | upcast "UInt16" 36 | upcast "UInt8" 37 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/def/uint64.rb: -------------------------------------------------------------------------------- 1 | set name: "uint64" 2 | set type_name: "uint64" 3 | set full_class_name: "Numo::UInt64" 4 | set class_name: "UInt64" 5 | set class_var: "cT" 6 | set ctype: "u_int64_t" 7 | 8 | set has_math: false 9 | set is_bit: false 10 | set is_int: true 11 | set is_unsigned: true 12 | set is_float: false 13 | set is_complex: false 14 | set is_object: false 15 | set is_real: true 16 | set is_comparable: true 17 | set is_double_precision: false 18 | set need_align: true 19 | 20 | upcast_rb "Integer" 21 | upcast_rb "Float", "DFloat" 22 | upcast_rb "Complex", "DComplex" 23 | 24 | upcast "RObject", "RObject" 25 | upcast "DComplex", "DComplex" 26 | upcast "SComplex", "SComplex" 27 | upcast "DFloat", "DFloat" 28 | upcast "SFloat", "SFloat" 29 | upcast "Int64", "Int64" 30 | upcast "Int32", "Int64" 31 | upcast "Int16", "Int64" 32 | upcast "Int8", "Int64" 33 | upcast "UInt64" 34 | upcast "UInt32" 35 | upcast "UInt16" 36 | upcast "UInt8" 37 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/def/uint8.rb: -------------------------------------------------------------------------------- 1 | set name: "uint8" 2 | set type_name: "uint8" 3 | set full_class_name: "Numo::UInt8" 4 | set class_name: "UInt8" 5 | set class_var: "cT" 6 | set ctype: "u_int8_t" 7 | 8 | set has_math: false 9 | set is_bit: false 10 | set is_int: true 11 | set is_unsigned: true 12 | set is_float: false 13 | set is_complex: false 14 | set is_object: false 15 | set is_real: true 16 | set is_comparable: true 17 | set is_double_precision: false 18 | set need_align: false 19 | 20 | upcast_rb "Integer" 21 | upcast_rb "Float", "DFloat" 22 | upcast_rb "Complex", "DComplex" 23 | 24 | upcast "RObject", "RObject" 25 | upcast "DComplex", "DComplex" 26 | upcast "SComplex", "SComplex" 27 | upcast "DFloat", "DFloat" 28 | upcast "SFloat", "SFloat" 29 | upcast "Int64", "Int64" 30 | upcast "Int32", "Int32" 31 | upcast "Int16", "Int16" 32 | upcast "Int8", "Int8" 33 | upcast "UInt64", "UInt64" 34 | upcast "UInt32", "UInt32" 35 | upcast "UInt16", "UInt16" 36 | upcast "UInt8" 37 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/erbln.rb: -------------------------------------------------------------------------------- 1 | require 'erb' 2 | 3 | class ErbPP 4 | 5 | class CountLnString < String 6 | 7 | def initialize(filename) 8 | @filename = filename 9 | @lnchar = "\n" 10 | @buf = "" 11 | @str = "" 12 | @countln = 1 13 | @current = 1 14 | super("\n"+report_line) 15 | end 16 | 17 | def report_line 18 | "#line #{@current} \"#{@filename}\"\n" 19 | end 20 | 21 | def concat0(s) 22 | ln(caller[0]) 23 | @buf.concat(s) 24 | @str.concat(s) 25 | end 26 | 27 | def concat1(s) 28 | ln(caller[0]) 29 | @buf.concat(s) 30 | end 31 | 32 | def ln(status=nil) 33 | case status 34 | when /:(\d+):/ 35 | n = $1.to_i 36 | else 37 | n = status.to_i 38 | end 39 | return if n == @current 40 | if @current != @countln || @postpone 41 | if /\A\s*\z/ =~ @str || /\A#line / =~ @buf 42 | @postpone = true 43 | elsif @in_comment 44 | @postpone = false 45 | else 46 | if self[-1] != "\n" 47 | concat("\n") 48 | end 49 | concat(report_line) 50 | @postpone = false 51 | end 52 | end 53 | concat(@buf) 54 | 55 | b = @buf.gsub(/".*?(? 2 | static void 3 | <%=c_iter%><%=j%>(na_loop_t *const lp) 4 | { 5 | size_t n; 6 | char *p1, *p2; 7 | ssize_t s1; 8 | 9 | INIT_COUNTER(lp, n); 10 | INIT_PTR(lp, 0, p1, s1); 11 | p2 = lp->args[1].ptr + lp->args[1].iter[0].pos; 12 | 13 | *(<%=dtype%>*)p2 = f_<%=name%><%=j%>(n,p1,s1); 14 | } 15 | <% end %> 16 | 17 | /* 18 | <%=name%> of self. 19 | <% if is_float %> 20 | @overload <%=name%>(axis:nil, keepdims:false, nan:false) 21 | @param [TrueClass] nan If true, apply NaN-aware algorithm (avoid NaN for sum/mean etc, or, return NaN for min/max etc). 22 | <% else %> 23 | @overload <%=name%>(axis:nil, keepdims:false) 24 | <% end %> 25 | @param [Numeric,Array,Range] axis Performs <%=name%> along the axis. 26 | @param [TrueClass] keepdims If true, the reduced axes are left in the result array as dimensions with size one. 27 | @return [Numo::<%=class_name%>] returns result of <%=name%>. 28 | */ 29 | static VALUE 30 | <%=c_func(-1)%>(int argc, VALUE *argv, VALUE self) 31 | { 32 | VALUE v, reduce; 33 | ndfunc_arg_in_t ain[2] = {{cT,0},{sym_reduce,0}}; 34 | ndfunc_arg_out_t aout[1] = {{<%=result_class%>,0}}; 35 | ndfunc_t ndf = { <%=c_iter%>, STRIDE_LOOP_NIP|NDF_FLAT_REDUCE, 2, 1, ain, aout }; 36 | 37 | <% if is_float %> 38 | reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, <%=c_iter%>_nan); 39 | <% else %> 40 | reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, 0); 41 | <% end %> 42 | v = na_ndloop(&ndf, 2, self, reduce); 43 | <% if result_class == "cT" %> 44 | return <%=type_name%>_extract(v); 45 | <% else %> 46 | return rb_funcall(v,rb_intern("extract"),0); 47 | <% end %> 48 | } 49 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/accum_arg.c: -------------------------------------------------------------------------------- 1 | <% (is_float ? ["","_nan"] : [""]).each do |j| 2 | [64,32].each do |i| %> 3 | #define idx_t int<%=i%>_t 4 | static void 5 | <%=c_iter%>_arg<%=i%><%=j%>(na_loop_t *const lp) 6 | { 7 | size_t n, idx; 8 | char *d_ptr, *o_ptr; 9 | ssize_t d_step; 10 | 11 | INIT_COUNTER(lp, n); 12 | INIT_PTR(lp, 0, d_ptr, d_step); 13 | 14 | idx = f_<%=name[3..5]%>_index<%=j%>(n,d_ptr,d_step); 15 | 16 | o_ptr = NDL_PTR(lp,1); 17 | *(idx_t*)o_ptr = (idx_t)idx; 18 | } 19 | #undef idx_t 20 | <% end;end %> 21 | 22 | /* 23 | Index of the <%=name[3..5]%>imum value. 24 | <% if is_float %> 25 | @overload <%=name%>(axis:nil, nan:false) 26 | @param [TrueClass] nan If true, apply NaN-aware algorithm (return NaN posision if exist). 27 | <% else %> 28 | @overload <%=name%>(axis:nil) 29 | <% end %> 30 | @param [Numeric,Array,Range] axis Finds <%=name[3..5]%>imum values along the axis and returns **indices along the axis**. 31 | @return [Integer,Numo::Int] returns the result indices. 32 | @see #<%=name[3..5]%>_index 33 | @see #<%=name[3..5]%> 34 | 35 | @example 36 | <% case name; when /min/ %> 37 | a = Numo::NArray[3,4,1,2] 38 | a.argmin #=> 2 39 | 40 | b = Numo::NArray[[3,4,1],[2,0,5]] 41 | b.argmin #=> 4 42 | b.argmin(axis:1) #=> [2, 1] 43 | b.argmin(axis:0) #=> [1, 1, 0] 44 | b.at(b.argmin(axis:0), 0..-1) #=> [2, 0, 1] 45 | <% when /max/ %> 46 | a = Numo::NArray[3,4,1,2] 47 | a.argmax #=> 1 48 | 49 | b = Numo::NArray[[3,4,1],[2,0,5]] 50 | b.argmax #=> 5 51 | b.argmax(axis:1) #=> [1, 2] 52 | b.argmax(axis:0) #=> [0, 0, 1] 53 | b.at(b.argmax(axis:0), 0..-1) #=> [3, 4, 5] 54 | <% end %> 55 | */ 56 | static VALUE 57 | <%=c_func(-1)%>(int argc, VALUE *argv, VALUE self) 58 | { 59 | narray_t *na; 60 | VALUE reduce; 61 | ndfunc_arg_in_t ain[2] = {{Qnil,0},{sym_reduce,0}}; 62 | ndfunc_arg_out_t aout[1] = {{0,0,0}}; 63 | ndfunc_t ndf = {0, STRIDE_LOOP_NIP|NDF_FLAT_REDUCE|NDF_EXTRACT, 2,1, ain,aout}; 64 | 65 | GetNArray(self,na); 66 | if (na->ndim==0) { 67 | return INT2FIX(0); 68 | } 69 | if (na->size > (~(u_int32_t)0)) { 70 | aout[0].type = numo_cInt64; 71 | ndf.func = <%=c_iter%>_arg64; 72 | <% if is_float %> 73 | reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, <%=c_iter%>_arg64_nan); 74 | <% else %> 75 | reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, 0); 76 | <% end %> 77 | } else { 78 | aout[0].type = numo_cInt32; 79 | ndf.func = <%=c_iter%>_arg32; 80 | <% if is_float %> 81 | reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, <%=c_iter%>_arg32_nan); 82 | <% else %> 83 | reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, 0); 84 | <% end %> 85 | } 86 | 87 | return na_ndloop(&ndf, 2, self, reduce); 88 | } 89 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/accum_binary.c: -------------------------------------------------------------------------------- 1 | //<% (is_float ? ["","_nan"] : [""]).each do |j| %> 2 | static void 3 | <%=c_iter%><%=j%>(na_loop_t *const lp) 4 | { 5 | size_t i, n; 6 | char *p1, *p2, *p3; 7 | ssize_t s1, s2, s3; 8 | 9 | INIT_COUNTER(lp, n); 10 | INIT_PTR(lp, 0, p1, s1); 11 | INIT_PTR(lp, 1, p2, s2); 12 | INIT_PTR(lp, 2, p3, s3); 13 | 14 | if (s3==0) { 15 | dtype z; 16 | // Reduce loop 17 | GET_DATA(p3,dtype,z); 18 | for (i=0; i<%=j%>(x,y,z); 23 | } 24 | SET_DATA(p3,dtype,z); 25 | return; 26 | } else { 27 | for (i=0; i<%=j%>(x,y,z); 33 | SET_DATA_STRIDE(p3,s3,dtype,z); 34 | } 35 | } 36 | } 37 | //<% end %> 38 | 39 | static VALUE 40 | <%=c_func%>_self(int argc, VALUE *argv, VALUE self) 41 | { 42 | VALUE v, reduce; 43 | VALUE naryv[2]; 44 | ndfunc_arg_in_t ain[4] = {{cT,0},{cT,0},{sym_reduce,0},{sym_init,0}}; 45 | ndfunc_arg_out_t aout[1] = {{cT,0}}; 46 | ndfunc_t ndf = { <%=c_iter%>, STRIDE_LOOP_NIP, 4, 1, ain, aout }; 47 | 48 | if (argc < 1) { 49 | rb_raise(rb_eArgError,"wrong number of arguments (%d for >=1)",argc); 50 | } 51 | // should fix below: [self.ndim,other.ndim].max or? 52 | naryv[0] = self; 53 | naryv[1] = argv[0]; 54 | //<% if is_float %> 55 | reduce = na_reduce_dimension(argc-1, argv+1, 2, naryv, &ndf, <%=c_iter%>_nan); 56 | //<% else %> 57 | reduce = na_reduce_dimension(argc-1, argv+1, 2, naryv, &ndf, 0); 58 | //<% end %> 59 | 60 | v = na_ndloop(&ndf, 4, self, argv[0], reduce, m_<%=name%>_init); 61 | return <%=type_name%>_extract(v); 62 | } 63 | 64 | /* 65 | Binary <%=name%>. 66 | 67 | <% if is_float %> 68 | @overload <%=op_map%>(other, axis:nil, keepdims:false, nan:false) 69 | <% else %> 70 | @overload <%=op_map%>(other, axis:nil, keepdims:false) 71 | <% end %> 72 | @param [Numo::NArray,Numeric] other 73 | @param [Numeric,Array,Range] axis Performs <%=name%> along the axis. 74 | @param [TrueClass] keepdims (keyword) If true, the reduced axes are left in the result array as dimensions with size one. 75 | <% if is_float %> 76 | @param [TrueClass] nan (keyword) If true, apply NaN-aware algorithm (avoid NaN if exists). 77 | <% end %> 78 | @return [Numo::NArray] <%=name%> of self and other. 79 | */ 80 | static VALUE 81 | <%=c_func(-1)%>(int argc, VALUE *argv, VALUE self) 82 | { 83 | //<% if !is_object %> 84 | VALUE klass, v; 85 | //<% end %> 86 | if (argc < 1) { 87 | rb_raise(rb_eArgError,"wrong number of arguments (%d for >=1)",argc); 88 | } 89 | //<% if is_object %> 90 | return <%=c_func%>_self(argc, argv, self); 91 | //<% else %> 92 | klass = na_upcast(rb_obj_class(self),rb_obj_class(argv[0])); 93 | if (klass==cT) { 94 | return <%=c_func%>_self(argc, argv, self); 95 | } else { 96 | v = rb_funcall(klass, id_cast, 1, self); 97 | //<% if Gem::Version.create(RUBY_VERSION) < Gem::Version.create('2.7.0') %> 98 | return rb_funcall2(v, rb_intern("<%=name%>"), argc, argv); 99 | //<% else %> 100 | return rb_funcallv_kw(v, rb_intern("<%=name%>"), argc, argv, RB_PASS_CALLED_KEYWORDS); 101 | //<% end %> 102 | } 103 | //<% end %> 104 | } 105 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/accum_index.c: -------------------------------------------------------------------------------- 1 | <% (is_float ? ["","_nan"] : [""]).each do |j| 2 | [64,32].each do |i| %> 3 | #define idx_t int<%=i%>_t 4 | static void 5 | <%=c_iter%>_index<%=i%><%=j%>(na_loop_t *const lp) 6 | { 7 | size_t n, idx; 8 | char *d_ptr, *i_ptr, *o_ptr; 9 | ssize_t d_step, i_step; 10 | 11 | INIT_COUNTER(lp, n); 12 | INIT_PTR(lp, 0, d_ptr, d_step); 13 | 14 | idx = f_<%=name%><%=j%>(n,d_ptr,d_step); 15 | 16 | INIT_PTR(lp, 1, i_ptr, i_step); 17 | o_ptr = NDL_PTR(lp,2); 18 | *(idx_t*)o_ptr = *(idx_t*)(i_ptr + i_step * idx); 19 | } 20 | #undef idx_t 21 | <% end;end %> 22 | 23 | /* 24 | Index of the <%=name[0..2]%>imum value. 25 | <% if is_float %> 26 | @overload <%=name%>(axis:nil, nan:false) 27 | @param [TrueClass] nan If true, apply NaN-aware algorithm (return NaN posision if exist). 28 | <% else %> 29 | @overload <%=name%>(axis:nil) 30 | <% end %> 31 | @param [Numeric,Array,Range] axis Finds <%=name[0..2]%>imum values along the axis and returns **flat 1-d indices**. 32 | @return [Integer,Numo::Int] returns result indices. 33 | @see #arg<%=name[0..2]%> 34 | @see #<%=name[0..2]%> 35 | 36 | @example 37 | <% case name; when /min/ %> 38 | a = Numo::NArray[3,4,1,2] 39 | a.min_index #=> 2 40 | 41 | b = Numo::NArray[[3,4,1],[2,0,5]] 42 | b.min_index #=> 4 43 | b.min_index(axis:1) #=> [2, 4] 44 | b.min_index(axis:0) #=> [3, 4, 2] 45 | b[b.min_index(axis:0)] #=> [2, 0, 1] 46 | <% when /max/ %> 47 | a = Numo::NArray[3,4,1,2] 48 | a.max_index #=> 1 49 | 50 | b = Numo::NArray[[3,4,1],[2,0,5]] 51 | b.max_index #=> 5 52 | b.max_index(axis:1) #=> [1, 5] 53 | b.max_index(axis:0) #=> [0, 1, 5] 54 | b[b.max_index(axis:0)] #=> [3, 4, 5] 55 | <% end %> 56 | */ 57 | static VALUE 58 | <%=c_func(-1)%>(int argc, VALUE *argv, VALUE self) 59 | { 60 | narray_t *na; 61 | VALUE idx, reduce; 62 | ndfunc_arg_in_t ain[3] = {{Qnil,0},{Qnil,0},{sym_reduce,0}}; 63 | ndfunc_arg_out_t aout[1] = {{0,0,0}}; 64 | ndfunc_t ndf = {0, STRIDE_LOOP_NIP|NDF_FLAT_REDUCE|NDF_EXTRACT, 3,1, ain,aout}; 65 | 66 | GetNArray(self,na); 67 | if (na->ndim==0) { 68 | return INT2FIX(0); 69 | } 70 | if (na->size > (~(u_int32_t)0)) { 71 | aout[0].type = numo_cInt64; 72 | idx = nary_new(numo_cInt64, na->ndim, na->shape); 73 | ndf.func = <%=c_iter%>_index64; 74 | <% if is_float %> 75 | reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, <%=c_iter%>_index64_nan); 76 | <% else %> 77 | reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, 0); 78 | <% end %> 79 | } else { 80 | aout[0].type = numo_cInt32; 81 | idx = nary_new(numo_cInt32, na->ndim, na->shape); 82 | ndf.func = <%=c_iter%>_index32; 83 | <% if is_float %> 84 | reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, <%=c_iter%>_index32_nan); 85 | <% else %> 86 | reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, 0); 87 | <% end %> 88 | } 89 | rb_funcall(idx, rb_intern("seq"), 0); 90 | 91 | return na_ndloop(&ndf, 3, self, idx, reduce); 92 | } 93 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/alloc_func.c: -------------------------------------------------------------------------------- 1 | static size_t 2 | <%=type_name%>_memsize(const void* ptr) 3 | { 4 | size_t size = sizeof(narray_data_t); 5 | const narray_data_t *na = (const narray_data_t*)ptr; 6 | 7 | assert(na->base.type == NARRAY_DATA_T); 8 | 9 | if (na->ptr != NULL) { 10 | <% if is_bit %> 11 | size += ((na->base.size-1)/8/sizeof(BIT_DIGIT)+1)*sizeof(BIT_DIGIT); 12 | <% else %> 13 | size += na->base.size * sizeof(dtype); 14 | <% end %> 15 | } 16 | if (na->base.size > 0) { 17 | if (na->base.shape != NULL && na->base.shape != &(na->base.size)) { 18 | size += sizeof(size_t) * na->base.ndim; 19 | } 20 | } 21 | return size; 22 | } 23 | 24 | static void 25 | <%=type_name%>_free(void* ptr) 26 | { 27 | narray_data_t *na = (narray_data_t*)ptr; 28 | 29 | assert(na->base.type == NARRAY_DATA_T); 30 | 31 | if (na->ptr != NULL) { 32 | if (na->owned) { 33 | xfree(na->ptr); 34 | } 35 | na->ptr = NULL; 36 | } 37 | if (na->base.size > 0) { 38 | if (na->base.shape != NULL && na->base.shape != &(na->base.size)) { 39 | xfree(na->base.shape); 40 | na->base.shape = NULL; 41 | } 42 | } 43 | xfree(na); 44 | } 45 | 46 | static narray_type_info_t <%=type_name%>_info = { 47 | <% if is_bit %> 48 | 1, // element_bits 49 | 0, // element_bytes 50 | 1, // element_stride (in bits) 51 | <% else %> 52 | 0, // element_bits 53 | sizeof(dtype), // element_bytes 54 | sizeof(dtype), // element_stride (in bytes) 55 | <% end %> 56 | }; 57 | 58 | <% if is_object %> 59 | static void 60 | <%=type_name%>_gc_mark(void *ptr) 61 | { 62 | size_t n, i; 63 | VALUE *a; 64 | narray_data_t *na = ptr; 65 | 66 | if (na->ptr) { 67 | a = (VALUE*)(na->ptr); 68 | n = na->base.size; 69 | for (i=0; i_data_type = { 76 | "<%=full_class_name%>", 77 | {<%=type_name%>_gc_mark, <%=type_name%>_free, <%=type_name%>_memsize,}, 78 | &na_data_type, 79 | &<%=type_name%>_info, 80 | 0, // flags 81 | }; 82 | 83 | <% else %> 84 | 85 | static const rb_data_type_t <%=type_name%>_data_type = { 86 | "<%=full_class_name%>", 87 | {0, <%=type_name%>_free, <%=type_name%>_memsize,}, 88 | &na_data_type, 89 | &<%=type_name%>_info, 90 | RUBY_TYPED_FROZEN_SHAREABLE, // flags 91 | }; 92 | 93 | <% end %> 94 | 95 | static VALUE 96 | <%=c_func(0)%>(VALUE klass) 97 | { 98 | narray_data_t *na = ALLOC(narray_data_t); 99 | 100 | na->base.ndim = 0; 101 | na->base.type = NARRAY_DATA_T; 102 | na->base.flag[0] = NA_FL0_INIT; 103 | na->base.flag[1] = NA_FL1_INIT; 104 | na->base.size = 0; 105 | na->base.shape = NULL; 106 | na->base.reduce = INT2FIX(0); 107 | na->ptr = NULL; 108 | na->owned = FALSE; 109 | return TypedData_Wrap_Struct(klass, &<%=type_name%>_data_type, (void*)na); 110 | } 111 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/allocate.c: -------------------------------------------------------------------------------- 1 | static VALUE 2 | <%=c_func(0)%>(VALUE self) 3 | { 4 | narray_t *na; 5 | char *ptr; 6 | 7 | GetNArray(self,na); 8 | 9 | switch(NA_TYPE(na)) { 10 | case NARRAY_DATA_T: 11 | ptr = NA_DATA_PTR(na); 12 | if (na->size > 0 && ptr == NULL) { 13 | ptr = xmalloc(sizeof(dtype) * na->size); 14 | <% if is_object %> 15 | { size_t i; 16 | VALUE *a = (VALUE*)ptr; 17 | for (i=na->size; i--;) { 18 | *a++ = Qnil; 19 | } 20 | } 21 | <% end %> 22 | NA_DATA_PTR(na) = ptr; 23 | NA_DATA_OWNED(na) = TRUE; 24 | } 25 | break; 26 | case NARRAY_VIEW_T: 27 | rb_funcall(NA_VIEW_DATA(na), rb_intern("allocate"), 0); 28 | break; 29 | case NARRAY_FILEMAP_T: 30 | //ptr = ((narray_filemap_t*)na)->ptr; 31 | // to be implemented 32 | default: 33 | rb_bug("invalid narray type : %d",NA_TYPE(na)); 34 | } 35 | return self; 36 | } 37 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/aref.c: -------------------------------------------------------------------------------- 1 | /* 2 | Multi-dimensional element reference. 3 | @overload [](dim0,...,dimL) 4 | @param [Numeric,Range,Array,Numo::Int32,Numo::Int64,Numo::Bit,TrueClass,FalseClass,Symbol] dim0,...,dimL multi-dimensional indices. 5 | @return [Numeric,Numo::<%=class_name%>] an element or NArray view. 6 | @see Numo::NArray#[] 7 | @see #[]= 8 | */ 9 | static VALUE 10 | <%=c_func(-1)%>(int argc, VALUE *argv, VALUE self) 11 | { 12 | int nd; 13 | size_t pos; 14 | char *ptr; 15 | 16 | nd = na_get_result_dimension(self, argc, argv, sizeof(dtype), &pos); 17 | if (nd) { 18 | return na_aref_main(argc, argv, self, 0, nd); 19 | } else { 20 | ptr = na_get_pointer_for_read(self) + pos; 21 | return m_extract(ptr); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/aset.c: -------------------------------------------------------------------------------- 1 | /* 2 | Multi-dimensional element assignment. 3 | @overload []=(dim0,...,dimL,val) 4 | @param [Numeric,Range,Array,Numo::Int32,Numo::Int64,Numo::Bit,TrueClass,FalseClass,Symbol] dim0,...,dimL multi-dimensional indices. 5 | @param [Numeric,Numo::NArray,Array] val Value(s) to be set to self. 6 | @return [Numeric,Numo::NArray,Array] returns `val` (last argument). 7 | @see Numo::NArray#[]= 8 | @see #[] 9 | */ 10 | static VALUE 11 | <%=c_func(-1)%>(int argc, VALUE *argv, VALUE self) 12 | { 13 | int nd; 14 | size_t pos; 15 | char *ptr; 16 | VALUE a; 17 | dtype x; 18 | 19 | argc--; 20 | if (argc==0) { 21 | <%=c_func.sub(/_aset/,"_store")%>(self, argv[argc]); 22 | } else { 23 | nd = na_get_result_dimension(self, argc, argv, sizeof(dtype), &pos); 24 | if (nd) { 25 | a = na_aref_main(argc, argv, self, 0, nd); 26 | <%=c_func.sub(/_aset/,"_store")%>(a, argv[argc]); 27 | } else { 28 | x = <%=type_name%>_extract_data(argv[argc]); 29 | ptr = na_get_pointer_for_read_write(self) + pos; 30 | *(dtype*)ptr = x; 31 | } 32 | 33 | } 34 | return argv[argc]; 35 | } 36 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/binary2.c: -------------------------------------------------------------------------------- 1 | static void 2 | <%=c_iter%>(na_loop_t *const lp) 3 | { 4 | size_t i, n; 5 | char *p1, *p2, *p3, *p4; 6 | ssize_t s1, s2, s3, s4; 7 | dtype x, y, a, b; 8 | INIT_COUNTER(lp, n); 9 | INIT_PTR(lp, 0, p1, s1); 10 | INIT_PTR(lp, 1, p2, s2); 11 | INIT_PTR(lp, 2, p3, s3); 12 | INIT_PTR(lp, 3, p4, s4); 13 | for (i=n; i--;) { 14 | GET_DATA_STRIDE(p1,s1,dtype,x); 15 | GET_DATA_STRIDE(p2,s2,dtype,y); 16 | <% if is_int and %w[divmod].include? name %> 17 | if (y==0) { 18 | lp->err_type = rb_eZeroDivError; 19 | return; 20 | } 21 | <% end %> 22 | m_<%=name%>(x,y,a,b); 23 | SET_DATA_STRIDE(p3,s3,dtype,a); 24 | SET_DATA_STRIDE(p4,s4,dtype,b); 25 | } 26 | } 27 | 28 | static VALUE 29 | <%=c_func%>_self(VALUE self, VALUE other) 30 | { 31 | ndfunc_arg_in_t ain[2] = {{cT,0},{cT,0}}; 32 | ndfunc_arg_out_t aout[2] = {{cT,0},{cT,0}}; 33 | ndfunc_t ndf = { <%=c_iter%>, STRIDE_LOOP, 2, 2, ain, aout }; 34 | 35 | return na_ndloop(&ndf, 2, self, other); 36 | } 37 | 38 | /* 39 | Binary <%=name%>. 40 | @overload <%=op_map%> other 41 | @param [Numo::NArray,Numeric] other 42 | @return [Numo::NArray] <%=name%> of self and other. 43 | */ 44 | static VALUE 45 | <%=c_func(1)%>(VALUE self, VALUE other) 46 | { 47 | <% if is_object %> 48 | return <%=c_func%>_self(self, other); 49 | <% else %> 50 | VALUE klass, v; 51 | klass = na_upcast(rb_obj_class(self),rb_obj_class(other)); 52 | if (klass==cT) { 53 | return <%=c_func%>_self(self, other); 54 | } else { 55 | v = rb_funcall(klass, id_cast, 1, self); 56 | return rb_funcall(v, <%=id_op%>, 1, other); 57 | } 58 | <% end %> 59 | } 60 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/binary_s.c: -------------------------------------------------------------------------------- 1 | static void 2 | <%=c_iter%>(na_loop_t *const lp) 3 | { 4 | size_t i; 5 | char *p1, *p2, *p3; 6 | ssize_t s1, s2, s3; 7 | dtype x, y; 8 | INIT_COUNTER(lp, i); 9 | INIT_PTR(lp, 0, p1, s1); 10 | INIT_PTR(lp, 1, p2, s2); 11 | INIT_PTR(lp, 2, p3, s3); 12 | for (; i--;) { 13 | GET_DATA_STRIDE(p1,s1,dtype,x); 14 | GET_DATA_STRIDE(p2,s2,dtype,y); 15 | x = m_<%=name%>(x,y); 16 | SET_DATA_STRIDE(p3,s3,dtype,x); 17 | } 18 | } 19 | 20 | /* 21 | Calculate <%=name%>(a1,a2). 22 | @overload <%=name%>(a1,a2) 23 | @param [Numo::NArray,Numeric] a1 first value 24 | @param [Numo::NArray,Numeric] a2 second value 25 | @return [Numo::<%=class_name%>] <%=name%>(a1,a2). 26 | */ 27 | static VALUE 28 | <%=c_func(2)%>(VALUE mod, VALUE a1, VALUE a2) 29 | { 30 | ndfunc_arg_in_t ain[2] = {{cT,0},{cT,0}}; 31 | ndfunc_arg_out_t aout[1] = {{cT,0}}; 32 | ndfunc_t ndf = { <%=c_iter%>, STRIDE_LOOP, 2, 1, ain, aout }; 33 | return na_ndloop(&ndf, 2, a1, a2); 34 | } 35 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/cast.c: -------------------------------------------------------------------------------- 1 | <% children.each do |c|%> 2 | <%= c.result %> 3 | 4 | <% end %> 5 | /* 6 | Cast object to Numo::<%=class_name%>. 7 | @overload [](elements) 8 | @overload <%=name%>(array) 9 | @param [Numeric,Array] elements 10 | @param [Array] array 11 | @return [Numo::<%=class_name%>] 12 | */ 13 | static VALUE 14 | <%=c_func(1)%>(VALUE type, VALUE obj) 15 | { 16 | VALUE v; 17 | narray_t *na; 18 | dtype x; 19 | 20 | if (rb_obj_class(obj)==cT) { 21 | return obj; 22 | } 23 | if (RTEST(rb_obj_is_kind_of(obj,rb_cNumeric))) { 24 | x = m_num_to_data(obj); 25 | return <%=type_name%>_new_dim0(x); 26 | } 27 | if (RTEST(rb_obj_is_kind_of(obj,rb_cArray))) { 28 | return <%=find_tmpl("cast_array").c_func%>(obj); 29 | } 30 | if (IsNArray(obj)) { 31 | GetNArray(obj,na); 32 | v = nary_new(cT, NA_NDIM(na), NA_SHAPE(na)); 33 | if (NA_SIZE(na) > 0) { 34 | <%=find_tmpl("store").c_func%>(v,obj); 35 | } 36 | return v; 37 | } 38 | if (rb_respond_to(obj,id_to_a)) { 39 | obj = rb_funcall(obj,id_to_a,0); 40 | if (TYPE(obj)!=T_ARRAY) { 41 | rb_raise(rb_eTypeError, "`to_a' did not return Array"); 42 | } 43 | return <%=find_tmpl("cast_array").c_func%>(obj); 44 | } 45 | <% if is_object %> 46 | return robject_new_dim0(obj); 47 | <% else %> 48 | rb_raise(nary_eCastError,"cannot cast to %s",rb_class2name(type)); 49 | return Qnil; 50 | <% end %> 51 | } 52 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/cast_array.c: -------------------------------------------------------------------------------- 1 | static VALUE 2 | <%=c_func(:nodef)%>(VALUE rary) 3 | { 4 | VALUE nary; 5 | narray_t *na; 6 | 7 | nary = na_s_new_like(cT, rary); 8 | GetNArray(nary,na); 9 | if (na->size > 0) { 10 | <%=find_tmpl("store").find("array").c_func%>(nary,rary); 11 | } 12 | return nary; 13 | } 14 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/class.c: -------------------------------------------------------------------------------- 1 | /* 2 | class definition: <%= full_class_name %> 3 | */ 4 | 5 | VALUE <%=class_var%>; 6 | 7 | static VALUE <%= find('store').c_func %>(VALUE,VALUE); 8 | 9 | <%= method_code %> 10 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/clip.c: -------------------------------------------------------------------------------- 1 | static void 2 | <%=c_iter%>(na_loop_t *const lp) 3 | { 4 | size_t i; 5 | char *p1, *p2, *p3, *p4; 6 | ssize_t s1, s2, s3, s4; 7 | dtype x, min, max; 8 | INIT_COUNTER(lp, i); 9 | INIT_PTR(lp, 0, p1, s1); 10 | INIT_PTR(lp, 1, p2, s2); 11 | INIT_PTR(lp, 2, p3, s3); 12 | INIT_PTR(lp, 3, p4, s4); 13 | for (; i--;) { 14 | GET_DATA_STRIDE(p1,s1,dtype,x); 15 | GET_DATA_STRIDE(p2,s2,dtype,min); 16 | GET_DATA_STRIDE(p3,s3,dtype,max); 17 | if (m_gt(min,max)) {rb_raise(nary_eOperationError,"min is greater than max");} 18 | if (m_lt(x,min)) {x=min;} 19 | if (m_gt(x,max)) {x=max;} 20 | SET_DATA_STRIDE(p4,s4,dtype,x); 21 | } 22 | } 23 | 24 | static void 25 | <%=c_iter%>_min(na_loop_t *const lp) 26 | { 27 | size_t i; 28 | char *p1, *p2, *p3; 29 | ssize_t s1, s2, s3; 30 | dtype x, min; 31 | INIT_COUNTER(lp, i); 32 | INIT_PTR(lp, 0, p1, s1); 33 | INIT_PTR(lp, 1, p2, s2); 34 | INIT_PTR(lp, 2, p3, s3); 35 | for (; i--;) { 36 | GET_DATA_STRIDE(p1,s1,dtype,x); 37 | GET_DATA_STRIDE(p2,s2,dtype,min); 38 | if (m_lt(x,min)) {x=min;} 39 | SET_DATA_STRIDE(p3,s3,dtype,x); 40 | } 41 | } 42 | 43 | static void 44 | <%=c_iter%>_max(na_loop_t *const lp) 45 | { 46 | size_t i; 47 | char *p1, *p2, *p3; 48 | ssize_t s1, s2, s3; 49 | dtype x, max; 50 | INIT_COUNTER(lp, i); 51 | INIT_PTR(lp, 0, p1, s1); 52 | INIT_PTR(lp, 1, p2, s2); 53 | INIT_PTR(lp, 2, p3, s3); 54 | for (; i--;) { 55 | GET_DATA_STRIDE(p1,s1,dtype,x); 56 | GET_DATA_STRIDE(p2,s2,dtype,max); 57 | if (m_gt(x,max)) {x=max;} 58 | SET_DATA_STRIDE(p3,s3,dtype,x); 59 | } 60 | } 61 | 62 | /* 63 | Clip array elements by [min,max]. 64 | If either of min or max is nil, one side is clipped. 65 | @overload <%=name%>(min,max) 66 | @param [Numo::NArray,Numeric] min 67 | @param [Numo::NArray,Numeric] max 68 | @return [Numo::NArray] result of clip. 69 | 70 | @example 71 | a = Numo::Int32.new(10).seq 72 | # => Numo::Int32#shape=[10] 73 | # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 74 | 75 | a.clip(1,8) 76 | # => Numo::Int32#shape=[10] 77 | # [1, 1, 2, 3, 4, 5, 6, 7, 8, 8] 78 | 79 | a.inplace.clip(3,6) 80 | a 81 | # => Numo::Int32#shape=[10] 82 | # [3, 3, 3, 3, 4, 5, 6, 6, 6, 6] 83 | 84 | b = Numo::Int32.new(10).seq 85 | # => Numo::Int32#shape=[10] 86 | # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 87 | 88 | b.clip([3,4,1,1,1,4,4,4,4,4], 8) 89 | # => Numo::Int32#shape=[10] 90 | # [3, 4, 2, 3, 4, 5, 6, 7, 8, 8] 91 | */ 92 | static VALUE 93 | <%=c_func(2)%>(VALUE self, VALUE min, VALUE max) 94 | { 95 | ndfunc_arg_in_t ain[3] = {{Qnil,0},{cT,0},{cT,0}}; 96 | ndfunc_arg_out_t aout[1] = {{cT,0}}; 97 | ndfunc_t ndf_min = { <%=c_iter%>_min, STRIDE_LOOP, 2, 1, ain, aout }; 98 | ndfunc_t ndf_max = { <%=c_iter%>_max, STRIDE_LOOP, 2, 1, ain, aout }; 99 | ndfunc_t ndf_both = { <%=c_iter%>, STRIDE_LOOP, 3, 1, ain, aout }; 100 | 101 | if (RTEST(min)) { 102 | if (RTEST(max)) { 103 | return na_ndloop(&ndf_both, 3, self, min, max); 104 | } else { 105 | return na_ndloop(&ndf_min, 2, self, min); 106 | } 107 | } else { 108 | if (RTEST(max)) { 109 | return na_ndloop(&ndf_max, 2, self, max); 110 | } 111 | } 112 | rb_raise(rb_eArgError,"min and max are not given"); 113 | return Qnil; 114 | } 115 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/coerce_cast.c: -------------------------------------------------------------------------------- 1 | /* 2 | return NArray with cast to the type of self. 3 | @overload coerce_cast(type) 4 | @return [nil] 5 | */ 6 | static VALUE 7 | <%=c_func(1)%>(VALUE self, VALUE type) 8 | { 9 | return Qnil; 10 | } 11 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/cond_binary.c: -------------------------------------------------------------------------------- 1 | static void 2 | <%=c_iter%>(na_loop_t *const lp) 3 | { 4 | size_t i; 5 | char *p1, *p2; 6 | BIT_DIGIT *a3; 7 | size_t p3; 8 | ssize_t s1, s2, s3; 9 | dtype x, y; 10 | BIT_DIGIT b; 11 | INIT_COUNTER(lp, i); 12 | INIT_PTR(lp, 0, p1, s1); 13 | INIT_PTR(lp, 1, p2, s2); 14 | INIT_PTR_BIT(lp, 2, a3, p3, s3); 15 | for (; i--;) { 16 | GET_DATA_STRIDE(p1,s1,dtype,x); 17 | GET_DATA_STRIDE(p2,s2,dtype,y); 18 | b = (m_<%=name%>(x,y)) ? 1:0; 19 | STORE_BIT(a3,p3,b); 20 | p3+=s3; 21 | } 22 | } 23 | 24 | static VALUE 25 | <%=c_func%>_self(VALUE self, VALUE other) 26 | { 27 | ndfunc_arg_in_t ain[2] = {{cT,0},{cT,0}}; 28 | ndfunc_arg_out_t aout[1] = {{numo_cBit,0}}; 29 | ndfunc_t ndf = { <%=c_iter%>, STRIDE_LOOP, 2, 1, ain, aout }; 30 | 31 | return na_ndloop(&ndf, 2, self, other); 32 | } 33 | 34 | /* 35 | Comparison <%=name%> other. 36 | @overload <%=op_map%> other 37 | @param [Numo::NArray,Numeric] other 38 | @return [Numo::Bit] result of self <%=name%> other. 39 | */ 40 | static VALUE 41 | <%=c_func(1)%>(VALUE self, VALUE other) 42 | { 43 | <% if is_object %> 44 | return <%=c_func%>_self(self, other); 45 | <% else %> 46 | VALUE klass, v; 47 | klass = na_upcast(rb_obj_class(self),rb_obj_class(other)); 48 | if (klass==cT) { 49 | return <%=c_func%>_self(self, other); 50 | } else { 51 | v = rb_funcall(klass, id_cast, 1, self); 52 | return rb_funcall(v, <%=id_op%>, 1, other); 53 | } 54 | <% end %> 55 | } 56 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/cond_unary.c: -------------------------------------------------------------------------------- 1 | static void 2 | <%=c_iter%>(na_loop_t *const lp) 3 | { 4 | size_t i; 5 | char *p1; 6 | BIT_DIGIT *a2; 7 | size_t p2; 8 | ssize_t s1, s2; 9 | size_t *idx1; 10 | dtype x; 11 | BIT_DIGIT b; 12 | INIT_COUNTER(lp, i); 13 | INIT_PTR_IDX(lp, 0, p1, s1, idx1); 14 | INIT_PTR_BIT(lp, 1, a2, p2, s2); 15 | if (idx1) { 16 | for (; i--;) { 17 | GET_DATA_INDEX(p1,idx1,dtype,x); 18 | b = (m_<%=name%>(x)) ? 1:0; 19 | STORE_BIT(a2,p2,b); 20 | p2+=s2; 21 | } 22 | } else { 23 | for (; i--;) { 24 | GET_DATA_STRIDE(p1,s1,dtype,x); 25 | b = (m_<%=name%>(x)) ? 1:0; 26 | STORE_BIT(a2,p2,b); 27 | p2+=s2; 28 | } 29 | } 30 | } 31 | 32 | /* 33 | Condition of <%=name%>. 34 | @overload <%=name%> 35 | @return [Numo::Bit] Condition of <%=name%>. 36 | */ 37 | static VALUE 38 | <%=c_func(0)%>(VALUE self) 39 | { 40 | ndfunc_arg_in_t ain[1] = {{cT,0}}; 41 | ndfunc_arg_out_t aout[1] = {{numo_cBit,0}}; 42 | ndfunc_t ndf = { <%=c_iter%>, FULL_LOOP, 1, 1, ain, aout }; 43 | 44 | return na_ndloop(&ndf, 1, self); 45 | } 46 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/cum.c: -------------------------------------------------------------------------------- 1 | <% (is_float ? ["","_nan"] : [""]).each do |j| %> 2 | static void 3 | <%=c_iter%><%=j%>(na_loop_t *const lp) 4 | { 5 | size_t i; 6 | char *p1, *p2; 7 | ssize_t s1, s2; 8 | dtype x, y; 9 | 10 | INIT_COUNTER(lp, i); 11 | INIT_PTR(lp, 0, p1, s1); 12 | INIT_PTR(lp, 1, p2, s2); 13 | //printf("i=%lu p1=%lx s1=%lu p2=%lx s2=%lu\n",i,(size_t)p1,s1,(size_t)p2,s2); 14 | 15 | GET_DATA_STRIDE(p1,s1,dtype,x); 16 | SET_DATA_STRIDE(p2,s2,dtype,x); 17 | //printf("i=%lu x=%f\n",i,x); 18 | for (i--; i--;) { 19 | GET_DATA_STRIDE(p1,s1,dtype,y); 20 | m_<%=name%><%=j%>(x,y); 21 | SET_DATA_STRIDE(p2,s2,dtype,x); 22 | //printf("i=%lu x=%f\n",i,x); 23 | } 24 | } 25 | <% end %> 26 | 27 | /* 28 | <%=name%> of self. 29 | @overload <%=name%>(axis:nil, nan:false) 30 | @param [Numeric,Array,Range] axis Performs <%=name%> along the axis. 31 | @param [TrueClass] nan If true, apply NaN-aware algorithm (avoid NaN if exists). 32 | @return [Numo::<%=class_name%>] <%=name%> of self. 33 | */ 34 | static VALUE 35 | <%=c_func(-1)%>(int argc, VALUE *argv, VALUE self) 36 | { 37 | VALUE reduce; 38 | ndfunc_arg_in_t ain[2] = {{cT,0},{sym_reduce,0}}; 39 | ndfunc_arg_out_t aout[1] = {{cT,0}}; 40 | ndfunc_t ndf = { <%=c_iter%>, STRIDE_LOOP|NDF_FLAT_REDUCE|NDF_CUM, 41 | 2, 1, ain, aout }; 42 | 43 | <% if is_float %> 44 | reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, <%=c_iter%>_nan); 45 | <% else %> 46 | reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, 0); 47 | <% end %> 48 | return na_ndloop(&ndf, 2, self, reduce); 49 | } 50 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/each.c: -------------------------------------------------------------------------------- 1 | static void 2 | <%=c_iter%>(na_loop_t *const lp) 3 | { 4 | size_t i, s1; 5 | char *p1; 6 | size_t *idx1; 7 | dtype x; 8 | VALUE y; 9 | 10 | INIT_COUNTER(lp, i); 11 | INIT_PTR_IDX(lp, 0, p1, s1, idx1); 12 | if (idx1) { 13 | for (; i--;) { 14 | GET_DATA_INDEX(p1,idx1,dtype,x); 15 | y = m_data_to_num(x); 16 | rb_yield(y); 17 | } 18 | } else { 19 | for (; i--;) { 20 | GET_DATA_STRIDE(p1,s1,dtype,x); 21 | y = m_data_to_num(x); 22 | rb_yield(y); 23 | } 24 | } 25 | } 26 | 27 | /* 28 | Calls the given block once for each element in self, 29 | passing that element as a parameter. 30 | @overload <%=name%> 31 | @return [Numo::NArray] self 32 | For a block `{|x| ... }`, 33 | @yieldparam [Numeric] x an element of NArray. 34 | @see #each_with_index 35 | @see #map 36 | */ 37 | static VALUE 38 | <%=c_func(0)%>(VALUE self) 39 | { 40 | ndfunc_arg_in_t ain[1] = {{Qnil,0}}; 41 | ndfunc_t ndf = {<%=c_iter%>, FULL_LOOP_NIP, 1,0, ain,0}; 42 | 43 | na_ndloop(&ndf, 1, self); 44 | return self; 45 | } 46 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/each_with_index.c: -------------------------------------------------------------------------------- 1 | static inline void 2 | yield_each_with_index(dtype x, size_t *c, VALUE *a, int nd, int md) 3 | { 4 | int j; 5 | 6 | a[0] = m_data_to_num(x); 7 | for (j=0; j<=nd; j++) { 8 | a[j+1] = SIZET2NUM(c[j]); 9 | } 10 | rb_yield(rb_ary_new4(md,a)); 11 | } 12 | 13 | 14 | static void 15 | <%=c_iter%>(na_loop_t *const lp) 16 | { 17 | size_t i, s1; 18 | char *p1; 19 | size_t *idx1; 20 | dtype x; 21 | VALUE *a; 22 | size_t *c; 23 | int nd, md; 24 | 25 | c = (size_t*)(lp->opt_ptr); 26 | nd = lp->ndim; 27 | if (nd > 0) {nd--;} 28 | md = nd + 2; 29 | a = ALLOCA_N(VALUE,md); 30 | 31 | INIT_COUNTER(lp, i); 32 | INIT_PTR_IDX(lp, 0, p1, s1, idx1); 33 | c[nd] = 0; 34 | if (idx1) { 35 | for (; i--;) { 36 | GET_DATA_INDEX(p1,idx1,dtype,x); 37 | yield_each_with_index(x,c,a,nd,md); 38 | c[nd]++; 39 | } 40 | } else { 41 | for (; i--;) { 42 | GET_DATA_STRIDE(p1,s1,dtype,x); 43 | yield_each_with_index(x,c,a,nd,md); 44 | c[nd]++; 45 | } 46 | } 47 | } 48 | 49 | /* 50 | Invokes the given block once for each element of self, 51 | passing that element and indices along each axis as parameters. 52 | @overload <%=name%> 53 | For a block `{|x,i,j,...| ... }`, 54 | @yieldparam [Numeric] x an element 55 | @yieldparam [Integer] i,j,... multitimensional indices 56 | @return [Numo::NArray] self 57 | @see #each 58 | @see #map_with_index 59 | */ 60 | static VALUE 61 | <%=c_func(0)%>(VALUE self) 62 | { 63 | ndfunc_arg_in_t ain[1] = {{Qnil,0}}; 64 | ndfunc_t ndf = {<%=c_iter%>, FULL_LOOP_NIP, 1,0, ain,0}; 65 | 66 | na_ndloop_with_index(&ndf, 1, self); 67 | return self; 68 | } 69 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/ewcomp.c: -------------------------------------------------------------------------------- 1 | /* 2 | Element-wise <%=name%> of two arrays. 3 | 4 | <% if is_float %> 5 | @overload <%=name%>(a1, a2, nan:false) 6 | @param [Numo::NArray,Numeric] a1 The array to be compared. 7 | @param [Numo::NArray,Numeric] a2 The array to be compared. 8 | @param [TrueClass] nan If true, apply NaN-aware algorithm (return NaN if exist). 9 | <% else %> 10 | @overload <%=name%>(a1, a2) 11 | @param [Numo::NArray,Numeric] a1,a2 The arrays holding the elements to be compared. 12 | <% end %> 13 | @return [Numo::<%=class_name%>] 14 | */ 15 | 16 | <% (is_float ? ["","_nan"] : [""]).each do |j| %> 17 | static void 18 | <%=c_iter%><%=j%>(na_loop_t *const lp) 19 | { 20 | size_t i, n; 21 | char *p1, *p2, *p3; 22 | ssize_t s1, s2, s3; 23 | 24 | INIT_COUNTER(lp, n); 25 | INIT_PTR(lp, 0, p1, s1); 26 | INIT_PTR(lp, 1, p2, s2); 27 | INIT_PTR(lp, 2, p3, s3); 28 | 29 | for (i=0; i<%=j%>(x,y); 35 | SET_DATA_STRIDE(p3,s3,dtype,z); 36 | } 37 | } 38 | <% end %> 39 | 40 | static VALUE 41 | <%=c_func(-1)%>(int argc, VALUE *argv, VALUE mod) 42 | { 43 | VALUE a1 = Qnil; 44 | VALUE a2 = Qnil; 45 | ndfunc_arg_in_t ain[2] = {{cT,0},{cT,0}}; 46 | ndfunc_arg_out_t aout[1] = {{cT,0}}; 47 | ndfunc_t ndf = { <%=c_iter%>, STRIDE_LOOP_NIP, 2, 1, ain, aout }; 48 | 49 | <% if is_float %> 50 | VALUE kw_hash = Qnil; 51 | ID kw_table[1] = {id_nan}; 52 | VALUE opts[1] = {Qundef}; 53 | 54 | rb_scan_args(argc, argv, "20:", &a1, &a2, &kw_hash); 55 | rb_get_kwargs(kw_hash, kw_table, 0, 1, opts); 56 | if (opts[0] != Qundef) { 57 | ndf.func = <%=c_iter%>_nan; 58 | } 59 | <% else %> 60 | rb_scan_args(argc, argv, "20", &a1, &a2); 61 | <% end %> 62 | 63 | return na_ndloop(&ndf, 2, a1, a2); 64 | } 65 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/extract.c: -------------------------------------------------------------------------------- 1 | /* 2 | Extract an element only if self is a dimensionless NArray. 3 | @overload extract 4 | @return [Numeric,Numo::NArray] 5 | --- Extract element value as Ruby Object if self is a dimensionless NArray, 6 | otherwise returns self. 7 | */ 8 | static VALUE 9 | <%=c_func(0)%>(VALUE self) 10 | { 11 | volatile VALUE v; 12 | char *ptr; 13 | narray_t *na; 14 | GetNArray(self,na); 15 | 16 | if (na->ndim==0) { 17 | ptr = na_get_pointer_for_read(self) + na_get_offset(self); 18 | v = m_extract(ptr); 19 | na_release_lock(self); 20 | return v; 21 | } 22 | return self; 23 | } 24 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/extract_data.c: -------------------------------------------------------------------------------- 1 | /* 2 | Convert a data value of obj (with a single element) to dtype. 3 | */ 4 | static dtype 5 | <%=c_func(:nodef)%>(VALUE obj) 6 | { 7 | narray_t *na; 8 | dtype x; 9 | char *ptr; 10 | size_t pos; 11 | VALUE r, klass; 12 | 13 | if (IsNArray(obj)) { 14 | GetNArray(obj,na); 15 | if (na->size != 1) { 16 | rb_raise(nary_eShapeError,"narray size should be 1"); 17 | } 18 | klass = rb_obj_class(obj); 19 | ptr = na_get_pointer_for_read(obj); 20 | pos = na_get_offset(obj); 21 | <% find_tmpl("store").definitions.select{|x| x.class==Store}.each do |x| %> 22 | if (<%=x.condition("klass")%>) { 23 | <%=x.extract_data("ptr","pos","x")%>; 24 | return x; 25 | } 26 | <% end %> 27 | 28 | // coerce 29 | r = rb_funcall(obj, rb_intern("coerce_cast"), 1, cT); 30 | if (rb_obj_class(r)==cT) { 31 | return <%=c_func%>(r); 32 | } 33 | <% if is_object %> 34 | return obj; 35 | <% else %> 36 | rb_raise(nary_eCastError, "unknown conversion from %s to %s", 37 | rb_class2name(rb_obj_class(obj)), 38 | rb_class2name(cT)); 39 | <% end %> 40 | } 41 | if (TYPE(obj)==T_ARRAY) { 42 | if (RARRAY_LEN(obj) != 1) { 43 | rb_raise(nary_eShapeError,"array size should be 1"); 44 | } 45 | return m_num_to_data(RARRAY_AREF(obj,0)); 46 | } 47 | return m_num_to_data(obj); 48 | } 49 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/eye.c: -------------------------------------------------------------------------------- 1 | static void 2 | <%=c_iter%>(na_loop_t *const lp) 3 | { 4 | size_t n0, n1; 5 | size_t i0, i1; 6 | ssize_t s0, s1; 7 | char *p0, *p1; 8 | char *g; 9 | ssize_t kofs; 10 | dtype data; 11 | 12 | g = (char*)(lp->opt_ptr); 13 | kofs = *(ssize_t*)g; 14 | data = *(dtype*)(g+sizeof(ssize_t)); 15 | 16 | n0 = lp->args[0].shape[0]; 17 | n1 = lp->args[0].shape[1]; 18 | s0 = lp->args[0].iter[0].step; 19 | s1 = lp->args[0].iter[1].step; 20 | p0 = NDL_PTR(lp,0); 21 | 22 | for (i0=0; i0 < n0; i0++) { 23 | p1 = p0; 24 | for (i1=0; i1 < n1; i1++) { 25 | *(dtype*)p1 = (i0+kofs==i1) ? data : m_zero; 26 | p1 += s1; 27 | } 28 | p0 += s0; 29 | } 30 | } 31 | 32 | /* 33 | Eye: Set a value to diagonal components, set 0 to non-diagonal components. 34 | @overload <%=name%>([element,offset]) 35 | @param [Numeric] element Diagonal element to be stored. Default is 1. 36 | @param [Integer] offset Diagonal offset from the main diagonal. The 37 | default is 0. k>0 for diagonals above the main diagonal, and k<0 38 | for diagonals below the main diagonal. 39 | @return [Numo::<%=class_name%>] <%=name%> of self. 40 | */ 41 | static VALUE 42 | <%=c_func(-1)%>(int argc, VALUE *argv, VALUE self) 43 | { 44 | ndfunc_arg_in_t ain[1] = {{OVERWRITE,2}}; 45 | ndfunc_t ndf = {<%=c_iter%>, NO_LOOP, 1,0, ain,0}; 46 | ssize_t kofs; 47 | dtype data; 48 | char *g; 49 | int nd; 50 | narray_t *na; 51 | 52 | // check arguments 53 | if (argc > 2) { 54 | rb_raise(rb_eArgError,"too many arguments (%d for 0..2)",argc); 55 | } else if (argc == 2) { 56 | data = m_num_to_data(argv[0]); 57 | kofs = NUM2SSIZET(argv[1]); 58 | } else if (argc == 1) { 59 | data = m_num_to_data(argv[0]); 60 | kofs = 0; 61 | } else { 62 | data = m_one; 63 | kofs = 0; 64 | } 65 | 66 | GetNArray(self,na); 67 | nd = na->ndim; 68 | if (nd < 2) { 69 | rb_raise(nary_eDimensionError,"less than 2-d array"); 70 | } 71 | 72 | // Diagonal offset from the main diagonal. 73 | if (kofs >= 0) { 74 | if ((size_t)(kofs) >= na->shape[nd-1]) { 75 | rb_raise(rb_eArgError,"invalid diagonal offset(%"SZF"d) for " 76 | "last dimension size(%"SZF"d)",kofs,na->shape[nd-1]); 77 | } 78 | } else { 79 | if ((size_t)(-kofs) >= na->shape[nd-2]) { 80 | rb_raise(rb_eArgError,"invalid diagonal offset(%"SZF"d) for " 81 | "last-1 dimension size(%"SZF"d)",kofs,na->shape[nd-2]); 82 | } 83 | } 84 | 85 | g = ALLOCA_N(char,sizeof(ssize_t)+sizeof(dtype)); 86 | *(ssize_t*)g = kofs; 87 | *(dtype*)(g+sizeof(ssize_t)) = data; 88 | 89 | na_ndloop3(&ndf, g, 1, self); 90 | return self; 91 | } 92 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/fill.c: -------------------------------------------------------------------------------- 1 | static void 2 | <%=c_iter%>(na_loop_t *const lp) 3 | { 4 | size_t i; 5 | char *p1; 6 | ssize_t s1; 7 | size_t *idx1; 8 | VALUE x = lp->option; 9 | dtype y; 10 | INIT_COUNTER(lp, i); 11 | INIT_PTR_IDX(lp, 0, p1, s1, idx1); 12 | y = m_num_to_data(x); 13 | if (idx1) { 14 | for (; i--;) { 15 | SET_DATA_INDEX(p1,idx1,dtype,y); 16 | } 17 | } else { 18 | for (; i--;) { 19 | SET_DATA_STRIDE(p1,s1,dtype,y); 20 | } 21 | } 22 | } 23 | 24 | /* 25 | Fill elements with other. 26 | @overload <%=name%> other 27 | @param [Numeric] other 28 | @return [Numo::<%=class_name%>] self. 29 | */ 30 | static VALUE 31 | <%=c_func(1)%>(VALUE self, VALUE val) 32 | { 33 | ndfunc_arg_in_t ain[2] = {{OVERWRITE,0},{sym_option}}; 34 | ndfunc_t ndf = { <%=c_iter%>, FULL_LOOP, 2, 0, ain, 0 }; 35 | 36 | na_ndloop(&ndf, 2, self, val); 37 | return self; 38 | } 39 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/format.c: -------------------------------------------------------------------------------- 1 | static VALUE 2 | format_<%=type_name%>(VALUE fmt, dtype* x) 3 | { 4 | // fix-me 5 | char s[48]; 6 | int n; 7 | 8 | if (NIL_P(fmt)) { 9 | n = m_sprintf(s,*x); 10 | return rb_str_new(s,n); 11 | } 12 | return rb_funcall(fmt, '%', 1, m_data_to_num(*x)); 13 | } 14 | 15 | static void 16 | <%=c_iter%>(na_loop_t *const lp) 17 | { 18 | size_t i; 19 | char *p1, *p2; 20 | ssize_t s1, s2; 21 | size_t *idx1; 22 | dtype *x; 23 | VALUE y; 24 | VALUE fmt = lp->option; 25 | INIT_COUNTER(lp, i); 26 | INIT_PTR_IDX(lp, 0, p1, s1, idx1); 27 | INIT_PTR(lp, 1, p2, s2); 28 | if (idx1) { 29 | for (; i--;) { 30 | x = (dtype*)(p1+*idx1); idx1++; 31 | y = format_<%=type_name%>(fmt, x); 32 | SET_DATA_STRIDE(p2, s2, VALUE, y); 33 | } 34 | } else { 35 | for (; i--;) { 36 | x = (dtype*)p1; p1+=s1; 37 | y = format_<%=type_name%>(fmt, x); 38 | SET_DATA_STRIDE(p2, s2, VALUE, y); 39 | } 40 | } 41 | } 42 | 43 | /* 44 | Format elements into strings. 45 | @overload <%=name%> format 46 | @param [String] format 47 | @return [Numo::RObject] array of formatted strings. 48 | */ 49 | static VALUE 50 | <%=c_func(-1)%>(int argc, VALUE *argv, VALUE self) 51 | { 52 | VALUE fmt=Qnil; 53 | 54 | ndfunc_arg_in_t ain[2] = {{Qnil,0},{sym_option}}; 55 | ndfunc_arg_out_t aout[1] = {{numo_cRObject,0}}; 56 | ndfunc_t ndf = { <%=c_iter%>, FULL_LOOP_NIP, 2, 1, ain, aout }; 57 | 58 | rb_scan_args(argc, argv, "01", &fmt); 59 | return na_ndloop(&ndf, 2, self, fmt); 60 | } 61 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/format_to_a.c: -------------------------------------------------------------------------------- 1 | static void 2 | <%=c_iter%>(na_loop_t *const lp) 3 | { 4 | size_t i; 5 | char *p1; 6 | ssize_t s1; 7 | size_t *idx1; 8 | dtype *x; 9 | VALUE y; 10 | volatile VALUE a; 11 | VALUE fmt = lp->option; 12 | INIT_COUNTER(lp, i); 13 | INIT_PTR_IDX(lp, 0, p1, s1, idx1); 14 | a = rb_ary_new2(i); 15 | rb_ary_push(lp->args[1].value, a); 16 | if (idx1) { 17 | for (; i--;) { 18 | x = (dtype*)(p1 + *idx1); idx1++; 19 | y = format_<%=type_name%>(fmt, x); 20 | rb_ary_push(a,y); 21 | } 22 | } else { 23 | for (; i--;) { 24 | x = (dtype*)p1; p1+=s1; 25 | y = format_<%=type_name%>(fmt, x); 26 | rb_ary_push(a,y); 27 | } 28 | } 29 | } 30 | 31 | /* 32 | Format elements into strings. 33 | @overload <%=name%> format 34 | @param [String] format 35 | @return [Array] array of formatted strings. 36 | */ 37 | static VALUE 38 | <%=c_func(-1)%>(int argc, VALUE *argv, VALUE self) 39 | { 40 | VALUE fmt=Qnil; 41 | ndfunc_arg_in_t ain[3] = {{Qnil,0},{sym_loop_opt},{sym_option}}; 42 | ndfunc_arg_out_t aout[1] = {{rb_cArray,0}}; // dummy? 43 | ndfunc_t ndf = { <%=c_iter%>, FULL_LOOP_NIP, 3, 1, ain, aout }; 44 | 45 | rb_scan_args(argc, argv, "01", &fmt); 46 | return na_ndloop_cast_narray_to_rarray(&ndf, self, fmt); 47 | } 48 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/frexp.c: -------------------------------------------------------------------------------- 1 | static void 2 | <%=c_iter%>(na_loop_t *const lp) 3 | { 4 | size_t i; 5 | char *p1, *p2, *p3; 6 | ssize_t s1, s2, s3; 7 | dtype x; 8 | int y; 9 | INIT_COUNTER(lp, i); 10 | INIT_PTR(lp, 0, p1, s1); 11 | INIT_PTR(lp, 1, p2, s2); 12 | INIT_PTR(lp, 2, p3, s3); 13 | for (; i--;) { 14 | GET_DATA_STRIDE(p1,s1,dtype,x); 15 | x = m_<%=name%>(x,&y); 16 | SET_DATA_STRIDE(p2,s2,dtype,x); 17 | SET_DATA_STRIDE(p3,s3,int32_t,y); 18 | } 19 | } 20 | 21 | /* 22 | split the number x into a normalized fraction and an exponent. 23 | Returns [mantissa, exponent], where x = mantissa * 2**exponent. 24 | 25 | @overload <%=name%>(x) 26 | @param [Numo::NArray,Numeric] x 27 | @return [Numo::<%=class_name%>,Numo::Int32] mantissa and exponent. 28 | 29 | */ 30 | static VALUE 31 | <%=c_func(1)%>(VALUE mod, VALUE a1) 32 | { 33 | ndfunc_arg_in_t ain[1] = {{cT,0}}; 34 | ndfunc_arg_out_t aout[2] = {{cT,0},{numo_cInt32,0}}; 35 | ndfunc_t ndf = { <%=c_iter%>, STRIDE_LOOP, 1,2, ain,aout }; 36 | return na_ndloop(&ndf, 1, a1); 37 | } 38 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/init_class.c: -------------------------------------------------------------------------------- 1 | /* 2 | Document-class: <%= full_class_name %> 3 | <%= description %> 4 | */ 5 | cT = rb_define_class_under(<%=ns_var%>, "<%=class_name%>", cNArray); 6 | 7 | <% for x in class_alias %> 8 | // alias of <%=class_name%> 9 | rb_define_const(<%=ns_var%>, "<%=x%>", <%=type_var%>); 10 | <% end %> 11 | 12 | hCast = rb_hash_new(); 13 | rb_define_const(cT, "UPCAST", hCast); 14 | rb_hash_aset(hCast, rb_cArray, cT); 15 | <% for x in upcast %> 16 | <%= x %><% end %> 17 | rb_obj_freeze(hCast); 18 | 19 | <% @children.each do |m| %> 20 | <%= m.init_def %><% end %> 21 | rb_define_singleton_method(cT, "[]", <%=find("cast").c_func%>, -2); 22 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/init_module.c: -------------------------------------------------------------------------------- 1 | /* 2 | Document-module: <%= full_module_name %> 3 | <%= description %> 4 | */ 5 | <% if module_var != ns_var %> 6 | <%=module_var%> = rb_define_module_under(<%=ns_var%>, "<%=module_name%>"); 7 | <% end %> 8 | <% @children.each do |m| %> 9 | <%= m.init_def %><% end %> 10 | 11 | // how to do this? 12 | //rb_extend_object(cT, mTM); 13 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/inspect.c: -------------------------------------------------------------------------------- 1 | static VALUE 2 | <%=c_iter%>(char *ptr, size_t pos, VALUE fmt) 3 | { 4 | <% if is_object %> 5 | return rb_inspect(*(VALUE*)(ptr+pos)); 6 | <% else %> 7 | return format_<%=type_name%>(fmt, (dtype*)(ptr+pos)); 8 | <% end %> 9 | } 10 | 11 | /* 12 | Returns a string containing a human-readable representation of NArray. 13 | @overload inspect 14 | @return [String] 15 | */ 16 | static VALUE 17 | <%=c_func(0)%>(VALUE ary) 18 | { 19 | return na_ndloop_inspect(ary, <%=c_iter%>, Qnil); 20 | } 21 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/lib.c: -------------------------------------------------------------------------------- 1 | /* 2 | <%= file_name %> 3 | Ruby/Numo::NArray - Numerical Array class for Ruby 4 | 5 | created on: 2017-03-11 6 | Copyright (C) 2017-2020 Masahiro Tanaka 7 | */ 8 | 9 | #include 10 | #include 11 | #include "numo/narray.h" 12 | #include "numo/template.h" 13 | #include "SFMT.h" 14 | 15 | #define m_map(x) m_num_to_data(rb_yield(m_data_to_num(x))) 16 | 17 | <% if is_simd %> 18 | #include 19 | #define SIMD_ALIGNMENT_SIZE 16 20 | <% end %> 21 | 22 | <% id_decl.each do |x| %> 23 | <%= x %> 24 | <% end %> 25 | 26 | <% include_files.each do |f| %> 27 | #include <<%=f%>> 28 | <% end %> 29 | 30 | VALUE cT; 31 | extern VALUE cRT; 32 | 33 | <% children.each do |c|%> 34 | <%= c.result+"\n\n" %> 35 | <% end %> 36 | 37 | void 38 | Init_<%=lib_name%>(void) 39 | { 40 | VALUE hCast, <%=ns_var%>; 41 | 42 | <%=ns_var%> = rb_define_module("Numo"); 43 | 44 | <% id_assign.each do |x| %> 45 | <%= x %><% end %> 46 | 47 | <% children.each do |c| %> 48 | <%= c.init_def %> 49 | <% end %> 50 | } 51 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/logseq.c: -------------------------------------------------------------------------------- 1 | typedef struct { 2 | seq_data_t beg; 3 | seq_data_t step; 4 | seq_data_t base; 5 | seq_count_t count; 6 | } logseq_opt_t; 7 | 8 | static void 9 | <%=c_iter%>(na_loop_t *const lp) 10 | { 11 | size_t i; 12 | char *p1; 13 | ssize_t s1; 14 | size_t *idx1; 15 | dtype x; 16 | seq_data_t beg, step, base; 17 | seq_count_t c; 18 | logseq_opt_t *g; 19 | 20 | INIT_COUNTER(lp, i); 21 | INIT_PTR_IDX(lp, 0, p1, s1, idx1); 22 | g = (logseq_opt_t*)(lp->opt_ptr); 23 | beg = g->beg; 24 | step = g->step; 25 | base = g->base; 26 | c = g->count; 27 | if (idx1) { 28 | for (; i--;) { 29 | x = f_seq(beg,step,c++); 30 | *(dtype*)(p1+*idx1) = m_pow(base,x); 31 | idx1++; 32 | } 33 | } else { 34 | for (; i--;) { 35 | x = f_seq(beg,step,c++); 36 | *(dtype*)(p1) = m_pow(base,x); 37 | p1 += s1; 38 | } 39 | } 40 | g->count = c; 41 | } 42 | 43 | /* 44 | Set logarithmic sequence of numbers to self. The sequence is obtained from 45 | `base**(beg+i*step)` 46 | where i is 1-dimensional index. 47 | Applicable classes: DFloat, SFloat, DComplex, SCopmplex. 48 | 49 | @overload logseq(beg,step,[base]) 50 | @param [Numeric] beg The beginning of sequence. 51 | @param [Numeric] step The step of sequence. 52 | @param [Numeric] base The base of log space. (default=10) 53 | @return [Numo::<%=class_name%>] self. 54 | 55 | @example 56 | Numo::DFloat.new(5).logseq(4,-1,2) 57 | # => Numo::DFloat#shape=[5] 58 | # [16, 8, 4, 2, 1] 59 | 60 | Numo::DComplex.new(5).logseq(0,1i*Math::PI/3,Math::E) 61 | # => Numo::DComplex#shape=[5] 62 | # [1+7.26156e-310i, 0.5+0.866025i, -0.5+0.866025i, -1+1.22465e-16i, ...] 63 | */ 64 | static VALUE 65 | <%=c_func(-1)%>(int argc, VALUE *args, VALUE self) 66 | { 67 | logseq_opt_t *g; 68 | VALUE vbeg, vstep, vbase; 69 | ndfunc_arg_in_t ain[1] = {{OVERWRITE,0}}; 70 | ndfunc_t ndf = {<%=c_iter%>, FULL_LOOP, 1,0, ain,0}; 71 | 72 | g = ALLOCA_N(logseq_opt_t,1); 73 | rb_scan_args(argc, args, "21", &vbeg, &vstep, &vbase); 74 | g->beg = m_num_to_data(vbeg); 75 | g->step = m_num_to_data(vstep); 76 | if (vbase==Qnil) { 77 | g->base = m_from_real(10); 78 | } else { 79 | g->base = m_num_to_data(vbase); 80 | } 81 | na_ndloop3(&ndf, g, 1, self); 82 | return self; 83 | } 84 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/map_with_index.c: -------------------------------------------------------------------------------- 1 | static inline dtype 2 | yield_map_with_index(dtype x, size_t *c, VALUE *a, int nd, int md) 3 | { 4 | int j; 5 | VALUE y; 6 | 7 | a[0] = m_data_to_num(x); 8 | for (j=0; j<=nd; j++) { 9 | a[j+1] = SIZET2NUM(c[j]); 10 | } 11 | y = rb_yield(rb_ary_new4(md,a)); 12 | return m_num_to_data(y); 13 | } 14 | 15 | static void 16 | <%=c_iter%>(na_loop_t *const lp) 17 | { 18 | size_t i; 19 | char *p1, *p2; 20 | ssize_t s1, s2; 21 | size_t *idx1, *idx2; 22 | dtype x; 23 | VALUE *a; 24 | size_t *c; 25 | int nd, md; 26 | 27 | c = (size_t*)(lp->opt_ptr); 28 | nd = lp->ndim; 29 | if (nd > 0) {nd--;} 30 | md = nd + 2; 31 | a = ALLOCA_N(VALUE,md); 32 | 33 | INIT_COUNTER(lp, i); 34 | INIT_PTR_IDX(lp, 0, p1, s1, idx1); 35 | INIT_PTR_IDX(lp, 1, p2, s2, idx2); 36 | 37 | c[nd] = 0; 38 | if (idx1) { 39 | if (idx2) { 40 | for (; i--;) { 41 | GET_DATA_INDEX(p1,idx1,dtype,x); 42 | x = yield_map_with_index(x,c,a,nd,md); 43 | SET_DATA_INDEX(p2,idx2,dtype,x); 44 | c[nd]++; 45 | } 46 | } else { 47 | for (; i--;) { 48 | GET_DATA_INDEX(p1,idx1,dtype,x); 49 | x = yield_map_with_index(x,c,a,nd,md); 50 | SET_DATA_STRIDE(p2,s2,dtype,x); 51 | c[nd]++; 52 | } 53 | } 54 | } else { 55 | if (idx2) { 56 | for (; i--;) { 57 | GET_DATA_STRIDE(p1,s1,dtype,x); 58 | x = yield_map_with_index(x,c,a,nd,md); 59 | SET_DATA_INDEX(p2,idx2,dtype,x); 60 | c[nd]++; 61 | } 62 | } else { 63 | for (; i--;) { 64 | GET_DATA_STRIDE(p1,s1,dtype,x); 65 | x = yield_map_with_index(x,c,a,nd,md); 66 | SET_DATA_STRIDE(p2,s2,dtype,x); 67 | c[nd]++; 68 | } 69 | } 70 | } 71 | } 72 | 73 | /* 74 | Invokes the given block once for each element of self, 75 | passing that element and indices along each axis as parameters. 76 | Creates a new NArray containing the values returned by the block. 77 | Inplace option is allowed, i.e., `nary.inplace.map` overwrites `nary`. 78 | @overload <%=name%> 79 | For a block `{|x,i,j,...| ... }`, 80 | @yieldparam [Numeric] x an element 81 | @yieldparam [Integer] i,j,... multitimensional indices 82 | @return [Numo::NArray] mapped array 83 | @see #map 84 | @see #each_with_index 85 | */ 86 | static VALUE 87 | <%=c_func(0)%>(VALUE self) 88 | { 89 | ndfunc_arg_in_t ain[1] = {{Qnil,0}}; 90 | ndfunc_arg_out_t aout[1] = {{cT,0}}; 91 | ndfunc_t ndf = {<%=c_iter%>, FULL_LOOP, 1,1, ain,aout}; 92 | 93 | return na_ndloop_with_index(&ndf, 1, self); 94 | } 95 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/median.c: -------------------------------------------------------------------------------- 1 | <% (is_float ? ["_ignan","_prnan"] : [""]).each do |j| %> 2 | static void 3 | <%=c_iter%><%=j%>(na_loop_t *const lp) 4 | { 5 | size_t n; 6 | char *p1, *p2; 7 | dtype *buf; 8 | 9 | INIT_COUNTER(lp, n); 10 | p1 = (lp->args[0]).ptr + (lp->args[0].iter[0]).pos; 11 | p2 = (lp->args[1]).ptr + (lp->args[1].iter[0]).pos; 12 | buf = (dtype*)p1; 13 | 14 | <%=type_name%>_qsort<%=j%>(buf, n, sizeof(dtype)); 15 | 16 | <% if is_float %> 17 | for (; n; n--) { 18 | if (!isnan(buf[n-1])) break; 19 | } 20 | <% end %> 21 | 22 | if (n==0) { 23 | *(dtype*)p2 = buf[0]; 24 | } 25 | else if (n%2==0) { 26 | *(dtype*)p2 = (buf[n/2-1]+buf[n/2])/2; 27 | } 28 | else { 29 | *(dtype*)p2 = buf[(n-1)/2]; 30 | } 31 | } 32 | <% end %> 33 | 34 | /* 35 | <%=name%> of self. 36 | <% if is_float %> 37 | @overload <%=name%>(axis:nil, keepdims:false, nan:false) 38 | @param [TrueClass] nan (keyword) If true, propagete NaN. If false, ignore NaN. 39 | <% else %> 40 | @overload <%=name%>(axis:nil, keepdims:false) 41 | <% end %> 42 | @param [Numeric,Array,Range] axis Finds <%=name%> along the axis. 43 | @param [TrueClass] keepdims If true, the reduced axes are left in the result array as dimensions with size one. 44 | @return [Numo::<%=class_name%>] returns <%=name%> of self. 45 | */ 46 | 47 | static VALUE 48 | <%=c_func(-1)%>(int argc, VALUE *argv, VALUE self) 49 | { 50 | VALUE v, reduce; 51 | ndfunc_arg_in_t ain[2] = {{OVERWRITE,0},{sym_reduce,0}}; 52 | ndfunc_arg_out_t aout[1] = {{INT2FIX(0),0}}; 53 | ndfunc_t ndf = {0, NDF_HAS_LOOP|NDF_FLAT_REDUCE, 2,1, ain,aout}; 54 | 55 | self = na_copy(self); // as temporary buffer 56 | <% if is_float %> 57 | ndf.func = <%=c_iter%>_ignan; 58 | reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, <%=c_iter%>_prnan); 59 | <% else %> 60 | ndf.func = <%=c_iter%>; 61 | reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, 0); 62 | <% end %> 63 | v = na_ndloop(&ndf, 2, self, reduce); 64 | return <%=type_name%>_extract(v); 65 | } 66 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/minmax.c: -------------------------------------------------------------------------------- 1 | <% (is_float ? ["","_nan"] : [""]).each do |j| %> 2 | static void 3 | <%=c_iter%><%=j%>(na_loop_t *const lp) 4 | { 5 | size_t n; 6 | char *p1; 7 | ssize_t s1; 8 | dtype xmin,xmax; 9 | 10 | INIT_COUNTER(lp, n); 11 | INIT_PTR(lp, 0, p1, s1); 12 | 13 | f_<%=name%><%=j%>(n,p1,s1,&xmin,&xmax); 14 | 15 | *(dtype*)(lp->args[1].ptr + lp->args[1].iter[0].pos) = xmin; 16 | *(dtype*)(lp->args[2].ptr + lp->args[2].iter[0].pos) = xmax; 17 | } 18 | <% end %> 19 | 20 | /* 21 | <%=name%> of self. 22 | <% if is_float %> 23 | @overload <%=name%>(axis:nil, keepdims:false, nan:false) 24 | @param [TrueClass] nan If true, apply NaN-aware algorithm (return NaN if exist). 25 | <% else %> 26 | @overload <%=name%>(axis:nil, keepdims:false) 27 | <% end %> 28 | @param [Numeric,Array,Range] axis Finds min-max along the axis. 29 | @param [TrueClass] keepdims (keyword) If true, the reduced axes are left in the result array as dimensions with size one. 30 | @return [Numo::<%=class_name%>,Numo::<%=class_name%>] min and max of self. 31 | */ 32 | static VALUE 33 | <%=c_func(-1)%>(int argc, VALUE *argv, VALUE self) 34 | { 35 | VALUE reduce; 36 | ndfunc_arg_in_t ain[2] = {{cT,0},{sym_reduce,0}}; 37 | ndfunc_arg_out_t aout[2] = {{cT,0},{cT,0}}; 38 | ndfunc_t ndf = {<%=c_iter%>, STRIDE_LOOP_NIP|NDF_FLAT_REDUCE|NDF_EXTRACT, 2,2, ain,aout}; 39 | 40 | <% if is_float %> 41 | reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, <%=c_iter%>_nan); 42 | <% else %> 43 | reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, 0); 44 | <% end %> 45 | return na_ndloop(&ndf, 2, self, reduce); 46 | } 47 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/module.c: -------------------------------------------------------------------------------- 1 | /* 2 | module definition: <%= full_module_name %> 3 | */ 4 | 5 | <% if module_var != ns_var %> 6 | VALUE <%=module_var%>; 7 | <% end %> 8 | 9 | <%= method_code %> 10 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/new_dim0.c: -------------------------------------------------------------------------------- 1 | static VALUE 2 | <%=c_func(:nodef)%>(dtype x) 3 | { 4 | VALUE v; 5 | dtype *ptr; 6 | 7 | v = nary_new(cT, 0, NULL); 8 | ptr = (dtype*)(char*)na_get_pointer_for_write(v); 9 | *ptr = x; 10 | na_release_lock(v); 11 | return v; 12 | } 13 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/poly.c: -------------------------------------------------------------------------------- 1 | static void 2 | <%=c_iter%>(na_loop_t *const lp) 3 | { 4 | size_t i; 5 | dtype x, y, a; 6 | 7 | x = *(dtype*)(lp->args[0].ptr + lp->args[0].iter[0].pos); 8 | i = lp->narg - 2; 9 | y = *(dtype*)(lp->args[i].ptr + lp->args[i].iter[0].pos); 10 | for (; --i;) { 11 | y = m_mul(x,y); 12 | a = *(dtype*)(lp->args[i].ptr + lp->args[i].iter[0].pos); 13 | y = m_add(y,a); 14 | } 15 | i = lp->narg - 1; 16 | *(dtype*)(lp->args[i].ptr + lp->args[i].iter[0].pos) = y; 17 | } 18 | 19 | /* 20 | Calculate polynomial. 21 | `x.poly(a0,a1,a2,...,an) = a0 + a1*x + a2*x**2 + ... + an*x**n` 22 | @overload <%=name%> a0, a1, ..., an 23 | @param [Numo::NArray,Numeric] a0,a1,...,an 24 | @return [Numo::<%=class_name%>] 25 | */ 26 | static VALUE 27 | <%=c_func(-2)%>(VALUE self, VALUE args) 28 | { 29 | int argc, i; 30 | VALUE *argv; 31 | volatile VALUE v, a; 32 | ndfunc_arg_out_t aout[1] = {{cT,0}}; 33 | ndfunc_t ndf = { <%=c_iter%>, NO_LOOP, 0, 1, 0, aout }; 34 | 35 | argc = RARRAY_LEN(args); 36 | ndf.nin = argc+1; 37 | ndf.ain = ALLOCA_N(ndfunc_arg_in_t,argc+1); 38 | for (i=0; i_extract(v); 49 | } 50 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/pow.c: -------------------------------------------------------------------------------- 1 | static void 2 | <%=c_iter%>(na_loop_t *const lp) 3 | { 4 | size_t i; 5 | char *p1, *p2, *p3; 6 | ssize_t s1, s2, s3; 7 | dtype x, y; 8 | INIT_COUNTER(lp, i); 9 | INIT_PTR(lp, 0, p1, s1); 10 | INIT_PTR(lp, 1, p2, s2); 11 | INIT_PTR(lp, 2, p3, s3); 12 | for (; i--;) { 13 | GET_DATA_STRIDE(p1,s1,dtype,x); 14 | GET_DATA_STRIDE(p2,s2,dtype,y); 15 | x = m_pow(x,y); 16 | SET_DATA_STRIDE(p3,s3,dtype,x); 17 | } 18 | } 19 | 20 | static void 21 | <%=c_iter%>_int32(na_loop_t *const lp) 22 | { 23 | size_t i; 24 | char *p1, *p2, *p3; 25 | ssize_t s1, s2, s3; 26 | dtype x; 27 | int32_t y; 28 | INIT_COUNTER(lp, i); 29 | INIT_PTR(lp, 0, p1, s1); 30 | INIT_PTR(lp, 1, p2, s2); 31 | INIT_PTR(lp, 2, p3, s3); 32 | for (; i--;) { 33 | GET_DATA_STRIDE(p1,s1,dtype,x); 34 | GET_DATA_STRIDE(p2,s2,int32_t,y); 35 | x = m_pow_int(x,y); 36 | SET_DATA_STRIDE(p3,s3,dtype,x); 37 | } 38 | } 39 | 40 | static VALUE 41 | <%=c_func%>_self(VALUE self, VALUE other) 42 | { 43 | ndfunc_arg_in_t ain[2] = {{cT,0},{cT,0}}; 44 | ndfunc_arg_in_t ain_i[2] = {{cT,0},{numo_cInt32,0}}; 45 | ndfunc_arg_out_t aout[1] = {{cT,0}}; 46 | ndfunc_t ndf = { <%=c_iter%>, STRIDE_LOOP, 2, 1, ain, aout }; 47 | ndfunc_t ndf_i = { <%=c_iter%>_int32, STRIDE_LOOP, 2, 1, ain_i, aout }; 48 | 49 | // fixme : use na.integer? 50 | if (FIXNUM_P(other) || rb_obj_is_kind_of(other,numo_cInt32)) { 51 | return na_ndloop(&ndf_i, 2, self, other); 52 | } else { 53 | return na_ndloop(&ndf, 2, self, other); 54 | } 55 | } 56 | 57 | /* 58 | Binary power. 59 | @overload <%=op_map%> other 60 | @param [Numo::NArray,Numeric] other 61 | @return [Numo::NArray] self to the other-th power. 62 | */ 63 | static VALUE 64 | <%=c_func(1)%>(VALUE self, VALUE other) 65 | { 66 | <% if is_object %> 67 | return <%=c_func%>_self(self,other); 68 | <% else %> 69 | VALUE klass, v; 70 | klass = na_upcast(rb_obj_class(self),rb_obj_class(other)); 71 | if (klass==cT) { 72 | return <%=c_func%>_self(self,other); 73 | } else { 74 | v = rb_funcall(klass, id_cast, 1, self); 75 | return rb_funcall(v, id_pow, 1, other); 76 | } 77 | <% end %> 78 | } 79 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/powint.c: -------------------------------------------------------------------------------- 1 | static dtype pow_<%=type_name%>(dtype x, int p) 2 | { 3 | dtype r = m_one; 4 | switch(p) { 5 | case 2: return m_square(x); 6 | case 3: return m_mul(m_square(x),x); 7 | case 1: return x; 8 | case 0: return m_one; 9 | } 10 | if (p<0) return m_zero; 11 | while (p) { 12 | if ((p%2) == 1) r = m_mul(r,x); 13 | x = m_square(x); 14 | p /= 2; 15 | } 16 | return r; 17 | } 18 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/rand_norm.c: -------------------------------------------------------------------------------- 1 | typedef struct { 2 | dtype mu; 3 | rtype sigma; 4 | } randn_opt_t; 5 | 6 | static void 7 | <%=c_iter%>(na_loop_t *const lp) 8 | { 9 | size_t i; 10 | char *p1; 11 | ssize_t s1; 12 | size_t *idx1; 13 | <% if is_complex %> 14 | dtype *a0; 15 | <% else %> 16 | dtype *a0, *a1; 17 | <% end %> 18 | dtype mu; 19 | rtype sigma; 20 | randn_opt_t *g; 21 | 22 | INIT_COUNTER(lp, i); 23 | INIT_PTR_IDX(lp, 0, p1, s1, idx1); 24 | g = (randn_opt_t*)(lp->opt_ptr); 25 | mu = g->mu; 26 | sigma = g->sigma; 27 | 28 | if (idx1) { 29 | <% if is_complex %> 30 | for (; i--;) { 31 | a0 = (dtype*)(p1+*idx1); 32 | m_rand_norm(mu,sigma,a0); 33 | idx1 += 1; 34 | } 35 | <% else %> 36 | for (; i>1; i-=2) { 37 | a0 = (dtype*)(p1+*idx1); 38 | a1 = (dtype*)(p1+*(idx1+1)); 39 | m_rand_norm(mu,sigma,a0,a1); 40 | idx1 += 2; 41 | } 42 | if (i>0) { 43 | a0 = (dtype*)(p1+*idx1); 44 | m_rand_norm(mu,sigma,a0,0); 45 | } 46 | <% end %> 47 | } else { 48 | <% if is_complex %> 49 | for (; i--;) { 50 | a0 = (dtype*)(p1); 51 | m_rand_norm(mu,sigma,a0); 52 | p1 += s1; 53 | } 54 | <% else %> 55 | for (; i>1; i-=2) { 56 | a0 = (dtype*)(p1); 57 | a1 = (dtype*)(p1+s1); 58 | m_rand_norm(mu,sigma,a0,a1); 59 | p1 += s1*2; 60 | } 61 | if (i>0) { 62 | a0 = (dtype*)(p1); 63 | m_rand_norm(mu,sigma,a0,0); 64 | } 65 | <% end %> 66 | } 67 | } 68 | 69 | /* 70 | Generates random numbers from the normal distribution on self narray 71 | using Box-Muller Transformation. 72 | @overload rand_norm([mu,[sigma]]) 73 | @param [Numeric] mu mean of normal distribution. (default=0) 74 | @param [Numeric] sigma standard deviation of normal distribution. (default=1) 75 | @return [Numo::<%=class_name%>] self. 76 | @example 77 | Numo::DFloat.new(5,5).rand_norm 78 | # => Numo::DFloat#shape=[5,5] 79 | # [[-0.581255, -0.168354, 0.586895, -0.595142, -0.802802], 80 | # [-0.326106, 0.282922, 1.68427, 0.918499, -0.0485384], 81 | # [-0.464453, -0.992194, 0.413794, -0.60717, -0.699695], 82 | # [-1.64168, 0.48676, -0.875871, -1.43275, 0.812172], 83 | # [-0.209975, -0.103612, -0.878617, -1.42495, 1.0968]] 84 | 85 | Numo::DFloat.new(5,5).rand_norm(10,0.1) 86 | # => Numo::DFloat#shape=[5,5] 87 | # [[9.9019, 9.90339, 10.0826, 9.98384, 9.72861], 88 | # [9.81507, 10.0272, 9.91445, 10.0568, 9.88923], 89 | # [10.0234, 9.97874, 9.96011, 9.9006, 9.99964], 90 | # [10.0186, 9.94598, 9.92236, 9.99811, 9.97003], 91 | # [9.79266, 9.95044, 9.95212, 9.93692, 10.2027]] 92 | 93 | Numo::DComplex.new(3,3).rand_norm(5+5i) 94 | # => Numo::DComplex#shape=[3,3] 95 | # [[5.84303+4.40052i, 4.00984+6.08982i, 5.10979+5.13215i], 96 | # [4.26477+3.99655i, 4.90052+5.00763i, 4.46607+2.3444i], 97 | # [4.5528+7.11003i, 5.62117+6.69094i, 5.05443+5.35133i]] 98 | */ 99 | static VALUE 100 | <%=c_func(-1)%>(int argc, VALUE *args, VALUE self) 101 | { 102 | int n; 103 | randn_opt_t g; 104 | VALUE v1=Qnil, v2=Qnil; 105 | ndfunc_arg_in_t ain[1] = {{OVERWRITE,0}}; 106 | ndfunc_t ndf = {<%=c_iter%>, FULL_LOOP, 1,0, ain,0}; 107 | 108 | n = rb_scan_args(argc, args, "02", &v1, &v2); 109 | if (n == 0) { 110 | g.mu = m_zero; 111 | } else { 112 | g.mu = m_num_to_data(v1); 113 | } 114 | if (n == 2) { 115 | g.sigma = NUM2DBL(v2); 116 | } else { 117 | g.sigma = 1; 118 | } 119 | na_ndloop3(&ndf, &g, 1, self); 120 | return self; 121 | } 122 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/seq.c: -------------------------------------------------------------------------------- 1 | <% if is_int && !is_object %> 2 | typedef double seq_data_t; 3 | <% else %> 4 | typedef dtype seq_data_t; 5 | <% end %> 6 | 7 | <% if is_object %> 8 | typedef size_t seq_count_t; 9 | <% else %> 10 | typedef double seq_count_t; 11 | <% end %> 12 | 13 | typedef struct { 14 | seq_data_t beg; 15 | seq_data_t step; 16 | seq_count_t count; 17 | } seq_opt_t; 18 | 19 | static void 20 | <%=c_iter%>(na_loop_t *const lp) 21 | { 22 | size_t i; 23 | char *p1; 24 | ssize_t s1; 25 | size_t *idx1; 26 | dtype x; 27 | seq_data_t beg, step; 28 | seq_count_t c; 29 | seq_opt_t *g; 30 | 31 | INIT_COUNTER(lp, i); 32 | INIT_PTR_IDX(lp, 0, p1, s1, idx1); 33 | g = (seq_opt_t*)(lp->opt_ptr); 34 | beg = g->beg; 35 | step = g->step; 36 | c = g->count; 37 | if (idx1) { 38 | for (; i--;) { 39 | x = f_seq(beg,step,c++); 40 | *(dtype*)(p1+*idx1) = x; 41 | idx1++; 42 | } 43 | } else { 44 | for (; i--;) { 45 | x = f_seq(beg,step,c++); 46 | *(dtype*)(p1) = x; 47 | p1 += s1; 48 | } 49 | } 50 | g->count = c; 51 | } 52 | 53 | /* 54 | Set linear sequence of numbers to self. The sequence is obtained from 55 | beg+i*step 56 | where i is 1-dimensional index. 57 | @overload seq([beg,[step]]) 58 | @param [Numeric] beg beginning of sequence. (default=0) 59 | @param [Numeric] step step of sequence. (default=1) 60 | @return [Numo::<%=class_name%>] self. 61 | @example 62 | Numo::DFloat.new(6).seq(1,-0.2) 63 | # => Numo::DFloat#shape=[6] 64 | # [1, 0.8, 0.6, 0.4, 0.2, 0] 65 | 66 | Numo::DComplex.new(6).seq(1,-0.2+0.2i) 67 | # => Numo::DComplex#shape=[6] 68 | # [1+0i, 0.8+0.2i, 0.6+0.4i, 0.4+0.6i, 0.2+0.8i, 0+1i] 69 | */ 70 | static VALUE 71 | <%=c_func(-1)%>(int argc, VALUE *args, VALUE self) 72 | { 73 | seq_opt_t *g; 74 | VALUE vbeg=Qnil, vstep=Qnil; 75 | ndfunc_arg_in_t ain[1] = {{OVERWRITE,0}}; 76 | ndfunc_t ndf = {<%=c_iter%>, FULL_LOOP, 1,0, ain,0}; 77 | 78 | g = ALLOCA_N(seq_opt_t,1); 79 | g->beg = m_zero; 80 | g->step = m_one; 81 | g->count = 0; 82 | rb_scan_args(argc, args, "02", &vbeg, &vstep); 83 | <% if is_int && !is_object %> 84 | if (vbeg!=Qnil) {g->beg = NUM2DBL(vbeg);} 85 | if (vstep!=Qnil) {g->step = NUM2DBL(vstep);} 86 | <% else %> 87 | if (vbeg!=Qnil) {g->beg = m_num_to_data(vbeg);} 88 | if (vstep!=Qnil) {g->step = m_num_to_data(vstep);} 89 | <% end %> 90 | 91 | na_ndloop3(&ndf, g, 1, self); 92 | return self; 93 | } 94 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/set2.c: -------------------------------------------------------------------------------- 1 | static void 2 | <%=c_iter%>(na_loop_t *const lp) 3 | { 4 | size_t i; 5 | char *p1, *p2; 6 | ssize_t s1, s2; 7 | size_t *idx1, *idx2; 8 | dtype x; 9 | <%=dtype%> y; 10 | INIT_COUNTER(lp, i); 11 | INIT_PTR_IDX(lp, 0, p1, s1, idx1); 12 | INIT_PTR_IDX(lp, 1, p2, s2, idx2); 13 | if (idx1) { 14 | if (idx2) { 15 | for (; i--;) { 16 | GET_DATA(p1+*idx1,dtype,x); 17 | GET_DATA_INDEX(p2,idx2,<%=dtype%>,y); 18 | x = m_<%=name%>(x,y); 19 | SET_DATA_INDEX(p1,idx1,dtype,x); 20 | } 21 | } else { 22 | for (; i--;) { 23 | GET_DATA(p1+*idx1,dtype,x); 24 | GET_DATA_STRIDE(p2,s2,<%=dtype%>,y); 25 | x = m_<%=name%>(x,y); 26 | SET_DATA_INDEX(p1,idx1,dtype,x); 27 | } 28 | } 29 | } else { 30 | if (idx2) { 31 | for (; i--;) { 32 | GET_DATA(p1,dtype,x); 33 | GET_DATA_INDEX(p2,idx2,<%=dtype%>,y); 34 | x = m_<%=name%>(x,y); 35 | SET_DATA_STRIDE(p1,s1,dtype,x); 36 | } 37 | } else { 38 | for (; i--;) { 39 | GET_DATA(p1,dtype,x); 40 | GET_DATA_STRIDE(p2,s2,<%=dtype%>,y); 41 | x = m_<%=name%>(x,y); 42 | SET_DATA_STRIDE(p1,s1,dtype,x); 43 | } 44 | } 45 | } 46 | } 47 | 48 | static VALUE 49 | <%=c_func(1)%>(VALUE self, VALUE a1) 50 | { 51 | ndfunc_arg_in_t ain[2] = {{OVERWRITE,0},{<%=result_class%>,0}}; 52 | ndfunc_t ndf = { <%=c_iter%>, FULL_LOOP, 2, 0, ain, 0 }; 53 | 54 | na_ndloop(&ndf, 2, self, a1); 55 | return a1; 56 | } 57 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/sort.c: -------------------------------------------------------------------------------- 1 | <% (is_float ? ["_ignan","_prnan"] : [""]).each do |j| %> 2 | static void 3 | <%=c_iter%><%=j%>(na_loop_t *const lp) 4 | { 5 | size_t n; 6 | char *ptr; 7 | ssize_t step; 8 | 9 | INIT_COUNTER(lp, n); 10 | INIT_PTR(lp, 0, ptr, step); 11 | <%=type_name%>_qsort<%=j%>(ptr, n, step); 12 | } 13 | <% end %> 14 | 15 | /* 16 | <%=name%> of self. 17 | <% if is_float %> 18 | @overload <%=name%>(axis:nil, nan:false) 19 | @param [TrueClass] nan If true, propagete NaN. If false, ignore NaN. 20 | <% else %> 21 | @overload <%=name%>(axis:nil) 22 | <% end %> 23 | @param [Numeric,Array,Range] axis Performs <%=name%> along the axis. 24 | @return [Numo::<%=class_name%>] returns result of <%=name%>. 25 | @example 26 | Numo::DFloat[3,4,1,2].sort #=> Numo::DFloat[1,2,3,4] 27 | */ 28 | static VALUE 29 | <%=c_func(-1)%>(int argc, VALUE *argv, VALUE self) 30 | { 31 | VALUE reduce; 32 | ndfunc_arg_in_t ain[2] = {{OVERWRITE,0},{sym_reduce,0}}; 33 | ndfunc_t ndf = {0, NDF_HAS_LOOP|NDF_FLAT_REDUCE, 2,0, ain,0}; 34 | 35 | if (!TEST_INPLACE(self)) { 36 | self = na_copy(self); 37 | } 38 | <% if is_float %> 39 | ndf.func = <%=c_iter%>_ignan; 40 | reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, <%=c_iter%>_prnan); 41 | <% else %> 42 | ndf.func = <%=c_iter%>; 43 | reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, 0); 44 | <% end %> 45 | na_ndloop(&ndf, 2, self, reduce); 46 | return self; 47 | } 48 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/sort_index.c: -------------------------------------------------------------------------------- 1 | <% (is_float ? ["_ignan","_prnan"] : [""]).each do |j| 2 | [64,32].each do |i| %> 3 | #define idx_t int<%=i%>_t 4 | static void 5 | <%=type_name%>_index<%=i%>_qsort<%=j%>(na_loop_t *const lp) 6 | { 7 | size_t i, n, idx; 8 | char *d_ptr, *i_ptr, *o_ptr; 9 | ssize_t d_step, i_step, o_step; 10 | char **ptr; 11 | 12 | INIT_COUNTER(lp, n); 13 | INIT_PTR(lp, 0, d_ptr, d_step); 14 | INIT_PTR(lp, 1, i_ptr, i_step); 15 | INIT_PTR(lp, 2, o_ptr, o_step); 16 | 17 | ptr = (char**)(lp->opt_ptr); 18 | 19 | //printf("(ptr=%lx, d_ptr=%lx,d_step=%ld, i_ptr=%lx,i_step=%ld, o_ptr=%lx,o_step=%ld)\n",(size_t)ptr,(size_t)d_ptr,(ssize_t)d_step,(size_t)i_ptr,(ssize_t)i_step,(size_t)o_ptr,(ssize_t)o_step); 20 | 21 | if (n==1) { 22 | *(idx_t*)o_ptr = *(idx_t*)(i_ptr); 23 | return; 24 | } 25 | 26 | for (i=0; i_index_qsort<%=j%>(ptr, n, sizeof(dtype*)); 32 | 33 | //d_ptr = lp->args[0].ptr; 34 | //printf("(d_ptr=%lx)\n",(size_t)d_ptr); 35 | 36 | for (i=0; i 46 | 47 | /* 48 | <%=name%>. Returns an index array of sort result. 49 | <% if is_float %> 50 | @overload <%=name%>(axis:nil, nan:false) 51 | @param [TrueClass] nan If true, propagete NaN. If false, ignore NaN. 52 | <% else %> 53 | @overload <%=name%>(axis:nil) 54 | <% end %> 55 | @param [Numeric,Array,Range] axis Performs <%=name%> along the axis. 56 | @return [Integer,Numo::Int] returns result index of <%=name%>. 57 | @example 58 | Numo::NArray[3,4,1,2].sort_index #=> Numo::Int32[2,3,0,1] 59 | */ 60 | static VALUE 61 | <%=c_func(-1)%>(int argc, VALUE *argv, VALUE self) 62 | { 63 | size_t size; 64 | narray_t *na; 65 | VALUE idx, tmp, reduce, res; 66 | char *buf; 67 | ndfunc_arg_in_t ain[3] = {{cT,0},{0,0},{sym_reduce,0}}; 68 | ndfunc_arg_out_t aout[1] = {{0,0,0}}; 69 | ndfunc_t ndf = {0, STRIDE_LOOP_NIP|NDF_FLAT_REDUCE|NDF_CUM, 3,1, ain,aout}; 70 | 71 | GetNArray(self,na); 72 | if (na->ndim==0) { 73 | return INT2FIX(0); 74 | } 75 | if (na->size > (~(u_int32_t)0)) { 76 | ain[1].type = 77 | aout[0].type = numo_cInt64; 78 | idx = nary_new(numo_cInt64, na->ndim, na->shape); 79 | <% if is_float %> 80 | ndf.func = <%=type_name%>_index64_qsort_ignan; 81 | reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, 82 | <%=type_name%>_index64_qsort_prnan); 83 | <% else %> 84 | ndf.func = <%=type_name%>_index64_qsort; 85 | reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, 0); 86 | <% end %> 87 | } else { 88 | ain[1].type = 89 | aout[0].type = numo_cInt32; 90 | idx = nary_new(numo_cInt32, na->ndim, na->shape); 91 | <% if is_float %> 92 | ndf.func = <%=type_name%>_index32_qsort_ignan; 93 | reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, 94 | <%=type_name%>_index32_qsort_prnan); 95 | <% else %> 96 | ndf.func = <%=type_name%>_index32_qsort; 97 | reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, 0); 98 | <% end %> 99 | } 100 | rb_funcall(idx, rb_intern("seq"), 0); 101 | 102 | size = na->size*sizeof(void*); // max capa 103 | buf = rb_alloc_tmp_buffer(&tmp, size); 104 | res = na_ndloop3(&ndf, buf, 3, self, idx, reduce); 105 | rb_free_tmp_buffer(&tmp); 106 | return res; 107 | } 108 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/store.c: -------------------------------------------------------------------------------- 1 | <% children.each do |c|%> 2 | <%= c.result %> 3 | 4 | <% end %> 5 | /* 6 | Store elements to Numo::<%=class_name%> from other. 7 | @overload store(other) 8 | @param [Object] other 9 | @return [Numo::<%=class_name%>] self 10 | */ 11 | static VALUE 12 | <%=c_func(1)%>(VALUE self, VALUE obj) 13 | { 14 | VALUE r, klass; 15 | 16 | klass = rb_obj_class(obj); 17 | 18 | <% definitions.each do |x| %> 19 | if (<%=x.condition("klass")%>) { 20 | <%=x.c_func%>(self,obj); 21 | return self; 22 | } 23 | <% end %> 24 | 25 | if (IsNArray(obj)) { 26 | r = rb_funcall(obj, rb_intern("coerce_cast"), 1, cT); 27 | if (rb_obj_class(r)==cT) { 28 | <%=c_func%>(self,r); 29 | return self; 30 | } 31 | } 32 | 33 | <% if is_object %> 34 | robject_store_numeric(self,obj); 35 | <% else %> 36 | rb_raise(nary_eCastError, "unknown conversion from %s to %s", 37 | rb_class2name(rb_obj_class(obj)), 38 | rb_class2name(rb_obj_class(self))); 39 | <% end %> 40 | return self; 41 | } 42 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/store_array.c: -------------------------------------------------------------------------------- 1 | static void 2 | <%=c_iter%>(na_loop_t *const lp) 3 | { 4 | size_t i, n; 5 | size_t i1, n1; 6 | VALUE v1, *ptr; 7 | char *p1; 8 | size_t s1, *idx1; 9 | VALUE x; 10 | double y; 11 | dtype z; 12 | size_t len, c; 13 | double beg, step; 14 | 15 | INIT_COUNTER(lp, n); 16 | INIT_PTR_IDX(lp, 0, p1, s1, idx1); 17 | v1 = lp->args[1].value; 18 | i = 0; 19 | 20 | if (lp->args[1].ptr) { 21 | if (v1 == Qtrue) { 22 | iter_<%=type_name%>_store_<%=type_name%>(lp); 23 | i = lp->args[1].shape[0]; 24 | if (idx1) { 25 | idx1 += i; 26 | } else { 27 | p1 += s1 * i; 28 | } 29 | } 30 | goto loop_end; 31 | } 32 | 33 | ptr = &v1; 34 | 35 | switch(TYPE(v1)) { 36 | case T_ARRAY: 37 | n1 = RARRAY_LEN(v1); 38 | ptr = RARRAY_PTR(v1); 39 | break; 40 | case T_NIL: 41 | n1 = 0; 42 | break; 43 | default: 44 | n1 = 1; 45 | } 46 | 47 | if (idx1) { 48 | for (i=i1=0; i1(VALUE self, VALUE rary) 108 | { 109 | ndfunc_arg_in_t ain[2] = {{OVERWRITE,0},{rb_cArray,0}}; 110 | ndfunc_t ndf = {<%=c_iter%>, FULL_LOOP, 2, 0, ain, 0}; 111 | 112 | na_ndloop_store_rarray(&ndf, self, rary); 113 | return self; 114 | } 115 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/store_bit.c: -------------------------------------------------------------------------------- 1 | static void 2 | <%=c_iter%>(na_loop_t *const lp) 3 | { 4 | size_t i; 5 | char *p1; 6 | size_t p2; 7 | ssize_t s1, s2; 8 | size_t *idx1, *idx2; 9 | BIT_DIGIT *a2, x; 10 | dtype y; 11 | 12 | INIT_COUNTER(lp, i); 13 | INIT_PTR_IDX(lp, 0, p1, s1, idx1); 14 | INIT_PTR_BIT_IDX(lp, 1, a2, p2, s2, idx2); 15 | if (idx2) { 16 | if (idx1) { 17 | for (; i--;) { 18 | LOAD_BIT(a2, p2+*idx2, x); idx2++; 19 | y = m_from_sint(x); 20 | SET_DATA_INDEX(p1,idx1,dtype,y); 21 | } 22 | } else { 23 | for (; i--;) { 24 | LOAD_BIT(a2, p2+*idx2, x); idx2++; 25 | y = m_from_sint(x); 26 | SET_DATA_STRIDE(p1,s1,dtype,y); 27 | } 28 | } 29 | } else { 30 | if (idx1) { 31 | for (; i--;) { 32 | LOAD_BIT(a2, p2, x); p2 += s2; 33 | y = m_from_sint(x); 34 | SET_DATA_INDEX(p1,idx1,dtype,y); 35 | } 36 | } else { 37 | for (; i--;) { 38 | LOAD_BIT(a2, p2, x); p2 += s2; 39 | y = m_from_sint(x); 40 | SET_DATA_STRIDE(p1,s1,dtype,y); 41 | } 42 | } 43 | } 44 | } 45 | 46 | 47 | static VALUE 48 | <%=c_func(:nodef)%>(VALUE self, VALUE obj) 49 | { 50 | ndfunc_arg_in_t ain[2] = {{OVERWRITE,0},{Qnil,0}}; 51 | ndfunc_t ndf = {<%=c_iter%>, FULL_LOOP, 2,0, ain,0}; 52 | 53 | na_ndloop(&ndf, 2, self, obj); 54 | return self; 55 | } 56 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/store_from.c: -------------------------------------------------------------------------------- 1 | static void 2 | <%=c_iter%>(na_loop_t *const lp) 3 | { 4 | size_t i, s1, s2; 5 | char *p1, *p2; 6 | size_t *idx1, *idx2; 7 | <%=dtype%> x; 8 | dtype y; 9 | 10 | INIT_COUNTER(lp, i); 11 | INIT_PTR_IDX(lp, 0, p1, s1, idx1); 12 | INIT_PTR_IDX(lp, 1, p2, s2, idx2); 13 | if (idx2) { 14 | if (idx1) { 15 | for (; i--;) { 16 | GET_DATA_INDEX(p2,idx2,<%=dtype%>,x); 17 | y = <%=macro%>(x); 18 | SET_DATA_INDEX(p1,idx1,dtype,y); 19 | } 20 | } else { 21 | for (; i--;) { 22 | GET_DATA_INDEX(p2,idx2,<%=dtype%>,x); 23 | y = <%=macro%>(x); 24 | SET_DATA_STRIDE(p1,s1,dtype,y); 25 | } 26 | } 27 | } else { 28 | if (idx1) { 29 | for (; i--;) { 30 | GET_DATA_STRIDE(p2,s2,<%=dtype%>,x); 31 | y = <%=macro%>(x); 32 | SET_DATA_INDEX(p1,idx1,dtype,y); 33 | } 34 | } else { 35 | for (; i--;) { 36 | GET_DATA_STRIDE(p2,s2,<%=dtype%>,x); 37 | y = <%=macro%>(x); 38 | SET_DATA_STRIDE(p1,s1,dtype,y); 39 | } 40 | } 41 | } 42 | } 43 | 44 | 45 | static VALUE 46 | <%=c_func(:nodef)%>(VALUE self, VALUE obj) 47 | { 48 | ndfunc_arg_in_t ain[2] = {{OVERWRITE,0},{Qnil,0}}; 49 | ndfunc_t ndf = { <%=c_iter%>, FULL_LOOP, 2, 0, ain, 0 }; 50 | 51 | na_ndloop(&ndf, 2, self, obj); 52 | return self; 53 | } 54 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/store_numeric.c: -------------------------------------------------------------------------------- 1 | static VALUE 2 | <%=c_func(:nodef)%>(VALUE self, VALUE obj) 3 | { 4 | dtype x; 5 | x = m_num_to_data(obj); 6 | obj = <%=type_name%>_new_dim0(x); 7 | <%=parent.c_func%>(self,obj); 8 | return self; 9 | } 10 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/to_a.c: -------------------------------------------------------------------------------- 1 | static void 2 | <%=c_iter%>(na_loop_t *const lp) 3 | { 4 | size_t i, s1; 5 | char *p1; 6 | size_t *idx1; 7 | dtype x; 8 | volatile VALUE a, y; 9 | 10 | INIT_COUNTER(lp, i); 11 | INIT_PTR_IDX(lp, 0, p1, s1, idx1); 12 | a = rb_ary_new2(i); 13 | rb_ary_push(lp->args[1].value, a); 14 | if (idx1) { 15 | for (; i--;) { 16 | GET_DATA_INDEX(p1,idx1,dtype,x); 17 | y = m_data_to_num(x); 18 | rb_ary_push(a,y); 19 | } 20 | } else { 21 | for (; i--;) { 22 | GET_DATA_STRIDE(p1,s1,dtype,x); 23 | y = m_data_to_num(x); 24 | rb_ary_push(a,y); 25 | } 26 | } 27 | } 28 | 29 | /* 30 | Convert self to Array. 31 | @overload <%=name%> 32 | @return [Array] 33 | */ 34 | static VALUE 35 | <%=c_func(0)%>(VALUE self) 36 | { 37 | ndfunc_arg_in_t ain[3] = {{Qnil,0},{sym_loop_opt},{sym_option}}; 38 | ndfunc_arg_out_t aout[1] = {{rb_cArray,0}}; // dummy? 39 | ndfunc_t ndf = { <%=c_iter%>, FULL_LOOP_NIP, 3, 1, ain, aout }; 40 | return na_ndloop_cast_narray_to_rarray(&ndf, self, Qnil); 41 | } 42 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/unary.c: -------------------------------------------------------------------------------- 1 | static void 2 | <%=c_iter%>(na_loop_t *const lp) 3 | { 4 | size_t i, n; 5 | char *p1, *p2; 6 | ssize_t s1, s2; 7 | size_t *idx1, *idx2; 8 | dtype x; 9 | 10 | INIT_COUNTER(lp, n); 11 | INIT_PTR_IDX(lp, 0, p1, s1, idx1); 12 | INIT_PTR_IDX(lp, 1, p2, s2, idx2); 13 | 14 | if (idx1) { 15 | if (idx2) { 16 | for (i=0; i(x); 19 | SET_DATA_INDEX(p2,idx2,dtype,x); 20 | } 21 | } else { 22 | for (i=0; i(x); 25 | SET_DATA_STRIDE(p2,s2,dtype,x); 26 | } 27 | } 28 | } else { 29 | if (idx2) { 30 | for (i=0; i(x); 33 | SET_DATA_INDEX(p2,idx2,dtype,x); 34 | } 35 | } else { 36 | //<% if need_align %> 37 | if (is_aligned(p1,sizeof(dtype)) && 38 | is_aligned(p2,sizeof(dtype)) ) { 39 | if (s1 == sizeof(dtype) && 40 | s2 == sizeof(dtype) ) { 41 | for (i=0; i(((dtype*)p1)[i]); 43 | } 44 | return; 45 | } 46 | if (is_aligned_step(s1,sizeof(dtype)) && 47 | is_aligned_step(s2,sizeof(dtype)) ) { 48 | //<% end %> 49 | for (i=0; i(*(dtype*)p1); 51 | p1 += s1; 52 | p2 += s2; 53 | } 54 | return; 55 | //<% if need_align %> 56 | } 57 | } 58 | for (i=0; i(x); 61 | SET_DATA_STRIDE(p2,s2,dtype,x); 62 | } 63 | //<% end %> 64 | } 65 | } 66 | } 67 | 68 | /* 69 | Unary <%=name%>. 70 | @overload <%=op_map%> 71 | @return [Numo::<%=class_name%>] <%=name%> of self. 72 | */ 73 | static VALUE 74 | <%=c_func(0)%>(VALUE self) 75 | { 76 | ndfunc_arg_in_t ain[1] = {{cT,0}}; 77 | ndfunc_arg_out_t aout[1] = {{cT,0}}; 78 | ndfunc_t ndf = {<%=c_iter%>, FULL_LOOP, 1,1, ain,aout}; 79 | 80 | return na_ndloop(&ndf, 1, self); 81 | } 82 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/unary2.c: -------------------------------------------------------------------------------- 1 | static void 2 | <%=c_iter%>(na_loop_t *const lp) 3 | { 4 | size_t i; 5 | char *p1, *p2; 6 | ssize_t s1, s2; 7 | size_t *idx1, *idx2; 8 | dtype x; 9 | <%=dtype%> y; 10 | INIT_COUNTER(lp, i); 11 | INIT_PTR_IDX(lp, 0, p1, s1, idx1); 12 | INIT_PTR_IDX(lp, 1, p2, s2, idx2); 13 | if (idx1) { 14 | if (idx2) { 15 | for (; i--;) { 16 | GET_DATA_INDEX(p1,idx1,dtype,x); 17 | y = m_<%=name%>(x); 18 | SET_DATA_INDEX(p2,idx2,<%=dtype%>,y); 19 | } 20 | } else { 21 | for (; i--;) { 22 | GET_DATA_INDEX(p1,idx1,dtype,x); 23 | y = m_<%=name%>(x); 24 | SET_DATA_STRIDE(p2,s2,<%=dtype%>,y); 25 | } 26 | } 27 | } else { 28 | if (idx2) { 29 | for (; i--;) { 30 | GET_DATA_STRIDE(p1,s1,dtype,x); 31 | y = m_<%=name%>(x); 32 | SET_DATA_INDEX(p2,idx2,<%=dtype%>,y); 33 | } 34 | } else { 35 | for (; i--;) { 36 | GET_DATA_STRIDE(p1,s1,dtype,x); 37 | y = m_<%=name%>(x); 38 | SET_DATA_STRIDE(p2,s2,<%=dtype%>,y); 39 | } 40 | } 41 | } 42 | } 43 | 44 | 45 | /* 46 | <%=name%> of self. 47 | @overload <%=name%> 48 | @return [Numo::<%=real_class_name%>] <%=name%> of self. 49 | */ 50 | static VALUE 51 | <%=c_func(0)%>(VALUE self) 52 | { 53 | ndfunc_arg_in_t ain[1] = {{cT,0}}; 54 | ndfunc_arg_out_t aout[1] = {{<%=result_class%>,0}}; 55 | ndfunc_t ndf = { <%=c_iter%>, FULL_LOOP, 1, 1, ain, aout }; 56 | 57 | return na_ndloop(&ndf, 1, self); 58 | } 59 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl/unary_ret2.c: -------------------------------------------------------------------------------- 1 | static void 2 | <%=c_iter%>(na_loop_t *const lp) 3 | { 4 | size_t i; 5 | char *p1, *p2, *p3; 6 | ssize_t s1, s2, s3; 7 | dtype x, y, z; 8 | INIT_COUNTER(lp, i); 9 | INIT_PTR(lp, 0, p1, s1); 10 | INIT_PTR(lp, 1, p2, s2); 11 | INIT_PTR(lp, 2, p3, s3); 12 | for (; i--;) { 13 | GET_DATA_STRIDE(p1,s1,dtype,x); 14 | m_<%=name%>(x,y,z); 15 | SET_DATA_STRIDE(p2,s2,dtype,y); 16 | SET_DATA_STRIDE(p3,s3,dtype,z); 17 | } 18 | } 19 | 20 | /* 21 | <%=name%> of self. 22 | @overload <%=name%> 23 | @return [Numo::<%=real_class_name%>] <%=name%> of self. 24 | */ 25 | static VALUE 26 | <%=c_func(0)%>(VALUE self) 27 | { 28 | ndfunc_arg_in_t ain[1] = {{cT,0}}; 29 | ndfunc_arg_out_t aout[2] = {{cT,0},{cT,0}}; 30 | ndfunc_t ndf = {<%=c_iter%>, STRIDE_LOOP, 1,2, ain,aout}; 31 | 32 | return na_ndloop(&ndf, 1, self); 33 | } 34 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl_bit/allocate.c: -------------------------------------------------------------------------------- 1 | static VALUE 2 | <%=c_func(0)%>(VALUE self) 3 | { 4 | narray_t *na; 5 | char *ptr; 6 | 7 | GetNArray(self,na); 8 | 9 | switch(NA_TYPE(na)) { 10 | case NARRAY_DATA_T: 11 | ptr = NA_DATA_PTR(na); 12 | if (na->size > 0 && ptr == NULL) { 13 | ptr = xmalloc(((na->size-1)/8/sizeof(BIT_DIGIT)+1)*sizeof(BIT_DIGIT)); 14 | NA_DATA_PTR(na) = ptr; 15 | NA_DATA_OWNED(na) = TRUE; 16 | } 17 | break; 18 | case NARRAY_VIEW_T: 19 | rb_funcall(NA_VIEW_DATA(na), rb_intern("allocate"), 0); 20 | break; 21 | default: 22 | rb_raise(rb_eRuntimeError,"invalid narray type"); 23 | } 24 | return self; 25 | } 26 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl_bit/aref.c: -------------------------------------------------------------------------------- 1 | /* 2 | Multi-dimensional element reference. 3 | @overload [](dim0,...,dimL) 4 | @param [Numeric,Range,Array,Numo::Int32,Numo::Int64,Numo::Bit,TrueClass,FalseClass,Symbol] dim0,...,dimL multi-dimensional indices. 5 | @return [Numeric,Numo::Bit] an element or NArray view. 6 | @see Numo::NArray#[] 7 | @see #[]= 8 | 9 | @example 10 | a = Numo::Int32.new(3,4).seq 11 | # => Numo::Int32#shape=[3,4] 12 | # [[0, 1, 2, 3], 13 | # [4, 5, 6, 7], 14 | # [8, 9, 10, 11]] 15 | 16 | b = (a%2).eq(0) 17 | # => Numo::Bit#shape=[3,4] 18 | # [[1, 0, 1, 0], 19 | # [1, 0, 1, 0], 20 | # [1, 0, 1, 0]] 21 | 22 | b[true,(0..-1)%2] 23 | # => Numo::Bit(view)#shape=[3,2] 24 | # [[1, 1], 25 | # [1, 1], 26 | # [1, 1]] 27 | 28 | b[1,1] 29 | # => 0 30 | */ 31 | static VALUE 32 | <%=c_func(-1)%>(int argc, VALUE *argv, VALUE self) 33 | { 34 | int nd; 35 | size_t pos; 36 | char *ptr; 37 | dtype x; 38 | 39 | nd = na_get_result_dimension(self, argc, argv, 1, &pos); 40 | if (nd) { 41 | return na_aref_main(argc, argv, self, 0, nd); 42 | } else { 43 | ptr = na_get_pointer_for_read(self); 44 | LOAD_BIT(ptr,pos,x); 45 | return m_data_to_num(x); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl_bit/aset.c: -------------------------------------------------------------------------------- 1 | /* 2 | Multi-dimensional element assignment. 3 | @overload []=(dim0,...,dimL,val) 4 | @param [Numeric,Range,Array,Numo::Int32,Numo::Int64,Numo::Bit,TrueClass,FalseClass,Symbol] dim0,...,dimL multi-dimensional indices. 5 | @param [Numeric,Numo::NArray,Array] val Value(s) to be set to self. 6 | @return [Numeric,Numo::NArray,Array] returns `val` (last argument). 7 | @see Numo::NArray#[]= 8 | @see #[] 9 | 10 | @example 11 | a = Numo::Bit.new(4,5).fill(0) 12 | # => Numo::Bit#shape=[4,5] 13 | # [[0, 0, 0, 0, 0], 14 | # [0, 0, 0, 0, 0], 15 | # [0, 0, 0, 0, 0], 16 | # [0, 0, 0, 0, 0]] 17 | 18 | a[(0..-1)%2,(1..-1)%2] = 1 19 | a 20 | # => Numo::Bit#shape=[4,5] 21 | # [[0, 1, 0, 1, 0], 22 | # [0, 0, 0, 0, 0], 23 | # [0, 1, 0, 1, 0], 24 | # [0, 0, 0, 0, 0]] 25 | */ 26 | static VALUE 27 | <%=c_func(-1)%>(int argc, VALUE *argv, VALUE self) 28 | { 29 | int nd; 30 | size_t pos; 31 | char *ptr; 32 | VALUE a; 33 | dtype x; 34 | 35 | argc--; 36 | if (argc==0) { 37 | <%=c_func.sub(/_aset/,"_store")%>(self, argv[argc]); 38 | } else { 39 | nd = na_get_result_dimension(self, argc, argv, 1, &pos); 40 | if (nd) { 41 | a = na_aref_main(argc, argv, self, 0, nd); 42 | <%=c_func.sub(/_aset/,"_store")%>(a, argv[argc]); 43 | } else { 44 | x = <%=type_name%>_extract_data(argv[argc]); 45 | ptr = na_get_pointer_for_read_write(self); 46 | STORE_BIT(ptr,pos,x); 47 | } 48 | 49 | } 50 | return argv[argc]; 51 | } 52 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl_bit/binary.c: -------------------------------------------------------------------------------- 1 | static void 2 | <%=c_iter%>(na_loop_t *const lp) 3 | { 4 | size_t n; 5 | size_t p1, p2, p3; 6 | ssize_t s1, s2, s3; 7 | size_t *idx1, *idx2, *idx3; 8 | int o1, o2, l1, l2, r1, r2, len; 9 | BIT_DIGIT *a1, *a2, *a3; 10 | BIT_DIGIT x, y; 11 | 12 | INIT_COUNTER(lp, n); 13 | INIT_PTR_BIT_IDX(lp, 0, a1, p1, s1, idx1); 14 | INIT_PTR_BIT_IDX(lp, 1, a2, p2, s2, idx2); 15 | INIT_PTR_BIT_IDX(lp, 2, a3, p3, s3, idx3); 16 | if (s1!=1 || s2!=1 || s3!=1 || idx1 || idx2 || idx3) { 17 | for (; n--;) { 18 | LOAD_BIT_STEP(a1, p1, s1, idx1, x); 19 | LOAD_BIT_STEP(a2, p2, s2, idx2, y); 20 | x = m_<%=name%>(x,y); 21 | STORE_BIT_STEP(a3, p3, s3, idx3, x); 22 | } 23 | } else { 24 | a1 += p1/NB; 25 | p1 %= NB; 26 | a2 += p2/NB; 27 | p2 %= NB; 28 | a3 += p3/NB; 29 | p3 %= NB; 30 | o1 = p1-p3; 31 | o2 = p2-p3; 32 | l1 = NB+o1; 33 | r1 = NB-o1; 34 | l2 = NB+o2; 35 | r2 = NB-o2; 36 | if (p3>0 || n=0) x = *a1>>o1; 40 | else x = *a1<<-o1; 41 | if (p1+len>NB) x |= *(a1+1)<=0) y = *a2>>o2; 44 | else y = *a2<<-o2; 45 | if (p2+len>NB) y |= *(a2+1)<(x,y); 48 | *a3 = (x & (SLB(len)<=NB; n-=NB) { 54 | x = *(a1++); 55 | y = *(a2++); 56 | x = m_<%=name%>(x,y); 57 | *(a3++) = x; 58 | } 59 | } else { 60 | for (; n>=NB; n-=NB) { 61 | if (o1==0) { 62 | x = *a1; 63 | } else if (o1>0) { 64 | x = *a1>>o1 | *(a1+1)<>l1; 67 | } 68 | a1++; 69 | if (o2==0) { 70 | y = *a2; 71 | } else if (o2>0) { 72 | y = *a2>>o2 | *(a2+1)<>l2; 75 | } 76 | a2++; 77 | x = m_<%=name%>(x,y); 78 | *(a3++) = x; 79 | } 80 | } 81 | if (n>0) { 82 | if (o1==0) { 83 | x = *a1; 84 | } else if (o1>0) { 85 | x = *a1>>o1; 86 | if ((int)n>r1) { 87 | x |= *(a1+1)<>l1; 91 | if ((int)n>-o1) { 92 | x |= *a1<<-o1; 93 | } 94 | } 95 | if (o2==0) { 96 | y = *a2; 97 | } else if (o2>0) { 98 | y = *a2>>o2; 99 | if ((int)n>r2) { 100 | y |= *(a2+1)<>l2; 104 | if ((int)n>-o2) { 105 | y |= *a2<<-o2; 106 | } 107 | } 108 | x = m_<%=name%>(x,y); 109 | *a3 = (x & SLB(n)) | (*a3 & BALL<. 116 | @overload <%=op_map%> other 117 | @param [Numo::NArray,Numeric] other 118 | @return [Numo::NArray] <%=name%> of self and other. 119 | */ 120 | static VALUE 121 | <%=c_func(1)%>(VALUE self, VALUE other) 122 | { 123 | ndfunc_arg_in_t ain[2] = {{cT,0},{cT,0}}; 124 | ndfunc_arg_out_t aout[1] = {{cT,0}}; 125 | ndfunc_t ndf = { <%=c_iter%>, FULL_LOOP, 2, 1, ain, aout }; 126 | 127 | return na_ndloop(&ndf, 2, self, other); 128 | } 129 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl_bit/bit_count.c: -------------------------------------------------------------------------------- 1 | #undef int_t 2 | #define int_t int64_t 3 | 4 | static void 5 | <%=c_iter%>(na_loop_t *const lp) 6 | { 7 | size_t i; 8 | BIT_DIGIT *a1; 9 | size_t p1; 10 | char *p2; 11 | ssize_t s1, s2; 12 | size_t *idx1; 13 | BIT_DIGIT x=0; 14 | int_t y; 15 | 16 | INIT_COUNTER(lp, i); 17 | INIT_PTR_BIT_IDX(lp, 0, a1, p1, s1, idx1); 18 | INIT_PTR(lp, 1, p2, s2); 19 | if (s2==0) { 20 | GET_DATA(p2, int_t, y); 21 | if (idx1) { 22 | for (; i--;) { 23 | LOAD_BIT(a1, p1+*idx1, x); 24 | idx1++; 25 | if (m_<%=name%>(x)) { 26 | y++; 27 | } 28 | } 29 | } else { 30 | for (; i--;) { 31 | LOAD_BIT(a1, p1, x); 32 | p1 += s1; 33 | if (m_<%=name%>(x)) { 34 | y++; 35 | } 36 | } 37 | } 38 | *(int_t*)p2 = y; 39 | } else { 40 | if (idx1) { 41 | for (; i--;) { 42 | LOAD_BIT(a1, p1+*idx1, x); 43 | idx1++; 44 | if (m_<%=name%>(x)) { 45 | GET_DATA(p2, int_t, y); 46 | y++; 47 | SET_DATA(p2, int_t, y); 48 | } 49 | p2+=s2; 50 | } 51 | } else { 52 | for (; i--;) { 53 | LOAD_BIT(a1, p1, x); 54 | p1+=s1; 55 | if (m_<%=name%>(x)) { 56 | GET_DATA(p2, int_t, y); 57 | y++; 58 | SET_DATA(p2, int_t, y); 59 | } 60 | p2+=s2; 61 | } 62 | } 63 | } 64 | } 65 | 66 | /* 67 | Returns the number of bits. 68 | If argument is supplied, return Int-array counted along the axes. 69 | @overload <%=op_map%>(axis:nil, keepdims:false) 70 | @param [Integer,Array,Range] axis (keyword) axes to be counted. 71 | @param [TrueClass] keepdims (keyword) If true, the reduced axes are left in the result array as dimensions with size one. 72 | @return [Numo::Int64] 73 | */ 74 | static VALUE 75 | <%=c_func(-1)%>(int argc, VALUE *argv, VALUE self) 76 | { 77 | VALUE v, reduce; 78 | narray_t *na; 79 | ndfunc_arg_in_t ain[3] = {{cT,0},{sym_reduce,0},{sym_init,0}}; 80 | ndfunc_arg_out_t aout[1] = {{numo_cInt64,0}}; 81 | ndfunc_t ndf = { <%=c_iter%>, FULL_LOOP_NIP, 3, 1, ain, aout }; 82 | 83 | GetNArray(self,na); 84 | if (NA_SIZE(na)==0) { 85 | return INT2FIX(0); 86 | } 87 | reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, 0); 88 | v = na_ndloop(&ndf, 3, self, reduce, INT2FIX(0)); 89 | return rb_funcall(v,rb_intern("extract"),0); 90 | } 91 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl_bit/bit_reduce.c: -------------------------------------------------------------------------------- 1 | static void 2 | <%=c_iter%>(na_loop_t *const lp) 3 | { 4 | size_t i; 5 | BIT_DIGIT *a1, *a2; 6 | size_t p1, p2; 7 | ssize_t s1, s2; 8 | size_t *idx1, *idx2; 9 | BIT_DIGIT x=0, y=0; 10 | 11 | INIT_COUNTER(lp, i); 12 | INIT_PTR_BIT_IDX(lp, 0, a1, p1, s1, idx1); 13 | INIT_PTR_BIT_IDX(lp, 1, a2, p2, s2, idx2); 14 | if (idx2) { 15 | if (idx1) { 16 | for (; i--;) { 17 | LOAD_BIT(a2, p2+*idx2, y); 18 | if (y == <%=init_bit%>) { 19 | LOAD_BIT(a1, p1+*idx1, x); 20 | if (x != <%=init_bit%>) { 21 | STORE_BIT(a2, p2+*idx2, x); 22 | } 23 | } 24 | idx1++; 25 | idx2++; 26 | } 27 | } else { 28 | for (; i--;) { 29 | LOAD_BIT(a2, p2+*idx2, y); 30 | if (y == <%=init_bit%>) { 31 | LOAD_BIT(a1, p1, x); 32 | if (x != <%=init_bit%>) { 33 | STORE_BIT(a2, p2+*idx2, x); 34 | } 35 | } 36 | p1 += s1; 37 | idx2++; 38 | } 39 | } 40 | } else if (s2) { 41 | if (idx1) { 42 | for (; i--;) { 43 | LOAD_BIT(a2, p2, y); 44 | if (y == <%=init_bit%>) { 45 | LOAD_BIT(a1, p1+*idx1, x); 46 | if (x != <%=init_bit%>) { 47 | STORE_BIT(a2, p2, x); 48 | } 49 | } 50 | idx1++; 51 | p2 += s2; 52 | } 53 | } else { 54 | for (; i--;) { 55 | LOAD_BIT(a2, p2, y); 56 | if (y == <%=init_bit%>) { 57 | LOAD_BIT(a1, p1, x); 58 | if (x != <%=init_bit%>) { 59 | STORE_BIT(a2, p2, x); 60 | } 61 | } 62 | p1 += s1; 63 | p2 += s2; 64 | } 65 | } 66 | } else { 67 | LOAD_BIT(a2, p2, x); 68 | if (x != <%=init_bit%>) { 69 | return; 70 | } 71 | if (idx1) { 72 | for (; i--;) { 73 | LOAD_BIT(a1, p1+*idx1, y); 74 | if (y != <%=init_bit%>) { 75 | STORE_BIT(a2, p2, y); 76 | return; 77 | } 78 | idx1++; 79 | } 80 | } else { 81 | for (; i--;) { 82 | LOAD_BIT(a1, p1, y); 83 | if (y != <%=init_bit%>) { 84 | STORE_BIT(a2, p2, y); 85 | return; 86 | } 87 | p1 += s1; 88 | } 89 | } 90 | } 91 | } 92 | 93 | /* 94 | <% case name 95 | when /^any/ %> 96 | Return true if any of bits is one (true). 97 | <% when /^all/ %> 98 | Return true if all of bits are one (true). 99 | <% end %> 100 | If argument is supplied, return Bit-array reduced along the axes. 101 | @overload <%=op_map%>(axis:nil, keepdims:false) 102 | @param [Integer,Array,Range] axis (keyword) axes to be reduced. 103 | @param [TrueClass] keepdims (keyword) If true, the reduced axes are left in the result array as dimensions with size one. 104 | @return [Numo::Bit] . 105 | */ 106 | static VALUE 107 | <%=c_func(-1)%>(int argc, VALUE *argv, VALUE self) 108 | { 109 | VALUE v, reduce; 110 | narray_t *na; 111 | ndfunc_arg_in_t ain[3] = {{cT,0},{sym_reduce,0},{sym_init,0}}; 112 | ndfunc_arg_out_t aout[1] = {{numo_cBit,0}}; 113 | ndfunc_t ndf = {<%=c_iter%>, FULL_LOOP_NIP, 3,1, ain,aout}; 114 | 115 | GetNArray(self,na); 116 | if (NA_SIZE(na)==0) { 117 | return Qfalse; 118 | } 119 | reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, 0); 120 | v = na_ndloop(&ndf, 3, self, reduce, INT2FIX(<%=init_bit%>)); 121 | if (argc > 0) { 122 | return v; 123 | } 124 | v = <%=find_tmpl("extract").c_func%>(v); 125 | switch (v) { 126 | case INT2FIX(0): 127 | return Qfalse; 128 | case INT2FIX(1): 129 | return Qtrue; 130 | default: 131 | rb_bug("unexpected result"); 132 | return v; 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl_bit/each.c: -------------------------------------------------------------------------------- 1 | static void 2 | <%=c_iter%>(na_loop_t *const lp) 3 | { 4 | size_t i; 5 | BIT_DIGIT *a1, x=0; 6 | size_t p1; 7 | ssize_t s1; 8 | size_t *idx1; 9 | VALUE y; 10 | 11 | INIT_COUNTER(lp, i); 12 | INIT_PTR_BIT_IDX(lp, 0, a1, p1, s1, idx1); 13 | if (idx1) { 14 | for (; i--;) { 15 | LOAD_BIT(a1, p1+*idx1, x); idx1++; 16 | y = m_data_to_num(x); 17 | rb_yield(y); 18 | } 19 | } else { 20 | for (; i--;) { 21 | LOAD_BIT(a1, p1, x); p1+=s1; 22 | y = m_data_to_num(x); 23 | rb_yield(y); 24 | } 25 | } 26 | } 27 | 28 | /* 29 | Calls the given block once for each element in self, 30 | passing that element as a parameter. 31 | @overload <%=name%> 32 | @return [Numo::NArray] self 33 | For a block {|x| ... } 34 | @yield [x] x is element of NArray. 35 | */ 36 | static VALUE 37 | <%=c_func(0)%>(VALUE self) 38 | { 39 | ndfunc_arg_in_t ain[1] = {{Qnil,0}}; 40 | ndfunc_t ndf = {<%=c_iter%>, FULL_LOOP_NIP, 1,0, ain,0}; 41 | 42 | na_ndloop(&ndf, 1, self); 43 | return self; 44 | } 45 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl_bit/each_with_index.c: -------------------------------------------------------------------------------- 1 | static inline void 2 | yield_each_with_index(dtype x, size_t *c, VALUE *a, int nd, int md) 3 | { 4 | int j; 5 | 6 | a[0] = m_data_to_num(x); 7 | for (j=0; j<=nd; j++) { 8 | a[j+1] = SIZET2NUM(c[j]); 9 | } 10 | rb_yield(rb_ary_new4(md,a)); 11 | } 12 | 13 | 14 | static void 15 | <%=c_iter%>(na_loop_t *const lp) 16 | { 17 | size_t i; 18 | BIT_DIGIT *a1, x=0; 19 | size_t p1; 20 | ssize_t s1; 21 | size_t *idx1; 22 | 23 | VALUE *a; 24 | size_t *c; 25 | int nd, md; 26 | 27 | c = (size_t*)(lp->opt_ptr); 28 | nd = lp->ndim - 1; 29 | md = lp->ndim + 1; 30 | a = ALLOCA_N(VALUE,md); 31 | 32 | INIT_COUNTER(lp, i); 33 | INIT_PTR_BIT_IDX(lp, 0, a1, p1, s1, idx1); 34 | c[nd] = 0; 35 | if (idx1) { 36 | for (; i--;) { 37 | LOAD_BIT(a1, p1+*idx1, x); idx1++; 38 | yield_each_with_index(x,c,a,nd,md); 39 | c[nd]++; 40 | } 41 | } else { 42 | for (; i--;) { 43 | LOAD_BIT(a1, p1, x); p1+=s1; 44 | yield_each_with_index(x,c,a,nd,md); 45 | c[nd]++; 46 | } 47 | } 48 | } 49 | 50 | /* 51 | Invokes the given block once for each element of self, 52 | passing that element and indices along each axis as parameters. 53 | @overload <%=name%> 54 | @return [Numo::NArray] self 55 | For a block {|x,i,j,...| ... } 56 | @yield [x,i,j,...] x is an element, i,j,... are multidimensional indices. 57 | */ 58 | static VALUE 59 | <%=c_func(0)%>(VALUE self) 60 | { 61 | ndfunc_arg_in_t ain[1] = {{Qnil,0}}; 62 | ndfunc_t ndf = {<%=c_iter%>, FULL_LOOP_NIP, 1,0, ain,0}; 63 | 64 | na_ndloop_with_index(&ndf, 1, self); 65 | return self; 66 | } 67 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl_bit/extract.c: -------------------------------------------------------------------------------- 1 | /* 2 | Extract an element only if self is a dimensionless NArray. 3 | @overload extract 4 | @return [Numeric,Numo::NArray] 5 | --- Extract element value as Ruby Object if self is a dimensionless NArray, 6 | otherwise returns self. 7 | */ 8 | 9 | static VALUE 10 | <%=c_func(0)%>(VALUE self) 11 | { 12 | BIT_DIGIT *ptr, val; 13 | size_t pos; 14 | narray_t *na; 15 | GetNArray(self,na); 16 | 17 | if (na->ndim==0) { 18 | pos = na_get_offset(self); 19 | ptr = (BIT_DIGIT*)na_get_pointer_for_read(self); 20 | val = ((*((ptr)+(pos)/NB)) >> ((pos)%NB)) & 1u; 21 | na_release_lock(self); 22 | return INT2FIX(val); 23 | } 24 | return self; 25 | } 26 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl_bit/fill.c: -------------------------------------------------------------------------------- 1 | static void 2 | <%=c_iter%>(na_loop_t *const lp) 3 | { 4 | size_t n; 5 | size_t p3; 6 | ssize_t s3; 7 | size_t *idx3; 8 | int len; 9 | BIT_DIGIT *a3; 10 | BIT_DIGIT y; 11 | VALUE x = lp->option; 12 | 13 | if (x==INT2FIX(0) || x==Qfalse) { 14 | y = 0; 15 | } else 16 | if (x==INT2FIX(1) || x==Qtrue) { 17 | y = ~(BIT_DIGIT)0; 18 | } else { 19 | rb_raise(rb_eArgError, "invalid value for Bit"); 20 | } 21 | 22 | INIT_COUNTER(lp, n); 23 | INIT_PTR_BIT_IDX(lp, 0, a3, p3, s3, idx3); 24 | if (idx3) { 25 | y = y&1; 26 | for (; n--;) { 27 | STORE_BIT(a3, p3+*idx3, y); idx3++; 28 | } 29 | } else if (s3!=1) { 30 | y = y&1; 31 | for (; n--;) { 32 | STORE_BIT(a3, p3, y); p3+=s3; 33 | } 34 | } else { 35 | if (p3>0 || n=NB; n-=NB) { 43 | *(a3++) = y; 44 | } 45 | if (n>0) { 46 | *a3 = (y & SLB(n)) | (*a3 & BALL< other 54 | @param [Numeric] other 55 | @return [Numo::<%=class_name%>] self. 56 | */ 57 | static VALUE 58 | <%=c_func(1)%>(VALUE self, VALUE val) 59 | { 60 | ndfunc_arg_in_t ain[2] = {{OVERWRITE,0},{sym_option}}; 61 | ndfunc_t ndf = {<%=c_iter%>, FULL_LOOP, 2,0, ain,0}; 62 | 63 | na_ndloop(&ndf, 2, self, val); 64 | return self; 65 | } 66 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl_bit/format.c: -------------------------------------------------------------------------------- 1 | static VALUE 2 | format_<%=type_name%>(VALUE fmt, dtype x) 3 | { 4 | if (NIL_P(fmt)) { 5 | char s[4]; 6 | int n; 7 | n = m_sprintf(s,x); 8 | return rb_str_new(s,n); 9 | } 10 | return rb_funcall(fmt, '%', 1, m_data_to_num(x)); 11 | } 12 | 13 | static void 14 | <%=c_iter%>(na_loop_t *const lp) 15 | { 16 | size_t i; 17 | BIT_DIGIT *a1, x=0; 18 | size_t p1; 19 | char *p2; 20 | ssize_t s1, s2; 21 | size_t *idx1; 22 | VALUE y; 23 | VALUE fmt = lp->option; 24 | 25 | INIT_COUNTER(lp, i); 26 | INIT_PTR_BIT_IDX(lp, 0, a1, p1, s1, idx1); 27 | INIT_PTR(lp, 1, p2, s2); 28 | 29 | if (idx1) { 30 | for (; i--;) { 31 | LOAD_BIT(a1, p1+*idx1, x); idx1++; 32 | y = format_<%=type_name%>(fmt, x); 33 | SET_DATA_STRIDE(p2, s2, VALUE, y); 34 | } 35 | } else { 36 | for (; i--;) { 37 | LOAD_BIT(a1, p1, x); p1+=s1; 38 | y = format_<%=type_name%>(fmt, x); 39 | SET_DATA_STRIDE(p2, s2, VALUE, y); 40 | } 41 | } 42 | } 43 | 44 | /* 45 | Format elements into strings. 46 | @overload <%=name%> format 47 | @param [String] format 48 | @return [Numo::RObject] array of formatted strings. 49 | */ 50 | static VALUE 51 | <%=c_func(-1)%>(int argc, VALUE *argv, VALUE self) 52 | { 53 | VALUE fmt=Qnil; 54 | 55 | ndfunc_arg_in_t ain[2] = {{Qnil,0},{sym_option}}; 56 | ndfunc_arg_out_t aout[1] = {{numo_cRObject,0}}; 57 | ndfunc_t ndf = {<%=c_iter%>, FULL_LOOP_NIP, 2,1, ain,aout}; 58 | 59 | rb_scan_args(argc, argv, "01", &fmt); 60 | return na_ndloop(&ndf, 2, self, fmt); 61 | } 62 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl_bit/format_to_a.c: -------------------------------------------------------------------------------- 1 | static void 2 | <%=c_iter%>(na_loop_t *const lp) 3 | { 4 | size_t i; 5 | BIT_DIGIT *a1, x=0; 6 | size_t p1; 7 | ssize_t s1; 8 | size_t *idx1; 9 | VALUE y; 10 | VALUE fmt = lp->option; 11 | volatile VALUE a; 12 | 13 | INIT_COUNTER(lp, i); 14 | INIT_PTR_BIT_IDX(lp, 0, a1, p1, s1, idx1); 15 | a = rb_ary_new2(i); 16 | rb_ary_push(lp->args[1].value, a); 17 | if (idx1) { 18 | for (; i--;) { 19 | LOAD_BIT(a1, p1+*idx1, x); idx1++; 20 | y = format_bit(fmt, x); 21 | rb_ary_push(a,y); 22 | } 23 | } else { 24 | for (; i--;) { 25 | LOAD_BIT(a1, p1, x); p1+=s1; 26 | y = format_bit(fmt, x); 27 | rb_ary_push(a,y); 28 | } 29 | } 30 | } 31 | 32 | /* 33 | Format elements into strings. 34 | @overload <%=name%> format 35 | @param [String] format 36 | @return [Array] array of formatted strings. 37 | */ 38 | static VALUE 39 | <%=c_func(-1)%>(int argc, VALUE *argv, VALUE self) 40 | { 41 | VALUE fmt=Qnil; 42 | ndfunc_arg_in_t ain[3] = {{Qnil,0},{sym_loop_opt},{sym_option}}; 43 | ndfunc_arg_out_t aout[1] = {{rb_cArray,0}}; // dummy? 44 | ndfunc_t ndf = {<%=c_iter%>, FULL_LOOP_NIP, 3,1, ain,aout}; 45 | 46 | rb_scan_args(argc, argv, "01", &fmt); 47 | return na_ndloop_cast_narray_to_rarray(&ndf, self, fmt); 48 | } 49 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl_bit/inspect.c: -------------------------------------------------------------------------------- 1 | static VALUE 2 | <%=c_iter%>(char *ptr, size_t pos, VALUE fmt) 3 | { 4 | dtype x; 5 | LOAD_BIT(ptr,pos,x); 6 | return format_<%=type_name%>(fmt, x); 7 | } 8 | 9 | /* 10 | Returns a string containing a human-readable representation of NArray. 11 | @overload inspect 12 | @return [String] 13 | */ 14 | static VALUE 15 | <%=c_func(0)%>(VALUE ary) 16 | { 17 | return na_ndloop_inspect(ary, <%=c_iter%>, Qnil); 18 | } 19 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl_bit/none_p.c: -------------------------------------------------------------------------------- 1 | static VALUE 2 | <%=c_func(-1)%>(int argc, VALUE *argv, VALUE self) 3 | { 4 | VALUE v; 5 | 6 | v = <%=find_tmpl("any?").c_func%>(argc,argv,self); 7 | 8 | if (v==Qtrue) { 9 | return Qfalse; 10 | } else if (v==Qfalse) { 11 | return Qtrue; 12 | } 13 | return <%=find_tmpl("not").c_func%>(v); 14 | } 15 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl_bit/store_array.c: -------------------------------------------------------------------------------- 1 | static void 2 | <%=c_iter%>(na_loop_t *const lp) 3 | { 4 | size_t i, n; 5 | size_t i1, n1; 6 | VALUE v1, *ptr; 7 | BIT_DIGIT *a1; 8 | size_t p1; 9 | size_t s1, *idx1; 10 | VALUE x; 11 | double y; 12 | BIT_DIGIT z; 13 | size_t len, c; 14 | double beg, step; 15 | 16 | INIT_COUNTER(lp, n); 17 | INIT_PTR_BIT_IDX(lp, 0, a1, p1, s1, idx1); 18 | v1 = lp->args[1].value; 19 | i = 0; 20 | 21 | if (lp->args[1].ptr) { 22 | if (v1 == Qtrue) { 23 | iter_<%=type_name%>_store_<%=type_name%>(lp); 24 | i = lp->args[1].shape[0]; 25 | if (idx1) { 26 | idx1 += i; 27 | } else { 28 | p1 += s1 * i; 29 | } 30 | } 31 | goto loop_end; 32 | } 33 | 34 | ptr = &v1; 35 | 36 | switch(TYPE(v1)) { 37 | case T_ARRAY: 38 | n1 = RARRAY_LEN(v1); 39 | ptr = RARRAY_PTR(v1); 40 | break; 41 | case T_NIL: 42 | n1 = 0; 43 | break; 44 | default: 45 | n1 = 1; 46 | } 47 | 48 | if (idx1) { 49 | for (i=i1=0; i1(VALUE self, VALUE rary) 110 | { 111 | ndfunc_arg_in_t ain[2] = {{OVERWRITE,0}, {rb_cArray,0}}; 112 | ndfunc_t ndf = {<%=c_iter%>, FULL_LOOP, 2, 0, ain, 0}; 113 | 114 | na_ndloop_store_rarray(&ndf, self, rary); 115 | return self; 116 | } 117 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl_bit/store_bit.c: -------------------------------------------------------------------------------- 1 | static void 2 | <%=c_iter%>(na_loop_t *const lp) 3 | { 4 | size_t n; 5 | ssize_t p1, p3; 6 | ssize_t s1, s3; 7 | size_t *idx1, *idx3; 8 | int o1, l1, r1, len; 9 | BIT_DIGIT *a1, *a3; 10 | BIT_DIGIT x; 11 | 12 | INIT_COUNTER(lp, n); 13 | INIT_PTR_BIT_IDX(lp, 0, a3, p3, s3, idx3); 14 | INIT_PTR_BIT_IDX(lp, 1, a1, p1, s1, idx1); 15 | if (s1!=1 || s3!=1 || idx1 || idx3) { 16 | for (; n--;) { 17 | LOAD_BIT_STEP(a1, p1, s1, idx1, x); 18 | STORE_BIT_STEP(a3, p3, s3, idx3, x); 19 | } 20 | } else { 21 | a1 += p1/NB; 22 | p1 %= NB; 23 | a3 += p3/NB; 24 | p3 %= NB; 25 | o1 = p1-p3; 26 | l1 = NB+o1; 27 | r1 = NB-o1; 28 | if (p3>0 || n=0) x = *a1>>o1; 32 | else x = *a1<<-o1; 33 | if (p1+len>(ssize_t)NB) x |= *(a1+1)<=NB; n-=NB) { 41 | x = *(a1++); 42 | *(a3++) = x; 43 | } 44 | } else { 45 | for (; n>=NB; n-=NB) { 46 | if (o1==0) { 47 | x = *a1; 48 | } else if (o1>0) { 49 | x = *a1>>o1 | *(a1+1)<>l1; 52 | } 53 | a1++; 54 | *(a3++) = x; 55 | } 56 | } 57 | if (n>0) { 58 | if (o1==0) { 59 | x = *a1; 60 | } else if (o1>0) { 61 | x = *a1>>o1; 62 | if ((int)n>r1) { 63 | x |= *(a1+1)<>l1; 67 | if ((int)n>-o1) { 68 | x |= *a1<<-o1; 69 | } 70 | } 71 | *a3 = (x & SLB(n)) | (*a3 & BALL<(VALUE self, VALUE obj) 78 | { 79 | ndfunc_arg_in_t ain[2] = {{OVERWRITE,0},{Qnil,0}}; 80 | ndfunc_t ndf = {<%=c_iter%>, FULL_LOOP, 2,0, ain,0}; 81 | 82 | na_ndloop(&ndf, 2, self, obj); 83 | return self; 84 | } 85 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl_bit/store_from.c: -------------------------------------------------------------------------------- 1 | static void 2 | <%=c_iter%>(na_loop_t *const lp) 3 | { 4 | ssize_t i, s1, s2; 5 | size_t p1; 6 | char *p2; 7 | size_t *idx1, *idx2; 8 | <%=dtype%> x; 9 | BIT_DIGIT *a1; 10 | BIT_DIGIT y; 11 | 12 | INIT_COUNTER(lp, i); 13 | INIT_PTR_BIT_IDX(lp, 0, a1, p1, s1, idx1); 14 | INIT_PTR_IDX(lp, 1, p2, s2, idx2); 15 | 16 | if (idx2) { 17 | if (idx1) { 18 | for (; i--;) { 19 | GET_DATA_INDEX(p2,idx2,<%=dtype%>,x); 20 | y = <%=macro%>(x); 21 | STORE_BIT(a1, p1+*idx1, y); idx1++; 22 | } 23 | } else { 24 | for (; i--;) { 25 | GET_DATA_INDEX(p2,idx2,<%=dtype%>,x); 26 | y = <%=macro%>(x); 27 | STORE_BIT(a1, p1, y); p1+=s1; 28 | } 29 | } 30 | } else { 31 | if (idx1) { 32 | for (; i--;) { 33 | GET_DATA_STRIDE(p2,s2,<%=dtype%>,x); 34 | y = <%=macro%>(x); 35 | STORE_BIT(a1, p1+*idx1, y); idx1++; 36 | } 37 | } else { 38 | for (; i--;) { 39 | GET_DATA_STRIDE(p2,s2,<%=dtype%>,x); 40 | y = <%=macro%>(x); 41 | STORE_BIT(a1, p1, y); p1+=s1; 42 | } 43 | } 44 | } 45 | } 46 | 47 | 48 | static VALUE 49 | <%=c_func(:nodef)%>(VALUE self, VALUE obj) 50 | { 51 | ndfunc_arg_in_t ain[2] = {{OVERWRITE,0},{Qnil,0}}; 52 | ndfunc_t ndf = {<%=c_iter%>, FULL_LOOP, 2,0, ain,0}; 53 | 54 | na_ndloop(&ndf, 2, self, obj); 55 | return self; 56 | } 57 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl_bit/to_a.c: -------------------------------------------------------------------------------- 1 | static void 2 | <%=c_iter%>(na_loop_t *const lp) 3 | { 4 | size_t i; 5 | BIT_DIGIT *a1; 6 | size_t p1; 7 | ssize_t s1; 8 | size_t *idx1; 9 | BIT_DIGIT x=0; 10 | VALUE a, y; 11 | 12 | INIT_COUNTER(lp, i); 13 | INIT_PTR_BIT_IDX(lp, 0, a1, p1, s1, idx1); 14 | a = rb_ary_new2(i); 15 | rb_ary_push(lp->args[1].value, a); 16 | if (idx1) { 17 | for (; i--;) { 18 | LOAD_BIT(a1,p1+*idx1,x); idx1++; 19 | y = m_data_to_num(x); 20 | rb_ary_push(a,y); 21 | } 22 | } else { 23 | for (; i--;) { 24 | LOAD_BIT(a1,p1,x); p1+=s1; 25 | y = m_data_to_num(x); 26 | rb_ary_push(a,y); 27 | } 28 | } 29 | } 30 | 31 | /* 32 | Convert self to Array. 33 | @overload <%=name%> 34 | @return [Array] 35 | */ 36 | static VALUE 37 | <%=c_func(0)%>(VALUE self) 38 | { 39 | ndfunc_arg_in_t ain[3] = {{Qnil,0},{sym_loop_opt},{sym_option}}; 40 | ndfunc_arg_out_t aout[1] = {{rb_cArray,0}}; // dummy? 41 | ndfunc_t ndf = {<%=c_iter%>, FULL_LOOP_NIP, 3,1, ain,aout}; 42 | return na_ndloop_cast_narray_to_rarray(&ndf, self, Qnil); 43 | } 44 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl_bit/unary.c: -------------------------------------------------------------------------------- 1 | static void 2 | <%=c_iter%>(na_loop_t *const lp) 3 | { 4 | size_t n; 5 | size_t p1, p3; 6 | ssize_t s1, s3; 7 | size_t *idx1, *idx3; 8 | int o1, l1, r1, len; 9 | BIT_DIGIT *a1, *a3; 10 | BIT_DIGIT x; 11 | BIT_DIGIT y; 12 | 13 | INIT_COUNTER(lp, n); 14 | INIT_PTR_BIT_IDX(lp, 0, a1, p1, s1, idx1); 15 | INIT_PTR_BIT_IDX(lp, 1, a3, p3, s3, idx3); 16 | if (s1!=1 || s3!=1 || idx1 || idx3) { 17 | for (; n--;) { 18 | LOAD_BIT_STEP(a1, p1, s1, idx1, x); 19 | y = m_<%=name%>(x); 20 | STORE_BIT_STEP(a3, p3, s3, idx3, y); 21 | } 22 | } else { 23 | a1 += p1/NB; 24 | p1 %= NB; 25 | a3 += p3/NB; 26 | p3 %= NB; 27 | o1 = p1-p3; 28 | l1 = NB+o1; 29 | r1 = NB-o1; 30 | if (p3>0 || n=0) x = *a1>>o1; 34 | else x = *a1<<-o1; 35 | if (p1+len>NB) x |= *(a1+1)<(x); 38 | *a3 = (y & (SLB(len)<=NB; n-=NB) { 44 | x = *(a1++); 45 | y = m_<%=name%>(x); 46 | *(a3++) = y; 47 | } 48 | } else { 49 | for (; n>=NB; n-=NB) { 50 | if (o1==0) { 51 | x = *a1; 52 | } else if (o1>0) { 53 | x = *a1>>o1 | *(a1+1)<>l1; 56 | } 57 | a1++; 58 | y = m_<%=name%>(x); 59 | *(a3++) = y; 60 | } 61 | } 62 | if (n>0) { 63 | if (o1==0) { 64 | x = *a1; 65 | } else if (o1>0) { 66 | x = *a1>>o1; 67 | if ((int)n>r1) { 68 | x |= *(a1+1)<>l1; 72 | if ((int)n>-o1) { 73 | x |= *a1<<-o1; 74 | } 75 | } 76 | y = m_<%=name%>(x); 77 | *a3 = (y & SLB(n)) | (*a3 & BALL<. 84 | @overload <%=name%> 85 | @return [Numo::<%=class_name%>] <%=name%> of self. 86 | */ 87 | static VALUE 88 | <%=c_func(0)%>(VALUE self) 89 | { 90 | ndfunc_arg_in_t ain[1] = {{cT,0}}; 91 | ndfunc_arg_out_t aout[1] = {{cT,0}}; 92 | ndfunc_t ndf = {<%=c_iter%>, FULL_LOOP, 1,1, ain,aout}; 93 | 94 | return na_ndloop(&ndf, 1, self); 95 | } 96 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl_bit/where.c: -------------------------------------------------------------------------------- 1 | typedef struct { 2 | size_t count; 3 | char *idx0; 4 | char *idx1; 5 | size_t elmsz; 6 | } where_opt_t; 7 | 8 | #define STORE_INT(ptr, esz, x) memcpy(ptr,&(x),esz) 9 | 10 | static void 11 | <%=c_iter%>(na_loop_t *const lp) 12 | { 13 | size_t i; 14 | BIT_DIGIT *a; 15 | size_t p; 16 | ssize_t s; 17 | size_t *idx; 18 | BIT_DIGIT x=0; 19 | char *idx1; 20 | size_t count; 21 | size_t e; 22 | where_opt_t *g; 23 | 24 | g = (where_opt_t*)(lp->opt_ptr); 25 | count = g->count; 26 | idx1 = g->idx1; 27 | e = g->elmsz; 28 | INIT_COUNTER(lp, i); 29 | INIT_PTR_BIT_IDX(lp, 0, a, p, s, idx); 30 | if (idx) { 31 | for (; i--;) { 32 | LOAD_BIT(a, p+*idx, x); 33 | idx++; 34 | if (x!=0) { 35 | STORE_INT(idx1,e,count); 36 | idx1 += e; 37 | } 38 | count++; 39 | } 40 | } else { 41 | for (; i--;) { 42 | LOAD_BIT(a, p, x); 43 | p+=s; 44 | if (x!=0) { 45 | STORE_INT(idx1,e,count); 46 | idx1 += e; 47 | } 48 | count++; 49 | } 50 | } 51 | g->count = count; 52 | g->idx1 = idx1; 53 | } 54 | 55 | /* 56 | Returns the array of index where the bit is one (true). 57 | @overload <%=op_map%> 58 | @return [Numo::Int32,Numo::Int64] 59 | */ 60 | static VALUE 61 | <%=c_func(0)%>(VALUE self) 62 | { 63 | volatile VALUE idx_1; 64 | size_t size, n_1; 65 | where_opt_t *g; 66 | 67 | ndfunc_arg_in_t ain[1] = {{cT,0}}; 68 | ndfunc_t ndf = { <%=c_iter%>, FULL_LOOP, 1, 0, ain, 0 }; 69 | 70 | size = RNARRAY_SIZE(self); 71 | n_1 = NUM2SIZET(<%=find_tmpl("count_true").c_func%>(0, NULL, self)); 72 | g = ALLOCA_N(where_opt_t,1); 73 | g->count = 0; 74 | if (size>4294967295ul) { 75 | idx_1 = nary_new(numo_cInt64, 1, &n_1); 76 | g->elmsz = 8; 77 | } else { 78 | idx_1 = nary_new(numo_cInt32, 1, &n_1); 79 | g->elmsz = 4; 80 | } 81 | g->idx1 = na_get_pointer_for_write(idx_1); 82 | g->idx0 = NULL; 83 | na_ndloop3(&ndf, g, 1, self); 84 | na_release_lock(idx_1); 85 | return idx_1; 86 | } 87 | -------------------------------------------------------------------------------- /ext/numo/narray/gen/tmpl_bit/where2.c: -------------------------------------------------------------------------------- 1 | static void 2 | <%=c_iter%>(na_loop_t *const lp) 3 | { 4 | size_t i; 5 | BIT_DIGIT *a; 6 | size_t p; 7 | ssize_t s; 8 | size_t *idx; 9 | BIT_DIGIT x=0; 10 | char *idx0, *idx1; 11 | size_t count; 12 | size_t e; 13 | where_opt_t *g; 14 | 15 | g = (where_opt_t*)(lp->opt_ptr); 16 | count = g->count; 17 | idx0 = g->idx0; 18 | idx1 = g->idx1; 19 | e = g->elmsz; 20 | INIT_COUNTER(lp, i); 21 | INIT_PTR_BIT_IDX(lp, 0, a, p, s, idx); 22 | if (idx) { 23 | for (; i--;) { 24 | LOAD_BIT(a, p+*idx, x); 25 | idx++; 26 | if (x==0) { 27 | STORE_INT(idx0,e,count); 28 | idx0 += e; 29 | } else { 30 | STORE_INT(idx1,e,count); 31 | idx1 += e; 32 | } 33 | count++; 34 | } 35 | } else { 36 | for (; i--;) { 37 | LOAD_BIT(a, p, x); 38 | p+=s; 39 | if (x==0) { 40 | STORE_INT(idx0,e,count); 41 | idx0 += e; 42 | } else { 43 | STORE_INT(idx1,e,count); 44 | idx1 += e; 45 | } 46 | count++; 47 | } 48 | } 49 | g->count = count; 50 | g->idx0 = idx0; 51 | g->idx1 = idx1; 52 | } 53 | 54 | /* 55 | Returns two index arrays. 56 | The first array contains index where the bit is one (true). 57 | The second array contains index where the bit is zero (false). 58 | @overload <%=op_map%> 59 | @return [Numo::Int32,Numo::Int64]*2 60 | */ 61 | static VALUE 62 | <%=c_func(0)%>(VALUE self) 63 | { 64 | VALUE idx_1, idx_0; 65 | size_t size, n_1, n_0; 66 | where_opt_t *g; 67 | 68 | ndfunc_arg_in_t ain[1] = {{cT,0}}; 69 | ndfunc_t ndf = { <%=c_iter%>, FULL_LOOP, 1, 0, ain, 0 }; 70 | 71 | size = RNARRAY_SIZE(self); 72 | n_1 = NUM2SIZET(<%=find_tmpl("count_true").c_func%>(0, NULL, self)); 73 | n_0 = size - n_1; 74 | g = ALLOCA_N(where_opt_t,1); 75 | g->count = 0; 76 | if (size>4294967295ul) { 77 | idx_1 = nary_new(numo_cInt64, 1, &n_1); 78 | idx_0 = nary_new(numo_cInt64, 1, &n_0); 79 | g->elmsz = 8; 80 | } else { 81 | idx_1 = nary_new(numo_cInt32, 1, &n_1); 82 | idx_0 = nary_new(numo_cInt32, 1, &n_0); 83 | g->elmsz = 4; 84 | } 85 | g->idx1 = na_get_pointer_for_write(idx_1); 86 | g->idx0 = na_get_pointer_for_write(idx_0); 87 | na_ndloop3(&ndf, g, 1, self); 88 | na_release_lock(idx_0); 89 | na_release_lock(idx_1); 90 | return rb_assoc_new(idx_1,idx_0); 91 | } 92 | -------------------------------------------------------------------------------- /ext/numo/narray/narray.def: -------------------------------------------------------------------------------- 1 | EXPORTS 2 | Init_narray 3 | nary_new 4 | nary_view_new 5 | nary_debug_info 6 | nary_make_view 7 | nary_element_stride 8 | nary_dtype_element_stride 9 | nary_get_pointer 10 | nary_get_pointer_for_write 11 | nary_get_pointer_for_read 12 | nary_get_pointer_for_read_write 13 | nary_get_offset 14 | nary_copy_flags 15 | nary_check_ladder 16 | nary_check_contiguous 17 | nary_flatten_dim 18 | nary_flatten 19 | nary_dup 20 | nary_store 21 | nary_reduce_dimension 22 | nary_reduce_options 23 | na_ndloop 24 | na_ndloop2 25 | na_ndloop3 26 | na_ndloop4 27 | nary_info_str 28 | nary_test_reduce 29 | -------------------------------------------------------------------------------- /ext/numo/narray/numo/compat.h: -------------------------------------------------------------------------------- 1 | #ifndef COMPAT_H 2 | #define COMPAT_H 3 | 4 | #if !defined RSTRING_LEN 5 | #define RSTRING_LEN(a) RSTRING(a)->len 6 | #endif 7 | #if !defined RSTRING_PTR 8 | #define RSTRING_PTR(a) RSTRING(a)->ptr 9 | #endif 10 | #if !defined RARRAY_LEN 11 | #define RARRAY_LEN(a) RARRAY(a)->len 12 | #endif 13 | #if !defined RARRAY_PTR 14 | #define RARRAY_PTR(a) RARRAY(a)->ptr 15 | #endif 16 | #if !defined RARRAY_AREF 17 | #define RARRAY_AREF(a,i) RARRAY_PTR(a)[i] 18 | #endif 19 | #if !defined RARRAY_ASET 20 | #define RARRAY_ASET(a,i,v) (RARRAY_PTR(a)[i] = v) 21 | #endif 22 | 23 | #endif /* ifndef COMPAT_H */ 24 | -------------------------------------------------------------------------------- /ext/numo/narray/numo/ndloop.h: -------------------------------------------------------------------------------- 1 | /* 2 | ndloop.h 3 | Ruby/Numo::NArray - Numerical Array class for Ruby 4 | Copyright (C) 1999-2020 Masahiro TANAKA 5 | */ 6 | #ifndef NDLOOP_H 7 | #define NDLOOP_H 8 | 9 | typedef struct NA_LOOP_ITER { 10 | ssize_t pos; // - required for each dimension. 11 | ssize_t step; 12 | size_t *idx; 13 | } na_loop_iter_t; 14 | 15 | typedef struct NA_LOOP_ARGS { 16 | VALUE value; 17 | ssize_t elmsz; 18 | char *ptr; 19 | //char *buf_ptr; // 20 | int ndim; // required for each argument. 21 | // ssize_t pos; - not required here. 22 | size_t *shape; 23 | na_loop_iter_t *iter; // moved from na_loop_t 24 | } na_loop_args_t; 25 | 26 | // pass this structure to user iterator 27 | typedef struct NA_LOOP { 28 | int narg; 29 | int ndim; // n of user dimension - required for each iterator. 30 | size_t *n; // n of elements for each dim (=shape) 31 | na_loop_args_t *args; // for each arg 32 | VALUE option; 33 | void *opt_ptr; 34 | VALUE err_type; 35 | } na_loop_t; 36 | 37 | 38 | // ------------------ ndfunc ------------------------------------------- 39 | 40 | #define NDF_HAS_LOOP (1<<0) // x[i] 41 | #define NDF_STRIDE_LOOP (1<<1) // *(x+stride*i) 42 | #define NDF_INDEX_LOOP (1<<2) // *(x+idx[i]) 43 | #define NDF_KEEP_DIM (1<<3) 44 | #define NDF_INPLACE (1<<4) 45 | #define NDF_ACCEPT_BYTESWAP (1<<5) 46 | 47 | #define NDF_FLAT_REDUCE (1<<6) 48 | #define NDF_EXTRACT (1<<7) 49 | #define NDF_CUM (1<<8) 50 | 51 | #define FULL_LOOP (NDF_HAS_LOOP|NDF_STRIDE_LOOP|NDF_INDEX_LOOP|NDF_INPLACE) 52 | #define FULL_LOOP_NIP (NDF_HAS_LOOP|NDF_STRIDE_LOOP|NDF_INDEX_LOOP) 53 | #define STRIDE_LOOP (NDF_HAS_LOOP|NDF_STRIDE_LOOP|NDF_INPLACE) 54 | #define STRIDE_LOOP_NIP (NDF_HAS_LOOP|NDF_STRIDE_LOOP) 55 | #define NO_LOOP 0 56 | 57 | #define OVERWRITE Qtrue // used for CASTABLE(t) 58 | 59 | #define NDF_TEST(nf,fl) ((nf)->flag & (fl)) 60 | #define NDF_SET(nf,fl) {(nf)->flag |= (fl);} 61 | 62 | #define NDF_ARG_READ_ONLY 1 63 | #define NDF_ARG_WRITE_ONLY 2 64 | #define NDF_ARG_READ_WRITE 3 65 | 66 | // type of user function 67 | typedef void (*na_iter_func_t) _((na_loop_t *const)); 68 | typedef VALUE (*na_text_func_t) _((char *ptr, size_t pos, VALUE opt)); 69 | //typedef void (*) void (*loop_func)(ndfunc_t*, na_md_loop_t*)) 70 | 71 | 72 | typedef struct NDF_ARG_IN { 73 | VALUE type; // argument types 74 | int dim; // # of dimension of argument handled by user function 75 | // if dim==-1, reduce dimension 76 | } ndfunc_arg_in_t; 77 | 78 | typedef struct NDF_ARG_OUT { 79 | VALUE type; // argument types 80 | int dim; // # of dimension of argument handled by user function 81 | size_t *shape; 82 | } ndfunc_arg_out_t; 83 | 84 | // spec of user function 85 | typedef struct NDFUNCTION { 86 | na_iter_func_t func; // user function 87 | unsigned int flag; // what kind of loop user function supports 88 | int nin; // # of arguments 89 | int nout; // # of results 90 | ndfunc_arg_in_t *ain; // spec of input arguments 91 | ndfunc_arg_out_t *aout; // spec of output result 92 | } ndfunc_t; 93 | 94 | #endif /* NDLOOP_H */ 95 | -------------------------------------------------------------------------------- /ext/numo/narray/numo/types/bit.h: -------------------------------------------------------------------------------- 1 | typedef BIT_DIGIT dtype; 2 | typedef BIT_DIGIT rtype; 3 | #define cT numo_cBit 4 | #define cRT cT 5 | 6 | #define m_zero 0 7 | #define m_one 1 8 | 9 | #define m_abs(x) (x) 10 | #define m_sign(x) (((x)==0) ? 0:1) 11 | 12 | #define m_from_double(x) (((x)==0) ? 0 : 1) 13 | #define m_from_real(x) (((x)==0) ? 0 : 1) 14 | #define m_from_sint(x) (((x)==0) ? 0 : 1) 15 | #define m_from_int32(x) (((x)==0) ? 0 : 1) 16 | #define m_from_int64(x) (((x)==0) ? 0 : 1) 17 | #define m_from_uint32(x) (((x)==0) ? 0 : 1) 18 | #define m_from_uint64(x) (((x)==0) ? 0 : 1) 19 | #define m_data_to_num(x) INT2FIX(x) 20 | #define m_sprintf(s,x) sprintf(s,"%1d",(int)(x)) 21 | 22 | #define m_copy(x) (x) 23 | #define m_not(x) (~(x)) 24 | #define m_and(x,y) ((x)&(y)) 25 | #define m_or(x,y) ((x)|(y)) 26 | #define m_xor(x,y) ((x)^(y)) 27 | #define m_eq(x,y) (~((x)^(y))) 28 | #define m_count_true(x) ((x)!=0) 29 | #define m_count_false(x) ((x)==0) 30 | 31 | static inline BIT_DIGIT m_num_to_data(VALUE num) { 32 | if (RTEST(num)) { 33 | if (!RTEST(rb_equal(num,INT2FIX(0)))) { 34 | return 1; 35 | } 36 | } 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /ext/numo/narray/numo/types/dcomplex.h: -------------------------------------------------------------------------------- 1 | typedef dcomplex dtype; 2 | typedef double rtype; 3 | #define cT numo_cDComplex 4 | #define cRT numo_cDFloat 5 | #define mTM numo_mDComplexMath 6 | 7 | #include "complex_macro.h" 8 | 9 | static inline bool c_nearly_eq(dtype x, dtype y) { 10 | return c_abs(c_sub(x,y)) <= (c_abs(x)+c_abs(y))*DBL_EPSILON*2; 11 | } 12 | 13 | #ifdef SFMT_H 14 | /* generates a random number on [0,1)-real-interval */ 15 | inline static dtype m_rand(dtype max) 16 | { 17 | dtype z; 18 | REAL(z) = genrand_res53_mix() * REAL(max); 19 | IMAG(z) = genrand_res53_mix() * IMAG(max); 20 | return z; 21 | } 22 | 23 | /* generates random numbers from the normal distribution 24 | using Box-Muller Transformation. 25 | */ 26 | inline static void m_rand_norm(dtype mu, rtype sigma, dtype *a0) 27 | { 28 | rtype x1, x2, w; 29 | do { 30 | x1 = genrand_res53_mix(); 31 | x1 = x1*2-1; 32 | x2 = genrand_res53_mix(); 33 | x2 = x2*2-1; 34 | w = x1 * x1 + x2 * x2; 35 | } while (w>=1); 36 | w = sqrt( (-2*log(w)) / w ); 37 | REAL(*a0) = x1*w * sigma + REAL(mu); 38 | IMAG(*a0) = x2*w * sigma + IMAG(mu); 39 | } 40 | #endif 41 | 42 | #define M_EPSILON rb_float_new(2.2204460492503131e-16) 43 | #define M_MIN rb_float_new(2.2250738585072014e-308) 44 | #define M_MAX rb_float_new(1.7976931348623157e+308) 45 | -------------------------------------------------------------------------------- /ext/numo/narray/numo/types/dfloat.h: -------------------------------------------------------------------------------- 1 | typedef double dtype; 2 | typedef double rtype; 3 | #define cT numo_cDFloat 4 | #define cRT numo_cDFloat 5 | #define mTM numo_mDFloatMath 6 | 7 | #include "float_macro.h" 8 | 9 | #ifdef SFMT_H 10 | /* generates a random number on [0,1)-real-interval */ 11 | inline static dtype m_rand(dtype max) 12 | { 13 | return genrand_res53_mix() * max; 14 | } 15 | 16 | /* generates random numbers from the normal distribution 17 | using Box-Muller Transformation. 18 | */ 19 | inline static void m_rand_norm(dtype mu, dtype sigma, dtype *a0, dtype *a1) 20 | { 21 | dtype x1, x2, w; 22 | do { 23 | x1 = genrand_res53_mix(); 24 | x1 = x1*2-1; 25 | x2 = genrand_res53_mix(); 26 | x2 = x2*2-1; 27 | w = x1 * x1 + x2 * x2; 28 | } while (w>=1); 29 | w = sqrt( (-2*log(w)) / w ); 30 | if (a0) {*a0 = x1*w * sigma + mu;} 31 | if (a1) {*a1 = x2*w * sigma + mu;} 32 | } 33 | #endif 34 | 35 | #define m_min_init numo_dfloat_new_dim0(0.0/0.0) 36 | #define m_max_init numo_dfloat_new_dim0(0.0/0.0) 37 | #define m_extract(x) rb_float_new(*(double*)x) 38 | #define m_nearly_eq(x,y) (fabs(x-y)<=(fabs(x)+fabs(y))*DBL_EPSILON*2) 39 | 40 | #define M_EPSILON rb_float_new(2.2204460492503131e-16) 41 | #define M_MIN rb_float_new(2.2250738585072014e-308) 42 | #define M_MAX rb_float_new(1.7976931348623157e+308) 43 | -------------------------------------------------------------------------------- /ext/numo/narray/numo/types/float_def.h: -------------------------------------------------------------------------------- 1 | #ifndef DBL_EPSILON 2 | #define DBL_EPSILON 2.2204460492503131e-16 3 | #endif 4 | #ifndef FLT_EPSILON 5 | #define FLT_EPSILON 1.1920928955078125e-07 6 | #endif 7 | #ifndef DBL_MAX 8 | #define DBL_MAX 1.7976931348623157e+308 9 | #endif 10 | #ifndef DBL_MAX 11 | #define DBL_MAX 1.7976931348623157e+308 12 | #endif 13 | #ifndef FLT_MIN 14 | #define FLT_MIN 1.1754943508222875e-38 15 | #endif 16 | #ifndef FLT_MAX 17 | #define FLT_MAX 3.4028234663852886e+38 18 | #endif 19 | 20 | #ifndef M_PI_2 21 | #define M_PI_2 1.57079632679489661923 /* pi/2 */ 22 | #endif 23 | #ifndef M_LOG2E 24 | #define M_LOG2E 1.4426950408889634074 /* log_2 e */ 25 | #endif 26 | #ifndef M_LOG10E 27 | #define M_LOG10E 0.43429448190325182765 /* log_10 e */ 28 | #endif 29 | #ifndef M_LN2 30 | #define M_LN2 0.69314718055994530942 /* log_e 2 */ 31 | #endif 32 | #ifndef M_LN10 33 | #define M_LN10 2.30258509299404568402 /* log_e 10 */ 34 | #endif 35 | -------------------------------------------------------------------------------- /ext/numo/narray/numo/types/int16.h: -------------------------------------------------------------------------------- 1 | typedef int16_t dtype; 2 | typedef int16_t rtype; 3 | #define cT numo_cInt16 4 | #define cRT cT 5 | 6 | #define m_num_to_data(x) ((dtype)NUM2INT(x)) 7 | #if SIZEOF_INT > 2 8 | #define m_data_to_num(x) INT2FIX(x) 9 | #else 10 | #define m_data_to_num(x) INT2NUM(x) 11 | #endif 12 | #define m_sprintf(s,x) sprintf(s,"%d",(int)(x)) 13 | 14 | #ifndef INT16_MIN 15 | #define INT16_MIN (-32767-1) 16 | #endif 17 | #ifndef INT16_MAX 18 | #define INT16_MAX (32767) 19 | #endif 20 | 21 | #define DATA_MIN INT16_MIN 22 | #define DATA_MAX INT16_MAX 23 | 24 | #define M_MIN m_data_to_num(INT16_MIN) 25 | #define M_MAX m_data_to_num(INT16_MAX) 26 | 27 | #include "int_macro.h" 28 | -------------------------------------------------------------------------------- /ext/numo/narray/numo/types/int32.h: -------------------------------------------------------------------------------- 1 | typedef int32_t dtype; 2 | typedef int32_t rtype; 3 | #define cT numo_cInt32 4 | #define cRT cT 5 | 6 | #define m_num_to_data(x) ((dtype)NUM2INT32(x)) 7 | #define m_data_to_num(x) INT322NUM((int32_t)(x)) 8 | #define m_sprintf(s,x) sprintf(s,"%"PRId32,(int32_t)(x)) 9 | 10 | #ifndef INT32_MIN 11 | #define INT32_MIN (-2147483647-1) 12 | #endif 13 | #ifndef INT32_MAX 14 | #define INT32_MAX (2147483647) 15 | #endif 16 | 17 | #define DATA_MIN INT32_MIN 18 | #define DATA_MAX INT32_MAX 19 | 20 | #define M_MIN m_data_to_num(INT32_MIN) 21 | #define M_MAX m_data_to_num(INT32_MAX) 22 | 23 | #include "int_macro.h" 24 | -------------------------------------------------------------------------------- /ext/numo/narray/numo/types/int64.h: -------------------------------------------------------------------------------- 1 | typedef int64_t dtype; 2 | typedef int64_t rtype; 3 | #define cT numo_cInt64 4 | #define cRT cT 5 | 6 | #define m_num_to_data(x) ((dtype)NUM2INT64(x)) 7 | #define m_data_to_num(x) INT642NUM((int64_t)(x)) 8 | #define m_sprintf(s,x) sprintf(s,"%"PRId64,(int64_t)(x)) 9 | 10 | #ifndef INT64_MIN 11 | #define INT64_MIN (-9223372036854775807l-1) 12 | #endif 13 | #ifndef INT64_MAX 14 | #define INT64_MAX (9223372036854775807l) 15 | #endif 16 | 17 | #define DATA_MIN INT64_MIN 18 | #define DATA_MAX INT64_MAX 19 | 20 | #define M_MIN m_data_to_num(INT64_MIN) 21 | #define M_MAX m_data_to_num(INT64_MAX) 22 | 23 | #include "int_macro.h" 24 | -------------------------------------------------------------------------------- /ext/numo/narray/numo/types/int8.h: -------------------------------------------------------------------------------- 1 | typedef int8_t dtype; 2 | typedef int8_t rtype; 3 | #define cT numo_cInt8 4 | #define cRT cT 5 | 6 | #define m_num_to_data(x) ((dtype)NUM2INT(x)) 7 | #define m_data_to_num(x) INT2FIX(x) 8 | #define m_sprintf(s,x) sprintf(s,"%d",(int)(x)) 9 | 10 | #ifndef INT8_MIN 11 | #define INT8_MIN (-127-1) 12 | #endif 13 | #ifndef INT8_MAX 14 | #define INT8_MAX (127) 15 | #endif 16 | 17 | #define DATA_MIN INT8_MIN 18 | #define DATA_MAX INT8_MAX 19 | 20 | #define M_MIN INT2FIX(INT8_MIN) 21 | #define M_MAX INT2FIX(INT8_MAX) 22 | 23 | #include "int_macro.h" 24 | -------------------------------------------------------------------------------- /ext/numo/narray/numo/types/int_macro.h: -------------------------------------------------------------------------------- 1 | #include "xint_macro.h" 2 | 3 | #define m_sign(x) (((x)==0) ? 0 : (((x)>0) ? 1 : -1)) 4 | 5 | static inline dtype m_abs(dtype x) { 6 | if (x==DATA_MIN) { 7 | rb_raise(nary_eValueError, "cannot convert the minimum integer"); 8 | } 9 | return (x<0)?-x:x; 10 | } 11 | 12 | static inline dtype int_reciprocal(dtype x) { 13 | switch (x) { 14 | case 1: 15 | return 1; 16 | case -1: 17 | return -1; 18 | case 0: 19 | rb_raise(rb_eZeroDivError, "divided by 0"); 20 | default: 21 | return 0; 22 | } 23 | } 24 | 25 | static dtype pow_int(dtype x, int p) 26 | { 27 | dtype r = m_one; 28 | switch(p) { 29 | case 0: return 1; 30 | case 1: return x; 31 | case 2: return x*x; 32 | case 3: return x*x*x; 33 | } 34 | if (p<0) return 0; 35 | while (p) { 36 | if (p&1) r *= x; 37 | x *= x; 38 | p >>= 1; 39 | } 40 | return r; 41 | } 42 | 43 | static inline int64_t f_sum(size_t n, char *p, ssize_t stride) 44 | { 45 | int64_t x,y=0; 46 | size_t i=n; 47 | for (; i--;) { 48 | x = *(dtype*)p; 49 | y += x; 50 | p += stride; 51 | } 52 | return y; 53 | } 54 | 55 | static inline int64_t f_prod(size_t n, char *p, ssize_t stride) 56 | { 57 | int64_t x,y=1; 58 | size_t i=n; 59 | for (; i--;) { 60 | x = *(dtype*)p; 61 | y *= x; 62 | p += stride; 63 | } 64 | return y; 65 | } 66 | -------------------------------------------------------------------------------- /ext/numo/narray/numo/types/robj_macro.h: -------------------------------------------------------------------------------- 1 | #define m_zero INT2FIX(0) 2 | #define m_one INT2FIX(1) 3 | 4 | #define m_num_to_data(x) (x) 5 | #define m_data_to_num(x) (x) 6 | 7 | #define m_from_double(x) rb_float_new(x) 8 | #define m_from_real(x) rb_float_new(x) 9 | #define m_from_sint(x) INT2FIX(x) 10 | #define m_from_int32(x) INT322NUM(x) 11 | #define m_from_int64(x) INT642NUM(x) 12 | #define m_from_uint32(x) UINT322NUM(x) 13 | #define m_from_uint64(x) UINT642NUM(x) 14 | 15 | #define m_add(x,y) rb_funcall(x,'+',1,y) 16 | #define m_sub(x,y) rb_funcall(x,'-',1,y) 17 | #define m_mul(x,y) rb_funcall(x,'*',1,y) 18 | #define m_div(x,y) rb_funcall(x,'/',1,y) 19 | #define m_mod(x,y) rb_funcall(x,'%',1,y) 20 | #define m_divmod(x,y,a,b) \ 21 | {x = rb_funcall(x,id_divmod,1,y); \ 22 | a = RARRAY_PTR(x)[0]; b = RARRAY_PTR(x)[0];} 23 | #define m_pow(x,y) rb_funcall(x,id_pow,1,y) 24 | #define m_pow_int(x,y) rb_funcall(x,id_pow,1,y) 25 | 26 | #define m_abs(x) rb_funcall(x,id_abs,0) 27 | #define m_minus(x) rb_funcall(x,id_minus,0) 28 | #define m_reciprocal(x) rb_funcall(x,id_reciprocal,0) 29 | #define m_square(x) rb_funcall(x,'*',1,x) 30 | #define m_floor(x) rb_funcall(x,id_floor,0) 31 | #define m_round(x) rb_funcall(x,id_round,0) 32 | #define m_ceil(x) rb_funcall(x,id_ceil,0) 33 | #define m_trunc(x) rb_funcall(x,id_truncate,0) 34 | #define m_sign(x) rb_funcall(x,id_ufo,1,INT2FIX(0)) 35 | 36 | #define m_eq(x,y) RTEST(rb_funcall(x,id_eq,1,y)) 37 | #define m_ne(x,y) RTEST(rb_funcall(x,id_ne,1,y)) 38 | #define m_gt(x,y) RTEST(rb_funcall(x,id_gt,1,y)) 39 | #define m_ge(x,y) RTEST(rb_funcall(x,id_ge,1,y)) 40 | #define m_lt(x,y) RTEST(rb_funcall(x,id_lt,1,y)) 41 | #define m_le(x,y) RTEST(rb_funcall(x,id_le,1,y)) 42 | 43 | #define m_bit_and(x,y) rb_funcall(x,id_bit_and,1,y) 44 | #define m_bit_or(x,y) rb_funcall(x,id_bit_or, 1,y) 45 | #define m_bit_xor(x,y) rb_funcall(x,id_bit_xor,1,y) 46 | #define m_bit_not(x) rb_funcall(x,id_bit_not,0) 47 | 48 | #define m_left_shift(x,y) rb_funcall(x,id_left_shift,1,y) 49 | #define m_right_shift(x,y) rb_funcall(x,id_right_shift,1,y) 50 | 51 | #define m_isnan(x) ((rb_respond_to(x,id_nan_p)) ? RTEST(rb_funcall(x,id_nan_p,0)) : 0) 52 | #define m_isinf(x) ((rb_respond_to(x,id_infinite_p)) ? RTEST(rb_funcall(x,id_infinite_p,0)) : 0) 53 | #define m_isposinf(x) ((rb_respond_to(x,id_infinite_p)) ? \ 54 | ((RTEST(rb_funcall(x,id_infinite_p,0))) ? \ 55 | m_gt(x,INT2FIX(0)) : 0) : 0) 56 | #define m_isneginf(x) ((rb_respond_to(x,id_infinite_p)) ? \ 57 | ((RTEST(rb_funcall(x,id_infinite_p,0))) ? \ 58 | m_lt(x,INT2FIX(0)) : 0) : 0) 59 | #define m_isfinite(x) ((rb_respond_to(x,id_finite_p)) ? RTEST(rb_funcall(x,id_finite_p,0)) : 0) 60 | 61 | #define m_mulsum_init INT2FIX(0) 62 | 63 | #define m_sprintf(s,x) robj_sprintf(s,x) 64 | 65 | static inline int robj_sprintf(char *s, VALUE x) { 66 | VALUE v = rb_funcall(x,rb_intern("to_s"),0); 67 | return sprintf(s,"%s",StringValuePtr(v)); 68 | } 69 | 70 | #define m_sqrt(x) \ 71 | rb_funcall(rb_const_get(rb_mKernel,rb_intern("Math")), \ 72 | rb_intern("sqrt"),1,x); 73 | 74 | static inline dtype f_seq(dtype x, dtype y, size_t c) 75 | { 76 | y = m_mul(y,SIZET2NUM(c)); 77 | return m_add(x,y); 78 | } 79 | 80 | #include "real_accum.h" 81 | -------------------------------------------------------------------------------- /ext/numo/narray/numo/types/robject.h: -------------------------------------------------------------------------------- 1 | typedef VALUE dtype; 2 | typedef VALUE rtype; 3 | #define cT numo_cRObject 4 | #define cRT cT 5 | //#define mTM mRObjectMath 6 | 7 | #include "float_def.h" 8 | #include "robj_macro.h" 9 | 10 | #define m_min_init (0.0/0.0) 11 | #define m_max_init (0.0/0.0) 12 | #define m_extract(x) (*(VALUE*)x) 13 | #define m_nearly_eq(x,y) robj_nearly_eq(x,y) 14 | 15 | inline static int robj_nearly_eq(VALUE vx, VALUE vy) 16 | { 17 | double x, y; 18 | x = NUM2DBL(vx); 19 | y = NUM2DBL(vy); 20 | return (fabs(x-y)<=(fabs(x)+fabs(y))*DBL_EPSILON*2); 21 | } 22 | 23 | /* generates a random number on [0,1)-real-interval */ 24 | inline static dtype m_rand(dtype max) 25 | { 26 | return DBL2NUM(genrand_res53_mix() * max); 27 | } 28 | -------------------------------------------------------------------------------- /ext/numo/narray/numo/types/scomplex.h: -------------------------------------------------------------------------------- 1 | typedef scomplex dtype; 2 | typedef float rtype; 3 | #define cT numo_cSComplex 4 | #define cRT numo_cSFloat 5 | #define mTM numo_mSComplexMath 6 | 7 | #include "complex_macro.h" 8 | 9 | static inline bool c_nearly_eq(dtype x, dtype y) { 10 | return c_abs(c_sub(x,y)) <= (c_abs(x)+c_abs(y))*FLT_EPSILON*2; 11 | } 12 | 13 | #ifdef SFMT_H 14 | /* generates a random number on [0,1)-real-interval */ 15 | inline static dtype m_rand(dtype max) 16 | { 17 | dtype z; 18 | REAL(z) = to_real2(gen_rand32()) * REAL(max); 19 | IMAG(z) = to_real2(gen_rand32()) * IMAG(max); 20 | return z; 21 | } 22 | 23 | /* generates random numbers from the normal distribution 24 | using Box-Muller Transformation. 25 | */ 26 | inline static void m_rand_norm(dtype mu, rtype sigma, dtype *a0) 27 | { 28 | rtype x1, x2, w; 29 | do { 30 | x1 = to_real2(gen_rand32()); 31 | x1 = x1*2-1; 32 | x2 = to_real2(gen_rand32()); 33 | x2 = x2*2-1; 34 | w = x1 * x1 + x2 * x2; 35 | } while (w>=1); 36 | w = sqrt( (-2*log(w)) / w ); 37 | REAL(*a0) = x1*w * sigma + REAL(mu); 38 | IMAG(*a0) = x2*w * sigma + IMAG(mu); 39 | } 40 | #endif 41 | 42 | #define M_EPSILON rb_float_new(1.1920928955078125e-07) 43 | #define M_MIN rb_float_new(1.1754943508222875e-38) 44 | #define M_MAX rb_float_new(3.4028234663852886e+38) 45 | -------------------------------------------------------------------------------- /ext/numo/narray/numo/types/sfloat.h: -------------------------------------------------------------------------------- 1 | typedef float dtype; 2 | typedef float rtype; 3 | #define cT numo_cSFloat 4 | #define cRT numo_cSFloat 5 | #define mTM numo_mSFloatMath 6 | 7 | #include "float_macro.h" 8 | 9 | #ifdef SFMT_H 10 | /* generates a random number on [0,1)-real-interval */ 11 | inline static dtype m_rand(dtype max) 12 | { 13 | return to_real2(gen_rand32()) * max; 14 | } 15 | 16 | /* generates random numbers from the normal distribution 17 | using Box-Muller Transformation. 18 | */ 19 | inline static void m_rand_norm(dtype mu, dtype sigma, dtype *a0, dtype *a1) 20 | { 21 | dtype x1, x2, w; 22 | do { 23 | x1 = to_real2(gen_rand32()); 24 | x1 = x1*2-1; 25 | x2 = to_real2(gen_rand32()); 26 | x2 = x2*2-1; 27 | w = x1 * x1 + x2 * x2; 28 | } while (w>=1); 29 | w = sqrt( (-2*log(w)) / w ); 30 | if (a0) {*a0 = x1*w * sigma + mu;} 31 | if (a1) {*a1 = x2*w * sigma + mu;} 32 | } 33 | #endif 34 | 35 | #define m_min_init numo_sfloat_new_dim0(0.0/0.0) 36 | #define m_max_init numo_sfloat_new_dim0(0.0/0.0) 37 | 38 | #define m_extract(x) rb_float_new(*(float*)x) 39 | #define m_nearly_eq(x,y) (fabs(x-y)<=(fabs(x)+fabs(y))*FLT_EPSILON*2) 40 | 41 | #define M_EPSILON rb_float_new(1.1920928955078125e-07) 42 | #define M_MIN rb_float_new(1.1754943508222875e-38) 43 | #define M_MAX rb_float_new(3.4028234663852886e+38) 44 | -------------------------------------------------------------------------------- /ext/numo/narray/numo/types/uint16.h: -------------------------------------------------------------------------------- 1 | typedef u_int16_t dtype; 2 | typedef u_int16_t rtype; 3 | #define cT numo_cUInt16 4 | #define cRT cT 5 | 6 | #define m_num_to_data(x) ((dtype)NUM2UINT(x)) 7 | #if SIZEOF_INT > 2 8 | #define m_data_to_num(x) INT2FIX(x) 9 | #else 10 | #define m_data_to_num(x) UINT2NUM(x) 11 | #endif 12 | #define m_sprintf(s,x) sprintf(s,"%u",(unsigned int)(x)) 13 | 14 | #ifndef UINT16_MAX 15 | #define UINT16_MAX (65535) 16 | #endif 17 | 18 | #define DATA_MIN UINT16_MIN 19 | #define DATA_MAX UINT16_MAX 20 | 21 | #define M_MIN INT2FIX(0) 22 | #define M_MAX m_data_to_num(UINT16_MAX) 23 | 24 | #include "uint_macro.h" 25 | -------------------------------------------------------------------------------- /ext/numo/narray/numo/types/uint32.h: -------------------------------------------------------------------------------- 1 | typedef u_int32_t dtype; 2 | typedef u_int32_t rtype; 3 | #define cT numo_cUInt32 4 | #define cRT cT 5 | 6 | #define m_num_to_data(x) ((dtype)NUM2UINT32(x)) 7 | #define m_data_to_num(x) UINT322NUM((u_int32_t)(x)) 8 | #define m_sprintf(s,x) sprintf(s,"%"PRIu32,(u_int32_t)(x)) 9 | 10 | #ifndef UINT32_MAX 11 | #define UINT32_MAX (4294967295u) 12 | #endif 13 | 14 | #define DATA_MIN UINT32_MIN 15 | #define DATA_MAX UINT32_MAX 16 | 17 | #define M_MIN INT2FIX(0) 18 | #define M_MAX m_data_to_num(UINT32_MAX) 19 | 20 | #include "uint_macro.h" 21 | -------------------------------------------------------------------------------- /ext/numo/narray/numo/types/uint64.h: -------------------------------------------------------------------------------- 1 | typedef u_int64_t dtype; 2 | typedef u_int64_t rtype; 3 | #define cT numo_cUInt64 4 | #define cRT cT 5 | 6 | #define m_num_to_data(x) ((dtype)NUM2UINT64(x)) 7 | #define m_data_to_num(x) UINT642NUM((u_int64_t)(x)) 8 | #define m_sprintf(s,x) sprintf(s,"%"PRIu64,(u_int64_t)(x)) 9 | 10 | #ifndef UINT64_MAX 11 | #define UINT64_MAX (18446744073709551615ul) 12 | #endif 13 | 14 | #define DATA_MIN UINT64_MIN 15 | #define DATA_MAX UINT64_MAX 16 | 17 | #define M_MIN INT2FIX(0) 18 | #define M_MAX m_data_to_num(UINT64_MAX) 19 | 20 | #include "uint_macro.h" 21 | -------------------------------------------------------------------------------- /ext/numo/narray/numo/types/uint8.h: -------------------------------------------------------------------------------- 1 | typedef u_int8_t dtype; 2 | typedef u_int8_t rtype; 3 | #define cT numo_cUInt8 4 | #define cRT cT 5 | 6 | #define m_num_to_data(x) ((dtype)NUM2UINT(x)) 7 | #define m_data_to_num(x) INT2FIX(x) 8 | #define m_sprintf(s,x) sprintf(s,"%u",(unsigned int)(x)) 9 | 10 | #ifndef UINT8_MAX 11 | #define UINT8_MAX (255) 12 | #endif 13 | 14 | #define DATA_MIN UINT8_MIN 15 | #define DATA_MAX UINT8_MAX 16 | 17 | #define M_MIN INT2FIX(0) 18 | #define M_MAX m_data_to_num(UINT8_MAX) 19 | 20 | #include "uint_macro.h" 21 | -------------------------------------------------------------------------------- /ext/numo/narray/numo/types/uint_macro.h: -------------------------------------------------------------------------------- 1 | #include "xint_macro.h" 2 | 3 | #define m_abs(x) (x) 4 | #define m_sign(x) (((x)==0) ? 0:1) 5 | 6 | static inline dtype int_reciprocal(dtype x) { 7 | switch (x) { 8 | case 1: 9 | return 1; 10 | case 0: 11 | rb_raise(rb_eZeroDivError, "divided by 0"); 12 | default: 13 | return 0; 14 | } 15 | } 16 | 17 | static dtype pow_int(dtype x, int p) 18 | { 19 | dtype r = m_one; 20 | switch(p) { 21 | case 0: return 1; 22 | case 1: return x; 23 | case 2: return x*x; 24 | case 3: return x*x*x; 25 | } 26 | while (p) { 27 | if (p&1) r *= x; 28 | x *= x; 29 | p >>= 1; 30 | } 31 | return r; 32 | } 33 | 34 | static inline u_int64_t f_sum(size_t n, char *p, ssize_t stride) 35 | { 36 | u_int64_t x,y=0; 37 | size_t i=n; 38 | for (; i--;) { 39 | x = *(dtype*)p; 40 | y += x; 41 | p += stride; 42 | } 43 | return y; 44 | } 45 | 46 | static inline u_int64_t f_prod(size_t n, char *p, ssize_t stride) 47 | { 48 | u_int64_t x,y=1; 49 | size_t i=n; 50 | for (; i--;) { 51 | x = *(dtype*)p; 52 | y *= x; 53 | p += stride; 54 | } 55 | return y; 56 | } 57 | -------------------------------------------------------------------------------- /ext/numo/narray/rand.c: -------------------------------------------------------------------------------- 1 | #include "ruby.h" 2 | #include "numo/narray.h" 3 | #include "SFMT.h" 4 | 5 | #ifdef HAVE_UNISTD_H 6 | #include 7 | #endif 8 | #include 9 | #ifdef HAVE_SYS_TIME_H 10 | #include 11 | #endif 12 | 13 | static u_int64_t 14 | random_seed(void) 15 | { 16 | static int n = 0; 17 | struct timeval tv; 18 | 19 | gettimeofday(&tv, 0); 20 | return tv.tv_sec ^ tv.tv_usec ^ getpid() ^ n++; 21 | } 22 | 23 | static VALUE 24 | nary_s_srand(int argc, VALUE *argv, VALUE obj) 25 | { 26 | VALUE vseed; 27 | u_int64_t seed; 28 | 29 | //rb_secure(4); 30 | if (rb_scan_args(argc, argv, "01", &vseed) == 0) { 31 | seed = random_seed(); 32 | } 33 | else { 34 | seed = NUM2UINT64(vseed); 35 | } 36 | init_gen_rand(seed); 37 | 38 | return Qnil; 39 | } 40 | 41 | void 42 | Init_nary_rand(void) { 43 | rb_define_singleton_method(cNArray, "srand", nary_s_srand, -1); 44 | init_gen_rand(0); 45 | } 46 | -------------------------------------------------------------------------------- /fft/README.md: -------------------------------------------------------------------------------- 1 | # Ruby wrapper of Ooura's FFT 2 | 3 | ## Ooura's FFT package 4 | * General Purpose FFT (Fast Fourier/Cosine/Sine Transform) Package 5 | * Author: Dr. Takuya OOURA 6 | * Visit [web site](http://www.kurims.kyoto-u.ac.jp/~ooura/fft.html) 7 | 8 | ## Ruby wrapper 9 | * [GitHub](https://github.com/masa16/narray-devel/tree/master/fft) 10 | (in narray-devel) 11 | -------------------------------------------------------------------------------- /fft/depend: -------------------------------------------------------------------------------- 1 | fft.c: fft.erb.c fft_tmpl.rb 2 | erb -T- fft.erb.c > fft.c 3 | 4 | doc: fft.c README.md 5 | yard -r README.md fft.c 6 | -------------------------------------------------------------------------------- /fft/extconf.rb: -------------------------------------------------------------------------------- 1 | require 'rbconfig.rb' 2 | 3 | #RbConfig::MAKEFILE_CONFIG["optflags"] = "-g3 -gdwarf-2" 4 | 5 | require 'mkmf' 6 | 7 | # $CFLAGS="-O0" 8 | $INCFLAGS = "-I../ext -I../ext/types #$INCFLAGS" 9 | 10 | srcs = %w( 11 | fft 12 | fftsg 13 | ) 14 | $objs = srcs.collect{|i| i+".o"} 15 | 16 | create_makefile('fft') 17 | -------------------------------------------------------------------------------- /fft/fft.erb.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "narray.h" 3 | #include "template.h" 4 | 5 | /* 6 | Fast Fourier/Cosine/Sine Transform 7 | using program code developed by Takuya OOURA. 8 | http://www.kurims.kyoto-u.ac.jp/~ooura/fft-j.html 9 | */ 10 | 11 | typedef dcomplex ctype; 12 | typedef double rtype; 13 | 14 | typedef struct { 15 | rtype *a; 16 | rtype *t; 17 | int *ip; 18 | rtype *w; 19 | int sign; 20 | } fft_opt_t; 21 | 22 | static VALUE rb_mFFT; 23 | static VALUE eRadixError; 24 | 25 | void cdft(int n2, int isig, double *a, int *ip, rtype *w); 26 | void rdft(int, int, double *, int *, double *); 27 | void ddct(int, int, double *, int *, double *); 28 | void ddst(int, int, double *, int *, double *); 29 | void dfct(int, double *, double *, int *, double *); 30 | void dfst(int, double *, double *, int *, double *); 31 | <% 32 | require "./fft_tmpl.rb" 33 | $defs.each do |x| 34 | $params = x 35 | %> 36 | static void 37 | iter_fft_<%=name%>(na_loop_t *const lp) 38 | { 39 | size_t i, n; 40 | char *p1, *p2; 41 | ssize_t s1, s2; 42 | size_t *idx1, *idx2; 43 | <%=dtype%> x; 44 | <%=dtype%> *a; 45 | fft_opt_t *g; 46 | 47 | INIT_COUNTER(lp, n); 48 | INIT_PTR(lp, 0, p1, s1, idx1); 49 | INIT_PTR(lp, 1, p2, s2, idx2); 50 | g = (fft_opt_t*)(lp->opt_ptr); 51 | a = (<%=dtype%>*)(g->a); 52 | for (i=0; i, x); 54 | a[i] = x; 55 | } 56 | 57 | <%=name%>(<%=args%>); 58 | 59 | for (i=0; i, x); 62 | } 63 | } 64 | 65 | /*<%=doc%>*/ 66 | static VALUE 67 | nary_fft_<%=name%>(int argc, VALUE *args, VALUE mod) 68 | { 69 | ndfunc_t *func; 70 | narray_t *na; 71 | VALUE vres, vna, vsign=INT2NUM(1); 72 | fft_opt_t *g; 73 | int n; 74 | 75 | rb_scan_args(argc, args, "12", &vna, &vsign); 76 | GetNArray(vna,na); 77 | n = NA_SHAPE(na)[NA_NDIM(na)-1]; 78 | if (n & (n-1)) { 79 | rb_raise(eRadixError,"array size(=%d) is not 2**n",n); 80 | } 81 | 82 | func = ndfunc_alloc(iter_fft_<%=name%>, NO_LOOP, 83 | 1, 1, <%=class_var%>, <%=class_var%>); 84 | func->args[0].dim = 1; 85 | func->args[1].dim = 1; 86 | func->args[1].aux.shape[0] = n; 87 | 88 | g = ALLOCA_N(fft_opt_t,1); 89 | g->sign = NUM2INT(vsign); 90 | g->a = ALLOC_N(rtype,<%=n_a%>); 91 | g->t = ALLOC_N(rtype,<%=n_t%>); 92 | g->ip = ALLOC_N(int,<%=n_ip%>); 93 | g->w = ALLOC_N(rtype,<%=n_w%>); 94 | g->ip[0]= 0; 95 | 96 | vres = ndloop_do3(func, g, 1, vna); 97 | ndfunc_free(func); 98 | 99 | xfree(g->a); 100 | xfree(g->t); 101 | xfree(g->ip); 102 | xfree(g->w); 103 | return vres; 104 | } 105 | <% end %> 106 | 107 | void 108 | Init_fft() 109 | { 110 | rb_mFFT = rb_define_module("FFT"); 111 | eRadixError = rb_define_class_under(rb_mFFT, "RadixError", rb_eStandardError); 112 | 113 | <% $defs.each do |x| 114 | $params = x %> 115 | rb_define_module_function(rb_mFFT, "<%=name%>", nary_fft_<%=name%>, -1); 116 | <% end %> 117 | } 118 | -------------------------------------------------------------------------------- /fft/fft_tmpl.rb: -------------------------------------------------------------------------------- 1 | module Delegate 2 | module_function 3 | alias method_missing_alias method_missing 4 | def method_missing(method, *args, &block) 5 | if $params.kind_of?(Hash) and param=$params[method] 6 | ERB.new(param).result(binding) 7 | elsif $params.respond_to? method 8 | param = $params.send(method, *args, &block) 9 | ERB.new(param).result(binding) 10 | else 11 | method_missing_alias(method, *args) 12 | end 13 | end 14 | end 15 | 16 | include Delegate 17 | 18 | $defs = [ 19 | { 20 | :name => "cdft", 21 | :n_a => "n*2", 22 | :n_t => "0", 23 | :n_ip => "2+sqrt(n)", 24 | :n_w => "n/2", 25 | :dtype => "dcomplex", 26 | :class_name => "DComplex", 27 | :class_var => "cDComplex", 28 | :args => "n*2, g->sign, (double*)a, g->ip, g->w", 29 | :doc => " 30 | Complex DFT (Discrete Fourier Transform), 31 | Fast Version (Split-Radix). 32 | @overload <%=name%>(narray,[sign]) 33 | @param [NArray::<%=class_name%>] narray 34 | @param [Numeric] sign 0 or 1 or -1. 35 | @return [NArray::<%=class_name%>] 36 | ", 37 | }, 38 | { 39 | :name => "rdft", 40 | :n_a => "n", 41 | :n_t => "0", 42 | :n_ip => "2+sqrt(n/2)", 43 | :n_w => "n/2", 44 | :dtype => "double", 45 | :class_name => "DFloat", 46 | :class_var => "cDFloat", 47 | :args => "n, g->sign, a, g->ip, g->w", 48 | :doc => " 49 | Real DFT (Discrete Fourier Transform), 50 | Fast Version (Split-Radix). 51 | @overload <%=name%>(narray,[sign]) 52 | @param [NArray::<%=class_name%>] narray 53 | @param [Numeric] sign 0 or 1 or -1. 54 | @return [NArray::<%=class_name%>] 55 | ", 56 | }, 57 | { 58 | :name => "ddct", 59 | :n_a => "n", 60 | :n_t => "0", 61 | :n_ip => "2+sqrt(n/2)", 62 | :n_w => "n*5/4", 63 | :dtype => "double", 64 | :class_name => "DFloat", 65 | :class_var => "cDFloat", 66 | :args => "n, g->sign, a, g->ip, g->w", 67 | :doc => " 68 | DCT (Discrete Cosine Transform), 69 | Fast Version (Split-Radix). 70 | @overload <%=name%>(narray,[sign]) 71 | @param [NArray::<%=class_name%>] narray 72 | @param [Numeric] sign 0 or 1 or -1. 73 | @return [NArray::<%=class_name%>] 74 | ", 75 | }, 76 | { 77 | :name => "ddst", 78 | :n_a => "n", 79 | :n_t => "0", 80 | :n_ip => "2+sqrt(n/2)", 81 | :n_w => "n*5/4", 82 | :dtype => "double", 83 | :class_name => "DFloat", 84 | :class_var => "cDFloat", 85 | :args => "n, g->sign, a, g->ip, g->w", 86 | :doc => " 87 | DST (Discrete Sine Transform), 88 | Fast Version (Split-Radix). 89 | @overload <%=name%>(narray,[sign]) 90 | @param [NArray::<%=class_name%>] narray 91 | @param [Numeric] sign 0 or 1 or -1. 92 | @return [NArray::<%=class_name%>] 93 | ", 94 | }, 95 | { 96 | :name => "dfct", 97 | :n_a => "n", 98 | :n_t => "n/2", 99 | :n_ip => "2+sqrt(n/4)", 100 | :n_w => "n*5/8", 101 | :dtype => "double", 102 | :class_name => "DFloat", 103 | :class_var => "cDFloat", 104 | :args => "n, a, g->t, g->ip, g->w", 105 | :doc => " 106 | Cosine Transform of RDFT (Real Symmetric DFT), 107 | Fast Version (Split-Radix). 108 | @overload <%=name%>(narray) 109 | @param [NArray::<%=class_name%>] narray 110 | @return [NArray::<%=class_name%>] 111 | ", 112 | }, 113 | { 114 | :name => "dfst", 115 | :n_a => "n", 116 | :n_t => "n/2", 117 | :n_ip => "2+sqrt(n/4)", 118 | :n_w => "n*5/8", 119 | :dtype => "double", 120 | :class_name => "DFloat", 121 | :class_var => "cDFloat", 122 | :args => "n, a, g->t, g->ip, g->w", 123 | :doc => " 124 | Sine Transform of RDFT (Real Anti-symmetric DFT), 125 | Fast Version (Split-Radix). 126 | @overload <%=name%>(narray) 127 | @param [NArray::<%=class_name%>] narray 128 | @return [NArray::<%=class_name%>] 129 | ", 130 | } 131 | ] 132 | -------------------------------------------------------------------------------- /fft/t.rb: -------------------------------------------------------------------------------- 1 | require "../ext/narray" 2 | require "./fft" 3 | 4 | p n = 2**24 5 | p n = 12345 6 | p n = 2**20 7 | p a = NArray::DComplex[1..n] 8 | p x = FFT.cdft(a,1) 9 | p y = FFT.cdft(x,-1) 10 | p (a-y/n).abs.max 11 | 12 | p a = NArray::DFloat[1..n] 13 | p x = FFT.rdft(a,1) 14 | p y = FFT.rdft(x,-1) 15 | p (a-y*(2.0/n)).abs.max 16 | 17 | p a = NArray::DFloat[1..n] 18 | p x = FFT.ddct(a,1) 19 | p y = FFT.ddct(x,-1) 20 | y[0] /= 2 21 | p (a-y*(2.0/n)).abs.max 22 | 23 | p a = NArray::DFloat[1..n] 24 | p x = FFT.ddst(a,1) 25 | p y = FFT.ddst(x,-1) 26 | y[0] /= 2 27 | p (a-y*(2.0/n)).abs.max 28 | -------------------------------------------------------------------------------- /lib/numo/narray.rb: -------------------------------------------------------------------------------- 1 | require "numo/narray.#{RUBY_PLATFORM.include?('darwin') ? 'bundle' : 'so'}" 2 | require "numo/narray/extra" 3 | -------------------------------------------------------------------------------- /numo-narray.gemspec: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | lib = File.expand_path('../lib', __FILE__) 3 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 4 | 5 | open("ext/numo/narray/numo/narray.h") do |f| 6 | f.each_line do |l| 7 | if /NARRAY_VERSION "([\d.]+)"/ =~ l 8 | NARRAY_VERSION = $1 9 | break 10 | end 11 | end 12 | end 13 | 14 | Gem::Specification.new do |spec| 15 | spec.name = "numo-narray" 16 | spec.version = NARRAY_VERSION 17 | spec.authors = ["Masahiro TANAKA"] 18 | spec.email = ["masa16.tanaka@gmail.com"] 19 | spec.description = %q{Numo::NArray - New NArray class library in Ruby/Numo.} 20 | spec.summary = %q{alpha release of Numo::NArray - New NArray class library in Ruby/Numo (NUmerical MOdule)} 21 | spec.homepage = "https://github.com/ruby-numo/numo-narray" 22 | spec.license = "BSD-3-Clause" 23 | spec.required_ruby_version = '>= 2.2' 24 | 25 | spec.files = `git ls-files Gemfile README.md Rakefile lib ext numo-narray.gemspec spec`.split($/) 26 | spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } 27 | spec.test_files = spec.files.grep(%r{^(test|spec|features)/}) 28 | spec.require_paths = ["lib"] 29 | spec.extensions = ["ext/numo/narray/extconf.rb"] 30 | 31 | spec.add_development_dependency "rake", ">= 12.3.3" 32 | spec.add_development_dependency "rake-compiler", "~> 1.1" 33 | spec.add_development_dependency "test-unit" 34 | end 35 | -------------------------------------------------------------------------------- /test/ractor_test.rb: -------------------------------------------------------------------------------- 1 | require_relative "test_helper" 2 | 3 | class NArrayRactorTest < NArrayTestBase 4 | if respond_to?(:ractor) 5 | ractor keep: true 6 | data(:dtype, TYPES, keep: true) 7 | def test_non_frozen(data) 8 | dtype = data.fetch(:dtype) 9 | ary = random_array(dtype) 10 | r = Ractor.new(ary) {|x| x } 11 | ary2 = r.take 12 | assert_equal(ary, ary2) 13 | assert_not_same(ary, ary2) 14 | end 15 | 16 | def test_frozen(data) 17 | dtype = data.fetch(:dtype) 18 | ary1 = random_array(dtype) 19 | ary1.freeze 20 | r = Ractor.new(ary1) do |ary2| 21 | [ary2, ary2 * 10] 22 | end 23 | ary2, res = r.take 24 | assert_equal((dtype != Numo::RObject), 25 | ary1.equal?(ary2)) 26 | assert_equal(ary1*10, res) 27 | end 28 | 29 | def test_parallel(data) 30 | dtype = data.fetch(:dtype) 31 | ary1 = random_array(dtype, 100000) 32 | r1 = Ractor.new(ary1) do |ary2| 33 | ary2 * 10 34 | end 35 | r2 = Ractor.new(ary1) do |ary4| 36 | ary4 * 10 37 | end 38 | assert_equal(r1.take, r2.take) 39 | end 40 | 41 | def random_array(dtype, n=1000) 42 | case dtype 43 | when Numo::DFloat, Numo::SFloat, Numo::DComplex, Numo::SComplex 44 | dtype.new(n).rand_norm 45 | else 46 | dtype.new(n).rand(10) 47 | end 48 | end 49 | end 50 | end 51 | -------------------------------------------------------------------------------- /test/test_helper.rb: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift File.expand_path("../../lib", __FILE__) 2 | require "numo/narray" 3 | require "test/unit" 4 | require "stringio" 5 | 6 | class NArrayTestBase < Test::Unit::TestCase 7 | FLOAT_TYPES = [ 8 | Numo::DFloat, 9 | Numo::DComplex, 10 | ] 11 | 12 | TYPES = [ 13 | *FLOAT_TYPES, 14 | Numo::SFloat, 15 | Numo::SComplex, 16 | Numo::Int64, 17 | Numo::Int32, 18 | Numo::Int16, 19 | Numo::Int8, 20 | Numo::UInt64, 21 | Numo::UInt32, 22 | Numo::UInt16, 23 | Numo::UInt8, 24 | Numo::RObject, 25 | ] 26 | end 27 | --------------------------------------------------------------------------------