Class: NumRu::Grid

Inherits:
Object
  • Object
show all
Defined in:
lib/numru/gphys/grid.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
# File 'lib/numru/gphys/grid.rb', line 225

def initialize( *axes )
	 @axes = Array.new
	 axes.each{|ag|
	    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.



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

def rank
  @rank
end

Instance Method Details

#[](*slicer) ⇒ Object



469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
# File 'lib/numru/gphys/grid.rb', line 469

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?(Axis)      # else its rank became zero (lost)
		  axes.push( ax )
         else
		  lost.push( ax )
  end
	    end
	    grid = self.class.new( *axes )
	    grid.set_lost_axes( lost ) if lost.length != 0
	    grid
	 end
   if @assoc_coords
     grid.assoc_coords = @assoc_coords[*slicer]
   end
   grid
end

#add_lost_axes(lost) ⇒ Object



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

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

#assoc_coord_gphys(name) ⇒ Object



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

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

#assoc_coordsObject



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

def assoc_coords
  @assoc_coords
end

#assoc_coords=(assoc_coords) ⇒ Object

  • assoc_coords : an AssocCoords



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

def assoc_coords=(assoc_coords)
  @assoc_coords = assoc_coords 
end

#assoccoordnamesObject



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

def assoccoordnames
	@assoc_coords && @assoc_coords.coordnames
end

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

def axis(i)

@axes[i]
    end


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

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

#axnamesObject



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

def axnames
	@axnames.dup
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


574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
# File 'lib/numru/gphys/grid.rb', line 574

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



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

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



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

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



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

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

#copyObject



432
433
434
435
436
437
438
# File 'lib/numru/gphys/grid.rb', line 432

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



522
523
524
# File 'lib/numru/gphys/grid.rb', line 522

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

#cut_assoccoord(hasharg) ⇒ Object



516
517
518
519
520
# File 'lib/numru/gphys/grid.rb', line 516

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



525
526
527
# File 'lib/numru/gphys/grid.rb', line 525

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

#delete_axes(at, deleted_by = nil) ⇒ Object



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

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
    newgrid.assoc_coords=@assoc_coords.subset_having_axnames(newgrid.axnames)
  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



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

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

#has_assoccoord?(*arg) ⇒ Boolean

Returns:

  • (Boolean)


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

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)


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

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

#has_coord?(name) ⇒ Boolean

Returns:

  • (Boolean)


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

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

#inspectObject



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

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

#lost_axesObject



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

def lost_axes
	@lost_axes.dup
end

#merge(other) ⇒ Object



440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
# File 'lib/numru/gphys/grid.rb', line 440

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



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

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



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

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



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

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

#shapeObject Also known as: shape_current



464
465
466
# File 'lib/numru/gphys/grid.rb', line 464

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

#transpose(*dims) ⇒ 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


625
626
627
628
629
630
631
632
633
634
635
636
637
638
# File 'lib/numru/gphys/grid.rb', line 625

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