Dlaczego ilość i jednostki są niezgodne ze zwykłym zachowaniem Mathematica?

Nov 29 2020

Kiedy wpisuję to w Wolfram Mathematica V12:

0 Dogs + 5 Cats

Mathematica rozsądnie zwraca to:

5 Cats

ALE, jeśli używam funkcji Jednostki i Ilość w Mathematica V12 i wpiszę to:

0 m + 37 m/s

Lub w długiej formie:

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

Dostaję:

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

Wiem, że jednostki nie są kompatybilne, ale ZERO „Metrów” wynosi tylko 0 i powinno logicznie zniknąć z równania, tak jak „0 psów” znika z pierwszego przykładu.

Ten błąd przerywa większość różnicowania i integracji symboli.

Myślę, że Wolfram naprawdę spieprzył, nie robiąc Units części V1 w latach 80-tych, a zamiast tego dodał go jako klejoną torbę , w V12. Porozmawiaj o „pełzających featuryzmie” ;-)

Przy okazji, jedynym sposobem, jaki znalazłem, aby kontrolować tę okropną funkcjonalność Mathematica, są strony brzydkich reguł zastępowania, takich jak ta:

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
  ]

Oczywiście ten brzydki hack umożliwia proste obliczenia jednowierszowe, które były tak piękne i eleganckie w V4, a teraz wiele wierszy paskudnego, nieczytelnego kodu.

czy robię coś źle?

Czy Mathematica V4 jest nadal na sprzedaż?

Dzięki,

  • Joe

Przykład

Oto bardziej szczegółowy obraz błędów, które otrzymuję w Mathematica V12 podczas próby obliczenia prostej całki. Wydaje mi się, że w ocenie takiej jak Times czy Plus, czy cokolwiek innego, wyrażenia jednostek o wielkości ZERO powinny zostać usunięte, tak jak w przypadku zwykłego pióra i papieru.

Odpowiedzi

17 Roman Nov 29 2020 at 16:22

Nie rozwiązanie, ale rozszerzony komentarz.

Źle rozumiesz fizyczne podstawy wielkości i jednostek.

Każda wielkość fizyczna ma nieodłączny margines błędu, nawet jeśli jest bardzo mała (pomijalna), a zatem milcząco tłumiona. Ilość 1 metr naprawdę oznacza około 1 metr, daj lub weź kilka milimetrów / nanometrów / odległości Plancka .

Wielkość 0 metrów oznacza odległość, która jest zgodna z zerem w granicach błędu mojego pomiaru . Ten margines błędu przenosi jednostki, nawet jeśli średnia wartość wynosi dokładnie zero. Nie możemy więc anulować jednostek, a 0 metrów nie jest równe 0 jabłek lub 0 sekund . Demokryt wymyślił to już prawie 2500 lat temu.

Z matematycznego punktu widzenia obserwujemy, że punkt 0 ma zerową miarę na osi rzeczywistej i jest jedynym punktem $x$ gdzie $x$można powiedzieć, że metryniczym . Ale wielkości fizyczne odnoszą się do interwałów , a nie do punktów na rzeczywistej osi, dlatego też jednostki nigdy nie można anulować w sposób sugerowany.

Zachowanie Mathematica w tej kwestii jest więc całkowicie oczekiwane i normalne.

10 AntonAntonov Nov 29 2020 at 15:18

Czy Mathematica V4 jest nadal na sprzedaż?

Ta odpowiedź proponuje mniej drastyczne rozwiązania niż powrót do wersji 4.

Rozwiązanie „globalne”

W przypadku problemów, które napotkasz i podchodzisz, wybierz jedną - niezbyt dobrą - propozycję przedefiniowania Quantity:

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

Uwaga 1: Nie sprawdzałem ani nie korzystałem zbyt często z powyższego kodu - ujął go bardziej jako stwierdzenie „Dzielę się Twoimi bólami” i, w pewnym sensie, aby zachęcić inne posty proponujące rozwiązania w tym stylu.

Uwaga 2: Za pomocą Quantity[x_,___]:=x;możesz „usunąć” Quantityfunkcje z większości obliczeń. Ale jest to również niebezpieczne, ponieważ niektóre wbudowane funkcje wymagają Quantityprawidłowego działania. Na przykład WeatherDatalub FinancialData. Osobiście 95% czasu po spożyciu datatych funkcji, których używam data /. Quantity[x_, _] :> x.

Ewaluacja z Quantityprzedefiniowaniem

Rozważ użycie tej funkcji zamiast „globalnego” podejścia powyżej (i / lub swojego removeUnitsOfZeroMagnitude):

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