For simple cases, Quantities appear to be handled well by Integrate:

m = Quantity["Meters"];
s = Quantity["Seconds"];

Integrate[1 m/s, {t, 1 s, 2 s}]

returns 1 m.

But Integrate has problems when Piecewise is introduced:

Integrate[Piecewise[{{1 m/s, 1 s <= t < 1.5 s}, {2 m/s, 1.5 s <= t <= 2 s}}], {t, 1 s, 2 s}]


Integrate::units: Integrate was unable to determine the units of quantities that appear in the input.

I've tried rearranging the units in a few different ways. For example:

Integrate[Piecewise[{{1 m/s, 1 <= t/s < 1.5}, {2 m/s, 1.5 <= t/s <= 2}}], {t, 1 s, 2 s}]

Integrate[Piecewise[{{1, 1 <= t/s < 1.5}, {2, 1.5 <= t/s <= 2}}] m/s, {t, 1 s, 2 s}]

But everything I've tried so far gives the same error.

I am aware I could completely remove the units from the integration and tack them back on afterwords, like this:

Integrate[Piecewise[{{1, 1 <= t < 1.5}, {2, 1.5 <= t <= 2}}], {t, 1, 2}] m

However, that's not what I'm looking for.

Is there a way to make this work?


Thanks to @zentient, whose answer led me to the solution I finally used, which is this:

I globally define my unit symbols like this:

m = Quantity["Meters"];
s = Quantity["Seconds"];

… so I couldn't use @zentient's solution directly. However, by wrapping Integrate in a Block, I can achieve the same effect. I also found that it worked better to assume that my unit symbols were greater than zero. This eliminates the piecewise result given by @zentient's approach.

Block[{m, s}, Integrate[Piecewise[{{1 m/s, 1 s <= t < 1.5 s}, {2 m/s, 1.5 s <= t <= 2 s}}], {t, 1 s, 2 s}, Assumptions -> {m > 0, s > 0}]]

This returns 1.5 m.

The Block temporarily undefines the unit symbols, so that they are treated as generic symbols within the Block. Upon exiting the Block, the unit symbols are automatically replaced with their global definitions.

(I'm sure there's a more technically precise way to explain that using DownValues and whatnot, but I don't quite grok all of that yet!)


Perhaps the following approach is acceptable.

Define a list of rules for the quantities

myrules = {
  m -> Quantity["Meters"],
  s -> Quantity["Seconds"]

Then carry out the integration, using the Assumptions option to overcome Integrate's objections and applying the rules afterwards with ReplaceAll (a.k.a. " /. ").

  Piecewise[{{1 m/s, 1 s <= t < 1.5 s}, {2 m/s, 1.5 s <= t <= 2 s}}],
  {t, 1 s, 2 s}, 
  Assumptions -> {t ∈ Reals, s ∈ Reals}
] /. myrules

This integration gives the following result:

enter image description here

  • $\begingroup$ Thanks! This answer led me to the solution I finally used. $\endgroup$
    – SWB
    Jan 13 '14 at 15:11
 Piecewise[{{1* m/s, 1 *s <= t < 1.5* s}, {2* m/s, 
    1.5* s <= t <= 2 *s}}], {t, 1*s, 2*s}, 
 Assumptions -> {m > 0, s > 0}]

(*   1.5 m   *)

The trick here is that I do not use the Quantity staff. I never do. Here m and s are variables, just like t. Important is that m and s should be declared positive (through the Assumptions in Integrate). Anyway it is faster than tinkering around with Quantity. Have fun


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.