Class: Cumo::NArray
- Inherits:
-
Object
- Object
- Cumo::NArray
- Defined in:
- ext/cumo/narray/narray.c,
lib/cumo/narray/extra.rb
Overview
Cumo::NArray is the abstract super class for Numerical N-dimensional Array in the Ruby/Cumo module. Use Typed Subclasses of NArray (Cumo::DFloat, Int32, etc) to create data array instances.
Constant Summary collapse
- @@warn_slow_dot =
false
Class Method Summary collapse
- .asarray(a) ⇒ Object
-
.cast(a) ⇒ Object
Convert the argument to an narray if not an narray.
-
.column_stack(arrays) ⇒ Object
Stack 1-d arrays into columns of a 2-d array.
- .concatenate(arrays, axis: 0) ⇒ Object
-
.diag_indices(m, n, k = 0) ⇒ Object
Return the k-th diagonal indices.
-
.dstack(arrays) ⇒ Object
Stack arrays in depth wise (along third axis).
-
.hstack(arrays) ⇒ Object
Stack arrays horizontally (column wise).
-
.parse(str, split1d: /\s+/, split2d: /;?$|;/, split3d: /\s*\n(\s*\n)+/m) ⇒ Object
parse matrix like matlab, octave.
-
.tril_indices(m, n, k = 0) ⇒ Object
Return the indices for the lower-triangle on and below the k-th diagonal.
-
.triu_indices(m, n, k = 0) ⇒ Object
Return the indices for the upper-triangle on and above the k-th diagonal.
-
.vstack(arrays) ⇒ Object
Stack arrays vertically (row wise).
Instance Method Summary collapse
-
#append(other, axis: nil) ⇒ Object
Append values to the end of an narray.
-
#argsort(axis: -1) ⇒ Cumo::Int32
Returns an index array of sort result.
- #concatenate(*arrays, axis: 0) ⇒ Object
-
#cov(y = nil, ddof: 1, fweights: nil, aweights: nil) ⇒ Cumo::NArray
Compute a covariance matrix.
-
#deg2rad ⇒ Object
Convert angles from degrees to radians.
- #delete(indice, axis = nil) ⇒ Object
-
#diag(k = 0) ⇒ Object
Return a matrix whose diagonal is constructed by self along the last axis.
-
#diag_indices(k = 0) ⇒ Object
Return the k-th diagonal indices.
-
#diff(n = 1, axis: -1)) ⇒ Object
Calculate the n-th discrete difference along given axis.
-
#dot(b) ⇒ Cumo::NArray
Dot product of two arrays.
- #dsplit(indices_or_sections) ⇒ Object
-
#each_over_axis(axis = 0) ⇒ Object
Iterate over an axis.
-
#fliplr ⇒ Object
Flip each row in the left/right direction.
-
#flipud ⇒ Object
Flip each column in the up/down direction.
-
#get(out = nil, stream: nil) ⇒ Object
Copies this array to the host.
- #hsplit(indices_or_sections) ⇒ Object
-
#inner(b, axis: -1)) ⇒ Cumo::NArray
Inner product of two arrays.
-
#insert(indice, values, axis: nil) ⇒ Object
Insert values along the axis before the indices.
-
#kron(b) ⇒ Cumo::NArray
Kronecker product of two arrays.
-
#new_fill(value) ⇒ Object
Return an array filled with value with the same shape and type as self.
- #new_narray ⇒ Object
-
#new_ones ⇒ Object
Return an array of ones with the same shape and type as self.
-
#new_zeros ⇒ Object
Return an array of zeros with the same shape and type as self.
-
#outer(b, axis: nil) ⇒ Cumo::NArray
Outer product of two arrays.
-
#percentile(q, axis: nil) ⇒ Numo::NArray
Percentile.
-
#rad2deg ⇒ Object
Convert angles from radians to degrees.
- #repeat(arg, axis: nil) ⇒ Object
-
#rot90(k = 1, axes = [0, 1]) ⇒ Object
Rotate in the plane specified by axes.
-
#set(src, stream: nil) ⇒ Object
Copies a host buffer into this array.
- #split(indices_or_sections, axis: 0) ⇒ Object
- #tile(*arg) ⇒ Object
- #to_c ⇒ Object
- #to_f ⇒ Object
- #to_i ⇒ Object
-
#trace(offset = nil, axis = nil, nan: false) ⇒ Object
Return the sum along diagonals of the array.
-
#tril(k = 0) ⇒ Object
Lower triangular matrix.
-
#tril!(k = 0) ⇒ Object
Lower triangular matrix.
-
#tril_indices(k = 0) ⇒ Object
Return the indices for the lower-triangle on and below the k-th diagonal.
-
#triu(k = 0) ⇒ Object
Upper triangular matrix.
-
#triu!(k = 0) ⇒ Object
Upper triangular matrix.
-
#triu_indices(k = 0) ⇒ Object
Return the indices for the upper-triangle on and above the k-th diagonal.
- #vsplit(indices_or_sections) ⇒ Object
Class Method Details
.asarray(a) ⇒ Object
155 156 157 158 159 160 161 162 163 164 |
# File 'lib/cumo/narray/extra.rb', line 155 def self.asarray(a) case a when NArray (a.ndim == 0) ? a[:new] : a when Numeric, Range self[a] else cast(a) end end |
.cast(a) ⇒ Object
Convert the argument to an narray if not an narray.
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
# File 'lib/cumo/narray/extra.rb', line 139 def self.cast(a) case a when NArray a when Array,Numeric NArray.array_type(a).cast(a) else if a.respond_to?(:to_a) a = a.to_a NArray.array_type(a).cast(a) else raise TypeError,"invalid type for NArray" end end end |
.column_stack(arrays) ⇒ Object
Stack 1-d arrays into columns of a 2-d array.
644 645 646 647 648 649 650 651 652 653 654 |
# File 'lib/cumo/narray/extra.rb', line 644 def column_stack(arrays) arys = arrays.map do |a| a = cast(a) case a.ndim when 0; a[:new, :new] when 1; a[true, :new] else; a end end concatenate(arys, axis:1) end |
.concatenate(arrays, axis: 0) ⇒ Object
498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 |
# File 'lib/cumo/narray/extra.rb', line 498 def concatenate(arrays, axis:0) klass = (self == NArray) ? NArray.array_type(arrays) : self nd = 0 arrays = arrays.map do |a| case a when NArray # ok when Numeric a = klass[a] when Array a = klass.cast(a) else raise TypeError, "not Cumo::NArray: #{a.inspect[0..48]}" end if a.ndim > nd nd = a.ndim end a end if axis < 0 axis += nd end if axis < 0 || axis >= nd raise ArgumentError, "axis is out of range" end new_shape = nil sum_size = 0 arrays.each do |a| a_shape = a.shape if nd != a_shape.size a_shape = [1] * (nd - a_shape.size) + a_shape end sum_size += a_shape.delete_at(axis) if new_shape if new_shape != a_shape raise ShapeError, "shape mismatch" end else new_shape = a_shape end end new_shape.insert(axis, sum_size) result = klass.zeros(*new_shape) lst = 0 refs = [true] * nd arrays.each do |a| fst = lst lst = fst + (a.shape[axis - nd] || 1) if lst > fst refs[axis] = fst...lst result[*refs] = a end end result end |
.diag_indices(m, n, k = 0) ⇒ Object
Return the k-th diagonal indices.
1138 1139 1140 1141 1142 |
# File 'lib/cumo/narray/extra.rb', line 1138 def self.diag_indices(m, n, k=0) x = Cumo::Int64.new(m, 1).seq + k y = Cumo::Int64.new(1, n).seq (x.eq y).where end |
.dstack(arrays) ⇒ Object
Stack arrays in depth wise (along third axis).
627 628 629 630 631 632 |
# File 'lib/cumo/narray/extra.rb', line 627 def dstack(arrays) arys = arrays.map do |a| _atleast_3d(cast(a)) end concatenate(arys, axis:2) end |
.hstack(arrays) ⇒ Object
Stack arrays horizontally (column wise).
597 598 599 600 601 602 603 604 605 606 607 |
# File 'lib/cumo/narray/extra.rb', line 597 def hstack(arrays) klass = (self == NArray) ? NArray.array_type(arrays) : self nd = 0 arys = arrays.map do |a| a = klass.cast(a) nd = a.ndim if a.ndim > nd a end dim = (nd >= 2) ? 1 : 0 concatenate(arys, axis:dim) end |
.parse(str, split1d: /\s+/, split2d: /;?$|;/, split3d: /\s*\n(\s*\n)+/m) ⇒ Object
parse matrix like matlab, octave
182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 |
# File 'lib/cumo/narray/extra.rb', line 182 def self.parse(str, split1d:/\s+/, split2d:/;?$|;/, split3d:/\s*\n(\s*\n)+/m) a = [] str.split(split3d).each do |block| b = [] #print "b"; p block block.split(split2d).each do |line| #p line line.strip! if !line.empty? c = [] line.split(split1d).each do |item| item = item.strip c << parse_token(item) if !item.empty? end b << c if !c.empty? end end a << b if !b.empty? end if a.size == 1 self.cast(a[0]) else self.cast(a) end end |
.tril_indices(m, n, k = 0) ⇒ Object
Return the indices for the lower-triangle on and below the k-th diagonal.
1122 1123 1124 1125 1126 |
# File 'lib/cumo/narray/extra.rb', line 1122 def self.tril_indices(m, n, k=0) x = Cumo::Int64.new(m, 1).seq + k y = Cumo::Int64.new(1, n).seq (x >= y).where end |
.triu_indices(m, n, k = 0) ⇒ Object
Return the indices for the upper-triangle on and above the k-th diagonal.
1083 1084 1085 1086 1087 |
# File 'lib/cumo/narray/extra.rb', line 1083 def self.triu_indices(m, n, k=0) x = Cumo::Int64.new(m, 1).seq + k y = Cumo::Int64.new(1, n).seq (x <= y).where end |
.vstack(arrays) ⇒ Object
Stack arrays vertically (row wise).
574 575 576 577 578 579 |
# File 'lib/cumo/narray/extra.rb', line 574 def vstack(arrays) arys = arrays.map do |a| _atleast_2d(cast(a)) end concatenate(arys, axis:0) end |
Instance Method Details
#append(other, axis: nil) ⇒ Object
Append values to the end of an narray.
312 313 314 315 316 317 318 319 320 321 322 323 324 325 |
# File 'lib/cumo/narray/extra.rb', line 312 def append(other, axis:nil) other = self.class.cast(other) if axis if ndim != other.ndim raise DimensionError, "dimension mismatch" end return concatenate(other, axis:axis) else a = self.class.zeros(size + other.size) a[0...size] = self[true] a[size..-1] = other[true] return a end end |
#argsort(axis: -1) ⇒ Cumo::Int32
Returns an index array of sort result.
1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 |
# File 'lib/cumo/narray/extra.rb', line 1188 def argsort(axis_ = 'none', axis: -1) raise NotImplementedError, "argsort is not implemented for #{self.class}" unless respond_to?(:sort_index) axis = axis_ unless axis_ == 'none' return flatten.sort_index if axis.nil? axis += ndim if axis < 0 raise NArray::DimensionError, "dimension is out of range" if axis < 0 || axis >= ndim return sort_index if ndim == 1 # sort_index answers with an index into the flattened array; the axes # after axis divide out of it and the ones before it fall to the modulo. idx = sort_index(axis) inner = shape[(axis + 1)..-1].reduce(1, :*) idx = idx / inner if inner > 1 idx % shape[axis] end |
#concatenate(*arrays, axis: 0) ⇒ Object
699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 |
# File 'lib/cumo/narray/extra.rb', line 699 def concatenate(*arrays, axis:0) axis = check_axis(axis) self_shape = shape self_shape.delete_at(axis) sum_size = shape[axis] arrays.map! do |a| case a when NArray # ok when Numeric a = self.class.new(1).store(a) when Array a = self.class.cast(a) else raise TypeError, "not Cumo::NArray: #{a.inspect[0..48]}" end if a.ndim > ndim raise ShapeError, "dimension mismatch" end a_shape = a.shape sum_size += a_shape.delete_at(axis - ndim) || 1 if self_shape != a_shape raise ShapeError, "shape mismatch" end a end self_shape.insert(axis, sum_size) result = self.class.zeros(*self_shape) lst = shape[axis] refs = [true] * ndim if lst > 0 refs[axis] = 0...lst result[*refs] = self end arrays.each do |a| fst = lst lst = fst + (a.shape[axis - ndim] || 1) if lst > fst refs[axis] = fst...lst result[*refs] = a end end result end |
#cov(y = nil, ddof: 1, fweights: nil, aweights: nil) ⇒ Cumo::NArray
Compute a covariance matrix.
1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 |
# File 'lib/cumo/narray/extra.rb', line 1433 def cov(y=nil, ddof:1, fweights:nil, aweights:nil) raise NArray::ShapeError, "ndim must be <= 2" if ndim > 2 raise NArray::ShapeError, "y.ndim must be <= 2" if !y.nil? && y.ndim > 2 raise ArgumentError, "ddof must be 0 or 1" unless [0, 1].include?(ddof) if y m = NArray.vstack([self, y]) else m = self end w = nil if fweights fweights = NArray.cast(fweights) unless fweights.is_a?(NArray) raise ArgumentError, "fweights must be 1-D array" unless fweights.ndim == 1 raise ArgumentError, "fweights size is wrong" unless fweights.size == m.shape[1] raise ArgumentError, "fweights must be non-negative" if (fweights < 0).any? raise ArgumentError, "fweights must be integer" unless fweights == fweights.floor w = fweights end if aweights aweights = NArray.cast(aweights) unless aweights.is_a?(NArray) raise ArgumentError, "aweights must be 1-D array" unless aweights.ndim == 1 raise ArgumentError, "aweights size is wrong" unless aweights.size == m.shape[1] raise ArgumentError, "aweights must be non-negative" if (aweights < 0).any? if w.nil? w = aweights else w *= aweights end end if w.nil? fact = m.shape[-1] - ddof elsif ddof == 0 fact = w.sum elsif aweights.nil? fact = w.sum - ddof else w_sum = w.sum fact = w_sum - ddof * (w * aweights).sum / w_sum end # numo's sum answers with a Ruby number, cumo's with a zero-dimensional # array, and every object is truthy. fact = fact.extract_cpu if fact.is_a?(NArray) if fact <= 0 warn("Degrees of freedom <= 0 for slice") fact = 0.0 end if w.nil? m -= m.mean(axis:-1, keepdims:true) mw = m else m -= (m * w).sum(axis:-1, keepdims:true) / w.sum mw = m * w end m.dot(mw.transpose.conj) / fact end |
#deg2rad ⇒ Object
Convert angles from degrees to radians.
61 62 63 |
# File 'lib/cumo/narray/extra.rb', line 61 def deg2rad self * (Math::PI / 180) end |
#delete(indice, axis = nil) ⇒ Object
347 348 349 350 351 352 353 354 355 356 357 358 359 |
# File 'lib/cumo/narray/extra.rb', line 347 def delete(indice, axis=nil) if axis bit = Bit.ones(shape[axis]) bit[indice] = 0 idx = [true] * ndim idx[axis] = bit.where return self[*idx].copy else bit = Bit.ones(size) bit[indice] = 0 return self[bit.where].copy end end |
#diag(k = 0) ⇒ Object
Return a matrix whose diagonal is constructed by self along the last axis.
1145 1146 1147 1148 1149 1150 1151 |
# File 'lib/cumo/narray/extra.rb', line 1145 def diag(k=0) *shp, n = shape n += k.abs a = self.class.zeros(*shp, n, n) a.diagonal(k).store(self) a end |
#diag_indices(k = 0) ⇒ Object
Return the k-th diagonal indices.
1129 1130 1131 1132 1133 1134 1135 |
# File 'lib/cumo/narray/extra.rb', line 1129 def diag_indices(k=0) if ndim < 2 raise NArray::ShapeError, "must be >= 2-dimensional array" end m, n = shape[-2..-1] NArray.diag_indices(m, n, k) end |
#diff(n = 1, axis: -1)) ⇒ Object
Calculate the n-th discrete difference along given axis.
1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 |
# File 'lib/cumo/narray/extra.rb', line 1023 def diff(n=1, axis:-1) axis = check_axis(axis) if n < 0 || n >= shape[axis] raise ShapeError, "n=#{n} is invalid for shape[#{axis}]=#{shape[axis]}" end # calculate polynomial coefficient c = self.class[-1, 1] 2.upto(n) do |i| x = self.class.zeros(i + 1) x[0..-2] = c y = self.class.zeros(i + 1) y[1..-1] = c c = y - x end s = [true] * ndim s[axis] = n..-1 result = self[*s].dup sum = result.inplace (n - 1).downto(0) do |i| s = [true] * ndim s[axis] = i..-n - 1 + i sum + self[*s] * c[i] # inplace addition end return result end |
#dot(b) ⇒ Cumo::NArray
Dot product of two arrays.
1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 |
# File 'lib/cumo/narray/extra.rb', line 1234 def dot(b) t = self.class::UPCAST[b.class] # Cumo::Bit names every other type but no table names Bit, so a pair can be # declared on one side only. cumo_na_upcast reads both tables; do the same # here, or the pair silently takes the slow route. t ||= b.class::UPCAST[self.class] if b.is_a?(NArray) if self.ndim == 0 and b.ndim == 0 return self * b end if GEMM_TYPES.include?(t) a = t.cast(self) b = t.asarray(t.cast(b)) case a.ndim when 1 case b.ndim when 1 a.mulsum(b, axis:-1) else a[:new, false].gemm(b).flatten end else case b.ndim when 1 a.gemm(b[false, :new]).flatten else a.gemm(b) end end else b = self.class.asarray(b) case b.ndim when 1 mulsum(b, axis:-1) else case ndim when 0 b.mulsum(self, axis:-2) when 1 self[true, :new].mulsum(b, axis:-2) else unless @@warn_slow_dot nx = 200 ns = 200000 am, an = shape[-2..-1] bm, bn = b.shape[-2..-1] if am > nx && an > nx && bm > nx && bn > nx && size > ns && b.size > ns @@warn_slow_dot = true warn "\nwarning: matrix dot for #{t} is slow. Consider SFloat, DFloat, SComplex, or DComplex to use cuBLAS, or BFloat or HFloat where sixteen bits are enough.\n\n" end end self[false, :new].mulsum(b[false, :new, true, true], axis:-2) end end end end |
#dsplit(indices_or_sections) ⇒ Object
849 850 851 |
# File 'lib/cumo/narray/extra.rb', line 849 def dsplit(indices_or_sections) split(indices_or_sections, axis:2) end |
#each_over_axis(axis = 0) ⇒ Object
Iterate over an axis
272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 |
# File 'lib/cumo/narray/extra.rb', line 272 def each_over_axis(axis=0) unless block_given? return to_enum(:each_over_axis, axis) end if ndim == 0 if axis != 0 raise ArgumentError, "axis=#{axis} is invalid" end niter = 1 else axis = check_axis(axis) niter = shape[axis] end idx = [true] * ndim niter.times do |i| idx[axis] = i yield(self[*idx]) end self end |
#fliplr ⇒ Object
Flip each row in the left/right direction.
Same as a[true, (-1..0).step(-1), ...].
67 68 69 |
# File 'lib/cumo/narray/extra.rb', line 67 def fliplr reverse(1) end |
#flipud ⇒ Object
Flip each column in the up/down direction.
Same as a[(-1..0).step(-1), ...].
73 74 75 |
# File 'lib/cumo/narray/extra.rb', line 73 def flipud reverse(0) end |
#get(out = nil, stream: nil) ⇒ Object
Copies this array to the host. Into a Cumo::CUDA::PinnedMemory it is asynchronous on the current stream, or on stream:, and answers the buffer; with nothing to copy into it answers the bytes as a String.
24 25 26 27 28 29 30 31 32 33 34 |
# File 'lib/cumo/narray/extra.rb', line 24 def get(out = nil, stream: nil) case out when nil raise ArgumentError, "a String is copied synchronously, so it takes no stream:" unless stream.nil? to_binary when Cumo::CUDA::PinnedMemory out.copy(self, :to_pinned, stream) else raise TypeError, "get takes a Cumo::CUDA::PinnedMemory or nothing, got a #{out.class}" end end |
#hsplit(indices_or_sections) ⇒ Object
845 846 847 |
# File 'lib/cumo/narray/extra.rb', line 845 def hsplit(indices_or_sections) split(indices_or_sections, axis:1) end |
#inner(b, axis: -1)) ⇒ Cumo::NArray
Inner product of two arrays.
Same as (a*b).sum(axis:-1).
1297 1298 1299 |
# File 'lib/cumo/narray/extra.rb', line 1297 def inner(b, axis:-1) mulsum(b, axis:axis) end |
#insert(indice, values, axis: nil) ⇒ Object
Insert values along the axis before the indices.
432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 |
# File 'lib/cumo/narray/extra.rb', line 432 def insert(indice, values, axis:nil) if axis values = self.class.asarray(values) nd = values.ndim midx = [:new] * (ndim - nd) + [true] * nd case indice when Numeric midx[-nd - 1] = true midx[axis] = :new end values = values[*midx] else values = self.class.asarray(values).flatten end idx = Int64.asarray(indice) nidx = idx.size if nidx == 1 nidx = values.shape[axis || 0] idx = idx + Int64.new(nidx).seq else sidx = idx.sort_index idx[sidx] += Int64.new(nidx).seq end if axis bit = Bit.ones(shape[axis] + nidx) bit[idx] = 0 new_shape = shape new_shape[axis] += nidx a = self.class.zeros(new_shape) mdidx = [true] * ndim mdidx[axis] = bit.where a[*mdidx] = self mdidx[axis] = idx a[*mdidx] = values else bit = Bit.ones(size + nidx) bit[idx] = 0 a = self.class.zeros(size + nidx) a[bit.where] = self.flatten a[idx] = values end return a end |
#kron(b) ⇒ Cumo::NArray
Kronecker product of two arrays.
kron(a,b)[k_0, k_1, ...] = a[i_0, i_1, ...] * b[j_0, j_1, ...]
where: k_n = i_n * b.shape[n] + j_n
1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 |
# File 'lib/cumo/narray/extra.rb', line 1394 def kron(b) b = NArray.cast(b) nda = ndim ndb = b.ndim shpa = shape shpb = b.shape adim = [:new] * (2 * [ndb - nda, 0].max) + [true, :new] * nda bdim = [:new] * (2 * [nda - ndb, 0].max) + [:new, true] * ndb shpr = (-[nda, ndb].max..-1).map { |i| (shpa[i] || 1) * (shpb[i] || 1) } (self[*adim] * b[*bdim]).reshape(*shpr) end |
#new_fill(value) ⇒ Object
Return an array filled with value with the same shape and type as self.
51 52 53 |
# File 'lib/cumo/narray/extra.rb', line 51 def new_fill(value) self.class.new(*shape).fill(value) end |
#new_narray ⇒ Object
36 37 38 |
# File 'lib/cumo/narray/extra.rb', line 36 def new_narray self.class.new(*shape) end |
#new_ones ⇒ Object
Return an array of ones with the same shape and type as self.
46 47 48 |
# File 'lib/cumo/narray/extra.rb', line 46 def new_ones self.class.ones(*shape) end |
#new_zeros ⇒ Object
Return an array of zeros with the same shape and type as self.
41 42 43 |
# File 'lib/cumo/narray/extra.rb', line 41 def new_zeros self.class.zeros(*shape) end |
#outer(b, axis: nil) ⇒ Cumo::NArray
Outer product of two arrays.
Same as self[false,:new] * b[false,:new,true].
1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 |
# File 'lib/cumo/narray/extra.rb', line 1324 def outer(b, axis:nil) b = NArray.cast(b) if axis.nil? self[false, :new] * ((b.ndim == 0) ? b : b[false, :new, true]) else md, nd = [ndim, b.ndim].minmax axis = check_axis(axis) - nd if axis < -md raise ArgumentError, "axis=#{axis} is out of range" end adim = [true] * ndim adim[axis + ndim + 1, 0] = :new bdim = [true] * b.ndim bdim[axis + b.ndim, 0] = :new self[*adim] * b[*bdim] end end |
#percentile(q, axis: nil) ⇒ Numo::NArray
Percentile
1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 |
# File 'lib/cumo/narray/extra.rb', line 1347 def percentile(q, axis: nil) raise ArgumentError, "q is out of range" if q < 0 || q > 100 x = self unless axis axis = 0 x = x.flatten end sorted = x.sort(axis: axis) x = q / 100.0 * (sorted.shape[axis] - 1) r = x % 1 i = x.floor refs = [true] * sorted.ndim refs[axis] = i if i == sorted.shape[axis] - 1 sorted[*refs] else refs_upper = refs.dup refs_upper[axis] = i + 1 sorted[*refs] + r * (sorted[*refs_upper] - sorted[*refs]) end end |
#rad2deg ⇒ Object
Convert angles from radians to degrees.
56 57 58 |
# File 'lib/cumo/narray/extra.rb', line 56 def rad2deg self * (180 / Math::PI) end |
#repeat(arg, axis: nil) ⇒ Object
961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 |
# File 'lib/cumo/narray/extra.rb', line 961 def repeat(arg, axis:nil) case axis when Integer axis = check_axis(axis) c = self when NilClass c = self.flatten axis = 0 else raise ArgumentError, "invalid axis" end case arg when Integer if !arg.kind_of?(Integer) || arg < 1 raise ArgumentError, "argument should be positive integer" end idx = c.shape[axis].times.map { |i| [i] * arg }.flatten else arg = arg.to_a if arg.size != c.shape[axis] raise ArgumentError, "repeat size should be equal to size along axis" end arg.each do |i| if !i.kind_of?(Integer) || i < 0 raise ArgumentError, "argument should be non-negative integer" end end idx = arg.each_with_index.map { |a, i| [i] * a }.flatten end ref = [true] * c.ndim ref[axis] = idx c[*ref].copy end |
#rot90(k = 1, axes = [0, 1]) ⇒ Object
Rotate in the plane specified by axes.
98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/cumo/narray/extra.rb', line 98 def rot90(k=1, axes=[0, 1]) case k % 4 when 0 view when 1 swapaxes(*axes).reverse(axes[0]) when 2 reverse(*axes) when 3 swapaxes(*axes).reverse(axes[1]) end end |
#set(src, stream: nil) ⇒ Object
Copies a host buffer into this array. A Cumo::CUDA::PinnedMemory is copied asynchronously on the current stream, or on stream:, and a String of bytes synchronously.
8 9 10 11 12 13 14 15 16 17 18 19 |
# File 'lib/cumo/narray/extra.rb', line 8 def set(src, stream: nil) case src when Cumo::CUDA::PinnedMemory src.copy(self, :to_narray, stream) when String raise ArgumentError, "a String is copied synchronously, so it takes no stream:" unless stream.nil? store_binary(src) else raise TypeError, "set takes a Cumo::CUDA::PinnedMemory or a String, got a #{src.class}" end self end |
#split(indices_or_sections, axis: 0) ⇒ Object
772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 |
# File 'lib/cumo/narray/extra.rb', line 772 def split(indices_or_sections, axis:0) axis = check_axis(axis) size_axis = shape[axis] case indices_or_sections when Integer div_axis, mod_axis = size_axis.divmod(indices_or_sections) refs = [true] * ndim beg_idx = 0 mod_axis.times.map do |i| end_idx = beg_idx + div_axis + 1 refs[axis] = beg_idx ... end_idx beg_idx = end_idx self[*refs] end + (indices_or_sections - mod_axis).times.map do |i| end_idx = beg_idx + div_axis refs[axis] = beg_idx ... end_idx beg_idx = end_idx self[*refs] end when NArray split(indices_or_sections.to_a, axis:axis) when Array refs = [true] * ndim fst = 0 (indices_or_sections + [size_axis]).map do |lst| lst = size_axis if lst > size_axis refs[axis] = (fst < size_axis) ? fst...lst : -1...-1 fst = lst self[*refs] end else raise TypeError, "argument must be Integer or Array" end end |
#tile(*arg) ⇒ Object
900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 |
# File 'lib/cumo/narray/extra.rb', line 900 def tile(*arg) arg.each do |i| if !i.kind_of?(Integer) || i < 1 raise ArgumentError, "argument should be positive integer" end end ns = arg.size nd = self.ndim shp = self.shape new_shp = [] src_shp = [] res_shp = [] (nd - ns).times do new_shp << 1 new_shp << (n = shp.shift) src_shp << :new src_shp << true res_shp << n end (ns - nd).times do new_shp << (m = arg.shift) new_shp << 1 src_shp << :new src_shp << :new res_shp << m end [nd, ns].min.times do new_shp << (m = arg.shift) new_shp << (n = shp.shift) src_shp << :new src_shp << true res_shp << n * m end self.class.new(*new_shp).store(self[*src_shp]).reshape(*res_shp) end |
#to_c ⇒ Object
129 130 131 132 133 134 135 136 |
# File 'lib/cumo/narray/extra.rb', line 129 def to_c if size == 1 Complex(self[0].extract_cpu) else # convert to DComplex? raise TypeError, "can't convert #{self.class} into Complex" end end |
#to_f ⇒ Object
120 121 122 123 124 125 126 127 |
# File 'lib/cumo/narray/extra.rb', line 120 def to_f if size == 1 self[0].extract_cpu.to_f else # convert to DFloat? raise TypeError, "can't convert #{self.class} into Float" end end |
#to_i ⇒ Object
111 112 113 114 115 116 117 118 |
# File 'lib/cumo/narray/extra.rb', line 111 def to_i if size == 1 self[0].extract_cpu.to_i else # convert to Int? raise TypeError, "can't convert #{self.class} into Integer" end end |
#trace(offset = nil, axis = nil, nan: false) ⇒ Object
Return the sum along diagonals of the array.
If 2-D array, computes the summation along its diagonal with the
given offset, i.e., sum of a[i,i+offset].
If more than 2-D array, the diagonal is determined from the axes
specified by axis argument. The default is axis=[-2,-1].
1218 1219 1220 |
# File 'lib/cumo/narray/extra.rb', line 1218 def trace(offset=nil, axis=nil, nan:false) diagonal(offset, axis).sum(nan:nan, axis:-1) end |
#tril(k = 0) ⇒ Object
Lower triangular matrix. Return a copy with the elements above the k-th diagonal filled with zero.
1091 1092 1093 |
# File 'lib/cumo/narray/extra.rb', line 1091 def tril(k=0) dup.tril!(k) end |
#tril!(k = 0) ⇒ Object
Lower triangular matrix. Fill the self elements above the k-th diagonal with zero.
1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 |
# File 'lib/cumo/narray/extra.rb', line 1097 def tril!(k=0) if ndim < 2 raise NArray::ShapeError, "must be >= 2-dimensional array" end if contiguous? idx = triu_indices(k + 1) *shp, m, n = shape reshape!(*shp, m * n) self[false, idx] = 0 reshape!(*shp, m, n) else store(tril(k)) end end |
#tril_indices(k = 0) ⇒ Object
Return the indices for the lower-triangle on and below the k-th diagonal.
1113 1114 1115 1116 1117 1118 1119 |
# File 'lib/cumo/narray/extra.rb', line 1113 def tril_indices(k=0) if ndim < 2 raise NArray::ShapeError, "must be >= 2-dimensional array" end m, n = shape[-2..-1] NArray.tril_indices(m, n, k) end |
#triu(k = 0) ⇒ Object
Upper triangular matrix. Return a copy with the elements below the k-th diagonal filled with zero.
1052 1053 1054 |
# File 'lib/cumo/narray/extra.rb', line 1052 def triu(k=0) dup.triu!(k) end |
#triu!(k = 0) ⇒ Object
Upper triangular matrix. Fill the self elements below the k-th diagonal with zero.
1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 |
# File 'lib/cumo/narray/extra.rb', line 1058 def triu!(k=0) if ndim < 2 raise NArray::ShapeError, "must be >= 2-dimensional array" end if contiguous? *shp, m, n = shape idx = tril_indices(k - 1) reshape!(*shp, m * n) self[false, idx] = 0 reshape!(*shp, m, n) else store(triu(k)) end end |
#triu_indices(k = 0) ⇒ Object
Return the indices for the upper-triangle on and above the k-th diagonal.
1074 1075 1076 1077 1078 1079 1080 |
# File 'lib/cumo/narray/extra.rb', line 1074 def triu_indices(k=0) if ndim < 2 raise NArray::ShapeError, "must be >= 2-dimensional array" end m, n = shape[-2..-1] NArray.triu_indices(m, n, k) end |
#vsplit(indices_or_sections) ⇒ Object
841 842 843 |
# File 'lib/cumo/narray/extra.rb', line 841 def vsplit(indices_or_sections) split(indices_or_sections, axis:0) end |