Почему количество и единицы несовместимы с обычным поведением системы Mathematica?
Когда я ввожу это в 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, или что-то еще, выражения единиц с НУЛЕВОЙ величиной должны быть удалены, как если бы это было с простой ручкой и бумагой.
Ответы
Не решение, а развернутый комментарий.
Вы неправильно понимаете физическую основу величин и единиц.
Каждой физической величине присуща погрешность, даже если она очень мала (пренебрежимо мала) и поэтому негласно подавляется. Величина 1 метр на самом деле означает примерно 1 метр, плюс-минус несколько миллиметров / нанометров / планковских расстояний .
Величина 0 метров означает расстояние, которое согласуется с нулем в пределах погрешности моих измерений . Этот предел погрешности содержит единицы измерения, даже если среднее значение точно равно нулю. Таким образом, мы не можем отменить единицы, а 0 метров не равно 0 яблокам или 0 секундам . Демокрит уже в значительной степени понял это 2500 лет назад.
Математически мы видим, что точка 0 имеет нулевую меру на действительной оси и является единственной точкой $x$ где $x$метров можно было бы сказать, что это ничто . Но физические величины относятся к интервалам , а не точкам на действительной оси, и поэтому единицы никогда не могут быть отменены так, как вы предлагаете.
Таким образом, поведение Mathematica в этом вопросе вполне ожидаемо и нормально.
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];