class Phys::Quantity

Phys::Quantity is the primary class of Phys-Units library, intended to be manipulated by users. This class represents Physical Quantities with a Unit of measurement. It contains Value and Unit.

@example

require 'phys/units'
Q = Phys::Quantity

Q[1.23,'km'] + Q[4.56,'m']    #=> Phys::Quantity[1.23456,'km']
Q[123,'mile'] / Q[2,'hr']     #=> Phys::Quantity[61,'mile/hr']
Q[61,'miles/hr'].want('m/s')  #=> Phys::Quantity[27.26944,'m/s']
Q[1.0,'are'] == Q[10,'m']**2  #=> true
Q[70,'tempF'] + Q[10,'degC']  #=> Phys::Quantity[88,'tempF']
Q[20,'tempC'].want('tempF')   #=> Phys::Quantity[68,'tempF']
Math.cos(Q[60,'degree'].to_f) #=> 0.5

@see Unit

Attributes

expr[R]

Unit expression. Given as the second parameter of the Quantity constructor. @return [String]

unit[R]

Unit of the quantity. Instance of Phys::Unit class. @return [Phys::Unit]

val[R]

Value of the quantity. Instance of classes with same arithmetic methods as Numeric. @return [Object]

value[R]

Value of the quantity. Instance of classes with same arithmetic methods as Numeric. @return [Object]

Public Class Methods

[](value,unit=nil) click to toggle source

Alias to Phys::Quantity.new. @param [Object] value Value of quantity. @param [String,Symbol,Phys::Unit] unit

* If +unit+ String or Symbol, it is regarded as a unit expression (to be parsed later).
* If +unit+ is Phys::Unit, it is used as the unit of new quantity.
* If +unit+ is not provided, the quantity is regarded as dimensionless.

@return [Phys::Quantity] @raise [TypeError] if invalid arg types. @raise [Phys::UnitError] if unit conversion is failed.

# File lib/phys/units/quantity.rb, line 63
def [](value,unit=nil)
  self.new(value,unit)
end
new(value,expr=nil,unit=nil) click to toggle source

Initialize a new quantity. @overload initialize(value,expr,unit=nil)

@param [Object]     value  Value of quantity.
@param [String,Symbol] expr  Unit expression.
@param [Phys::Unit] unit   If exists, this parameter is used as the unit of new quantity.

@overload initialize(value,unit)

@param [Object]     value  Value of quantity.
@param [Phys::Unit] unit   This parameter is used as the unit of new quantity.

@overload initialize(value)

@param [Object]     value  Value of a dimensionless quantity.

@raise [TypeError] if invalid arg types. @raise [Phys::UnitError] if unit conversion is failed.

# File lib/phys/units/quantity.rb, line 81
def initialize(value,expr=nil,unit=nil)
  @value = value
  case expr
  when String, Symbol
    @expr = expr.to_s.strip
    @expr = nil if @expr==''
    @unit = unit
  when NilClass
    @expr = nil
    @unit = unit
  when Unit
    raise ArgumentError,"Wrong # of argument" if unit
    @expr = nil
    @unit = expr
  else
    raise ArgumentError,"Second argument is invalid: #{expr.inspect}"
  end
  case @unit
  when NilClass
    @unit = Unit.parse(@expr||1)
  when Unit
  else
    raise ArgumentError, "Third argument is invalid: #{@unit.inspect}"
  end
end

Public Instance Methods

%(other) click to toggle source

Modulo.

  • If the other param is Phys::Quantity, other is converted to the unit of self, and returns modulo of values.

  • If the other param is not Phys::Quantity, other is regarded as dimensionless, and returns modulo of Phys::Quantity.

@param [Object] other @return [Object] modulo @raise [Phys::UnitError] if unit conversion is failed.

# File lib/phys/units/quantity.rb, line 453
def %(other)
  if Quantity===other
    @value % @unit.convert(other)
  else
    self.class.new( @value % other, @expr, @unit )
  end
end
Also aliased as: modulo
*(other) click to toggle source

Multiplication. If the other param is not Phys::Quantity, other is regarded as a dimensionless value. The values and units are multiplied respectively. @param [Object] other @return [Phys::Quantity] a quantity @raise [Phys::UnitError] if unit is not operable.

# File lib/phys/units/quantity.rb, line 354
def *(other)
  if Quantity===other
    a = [self.enclose_expr, other.enclose_expr]
    a.delete(nil)
    self.class.new( @value*other.value, a.join(' '), @unit*other.unit )
  else
    self.class.new( @value*other, @expr, @unit )
  end
end
**(n) click to toggle source

Exponentiation. @param [Numeric] n @return [Phys::Quantity] a quantity in the n -powered unit of self. @raise [Phys::UnitError] if unit conversion is failed.

# File lib/phys/units/quantity.rb, line 311
def **(n)
  if @expr.nil?
    expr = nil
  elsif /^[A-Za-z_]+$/o =~ @expr
    expr = @expr+'^'+n.to_s
  else
    expr = '('+@expr+')^'+n.to_s+''
  end
  self.class.new( @value**n, expr, @unit**n )
end
+(other) click to toggle source

Addition. Before the operation, it converts other to the unit of self.

  • If the other param is Phys::Quantity, other is converted to the unit of self.

  • If the other param is not Phys::Quantity, both params must be dimensionless.

@param [Object] other @return [Phys::Quantity] a quantity in the unit of self. @raise [Phys::UnitError] if unit conversion is failed.

# File lib/phys/units/quantity.rb, line 159
def +(other)
  val = @value + @unit.convert_scale(other)
  self.class.new( val, @expr, @unit )
end
+@() click to toggle source

Unary Plus. Returns self. @return [Phys::Quantity]

# File lib/phys/units/quantity.rb, line 223
def +@
  self.class.new(  @value, @expr, @unit )
end
-(other) click to toggle source

Subtraction. Before the operation, it converts other to the unit of self.

  • If the other param is Phys::Quantity, other is converted to the unit of self.

  • If the other param is not Phys::Quantity, both params must be dimensionless.

@param [Object] other @return [Phys::Quantity] a quantity in the unit of self. @raise [Phys::UnitError] if unit conversion is failed.

# File lib/phys/units/quantity.rb, line 174
def -(other)
  val = @value - @unit.convert_scale(other)
  self.class.new( val, @expr, @unit )
end
-@() click to toggle source

Unary Minus. Returns a quantity with negative value in the same unit of self. @return [Phys::Quantity]

# File lib/phys/units/quantity.rb, line 230
def -@
  self.class.new( -@value, @expr, @unit )
end
/(other) click to toggle source

Division. If the other param is not Phys::Quantity, other is regarded as a dimensionless value. The values and units are divided respectively. Note that the method of the value's class is used. @example

Phys::Quantity[3,:m]/2 #=> Phys::Quantity[1,"m"]

@param [Object] other @return [Phys::Quantity] a quantity @raise [Phys::UnitError] if unit is not operable.

# File lib/phys/units/quantity.rb, line 375
def /(other)
  if Quantity===other
    a = [self.enclose_expr, other.enclose_expr_div]
    a.delete(nil)
    self.class.new( @value/other.value, a.join, @unit/other.unit )
  else
    self.class.new( @value/other, @expr, @unit )
  end
end
<(other) click to toggle source

Comparison. Returns true if self is less than other. Before the comparison, it converts other to the unit of self. @param [Phys::Quantity] other @return [Boolean] @raise [Phys::UnitError] if unit conversion is failed.

# File lib/phys/units/quantity.rb, line 281
def < (other)
  @value < @unit.convert(other)
end
<=(other) click to toggle source

Comparison. Returns true if self is less-than or equal-to other. Before the comparison, it converts other to the unit of self. @param [Phys::Quantity] other @return [Boolean] @raise [Phys::UnitError] if unit conversion is failed.

# File lib/phys/units/quantity.rb, line 272
def <= (other)
  @value <= @unit.convert(other)
end
<=>(other) click to toggle source

Comparison of quantities. Before the comparison, it converts other to the unit of self. @param [Phys::Quantity] other @return [Integer] @raise [Phys::UnitError] if unit conversion is failed.

# File lib/phys/units/quantity.rb, line 239
def <=> (other)
  @value <=> @unit.convert(other)
end
==(other) click to toggle source

Equality. Returns true if self has the same value as other. Before the comparison, it converts other to the unit of self. @param [Phys::Quantity] other @return [Boolean]

# File lib/phys/units/quantity.rb, line 247
def == (other)
  if Quantity===other
    @unit.conformable?(other.unit) &&
      @value == @unit.convert(other)
  elsif @unit.dimensionless?
    @unit.convert_value_to_base_unit(@value) == other
  else
    false
  end
end
===(x) click to toggle source

Conformability of quantity. Returns true if unit conversion between self and x is possible. @param [Object] x other object (Unit or Quantity or Numeric or something else) @return [Boolean]

# File lib/phys/units/quantity.rb, line 557
def ===(x)
  case x
  when Unit
    unit === x
  when Quantity
    unit === x.unit
  when Numeric
    unit.dimensionless?
  else
    false
  end
end
>(other) click to toggle source

Comparison. Returns true if self is greater than other. Before the comparison, it converts other to the unit of self. @param [Phys::Quantity] other @return [Boolean] @raise [Phys::UnitError] if unit conversion is failed.

# File lib/phys/units/quantity.rb, line 290
def > (other)
  @value > @unit.convert(other)
end
>=(other) click to toggle source

Comparison. Returns true if self is greater-than or equal-to other. Before the comparison, it converts other to the unit of self. @param [Phys::Quantity] other @return [Boolean] @raise [Phys::UnitError] if unit conversion is failed.

# File lib/phys/units/quantity.rb, line 263
def >= (other)
  @value >= @unit.convert(other)
end
>>(unit=nil)
Alias for: want
abs() click to toggle source

Absolute. Returns a quantity in the same unit of self. @return [Phys::Quantity]

# File lib/phys/units/quantity.rb, line 181
def abs
  self.class.new( @value.abs, @expr, @unit )
end
abs2() click to toggle source

Square. Returns a quantity in squared unit of self. @return [Phys::Quantity]

# File lib/phys/units/quantity.rb, line 187
def abs2
  self**2
end
ceil() click to toggle source

Ceil. Returns a quantity with the smallest Integer value greater than or equal to self value, in the same unit of self. @return [Phys::Quantity]

# File lib/phys/units/quantity.rb, line 194
def ceil
  self.class.new( @value.ceil, @expr, @unit )
end
close_to(other,epsilon=Float::EPSILON) click to toggle source

Closeness. Returns true if

(self-other).abs <= (self.abs+other.abs) * epsilon

Before the comparison, it converts other to the unit of self. @param [Phys::Quantity] other @param [Numeric] epsilon @return [Boolean] @raise [Phys::UnitError] if unit conversion is failed.

# File lib/phys/units/quantity.rb, line 301
def close_to(other,epsilon=Float::EPSILON)
  other_value = @unit.convert(other)
  abs_sum = @value.abs+other_value.abs
  (@value-other_value).abs <= abs_sum*epsilon
end
coerce(other) click to toggle source

@return [Array]

# File lib/phys/units/quantity.rb, line 484
def coerce(other)
  [ self.class.new(other), self ]
end
compatible?(x)
Alias for: ===
conformable?(x)
Alias for: ===
conversion_allowed?(x)
Alias for: ===
convert(unit=nil)
Alias for: want
div(other) click to toggle source

Division without Modulo.

  • If the other param is Phys::Quantity, other is converted to the unit of self, and returns div of values.

  • If the other param is not Phys::Quantity, other is regarded as dimensionless, and returns div of Phys::Quantity.

@param [Object] other @return [Object] div @raise [Phys::UnitError] if unit conversion is failed.

# File lib/phys/units/quantity.rb, line 415
def div(other)
  if Quantity===other
    @value.div( @unit.convert(other) )
  else
    self.class.new( @value.div(other), @expr, @unit )
  end
end
divmod(other) click to toggle source

Division with Modulo.

  • If the other param is Phys::Quantity, other is converted to the unit of self, and returns divmod of values.

  • If the other param is not Phys::Quantity, other is regarded as dimensionless, and returns divmod of Phys::Quantity.

@param [Object] other @return [Array] result of divmod, an array of [quotient, modulo]. @raise [Phys::UnitError] if unit conversion is failed.

# File lib/phys/units/quantity.rb, line 473
def divmod(other)
  if Quantity===other
    @value.divmod( @unit.convert(other) )
  else
    d,m = @value.divmod(other)
    [ self.class.new( d, @expr, @unit ),
      self.class.new( m, @expr, @unit ) ]
  end
end
fdiv(other)
Alias for: quo
floor() click to toggle source

Floor. Returns a quantity with the largest integer value less than or equal to self value, in the same unit of self. @return [Phys::Quantity]

# File lib/phys/units/quantity.rb, line 210
def floor
  self.class.new( @value.floor, @expr, @unit )
end
inspect() click to toggle source

Inspect String. @return [String]

# File lib/phys/units/quantity.rb, line 547
def inspect
  expr = @expr || @unit.expr
  expr = (expr) ? ","+expr.inspect : ""
  sufx = (@@verbose_inspect) ? " "+@unit.inspect : ""
  self.class.to_s+"["+Unit::Utils.num_inspect(@value)+expr+"]"+sufx
end
modulo(other)
Alias for: %
quo(other) click to toggle source

Division more correctly. If the other param is not Phys::Quantity, other is regarded as a dimensionless value. The values and units are divided respectively. @param [Object] other @return [Phys::Quantity] a quantity @raise [Phys::UnitError] if unit is not operable.

# File lib/phys/units/quantity.rb, line 393
def quo(other)
  if Quantity===other
    a = [self.enclose_expr, other.enclose_expr_div]
    a.delete(nil)
    self.class.new( @value.quo(other.value), a.join, @unit/other.unit )
  else
    self.class.new( @value.quo(other), @expr, @unit )
  end
end
Also aliased as: fdiv
round(ndigits=nil) click to toggle source

Round. Rounds self value to a given precision in decimal digits (default 0 digits). Returns a quantity with the rounded value in the same unit of self. @return [Phys::Quantity]

# File lib/phys/units/quantity.rb, line 202
def round(ndigits=nil)
  val = ndigits ? @value.round(ndigits) : @value.round
  self.class.new( val, @expr, @unit )
end
to_SI()
Alias for: to_base_unit
to_base_unit() click to toggle source

Conversion to base unit. Returns the quantity converted to a base unit. @return [Phys::Quantity] a quantity in the base unit. @raise [Phys::UnitError] if unit conversion is failed.

# File lib/phys/units/quantity.rb, line 492
def to_base_unit
  unit = @unit.base_unit
  val  = unit.convert(self)
  expr = unit.unit_string
  self.class.new( val, expr, unit )
end
Also aliased as: to_si, to_SI
to_f() click to toggle source

Conversion to Float. @return [Float] @raise [Phys::UnitError] if the unit is not dimensionless.

# File lib/phys/units/quantity.rb, line 512
def to_f
  to_numeric.to_f
end
Also aliased as: to_float
to_float()
Alias for: to_f
to_i() click to toggle source

Conversion to Integer. @return [Integer] @raise [Phys::UnitError] if the unit is not dimensionless.

# File lib/phys/units/quantity.rb, line 520
def to_i
  to_numeric.to_i
end
Also aliased as: to_int, to_integer
to_int()
Alias for: to_i
to_integer()
Alias for: to_i
to_num()
Alias for: to_numeric
to_numeric() click to toggle source

Conversion to Numeric. @return [Numeric] @raise [Phys::UnitError] if the unit is not dimensionless.

# File lib/phys/units/quantity.rb, line 504
def to_numeric
  @unit.to_numeric * @value
end
Also aliased as: to_num
to_r() click to toggle source

Conversion to Rational. @return [Rational] @raise [Phys::UnitError] if the unit is not dimensionless.

# File lib/phys/units/quantity.rb, line 529
def to_r
  to_numeric.to_r
end
Also aliased as: to_rational
to_rational()
Alias for: to_r
to_s() click to toggle source

Conversion to String. @return [String]

# File lib/phys/units/quantity.rb, line 536
def to_s
  if @expr
    expr = ",'" +@expr+"'"
  else
    expr = ""
  end
  self.class.to_s+"["+Unit::Utils.num_inspect(@value)+expr+"]"
end
to_si()
Alias for: to_base_unit
truncate() click to toggle source

Truncate. Returns a quantity with the value truncated to an integer, in the same unit of self. @return [Phys::Quantity]

# File lib/phys/units/quantity.rb, line 217
def truncate
  self.class.new( @value.truncate, @expr, @unit )
end
want(unit=nil) click to toggle source

Conversion to a quantity in another unit. @param [String,Symbol,Unit,Quantity] unit unit expression. @return [Phys::Quantity] quantity in the unit of unit. @raise [Phys::UnitError] if unit conversion is failed.

# File lib/phys/units/quantity.rb, line 126
def want(unit=nil)
  case unit
  when Unit
    expr = unit.expr
  when Quantity
    expr = unit.expr
    unit = unit.unit
  when String,Symbol
    expr = unit
    unit = Unit.parse(expr)
  when Numeric
    unit = Unit.cast(unit)
  when NilClass
    unit = Unit.cast(1)
  else
    raise TypeError, "invalid argument: #{unit.inspect}"
  end
  val = unit.convert(self)
  self.class.new( val, expr, unit )
end
Also aliased as: convert, >>