Почему количество и единицы несовместимы с обычным поведением системы Mathematica?

Nov 29 2020

Когда я ввожу это в Wolfram Mathematica V12:

0 Dogs + 5 Cats

Mathematica разумно возвращает это:

5 Cats

НО, если я использую функции Units и Quantity в Mathematica V12, и введите это:

0 m + 37 m/s

Или в полной форме:

Quantity[0, "Meters"] + Quantity[37, "Meters"/"Seconds"]

Я получил:

 Quantity::compat: Meters/Seconds and Meters are incompatible units

Я знаю, что единицы несовместимы, но ZERO «Meters» - это просто 0 и должен логически исчезнуть из уравнения, так же как «0 Dogs» исчезнет из первого примера.

Эта ошибка нарушает большинство различий и интеграции символов.

Полагаю, Вольфрам действительно облажался, не сделав Units частью V1 еще в 1980-х, а вместо этого добавил их в V12 как наклеенный пакет . Поговорим о "ползучем фатуризме" ;-)

Кстати, единственное средство, которое я нашел для управления этой ужасной функциональностью Mathematica, - это страницы с уродливыми правилами замены, такими как:

removeUnitsOfZeroMagnitude[myExpression_] := Module[{},
  myExpression /. Quantity[0, "Meters"] -> 0 /. 
     Quantity[0, "Meters"/"Seconds"] -> 0 /. 
    Quantity[0, "Meters"/"Seconds"^2] -> 0 /. 
   Quantity[0, "Meters"/"Seconds"^3] -> 0
  ]

Конечно, этот уродливый хакер делает простые однострочные вычисления, которые были такими красивыми и элегантными в V4, теперь же много строк неприятного, нечитаемого кода.

Я делаю что-то неправильно?

Mathematica V4 все еще продается?

Благодарность,

  • Джо

пример

Вот более подробное изображение ошибок, которые я получаю в Mathematica V12 при попытке вычислить простой интеграл. Мне кажется, что в таких оценках, как Times или Plus, или что-то еще, выражения единиц с НУЛЕВОЙ величиной должны быть удалены, как если бы это было с простой ручкой и бумагой.

Ответы

17 Roman Nov 29 2020 at 16:22

Не решение, а развернутый комментарий.

Вы неправильно понимаете физическую основу величин и единиц.

Каждой физической величине присуща погрешность, даже если она очень мала (пренебрежимо мала) и поэтому негласно подавляется. Величина 1 метр на самом деле означает примерно 1 метр, плюс-минус несколько миллиметров / нанометров / планковских расстояний .

Величина 0 метров означает расстояние, которое согласуется с нулем в пределах погрешности моих измерений . Этот предел погрешности содержит единицы измерения, даже если среднее значение точно равно нулю. Таким образом, мы не можем отменить единицы, а 0 метров не равно 0 яблокам или 0 секундам . Демокрит уже в значительной степени понял это 2500 лет назад.

Математически мы видим, что точка 0 имеет нулевую меру на действительной оси и является единственной точкой $x$ где $x$метров можно было бы сказать, что это ничто . Но физические величины относятся к интервалам , а не точкам на действительной оси, и поэтому единицы никогда не могут быть отменены так, как вы предлагаете.

Таким образом, поведение Mathematica в этом вопросе вполне ожидаемо и нормально.

10 AntonAntonov Nov 29 2020 at 15:18

Mathematica V4 все еще продается?

Этот ответ предлагает менее радикальные решения, чем возврат к версии 4.

«Глобальное» решение

Для решения проблем, с которыми вы сталкиваетесь и к которым подходите, вы берете одно - не очень хорошее - предложение - переопределить Quantity:

Unprotect[Quantity];
(*Quantity[x_,___]:=x;*)
Quantity[0, ___] := 0;
Protect[Quantity];

Замечание 1: Я не проверял и не использовал приведенный выше код широко - он выразился скорее как утверждение «Я разделяю ваши боли» и, как бы, чтобы поощрить другие сообщения, предлагающие решения в этом стиле.

Замечание 2: С Quantity[x_,___]:=x;его помощью вы можете «убрать» Quantityфункциональные возможности из большинства вычислений. Но это также опасно, потому что некоторые встроенные функции полагаются на Quantityправильную работу. Например, WeatherDataили FinancialData. Лично я 95% времени после приема dataс этими функциями использую data /. Quantity[x_, _] :> x.

Оценка с Quantityпереопределением

Рассмотрите возможность использования этой функции вместо «глобального» подхода, описанного выше (и / или вашего removeUnitsOfZeroMagnitude):

Clear[RemoveQuantity]
SetAttributes[RemoveQuantity, {HoldFirst}];
RemoveQuantity[myExpression_] := Block[{Quantity = #1 &}, myExpression];