Почему С++ определяет норму как квадрат евклидовой нормы
Это может показаться немного риторическим вопросом, но я прошу его здесь по двум причинам:
- Мне потребовалось некоторое время, чтобы выяснить, что С++ std:: norm() делает иначе, чем Matlab/Octave, поэтому другие могут наткнуться на него здесь.
- Мне кажется нечетным определить функцию
norm()
как нечто другое (хотя и тесно связанное) с тем, что обычно считается нормой (или L2-нормой, или евклидовой нормой и т.д.).
В частности, стандартная библиотека С++ определяет norm()
для комплексных чисел как квадрат модуля (или абсолютного значения), где модуль является sqrt (a ^ 2 + b ^ 2), когда комплексное число имеет вид a + я * b.
Это противоречит моему пониманию нормы, которая при указании как евклидовой нормы (которая соответствует используемому здесь модулю) является квадратным корнем из суммы квадратов. Я опишу Определение сложного модуля в Mathworld.
Это что-то другое? Я нашел его в результате переноса некоторого кода обработки сигналов с Octave на С++, и единственное место, где я нашел ссылку на эту разницу, было в списке рассылки GCC (не могу опубликовать ссылку из-за ограничения по 1 ссылке).
Ответы
Ответ 1
Использование слова "норма" на С++ довольно сбивает с толку, так как большинство людей только когда-либо сталкиваются с нормами в контексте векторных пространств. Если вы рассматриваете комплексные числа как векторное пространство над действиями, это определенно не норма. Справедливость к С++, функция std:: norm() вычисляет так называемый Field Norm из комплексных чисел к действиям.
К счастью, существует функция std:: abs(), которая делает то, что вы хотите.
Ответ 2
Кстати, квадрат евклидовой нормы может быть полезен как оптимизация, особенно в игровой физике; если вы хотите сравнить величины/расстояния или по какой-либо другой причине не нуждаетесь в линейности, тогда вы можете работать с квадратными расстояниями, а не с фактическими расстояниями, и избегать вычисления квадратных корней.
norm(v1) < norm(v2) instead of abs(v1) < abs(v2)
norm(v) < CONSTANT_SQUARED instead of abs(v) < CONSTANT
(используя тот факт, что abs() является величиной, как указано в другом ответе)