Symbolic Calculations with Units

The Wolfram System's ability to deal with symbolic expressions, as well as numbers, allows you to use it for many kinds of mathematics. The Wolfram System's unit system utilizes this symbolic code base, facilitating calculus using (RefLink[Quantity, paclet:ref/Quantity]) expressions.

Some symbolic mathematical operations that operate on (RefLink[Quantity, paclet:ref/Quantity]) expressions.

General

Many symbolic commands are capable of understanding units. Still, there are times when you might wish to add or remove units. These can be handled by the Wolfram System's general substitution mechanism.

This assigns units to each symbol. Notice that the input symbols are dimensionful, but the output symbols are dimensionless:

(1/2)a t^2 + v t + x0 /. {a ->Quantity[(Subscript[a, d]), "Meters"/"Seconds"^2],t->Quantity[(Subscript[t, d]),"Seconds"], v->Quantity[(Subscript[v, d]),"Meters"/"Seconds"], x0->Quantity[(Subscript[x0, d]),"Meters"]}

A quick way to test whether an equation is dimensionally consistent is to subtract both sides, substitute in quantity values, and check whether it evaluates to a valid (RefLink[Quantity, paclet:ref/Quantity]) object:

s == v * t

Subtract @@ %

% /. {t->Quantity[(Subscript[t, d]),"Seconds"], v->Quantity[(Subscript[v, d]),"Meters"/"Seconds"], s->Quantity[(Subscript[s, d]),"Meters"]}

Head[%]

These values are inconsistent with the equation, so messages are issued, and the computation returns only partially evaluated. As a result, the output has (RefLink[Head, paclet:ref/Head]) (RefLink[Plus, paclet:ref/Plus]):

s-v t/. {t->Quantity[(Subscript[t, d]),"Seconds"^2], v->Quantity[(Subscript[v, d]),"Meters"/"Seconds"], s->Quantity[(Subscript[s, d]),"Meters"]}

Head[%]

This substitution replaces each quantity with just the numerical portion, leaving a purely symbolic expression:

Quantity[s, "Meters"]-v Quantity[t,"Seconds"]

%/.q_Quantity :> QuantityMagnitude[q]

Solve

(RefLink[Solve, paclet:ref/Solve]) is aware of (RefLink[Quantity, paclet:ref/Quantity]) and will automatically determine the units of unknown variables within the equation. Units for variables can be specified by inserting the variable inside a (RefLink[Quantity, paclet:ref/Quantity]) expression with the desired units.

This finds the ratio of "Yards" per "Meters":

Solve[Quantity[m,"Meters"]==Quantity[y,"Yards"],m]

This gives the two solutions to the equation (QuantityUnit[2.2`*^12])==(v^2) ((QuantityUnit[34000.`])). The solutions are given as replacements for v:

Solve[Quantity[2.2*10^12,"Joules"]==(1/2)Quantity[6.8*10^4,"Kilograms"]*v^2,v]

Units can be specified by entering the unknown variable as a (RefLink[Quantity, paclet:ref/Quantity]):

Solve[Quantity[2.2*10^12,"Joules"]==(1/2)Quantity[6.8*10^4,"Kilograms"]*Quantity[v,"Miles"/"Hours"]^2,v]

If (RefLink[Solve, paclet:ref/Solve]) cannot determine the units of an unknown variable, because of ambiguity or a dimensionality conflict, it will return unevaluated:

Solve[Quantity[13,"Feet"]==x+1,x]

Integrate

(RefLink[Integrate, paclet:ref/Integrate]) is aware of (RefLink[Quantity, paclet:ref/Quantity]) and will correctly combine the units of the integrand and integration variables. If the variable of integration is a (RefLink[Quantity, paclet:ref/Quantity]) object, then its (RefLink[QuantityMagnitude, paclet:ref/QuantityMagnitude]) is used as the integration variable for performing the integration, and its (RefLink[QuantityUnit, paclet:ref/QuantityUnit]) will be combined with the units of the integrand in the result. In general, it is best to enter the input in one of two forms:

The integrand and all the integration variables are (RefLink[Quantity, paclet:ref/Quantity]) objects.

(RefLink[Quantity, paclet:ref/Quantity]) objects only appear in the limits of definite integration.

Input can be entered in other ways, but (RefLink[Integrate, paclet:ref/Integrate]) will fail if it cannot determine a consistent assignment of units for all expressions. The assumed dimensions of the integration variable in definite integration will vary depending on how the variable and limits are expressed. For a specification like {x,(RefLink[Quantity, paclet:ref/Quantity])[a,"unit1"],(RefLink[Quantity, paclet:ref/Quantity])[b,"unit2"]}, x is assumed to have the same dimensions as "unit1" and "unit2". For a specification like {(RefLink[Quantity, paclet:ref/Quantity])[x,"unit"],a,b}, x itself is generally assumed to be dimensionless. In this latter case, a and b must be quantities of the same dimensions as unit.

Calculate displacement over a given time:

Integrate[Quantity[5,"Meters"/"Seconds"^2]*t,{t,Quantity[0,"Seconds"],Quantity[10,"Seconds"]}]

In this form, the variable t is dimensionless, and the actual time is (RefLink[Quantity, paclet:ref/Quantity])[t,"Seconds"]:

Integrate[Quantity[5,"Meters"/"Seconds"^2]*Quantity[t, "Seconds"],{Quantity[t, "Seconds"],Quantity[0,"Seconds"],Quantity[10,"Seconds"]}]

If the (RefLink[Quantity, paclet:ref/Quantity]) wrapper around t in the integrand is omitted, the final result will have dimensions (([Length])/([Time])):

Integrate[Quantity[5,"Meters"/"Seconds"^2]*t,{Quantity[t, "Seconds"],Quantity[0,"Seconds"],Quantity[10,"Seconds"]}]

Calculate displacement symbolically:

Integrate[Quantity[a,"Meters"/"Seconds"^2]*t,{t,Quantity[ti,"Seconds"],Quantity[tf,"Seconds"]}]

Integrate a linear charge density function. Notice that the whole integrand is a (RefLink[Quantity, paclet:ref/Quantity]), allowing an easy combination of the units:

Integrate[ Quantity[a x^2 + b x, "Coulombs"/"Meters"], {Quantity[x,"Meters"],Quantity[xi,"Meters"], Quantity[xf,"Meters"]}]

If the integration variables are not declared as quantities, and quantity objects in the integrand are constants, (RefLink[Integrate, paclet:ref/Integrate]) will maintain the separated form of the integrand:

Integrate[ Quantity[a , "Coulombs"/"Meters"^3]x^2 + Quantity[b, "Coulombs"/"Meters"^2]x, x]

If a variable of integration is a (RefLink[Quantity, paclet:ref/Quantity]), then the result will be a (RefLink[Quantity, paclet:ref/Quantity]) object:

Integrate[ Quantity[a , "Coulombs"/"Meters"^3]x^2 + Quantity[b, "Coulombs"/"Meters"^2]x, Quantity[x, "Meters"]]

When the integrand has nonconstant (RefLink[Quantity, paclet:ref/Quantity]) objects as subexpressions, (RefLink[Integrate, paclet:ref/Integrate]) must infer units from the various expressions. If these inferences lead to contradictions, (RefLink[Integrate, paclet:ref/Integrate]) will fail:

Integrate[a Quantity[t, "Meters"],Quantity[t, "Seconds"]]

D

(RefLink[D, paclet:ref/D]) is aware of (RefLink[Quantity, paclet:ref/Quantity]) and will correctly combine the units of (RefLink[Quantity, paclet:ref/Quantity]) objects in the expression being differentiated with the units of the differentiation variables.

Compute the derivative of one quantity with respect to another:

D[Quantity[(1/2)*a*(t - ti)^2 + v0*(t - ti) + x0, "Meters"],Quantity[t, "Seconds"]]

Compute the second derivative of position, the acceleration:

D[Quantity[(1/2)*a*(t - ti)^2 + v0*(t - ti) + x0, "Meters"],{Quantity[t, "Seconds"],2}]

(RefLink[D, paclet:ref/D]) will automatically keep track of units:

D[Quantity[a*(t - ti) + v0, "Meters"/"Seconds"],Quantity[t, "Hours"]]

Differentiate an expression containing several (RefLink[Quantity, paclet:ref/Quantity]) objects:

D[x^3*Quantity[a/3, "Coulombs"/"Meters"^3] + 
  x^2*Quantity[b/2, "Coulombs"/"Meters"^2],x]

When differentiating a sum of (RefLink[Quantity, paclet:ref/Quantity]) objects, (RefLink[Expand, paclet:ref/Expand]) can often provide simplification:

D[a Sin[Quantity[ω,"Seconds"^-1] * t] + b Cos[Quantity[ω,"Seconds"^-1] * t],Quantity[ω,"Seconds"^-1]]

%//Expand

Computing a gradient with respect to (RefLink[Quantity, paclet:ref/Quantity]) variables:

D[{Quantity[e[t,x], "Joules"], Quantity[p[t,x],"Kilograms" * "Meters"/"Seconds"]}, {{Quantity[t,"Seconds"], Quantity[x,"Meters"]}}]