Class: NumRu::Grid

Inherits:
Object
  • Object
show all
Defined in:
lib/numru/gphys/grid.rb,
lib/numru/gphys/gphys_dim_op.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*axes) ⇒ Grid

Returns a new instance of Grid.



225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
# File 'lib/numru/gphys/grid.rb', line 225

def initialize( *axes )
	 @axes = Array.new
	 axes.each{|ag|
      ### commented out for the duck typing:
      #if ag.is_a?(Axis)
      @axes.push(ag)
      #else
      #   raise ArgumentError, "each argument must be an Axis"
	    #end
	 }
	 @lost_axes = Array.new   # Array of String
	 @rank = @axes.length
	 @axnames = Array.new
	 __check_and_set_axnames
   @assoc_coords = nil
end

Instance Attribute Details

#rankObject (readonly)

Returns the value of attribute rank.



280
281
282
# File 'lib/numru/gphys/grid.rb', line 280

def rank
  @rank
end

Instance Method Details

#[](*slicer) ⇒ Object



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
# File 'lib/numru/gphys/grid.rb', line 501

def [] (*slicer)
	 if slicer.length == 0
	    # make a clone
	    axes = Array.new
	    (0...rank).each{ |i| axes.push( @axes[i][0..-1] ) }
	    grid = self.class.new( *axes )
	 else
	    slicer = __rubber_expansion(slicer)
	    if slicer.length != rank
  raise ArgumentError,"# of the args does not agree with the rank"
	    end
	    axes = Array.new
	    lost = self.lost_axes  #Array.new
	    for i in 0...rank
  ax = @axes[i][slicer[i]]
  if ax.is_a?(String)
           lost.push( ax )
         else
           axes.push( ax )
  end
	    end
	    grid = self.class.new( *axes )
	    grid.set_lost_axes( lost ) if lost.length != 0
	 end
   if @assoc_coords
     grid.assoc_coords = @assoc_coords[*slicer]
   end
   grid
end

#add_lost_axes(lost) ⇒ Object



368
369
370
371
# File 'lib/numru/gphys/grid.rb', line 368

def add_lost_axes( lost )
	 @lost_axes = @lost_axes + lost   # Array of String
   self
end

#assoc_coord_gphys(name) ⇒ Object



338
339
340
# File 'lib/numru/gphys/grid.rb', line 338

def assoc_coord_gphys(name)
  @assoc_coords && @assoc_coords.coord_gphys(name)
end

#assoc_coordsObject



260
261
262
# File 'lib/numru/gphys/grid.rb', line 260

def assoc_coords
  @assoc_coords
end

#assoc_coords=(assoc_coords) ⇒ Object

  • assoc_coords : an AssocCoords



256
257
258
# File 'lib/numru/gphys/grid.rb', line 256

def assoc_coords=(assoc_coords)
  @assoc_coords = assoc_coords 
end

#assoccoordnamesObject



316
317
318
# File 'lib/numru/gphys/grid.rb', line 316

def assoccoordnames
	@assoc_coords && @assoc_coords.coordnames
end

#axis(dim_or_dimname) ⇒ Object Also known as: get_axis

def axis(i)

@axes[i]
    end


324
325
326
# File 'lib/numru/gphys/grid.rb', line 324

def axis(dim_or_dimname)
	 ax_dim(dim_or_dimname)[0]
end

#axnamesObject



282
283
284
# File 'lib/numru/gphys/grid.rb', line 282

def axnames
	@axnames.dup
end

#binning(dim, len) ⇒ Object



188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
# File 'lib/numru/gphys/gphys_dim_op.rb', line 188

def binning(dim, len)
  dim = dim_index(dim)  # to handle String or negative specification

  #< axes >
  axes = (0...rank).collect{|d| axis(d)}
  axes[dim] = axes[dim].binning(len)  # bin the dim-th axis
  newgrid = Grid.new(*axes)

  #< assoc coords are retained if it does not have the dim >
  if assoc_coords
    dimname = self.axis(dim).name
    acs = Array.new
    assoccoordnames.each do |nm|
      ac = assoc_coord_gphys(nm)
      acs.push(ac) if !ac.dimnames.include?(dimname)
    end
    newgrid.set_assoc_coords(acs) if acs.length > 0
  end

  #< return >
  newgrid
end

#change_axis(dim, axis) ⇒ Object

def exclude(dim_or_dimname)

dim = dim_index(dim_or_dimname)
axes = @axes.dup
axes.delete_at(dim)
self.class.new( *axes )
    end


606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
# File 'lib/numru/gphys/grid.rb', line 606

def change_axis(dim, axis)
	 axes = @axes.dup
	 lost = @lost_axes.dup
	 if axis.is_a?(Axis)
	    axes[dim] = axis
	 else
	    lost.push(axis) if axis.is_a?(String)
	    axes.delete_at(dim)
	 end
	 grid = self.class.new( *axes ).add_lost_axes( lost )
   if @assoc_coords
     grid.assoc_coords=@assoc_coords.subset_having_axnames(grid.axnames)
   end
   grid
end

#coord(i) ⇒ Object



330
331
332
333
334
335
336
# File 'lib/numru/gphys/grid.rb', line 330

def coord(i)
  if @assoc_coords && i.is_a?(String) && @assoc_coords.has_coord?(i)
    @assoc_coords.coord(i)
  else
    axis(i).pos
  end
end

#coord_dim_indices(coordname) ⇒ Object



346
347
348
349
350
351
352
353
354
355
356
# File 'lib/numru/gphys/grid.rb', line 346

def coord_dim_indices(coordname)
  dim = @axnames.index(coordname)
  if dim
    [dim]
  elsif @assoc_coords && @assoc_coords.has_coord?(coordname)
    axnms = @assoc_coords.coord_gphys(coordname).axnames
    axnms.collect{|nm| @axnames.index(nm)}
  else
    nil
  end
end

#coordnamesObject



289
290
291
292
293
# File 'lib/numru/gphys/grid.rb', line 289

def coordnames
  ret = axnames
  ret.concat(@assoc_coords.coordnames) if @assoc_coords
  ret
end

#copyObject



444
445
446
447
448
449
450
# File 'lib/numru/gphys/grid.rb', line 444

def copy
	 # deep clone onto memory
	 out = self.class.new( *@axes.collect{|ax| ax.copy} )
	 out.set_lost_axes( @lost_axes.dup )
   out.assoc_coords = @assoc_coords.copy if @assoc_coords
	 out
end

#cut(*args) ⇒ Object



553
554
555
# File 'lib/numru/gphys/grid.rb', line 553

def cut(*args)
	_cut_(false, *args)
end

#cut_assoccoord(hasharg) ⇒ Object



547
548
549
550
551
# File 'lib/numru/gphys/grid.rb', line 547

def cut_assoccoord(hasharg)
  ac, acsl = @assoc_coords.cut(hasharg)
  sl = @axnames.collect{|nm| acsl[nm] || true}
  [ self[*sl], sl ]
end

#cut_rank_conserving(*args) ⇒ Object



556
557
558
# File 'lib/numru/gphys/grid.rb', line 556

def cut_rank_conserving(*args)
	_cut_(true, *args)
end

#delete_axes(at, deleted_by = nil) ⇒ Object



373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
# File 'lib/numru/gphys/grid.rb', line 373

def delete_axes( at, deleted_by=nil )
	case at
  when String
    at = [dim_index(at)]
	when Numeric
	  at = [at]
	when Array
    at = at.collect{|x|
      case x
      when String
        dim_index(x)
      when Integer
        x
      else
        raise ArgumentError,"'at' must consist of Integer and/or String"
      end
    }
	else
	  raise TypeError, "1st arg not an Array"
	end

	at.collect!{|pos| 
	  if pos < 0
	    pos + a.length
	  else
	    pos
	  end
	}
	at.sort!
	newaxes = @axes.dup
	at.reverse.each{|pos| 
	  del = newaxes.delete_at(pos)
	  if !del
	    raise ArgumentError, "dimension #{pos} does not exist in a #{rank}D Grid"
	  end
	}

	newgrid = self.class.new( *newaxes )
	newgrid.set_lost_axes( @lost_axes.dup )
  if @assoc_coords
    if deleted_by && VArray::NArray_type3_methods.include?(deleted_by)
      assoc_coords = Array.new
      assoccoordnames.each do |aname|
        g = assoc_coord_gphys(aname)
        args = g.axnames & at.collect{|i| @axnames[i]}
        g = g.mean(*args) unless args.empty?
        assoc_coords.push g if GPhys === g
      end
      newgrid.set_assoc_coords assoc_coords
    else
      newgrid.assoc_coords = @assoc_coords.subset_having_axnames(newgrid.axnames)
    end
  end

	if !deleted_by 
	  msg = '(deleted) '
	else
	  raise TypeError, "2nd arg not a String" if !deleted_by.is_a?(String)
	  msg = '('+deleted_by+') '
	end
	lost = at.collect{|pos|
	  mn = sprintf("%g", ( UNumeric===(a=@axes[pos].pos.min) ? a.val : a) )
	  mx = sprintf("%g", ( UNumeric===(a=@axes[pos].pos.max) ? a.val : a) )
	  msg + 
	  "#{@axes[pos].name}:#{mn}..#{mx}"
	}

	newgrid.add_lost_axes( lost )
	newgrid
end

#dim_index(dimname) ⇒ Object



342
343
344
# File 'lib/numru/gphys/grid.rb', line 342

def dim_index(dimname)
	 ax_dim(dimname)[1]
end

#has_assoccoord?(*arg) ⇒ Boolean

Returns:

  • (Boolean)


299
300
301
302
303
304
305
306
307
308
309
310
# File 'lib/numru/gphys/grid.rb', line 299

def has_assoccoord?(*arg)
  if arg.length == 0
    !@assoc_coords.nil?   # if a grid has assoc coords
  else
    name = arg[0]
    if @assoc_coords
      @assoc_coords.has_coord?(name)
    else
      false
    end
  end
end

#has_axis?(name) ⇒ Boolean

Returns:

  • (Boolean)


295
296
297
# File 'lib/numru/gphys/grid.rb', line 295

def has_axis?(name)
	@axnames.include?(name)
end

#has_coord?(name) ⇒ Boolean

Returns:

  • (Boolean)


312
313
314
# File 'lib/numru/gphys/grid.rb', line 312

def has_coord?(name)
  has_axis?(name) || has_assoccoord?(name)
end

#insert_axis(dim, axis) ⇒ Object

def insert_axis!(dim_or_dimname, axis)

dim = dim_index(dim_or_dimname)
if axis == nil
   # do nothing
else
   @axes[dim+1,0] = axis    # @axes.insert(dim, axis) if ruby 1.7
   @rank = @axes.length
   __check_and_set_axnames
end
self
    end


646
647
648
649
650
651
652
653
654
655
656
657
658
# File 'lib/numru/gphys/grid.rb', line 646

def insert_axis(dim, axis)
  axes = @axes.dup
  ### commented out for the duck typing:
  #if axis.is_a?(Axis)
    axes.insert(dim, axis)
  #else
  #  raise ArgumentError, "2nd arg must be an Axis"
  #end
  grid = self.class.new( *axes )
	grid.set_lost_axes( lost_axes )
  grid.assoc_coords = @assoc_coords.dup if @assoc_coords
	grid
end

#inspectObject



264
265
266
# File 'lib/numru/gphys/grid.rb', line 264

def inspect
  "<#{rank}D grid #{@axes.collect{|ax| ax.inspect}.join("\n\t")}#{@assoc_coords ? "\n"+@assoc_coords.inspect.gsub(/^/,"\t") : ''}>"
end

#lost_axesObject



285
286
287
# File 'lib/numru/gphys/grid.rb', line 285

def lost_axes
	@lost_axes.dup
end

#merge(other) ⇒ Object



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/numru/gphys/grid.rb', line 452

def merge(other)
	# merge two grids by basically using copies of self's axes but
	# using the other's if the length in self is 1 and 
  # the length in the other is longer
	if self.rank != other.rank
	  raise "ranks do not agree (self:#{self.rank} vs other:#{other.rank})"
	end
	axes = Array.new
	for i in 0...self.rank
	  if @axes[i].length == 1 and other.axis(i).length > 1
	    axes[i] = other.axis(i)
	  else
	    axes[i] = @axes[i]
	  end
	end
	out = self.class.new( *axes )
	out.set_lost_axes( (@lost_axes.dup + other.lost_axes).uniq )
  if (oac = other.assoc_coords) || (sac = self.assoc_coords)
    sac ? ac=sac.merge(oac) : ac=oac.merge(sac)
    out.assoc_coords = ac
  end
	out
end

#set_assoc_coords(assoc_crds) ⇒ Object

  • assoc_crds : an Array of GPhys



244
245
246
247
248
249
250
251
252
# File 'lib/numru/gphys/grid.rb', line 244

def set_assoc_coords(assoc_crds)
  @assoc_coords = AssocCoords.new(assoc_crds, @axnames)
  @assoc_coords.axlens.each do |nm,l|
    if l && l != (l0 = shape[dim_index(nm)])
      raise ArgumentError, "Length mismatch in coord #{nm} (#{l0}) and assoc_crds (#{l}). You may need to regrid (use GPhys#regrid method) associated coordinate(s) in advance."
    end
  end
  self
end

#set_axis(dim_or_dimname, ax) ⇒ Object



358
359
360
361
362
# File 'lib/numru/gphys/grid.rb', line 358

def set_axis(dim_or_dimname,ax)
	 @axes[ i = dim_index(dim_or_dimname) ] = ax
   @axnames[ i ] = ax.name
	 self
end

#set_lost_axes(lost) ⇒ Object



364
365
366
367
# File 'lib/numru/gphys/grid.rb', line 364

def set_lost_axes( lost )
	 @lost_axes = lost   # Array of String
   self
end

#shapeObject Also known as: shape_current



476
477
478
# File 'lib/numru/gphys/grid.rb', line 476

def shape
	 @axes.collect{|ax| ax.length}
end

#transpose(*dims) ⇒ Object



660
661
662
663
664
665
666
667
668
669
670
671
672
673
# File 'lib/numru/gphys/grid.rb', line 660

def transpose( *dims )
	if dims.sort != NArray.int(rank).indgen!.to_a
	  raise ArgumentError, 
      "Args must a permutation of 0..rank-1 (eg, if 3D 2,1,0; 1,0,2;etc)"
	end
	axes = Array.new
	for i in 0...rank
	  axes[i] = @axes[dims[i]]
	end
	grid = self.class.new(*axes)
	grid.set_lost_axes( lost_axes )
  grid.assoc_coords = @assoc_coords.dup if @assoc_coords
	grid
end