numo-narray 0.9.1.4 → 0.9.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +10 -4
  3. data/ext/numo/narray/array.c +17 -7
  4. data/ext/numo/narray/data.c +39 -36
  5. data/ext/numo/narray/extconf.rb +1 -0
  6. data/ext/numo/narray/gen/narray_def.rb +4 -0
  7. data/ext/numo/narray/gen/spec.rb +5 -1
  8. data/ext/numo/narray/gen/tmpl/accum.c +2 -2
  9. data/ext/numo/narray/gen/tmpl/accum_arg.c +88 -0
  10. data/ext/numo/narray/gen/tmpl/accum_binary.c +1 -1
  11. data/ext/numo/narray/gen/tmpl/accum_index.c +25 -14
  12. data/ext/numo/narray/gen/tmpl/aref.c +5 -35
  13. data/ext/numo/narray/gen/tmpl/aset.c +7 -37
  14. data/ext/numo/narray/gen/tmpl/bincount.c +7 -7
  15. data/ext/numo/narray/gen/tmpl/clip.c +11 -15
  16. data/ext/numo/narray/gen/tmpl/cum.c +1 -1
  17. data/ext/numo/narray/gen/tmpl/each.c +4 -2
  18. data/ext/numo/narray/gen/tmpl/each_with_index.c +5 -2
  19. data/ext/numo/narray/gen/tmpl/lib.c +2 -2
  20. data/ext/numo/narray/gen/tmpl/logseq.c +6 -5
  21. data/ext/numo/narray/gen/tmpl/map_with_index.c +5 -6
  22. data/ext/numo/narray/gen/tmpl/median.c +2 -2
  23. data/ext/numo/narray/gen/tmpl/minmax.c +1 -1
  24. data/ext/numo/narray/gen/tmpl/poly.c +4 -4
  25. data/ext/numo/narray/gen/tmpl/qsort.c +1 -1
  26. data/ext/numo/narray/gen/tmpl/rand.c +8 -6
  27. data/ext/numo/narray/gen/tmpl/rand_norm.c +18 -16
  28. data/ext/numo/narray/gen/tmpl/seq.c +5 -4
  29. data/ext/numo/narray/gen/tmpl/sort.c +3 -3
  30. data/ext/numo/narray/gen/tmpl/sort_index.c +2 -2
  31. data/ext/numo/narray/gen/tmpl/store_array.c +14 -2
  32. data/ext/numo/narray/gen/tmpl/unary_s.c +55 -31
  33. data/ext/numo/narray/gen/tmpl_bit/aref.c +22 -30
  34. data/ext/numo/narray/gen/tmpl_bit/aset.c +20 -34
  35. data/ext/numo/narray/gen/tmpl_bit/binary.c +42 -14
  36. data/ext/numo/narray/gen/tmpl_bit/bit_count.c +5 -0
  37. data/ext/numo/narray/gen/tmpl_bit/bit_reduce.c +5 -0
  38. data/ext/numo/narray/gen/tmpl_bit/store_array.c +14 -2
  39. data/ext/numo/narray/gen/tmpl_bit/store_bit.c +21 -7
  40. data/ext/numo/narray/gen/tmpl_bit/unary.c +21 -7
  41. data/ext/numo/narray/index.c +369 -59
  42. data/ext/numo/narray/math.c +2 -2
  43. data/ext/numo/narray/narray.c +45 -27
  44. data/ext/numo/narray/ndloop.c +2 -2
  45. data/ext/numo/narray/numo/intern.h +3 -2
  46. data/ext/numo/narray/numo/narray.h +24 -5
  47. data/ext/numo/narray/numo/ndloop.h +2 -2
  48. data/ext/numo/narray/numo/template.h +4 -6
  49. data/ext/numo/narray/numo/types/complex.h +2 -2
  50. data/ext/numo/narray/step.c +58 -252
  51. data/ext/numo/narray/struct.c +2 -2
  52. data/lib/numo/narray/extra.rb +172 -212
  53. data/numo-narray.gemspec +9 -5
  54. metadata +18 -17
@@ -44,44 +44,68 @@ static void
44
44
  SET_DATA_INDEX(p2,idx2,dtype,x);
45
45
  }
46
46
  } else {
47
- <% if is_simd and !is_complex and %w[sqrt].include? name %>
48
- // Check number of elements. & Check same alignment.
49
- if ((n >= num_pack) && is_same_aligned2(&((dtype*)p1)[i], &((dtype*)p2)[i], SIMD_ALIGNMENT_SIZE)){
50
- // Calculate up to the position just before the start of SIMD computation.
51
- cnt = get_count_of_elements_not_aligned_to_simd_size(&((dtype*)p1)[i], SIMD_ALIGNMENT_SIZE, sizeof(dtype));
52
- for (i=0; i < cnt; i++) {
53
- ((dtype*)p2)[i] = m_<%=name%>(((dtype*)p1)[i]);
54
- }
47
+ //<% if need_align %>
48
+ if (is_aligned(p1,sizeof(dtype)) &&
49
+ is_aligned(p2,sizeof(dtype)) ) {
50
+ if (s1 == sizeof(dtype) &&
51
+ s2 == sizeof(dtype) ) {
52
+ //<% if is_simd and !is_complex and %w[sqrt].include? name %>
53
+ // Check number of elements. & Check same alignment.
54
+ if ((n >= num_pack) && is_same_aligned2(&((dtype*)p1)[i], &((dtype*)p2)[i], SIMD_ALIGNMENT_SIZE)){
55
+ // Calculate up to the position just before the start of SIMD computation.
56
+ cnt = get_count_of_elements_not_aligned_to_simd_size(&((dtype*)p1)[i], SIMD_ALIGNMENT_SIZE, sizeof(dtype));
57
+ for (i=0; i < cnt; i++) {
58
+ ((dtype*)p2)[i] = m_<%=name%>(((dtype*)p1)[i]);
59
+ }
55
60
 
56
- // Get the count of SIMD computation loops.
57
- cnt_simd_loop = (n - i) % num_pack;
61
+ // Get the count of SIMD computation loops.
62
+ cnt_simd_loop = (n - i) % num_pack;
63
+
64
+ // SIMD computation.
65
+ if (p1 == p2) { // inplace case
66
+ for(; i < n - cnt_simd_loop; i += num_pack){
67
+ a = _mm_load_<%=simd_type%>(&((dtype*)p1)[i]);
68
+ a = _mm_<%=name%>_<%=simd_type%>(a);
69
+ _mm_store_<%=simd_type%>(&((dtype*)p1)[i], a);
70
+ }
71
+ } else {
72
+ for(; i < n - cnt_simd_loop; i += num_pack){
73
+ a = _mm_load_<%=simd_type%>(&((dtype*)p1)[i]);
74
+ a = _mm_<%=name%>_<%=simd_type%>(a);
75
+ _mm_stream_<%=simd_type%>(&((dtype*)p2)[i], a);
76
+ }
77
+ }
58
78
 
59
- // SIMD computation.
60
- if (p1 == p2) { // inplace case
61
- for(; i < n - cnt_simd_loop; i += num_pack){
62
- a = _mm_load_<%=simd_type%>(&((dtype*)p1)[i]);
63
- a = _mm_<%=name%>_<%=simd_type%>(a);
64
- _mm_store_<%=simd_type%>(&((dtype*)p1)[i], a);
65
79
  }
66
- } else {
67
- for(; i < n - cnt_simd_loop; i += num_pack){
68
- a = _mm_load_<%=simd_type%>(&((dtype*)p1)[i]);
69
- a = _mm_<%=name%>_<%=simd_type%>(a);
70
- _mm_stream_<%=simd_type%>(&((dtype*)p2)[i], a);
80
+ // Compute the remainder of the SIMD operation.
81
+ if (cnt_simd_loop != 0){
82
+ //<% end %>
83
+ for (; i<n; i++) {
84
+ ((dtype*)p2)[i] = m_<%=name%>(((dtype*)p1)[i]);
85
+ }
86
+ //<% if is_simd and !is_complex and %w[sqrt].include? name %>
71
87
  }
88
+ //<% end %>
89
+ return;
72
90
  }
73
-
74
- }
75
- // Compute the remainder of the SIMD operation.
76
- if (cnt_simd_loop != 0){
77
- <% end %>
78
- for (; i<n; i++) {
79
- ((dtype*)p2)[i] = m_<%=name%>(((dtype*)p1)[i]);
91
+ if (is_aligned_step(s1,sizeof(dtype)) &&
92
+ is_aligned_step(s2,sizeof(dtype)) ) {
93
+ //<% end %>
94
+ for (i=0; i<n; i++) {
95
+ *(dtype*)p2 = m_<%=name%>(*(dtype*)p1);
96
+ p1 += s1;
97
+ p2 += s2;
98
+ }
99
+ return;
100
+ //<% if need_align %>
80
101
  }
81
- <% if is_simd and !is_complex and %w[sqrt].include? name %>
82
102
  }
83
- <% end %>
84
- return;
103
+ for (i=0; i<n; i++) {
104
+ GET_DATA_STRIDE(p1,s1,dtype,x);
105
+ x = m_<%=name%>(x);
106
+ SET_DATA_STRIDE(p2,s2,dtype,x);
107
+ }
108
+ //<% end %>
85
109
  }
86
110
  }
87
111
  }
@@ -1,40 +1,32 @@
1
1
  /*
2
- Array element referenece or slice view.
2
+ Multi-dimensional element reference.
3
3
  @overload [](dim0,...,dimL)
4
- @param [Numeric,Range,etc] dim0,...,dimL Multi-dimensional Index.
5
- @return [Numeric,NArray::<%=class_name%>] Element object or NArray view.
6
-
7
- --- Returns the element at +dim0+, +dim1+, ... are Numeric indices
8
- for each dimension, or returns a NArray View as a sliced subarray if
9
- +dim0+, +dim1+, ... includes other than Numeric index, e.g., Range
10
- or Array or true.
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 #[]=
11
8
 
12
9
  @example
13
- a = Numo::DFloat.new(4,5).seq
14
- => Numo::DFloat#shape=[4,5]
15
- [[0, 1, 2, 3, 4],
16
- [5, 6, 7, 8, 9],
17
- [10, 11, 12, 13, 14],
18
- [15, 16, 17, 18, 19]]
19
-
20
- a[1,1]
21
- => 6.0
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]]
22
15
 
23
- a[1..3,1]
24
- => Numo::DFloat#shape=[3]
25
- [6, 11, 16]
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]]
26
21
 
27
- a[1,[1,3,4]]
28
- => Numo::DFloat#shape=[3]
29
- [6, 8, 9]
22
+ b[true,(0..-1)%2]
23
+ # => Numo::Bit(view)#shape=[3,2]
24
+ # [[1, 1],
25
+ # [1, 1],
26
+ # [1, 1]]
30
27
 
31
- a[true,2].fill(99)
32
- a
33
- => Numo::DFloat#shape=[4,5]
34
- [[0, 1, 99, 3, 4],
35
- [5, 6, 99, 8, 9],
36
- [10, 11, 99, 13, 14],
37
- [15, 16, 99, 18, 19]]
28
+ b[1,1]
29
+ # => 0
38
30
  */
39
31
  static VALUE
40
32
  <%=c_func(-1)%>(int argc, VALUE *argv, VALUE self)
@@ -1,41 +1,27 @@
1
1
  /*
2
- Array element(s) set.
3
- @overload []=(dim0,..,dimL,val)
4
- @param [Numeric,Range,etc] dim0,..,dimL Multi-dimensional Index.
5
- @param [Numeric,Numo::NArray,etc] val Value(s) to be set to self.
6
- @return [Numeric] returns val (last argument).
7
-
8
- --- Replace element(s) at +dim0+, +dim1+, ... (index/range/array/true
9
- for each dimention). Broadcasting mechanism is applied.
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 #[]
10
9
 
11
10
  @example
12
- a = Numo::DFloat.new(3,4).seq
13
- => Numo::DFloat#shape=[3,4]
14
- [[0, 1, 2, 3],
15
- [4, 5, 6, 7],
16
- [8, 9, 10, 11]]
17
-
18
- a[1,2]=99
19
- a
20
- => Numo::DFloat#shape=[3,4]
21
- [[0, 1, 2, 3],
22
- [4, 5, 99, 7],
23
- [8, 9, 10, 11]]
24
-
25
- a[1,[0,2]] = [101,102]
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
26
19
  a
27
- => Numo::DFloat#shape=[3,4]
28
- [[0, 1, 2, 3],
29
- [101, 5, 102, 7],
30
- [8, 9, 10, 11]]
31
-
32
- a[1,true]=99
33
- a
34
- => Numo::DFloat#shape=[3,4]
35
- [[0, 1, 2, 3],
36
- [99, 99, 99, 99],
37
- [8, 9, 10, 11]]
38
-
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]]
39
25
  */
40
26
  static VALUE
41
27
  <%=c_func(-1)%>(int argc, VALUE *argv, VALUE self)
@@ -21,10 +21,8 @@ static void
21
21
  STORE_BIT_STEP(a3, p3, s3, idx3, x);
22
22
  }
23
23
  } else {
24
- o1 = p1 % NB;
25
- o1 -= p3;
26
- o2 = p2 % NB;
27
- o2 -= p3;
24
+ o1 = p1-p3;
25
+ o2 = p2-p3;
28
26
  l1 = NB+o1;
29
27
  r1 = NB-o1;
30
28
  l2 = NB+o2;
@@ -54,23 +52,53 @@ static void
54
52
  }
55
53
  } else {
56
54
  for (; n>=NB; n-=NB) {
57
- x = *a1>>o1;
58
- if (o1<0) x |= *(a1-1)>>l1;
59
- if (o1>0) x |= *(a1+1)<<r1;
55
+ if (o1==0) {
56
+ x = *a1;
57
+ } else if (o1>0) {
58
+ x = *a1>>o1 | *(a1+1)<<r1;
59
+ } else {
60
+ x = *a1<<-o1 | *(a1-1)>>l1;
61
+ }
60
62
  a1++;
61
- y = *a2>>o2;
62
- if (o2<0) y |= *(a2-1)>>l2;
63
- if (o2>0) y |= *(a2+1)<<r2;
63
+ if (o2==0) {
64
+ y = *a2;
65
+ } else if (o2>0) {
66
+ y = *a2>>o2 | *(a2+1)<<r2;
67
+ } else {
68
+ y = *a2<<-o2 | *(a2-1)>>l2;
69
+ }
64
70
  a2++;
65
71
  x = m_<%=name%>(x,y);
66
72
  *(a3++) = x;
67
73
  }
68
74
  }
69
75
  if (n>0) {
70
- x = *a1>>o1;
71
- if (o1<0) x |= *(a1-1)>>l1;
72
- y = *a2>>o2;
73
- if (o2<0) y |= *(a2-1)>>l2;
76
+ if (o1==0) {
77
+ x = *a1;
78
+ } else if (o1>0) {
79
+ x = *a1>>o1;
80
+ if ((int)n>r1) {
81
+ x |= *(a1+1)<<r1;
82
+ }
83
+ } else {
84
+ x = *(a1-1)>>l1;
85
+ if ((int)n>-o1) {
86
+ x |= *a1<<-o1;
87
+ }
88
+ }
89
+ if (o2==0) {
90
+ y = *a2;
91
+ } else if (o2>0) {
92
+ y = *a2>>o2;
93
+ if ((int)n>r2) {
94
+ y |= *(a2+1)<<r2;
95
+ }
96
+ } else {
97
+ y = *(a2-1)>>l2;
98
+ if ((int)n>-o2) {
99
+ y |= *a2<<-o2;
100
+ }
101
+ }
74
102
  x = m_<%=name%>(x,y);
75
103
  *a3 = (x & SLB(n)) | (*a3 & BALL<<n);
76
104
  }
@@ -75,10 +75,15 @@ static VALUE
75
75
  <%=c_func(-1)%>(int argc, VALUE *argv, VALUE self)
76
76
  {
77
77
  VALUE v, reduce;
78
+ narray_t *na;
78
79
  ndfunc_arg_in_t ain[3] = {{cT,0},{sym_reduce,0},{sym_init,0}};
79
80
  ndfunc_arg_out_t aout[1] = {{numo_cInt64,0}};
80
81
  ndfunc_t ndf = { <%=c_iter%>, FULL_LOOP_NIP, 3, 1, ain, aout };
81
82
 
83
+ GetNArray(self,na);
84
+ if (NA_SIZE(na)==0) {
85
+ return INT2FIX(0);
86
+ }
82
87
  reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, 0);
83
88
  v = na_ndloop(&ndf, 3, self, reduce, INT2FIX(0));
84
89
  return rb_funcall(v,rb_intern("extract"),0);
@@ -107,10 +107,15 @@ static VALUE
107
107
  <%=c_func(-1)%>(int argc, VALUE *argv, VALUE self)
108
108
  {
109
109
  VALUE v, reduce;
110
+ narray_t *na;
110
111
  ndfunc_arg_in_t ain[3] = {{cT,0},{sym_reduce,0},{sym_init,0}};
111
112
  ndfunc_arg_out_t aout[1] = {{numo_cBit,0}};
112
113
  ndfunc_t ndf = {<%=c_iter%>, FULL_LOOP_NIP, 3,1, ain,aout};
113
114
 
115
+ GetNArray(self,na);
116
+ if (NA_SIZE(na)==0) {
117
+ return Qfalse;
118
+ }
114
119
  reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, 0);
115
120
  v = na_ndloop(&ndf, 3, self, reduce, INT2FIX(<%=init_bit%>));
116
121
  if (argc > 0) {
@@ -48,7 +48,13 @@ static void
48
48
  if (idx1) {
49
49
  for (i=i1=0; i1<n1 && i<n; i++,i1++) {
50
50
  x = ptr[i1];
51
- if (rb_obj_is_kind_of(x, rb_cRange) || rb_obj_is_kind_of(x, na_cStep)) {
51
+ if (rb_obj_is_kind_of(x, rb_cRange)
52
+ #ifdef HAVE_RB_ARITHMETIC_SEQUENCE_EXTRACT
53
+ || rb_obj_is_kind_of(x, rb_cArithSeq)
54
+ #else
55
+ || rb_obj_is_kind_of(x, rb_cEnumerator)
56
+ #endif
57
+ ) {
52
58
  nary_step_sequence(x,&len,&beg,&step);
53
59
  for (c=0; c<len && i<n; c++,i++) {
54
60
  y = beg + step * c;
@@ -65,7 +71,13 @@ static void
65
71
  } else {
66
72
  for (i=i1=0; i1<n1 && i<n; i++,i1++) {
67
73
  x = ptr[i1];
68
- if (rb_obj_is_kind_of(x, rb_cRange) || rb_obj_is_kind_of(x, na_cStep)) {
74
+ if (rb_obj_is_kind_of(x, rb_cRange)
75
+ #ifdef HAVE_RB_ARITHMETIC_SEQUENCE_EXTRACT
76
+ || rb_obj_is_kind_of(x, rb_cArithSeq)
77
+ #else
78
+ || rb_obj_is_kind_of(x, rb_cEnumerator)
79
+ #endif
80
+ ) {
69
81
  nary_step_sequence(x,&len,&beg,&step);
70
82
  for (c=0; c<len && i<n; c++,i++) {
71
83
  y = beg + step * c;
@@ -18,8 +18,7 @@ static void
18
18
  STORE_BIT_STEP(a3, p3, s3, idx3, x);
19
19
  }
20
20
  } else {
21
- o1 = p1 % NB;
22
- o1 -= p3;
21
+ o1 = p1-p3;
23
22
  l1 = NB+o1;
24
23
  r1 = NB-o1;
25
24
  if (p3>0 || n<NB) {
@@ -40,16 +39,31 @@ static void
40
39
  }
41
40
  } else {
42
41
  for (; n>=NB; n-=NB) {
43
- x = *a1>>o1;
44
- if (o1<0) x |= *(a1-1)>>l1;
45
- if (o1>0) x |= *(a1+1)<<r1;
42
+ if (o1==0) {
43
+ x = *a1;
44
+ } else if (o1>0) {
45
+ x = *a1>>o1 | *(a1+1)<<r1;
46
+ } else {
47
+ x = *a1<<-o1 | *(a1-1)>>l1;
48
+ }
46
49
  a1++;
47
50
  *(a3++) = x;
48
51
  }
49
52
  }
50
53
  if (n>0) {
51
- x = *a1>>o1;
52
- if (o1<0) x |= *(a1-1)>>l1;
54
+ if (o1==0) {
55
+ x = *a1;
56
+ } else if (o1>0) {
57
+ x = *a1>>o1;
58
+ if ((int)n>r1) {
59
+ x |= *(a1+1)<<r1;
60
+ }
61
+ } else {
62
+ x = *(a1-1)>>l1;
63
+ if ((int)n>-o1) {
64
+ x |= *a1<<-o1;
65
+ }
66
+ }
53
67
  *a3 = (x & SLB(n)) | (*a3 & BALL<<n);
54
68
  }
55
69
  }
@@ -20,8 +20,7 @@ static void
20
20
  STORE_BIT_STEP(a3, p3, s3, idx3, y);
21
21
  }
22
22
  } else {
23
- o1 = p1 % NB;
24
- o1 -= p3;
23
+ o1 = p1-p3;
25
24
  l1 = NB+o1;
26
25
  r1 = NB-o1;
27
26
  if (p3>0 || n<NB) {
@@ -44,17 +43,32 @@ static void
44
43
  }
45
44
  } else {
46
45
  for (; n>=NB; n-=NB) {
47
- x = *a1>>o1;
48
- if (o1<0) x |= *(a1-1)>>l1;
49
- if (o1>0) x |= *(a1+1)<<r1;
46
+ if (o1==0) {
47
+ x = *a1;
48
+ } else if (o1>0) {
49
+ x = *a1>>o1 | *(a1+1)<<r1;
50
+ } else {
51
+ x = *a1<<-o1 | *(a1-1)>>l1;
52
+ }
50
53
  a1++;
51
54
  y = m_<%=name%>(x);
52
55
  *(a3++) = y;
53
56
  }
54
57
  }
55
58
  if (n>0) {
56
- x = *a1>>o1;
57
- if (o1<0) x |= *(a1-1)>>l1;
59
+ if (o1==0) {
60
+ x = *a1;
61
+ } else if (o1>0) {
62
+ x = *a1>>o1;
63
+ if ((int)n>r1) {
64
+ x |= *(a1+1)<<r1;
65
+ }
66
+ } else {
67
+ x = *(a1-1)>>l1;
68
+ if ((int)n>-o1) {
69
+ x |= *a1<<-o1;
70
+ }
71
+ }
58
72
  y = m_<%=name%>(x);
59
73
  *a3 = (y & SLB(n)) | (*a3 & BALL<<n);
60
74
  }