Ошибка округления в дгесв?

Я использую подпрограммы dgesv и dgemm fortran в C ++ для простого умножения матриц и деления влево.

Для случайных матриц A и B я делаю:

A\(A\(A*B));

где * определяется с использованием dgemm и \ с использованием dgesv. Очевидно, это выражение должно упрощаться до единичной матрицы. Я проверяю свои ответы против MATLAB, и я получаю более или менее 1 по диагонали, но другие записи очень немного отклонены (числа имеют порядок e-15, поэтому они уже близки к 0) ,

Мне просто интересно, стоит ли ожидать такого результата или нет? Потому что, если я сделаю что-то вроде этого:

C = A+B;
D = A*B;

D\(C\(C*C));

результат должен выйти на D \ C. По сути, C (C * C) очень точен (идеально соответствует MATLAB), но во второй раз, когда я делаю D \ C, я получаю что-то, что отключается с помощью e-1 или даже e + 00. Я предполагаю, что это не должно произойти?

0

Решение

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

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]