mirror of
https://github.com/gonum/gonum.git
synced 2025-10-06 15:47:01 +08:00
unit: Update documentation, create examples, and comment types
Updates 90.
This commit is contained in:
@@ -1,13 +0,0 @@
|
|||||||
# Gonum unit [](https://travis-ci.org/gonum/unit) [](https://coveralls.io/github/gonum/unit?branch=master) [](https://godoc.org/github.com/gonum/unit)
|
|
||||||
|
|
||||||
Package unit provides a set of types and constants that facilitate the use of the International System of Units (SI).
|
|
||||||
|
|
||||||
## Issues
|
|
||||||
|
|
||||||
If you find any bugs, feel free to file an issue on the github issue tracker. Discussions on API changes, added features, code review, or similar requests are preferred on the gonum-dev Google Group.
|
|
||||||
|
|
||||||
https://groups.google.com/forum/#!forum/gonum-dev
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
Please see github.com/gonum/license for general license information, contributors, authors, etc on the Gonum suite of packages.
|
|
29
unit/consts.go
Normal file
29
unit/consts.go
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
// Copyright ©2017 The gonum Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package unit
|
||||||
|
|
||||||
|
const (
|
||||||
|
Yotta = 1e24
|
||||||
|
Zetta = 1e21
|
||||||
|
Exa = 1e18
|
||||||
|
Peta = 1e15
|
||||||
|
Tera = 1e12
|
||||||
|
Giga = 1e9
|
||||||
|
Mega = 1e6
|
||||||
|
Kilo = 1e3
|
||||||
|
Hecto = 1e2
|
||||||
|
Deca = 1e1
|
||||||
|
|
||||||
|
Deci = 1e-1
|
||||||
|
Centi = 1e-2
|
||||||
|
Milli = 1e-3
|
||||||
|
Micro = 1e-6
|
||||||
|
Nano = 1e-9
|
||||||
|
Pico = 1e-12
|
||||||
|
Femto = 1e-15
|
||||||
|
Atto = 1e-18
|
||||||
|
Zepto = 1e-21
|
||||||
|
Yocto = 1e-24
|
||||||
|
)
|
22
unit/doc.go
22
unit/doc.go
@@ -26,7 +26,7 @@
|
|||||||
// func main(){
|
// func main(){
|
||||||
// t := 300 * unit.Kelvin
|
// t := 300 * unit.Kelvin
|
||||||
// p := 5 * unit.Bar
|
// p := 5 * unit.Bar
|
||||||
// rho := UnitDensity(p, t) // gives compile-time error
|
// rho := UnitDensity(p, t) // compile-time error
|
||||||
// }
|
// }
|
||||||
// gives a compile-time error (temperature type does not match pressure type)
|
// gives a compile-time error (temperature type does not match pressure type)
|
||||||
// while the corresponding code using float64 runs without error.
|
// while the corresponding code using float64 runs without error.
|
||||||
@@ -39,11 +39,11 @@
|
|||||||
// rho := Float64Density(p, t) // no error
|
// rho := Float64Density(p, t) // no error
|
||||||
// }
|
// }
|
||||||
// Many types have constants defined representing named SI units (Meter,
|
// Many types have constants defined representing named SI units (Meter,
|
||||||
// Kilogram, etc. ) or SI derived units (Bar, Milligram, etc.). These are
|
// Kilogram, etc. ) or SI derived units (Bar, Hz, etc.). The Unit package
|
||||||
// all defined as multiples of the base unit, so, for example, the following
|
// additionally provides untyped constants for SI prefixes, so the following
|
||||||
// are euqivalent
|
// are all equivalent.
|
||||||
// l := 0.001 * unit.Meter
|
// l := 0.001 * unit.Meter
|
||||||
// k := 1 * unit.Millimeter
|
// k := 1 * unit.Milli * unit.Meter
|
||||||
// j := unit.Length(0.001)
|
// j := unit.Length(0.001)
|
||||||
//
|
//
|
||||||
// 2)
|
// 2)
|
||||||
@@ -72,18 +72,6 @@
|
|||||||
// used, however, to create the unit of 'Slide', because in this case slide
|
// used, however, to create the unit of 'Slide', because in this case slide
|
||||||
// is just a measurement of area. Instead, a constant could be defined.
|
// is just a measurement of area. Instead, a constant could be defined.
|
||||||
// const Slide unit.Area = 0.001875 // m^2
|
// const Slide unit.Area = 0.001875 // m^2
|
||||||
// var WhiteBloodCellDim unit.Dimension
|
|
||||||
// func init(){
|
|
||||||
// WhiteBloodCellDim = unit.NewDimension("wbc")
|
|
||||||
// }
|
|
||||||
// type WbcPerArea float64
|
|
||||||
// func (w WbcPerArea) Unit() *Unit{
|
|
||||||
// return unit.New(float64(w), unit.Dimensions{WhiteBloodCellDim: 1, unit.LengthDim: -2})
|
|
||||||
// }
|
|
||||||
// func main(){
|
|
||||||
// v := WbcPerArea(15)
|
|
||||||
// fmt.Println(v.Unit()) // prints: 1.5e+01 m^-2 wbc
|
|
||||||
// }
|
|
||||||
// Please note that Unit cannot catch all errors related to dimensionality.
|
// Please note that Unit cannot catch all errors related to dimensionality.
|
||||||
// Different physical ideas are sometimes expressed with the same dimensions
|
// Different physical ideas are sometimes expressed with the same dimensions
|
||||||
// and Unit is incapable of catching these mismatches. For example, energy and
|
// and Unit is incapable of catching these mismatches. For example, energy and
|
||||||
|
29
unit/unitexample_test.go
Normal file
29
unit/unitexample_test.go
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
// Copyright ©2017 The gonum Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package unit_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"gonum.org/v1/gonum/unit"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ExampleNew() {
|
||||||
|
// Create an acceleration of 3 m/s^2
|
||||||
|
accel := unit.New(3.0, unit.Dimensions{unit.LengthDim: 1, unit.TimeDim: -2})
|
||||||
|
fmt.Println(accel)
|
||||||
|
|
||||||
|
// Output: 3 m s^-2
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleNewDimension() {
|
||||||
|
// Create a "trees" dimension
|
||||||
|
// Typically, this should be used within an init function
|
||||||
|
treeDim := unit.NewDimension("tree")
|
||||||
|
countPerArea := unit.New(0.1, unit.Dimensions{treeDim: 1, unit.LengthDim: -2})
|
||||||
|
fmt.Println(countPerArea)
|
||||||
|
|
||||||
|
// Output: 0.1 tree m^-2
|
||||||
|
}
|
@@ -10,26 +10,17 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Uniter is an interface representing a type that can be converted
|
// Uniter is a type that can be converted to a Unit.
|
||||||
// to a unit.
|
|
||||||
type Uniter interface {
|
type Uniter interface {
|
||||||
Unit() *Unit
|
Unit() *Unit
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dimension is a type representing an SI base dimension or other
|
// Dimension is a type representing an SI base dimension or a distinct
|
||||||
// orthogonal dimension. If a new dimension is desired for a
|
// orthogonal dimension. Non-SI dimensions can be created using the NewDimension
|
||||||
// domain-specific problem, NewDimension should be used. Integers
|
// function, typically within an init function.
|
||||||
// should never be cast as type dimension
|
|
||||||
// // Good: Create a package constant with an init function
|
|
||||||
// var MyDimension unit.Dimension
|
|
||||||
// init(){
|
|
||||||
// MyDimension = NewDimension("my")
|
|
||||||
// }
|
|
||||||
// main(){
|
|
||||||
// var := MyDimension(28.2)
|
|
||||||
// }
|
|
||||||
type Dimension int
|
type Dimension int
|
||||||
|
|
||||||
|
// String returns the string for the dimension.
|
||||||
func (d Dimension) String() string {
|
func (d Dimension) String() string {
|
||||||
switch {
|
switch {
|
||||||
case d == reserved:
|
case d == reserved:
|
||||||
@@ -65,7 +56,8 @@ var (
|
|||||||
AngleDim: "rad",
|
AngleDim: "rad",
|
||||||
}
|
}
|
||||||
|
|
||||||
// for guaranteeing there aren't two identical symbols
|
// dimensions guarantees there aren't two identical symbols
|
||||||
|
// SI symbol list from http://lamar.colostate.edu/~hillger/basic.htm
|
||||||
dimensions = map[string]Dimension{
|
dimensions = map[string]Dimension{
|
||||||
"A": CurrentDim,
|
"A": CurrentDim,
|
||||||
"m": LengthDim,
|
"m": LengthDim,
|
||||||
@@ -132,10 +124,6 @@ var (
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: Should we actually reserve "common" SI unit symbols ("N", "J", etc.) so there isn't confusion
|
|
||||||
// TODO: If we have a fancier ParseUnit, maybe the 'reserved' symbols should be a different map
|
|
||||||
// map[string]string which says how they go?
|
|
||||||
|
|
||||||
// Dimensions represent the dimensionality of the unit in powers
|
// Dimensions represent the dimensionality of the unit in powers
|
||||||
// of that dimension. If a key is not present, the power of that
|
// of that dimension. If a key is not present, the power of that
|
||||||
// dimension is zero. Dimensions is used in conjunction with New.
|
// dimension is zero. Dimensions is used in conjunction with New.
|
||||||
@@ -178,53 +166,58 @@ func (u unitPrinters) Len() int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (u unitPrinters) Less(i, j int) bool {
|
func (u unitPrinters) Less(i, j int) bool {
|
||||||
return (u[i].pow > 0 && u[j].pow < 0) || u[i].String() < u[j].String()
|
// Order first by positive powers, then by name.
|
||||||
|
if u[i].pow*u[j].pow < 0 {
|
||||||
|
return u[i].pow > 0
|
||||||
|
}
|
||||||
|
return u[i].String() < u[j].String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u unitPrinters) Swap(i, j int) {
|
func (u unitPrinters) Swap(i, j int) {
|
||||||
u[i], u[j] = u[j], u[i]
|
u[i], u[j] = u[j], u[i]
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDimension returns a new dimension variable which will have a
|
// NewDimension creates a new orthogonal dimension with the given symbol, and
|
||||||
// unique representation across packages to prevent accidental overlap.
|
// returns the value of that dimension. The input symbol must not overlap with
|
||||||
// The input string represents a symbol name which will be used for printing
|
// any of the any of the SI base units or other symbols of common use in SI ("kg",
|
||||||
// Unit types. This symbol may not overlap with any of the SI base units
|
// "J", etc.), and must not overlap with any other dimensions created by calls
|
||||||
// or other symbols of common use in SI ("kg", "J", "μ", etc.). A list of
|
// to NewDimension. The SymbolExists function can check if the symbol exists.
|
||||||
// such symbols can be found at http://lamar.colostate.edu/~hillger/basic.htm or
|
// NewDimension will panic if the input symbol matches an existing symbol.
|
||||||
// by consulting the package source. Furthermore, the provided symbol is also
|
//
|
||||||
// forbidden from overlapping with other packages calling NewDimension. NewDimension
|
|
||||||
// is expecting to be used only during initialization, and as such it will panic
|
|
||||||
// if the symbol matching an existing symbol
|
|
||||||
// NewDimension should only be called for unit types that are actually orthogonal
|
// NewDimension should only be called for unit types that are actually orthogonal
|
||||||
// to the base dimensions defined in this package. Please see the package-level
|
// to the base dimensions defined in this package. Please see the package-level
|
||||||
// documentation for further explanation. Calls to NewDimension are not thread safe.
|
// documentation for further explanation.
|
||||||
func NewDimension(symbol string) Dimension {
|
func NewDimension(symbol string) Dimension {
|
||||||
_, ok := dimensions[symbol]
|
_, ok := dimensions[symbol]
|
||||||
if ok {
|
if ok {
|
||||||
panic("unit: dimension string \"" + symbol + "\" already used")
|
panic("unit: dimension string \"" + symbol + "\" already used")
|
||||||
}
|
}
|
||||||
symbols = append(symbols, symbol)
|
|
||||||
d := Dimension(len(symbols))
|
d := Dimension(len(symbols))
|
||||||
|
symbols = append(symbols, symbol)
|
||||||
dimensions[symbol] = d
|
dimensions[symbol] = d
|
||||||
return d
|
return d
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unit is a type a value with generic SI units. Most useful for
|
// SymoblExists returns whether the given symbol is already in use.
|
||||||
// translating between dimensions, for example, by multiplying
|
func SymbolExists(symbol string) bool {
|
||||||
// an acceleration with a mass to get a force. Please see the
|
_, ok := dimensions[symbol]
|
||||||
// package documentation for further explanation.
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unit represents a dimensional value. The dimensions will typically be in SI
|
||||||
|
// units, but can also include dimensions created with NewDimension. The Unit type
|
||||||
|
// is most useful for ensuring dimensional consistency when manipulating types
|
||||||
|
// with different units, for example, by multiplying an acceleration with a
|
||||||
|
// mass to get a force. Please see the package documentation for further explanation.
|
||||||
type Unit struct {
|
type Unit struct {
|
||||||
dimensions Dimensions // Map for custom dimensions
|
dimensions Dimensions
|
||||||
formatted string
|
formatted string
|
||||||
value float64
|
value float64
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new variable of type Unit which has the value
|
// New creates a new variable of type Unit which has the value and dimensions
|
||||||
// specified by value and the dimensions specified by the
|
// specified by the inputs. The built-in dimensions are always in SI units
|
||||||
// base units struct. The value is always in SI Units.
|
// (meters, kilograms, etc.).
|
||||||
//
|
|
||||||
// Example: To create an acceleration of 3 m/s^2, one could do
|
|
||||||
// myvar := CreateUnit(3.0, &Dimensions{unit.LengthDim: 1, unit.TimeDim: -2})
|
|
||||||
func New(value float64, d Dimensions) *Unit {
|
func New(value float64, d Dimensions) *Unit {
|
||||||
u := &Unit{
|
u := &Unit{
|
||||||
dimensions: make(map[Dimension]int),
|
dimensions: make(map[Dimension]int),
|
||||||
|
Reference in New Issue
Block a user