Download or view planckify.frink in plain text format
/** This program tries to find a combination of basic constants that can
produce the desired dimensions. */
use Matrix.frink
use formatEquation.frink
/** Finds a combination of base units that can be combined to produce a unit
with the specified dimensions. */
planckify[unit, bases = ["c", "G", "hbar", "k", "electroncharge", "cd", "dollar", "mol", "bit"]] :=
{
[expMatrix, solMatrix, dims] = makeExponentMatrix[unit, bases]
if exp == undef
return undef
println[formatTable[[[expMatrix.formatMatrix[], solMatrix.formatMatrix[]]]]]
col = expMatrix.solve[solMatrix] // Perform the solution of exp * x = sol
str = ""
for i = 0 to length[col]-1
{
ee = col@i
if ee != 0
{
if isInteger[ee]
if ee == 1
expStr = ""
else
expStr = "^$ee"
else
expStr = "^(" + inputForm[ee] + ")"
if str != ""
str = str + " "
str = str + bases@i + expStr
}
}
println[str]
println[]
println[formatExpression[parseToExpression[str]]]
println[]
println[eval[str, false, true]]
}
makeExponentMatrix[unit, bases] :=
{
dims = new set // Set of base dimension names
combos = new set // Set of exponent combos
for uu = bases
{
combo = dimensionsToArray[resolveUnit[uu]]
if combos.contains[combo]
{
println["makeExponentMatrix: overconstrained. Exponent combo is repeated for $uu: $combo"]
return undef
} else
combos.put[combo]
for [dimname, exp] = combo
dims.put[dimname]
}
// println["combos is $combos"]
numBases = length[bases]
numDims = length[dims]
// Sort dimArray by the order that the exponents occur in standard order.
dimArray = toArray[dims]
sort[dimArray, {|a,b,data| data.indexOf[a] <=> data.indexOf[b]}, baseUnitNames[]]
// println["dims is $dims"]
// println["dimArray is $dimArray"]
// println["Base units " + baseUnitNames[]]
// TODO: If unit contains a dimension not in dims, solution is impossible
udims = dimensionsToArray[resolveUnit[unit]]
// println["udims is $udims"]
for [uname, exp] = udims
if ! dims.contains[uname]
{
println["Unit $unit has base unit \"$uname\" which does not occur in the specified bases: $dimArray"]
return undef
}
// Note that we transpose this matrix before returning it.
grid = new array[numBases]
for uu = bases
{
resolved = resolveUnit[uu]
row = new array[numDims]
for dim = dimArray
row.push[getExponent[resolved, dim]]
grid.push[row]
}
// Note that we will transpose into a column this before returning it
umatrix = new array
ures = resolveUnit[unit]
for dim = dimArray
umatrix.push[getExponent[ures, dim]]
return [new Matrix[grid.transpose[]],
new Matrix[umatrix.transpose[]],
dimArray]
}
/** Resolves a unit name to its value. */
resolveUnit[uu] :=
{
if isUnit[uu]
return uu
if isString[uu]
return unit[uu]
println["resolveUnit: Unhandled unit type " + type[uu]]
return undef
}
for [name, unit] = dimensionsWithValues[]
{
println[name + "\t" + planckify[unit]]
}
Download or view planckify.frink in plain text format
This is a program written in the programming language Frink.
For more information, view the Frink
Documentation or see More Sample Frink Programs.
Alan Eliasen, eliasen@mindspring.com