Как я могу сделать точность matlab такой же, как в c ?

#c #matlab #precision

#c #matlab #точность

Вопрос:

У меня проблема с точностью. Я должен сделать так, чтобы мой код c имел ту же точность, что и matlab. В matlab у меня есть скрипт, который выполняет некоторые действия с числами и т. Д. Я получил код на c , который выполняет то же самое, что и этот скрипт. Вывод на одном и том же входе отличается: ( Я обнаружил, что в моем скрипте, когда я пытаюсь 104> = 104, он возвращает false . Я пытался использовать format long, но это не помогло мне выяснить, почему это false. Оба числа имеют тип double . я подумал, что, возможно, matlab хранит где-то реальное значение 104, а его реальное значение равно 103.9999… Итак, я повысил свою точность в c . Это также не помогло, потому что, когда matlab возвращает мне значение 50.000 в c , я получаю значение 50.050 с высокой точностью. Эти 2 значения получены из нескольких вычислений, таких как или *. Есть ли какой-нибудь способ сделать так, чтобы мои скрипты c и matlab имели одинаковую точность?

 for i = 1:neighbors
  y = spoints(i,1) origy;
  x = spoints(i,2) origx;
  % Calculate floors, ceils and rounds for the x and y.
  fy = floor(y); cy = ceil(y); ry = round(y);
  fx = floor(x); cx = ceil(x); rx = round(x);
  % Check if interpolation is needed.
  if (abs(x - rx) < 1e-6) amp;amp; (abs(y - ry) < 1e-6)
    % Interpolation is not needed, use original datatypes
    N = image(ry:ry dy,rx:rx dx);
    D = N >= C; 
  else
    % Interpolation needed, use double type images 
    ty = y - fy;
    tx = x - fx;

    % Calculate the interpolation weights.
    w1 = (1 - tx) * (1 - ty);
    w2 =      tx  * (1  - ty);
    w3 = (1  - tx) *   ty ;
    w4 =      tx  *    ty ;

    %Compute interpolated pixel values
    N = w1*d_image(fy:fy dy,fx:fx dx)   w2*d_image(fy:fy dy,cx:cx dx)   ...
    w3*d_image(cy:cy dy,fx:fx dx)   w4*d_image(cy:cy dy,cx:cx dx);

    D = N >= d_C; 

 end  
  

У меня возникли проблемы в else, который находится в строке 12. tx и ty eqauls 0.707106781186547 или 1 — 0.707106781186547. Значения из d_image находятся в диапазоне от 0 до 255. N — значение 0 ..255 для интерполяции 4 пикселей из изображения. d_C — значение 0.255. До сих пор не знаю, почему matlab показывает, что, когда у меня есть N значений типа: x x x 140.0000 140.0000 и в d_C: x x x 140 x. D дает мне 0 на 4-й позиции, так что 140.0000 ! = 140. Я отладил его, пытаясь повысить точность, но он по-прежнему говорит, что его 140.00000000000000, и он все еще не равен 140.

 int Codes::Interpolation( Point_<int> point, Point_<int> center , Mat *mat)
{


int x = center.x-point.x;
int y = center.y-point.y;

Point_<double> my;
if(x<0)
{
    if(y<0)
    {
        my.x=center.x LEN;
        my.y=center.y LEN;
    }   
    else
    {
        my.x=center.x LEN;
        my.y=center.y-LEN;
    }

}
else
{
    if(y<0)
    {
        my.x=center.x-LEN;
        my.y=center.y LEN;
    }   
    else
    {
        my.x=center.x-LEN;
        my.y=center.y-LEN;
    }
}


int a=my.x; 
int b=my.y;

double tx = my.x - a;
double ty = my.y - b;


double wage[4];
wage[0] = (1 - tx) * (1 - ty);
wage[1] =      tx  * (1 - ty);
wage[2] = (1 - tx) *      ty ;
wage[3] =      tx  *      ty ;



int values[4];

//wpisanie do tablicy 4 pixeli ktore wchodza do interpolacji
for(int i=0;i<4;i  )
{
    int val = mat->at<uchar>(Point_<int>(a help[i].x,a help[i].y));

    values[i]=val;
}




double moze = (wage[0]) * (values[0])    (wage[1]) * (values[1])   (wage[2]) * (values[2])    (wage[3]) * (values[3]);
return moze;
}
  

Значения LEN = 0.707106781186547 в значениях массива на 100% совпадают со значениями matlab.

Комментарии:

1. Вы хотите сказать, что у вас один и тот же набор вычислений, выполняемых в Matlab и C , на идентичных double входных данных, которые дают разные результаты? Если да, пожалуйста, опубликуйте вычисления, которые вы выполняете, как в Matlab, так и в C .

2. Ваша проблема не в том, что вы думаете.

3. 104>=104 всегда верно во всех известных системах программирования. Вы не рассказываете нам правдивую историю. Пока вы не сможете выработать некоторые точные точные детали, вы тратите наше время (и свое собственное).

4. @DavidHeffernan Я думаю, что он просто думает, что это 104. 104.000 >= 104.0000001 неверно, но matlab disp оба числа одинаковы.

Ответ №1:

Matlab использует двойную точность. Вы можете использовать двойной тип C . Это должно сделать большинство вещей похожими, но не на 100%. Как заметил кто-то еще, это, вероятно, не источник вашей проблемы. Либо есть разница в алгоритмах, либо это может быть что-то вроде библиотечной функции, определенной по-разному в Matlab и в C . Например, std() Matlab делится на (n-1), а ваш код может делиться на n .

Комментарии:

1. В библиотеке C есть функция стандартного отклонения?

Ответ №2:

Во-первых, как правило, никогда не рекомендуется сравнивать переменные с плавающей запятой напрямую. Вместо, например, вместо if (nr >= 104) вы должны использовать if (nr >= 104-e) , где e — небольшое число, например 0.00001 .

Однако где-то в вашем скрипте должна быть какая-то серьезная ошибка при занижении выборки или округлении, потому что получение 50050 вместо 50000 не соответствует пределу обычной неточности с плавающей запятой. Например, Matlab может иметь шаг всего 15 цифр!

Я предполагаю, что в вашем коде есть некоторые проблемы с приведением, например

 int i;
double d;
// ...
d = i/3 * d;
  

will даст очень неточный результат, потому что у вас есть целочисленное деление. d = (double)i/3 * d или d = i/3. * d даст гораздо более точный результат.

Приведенный выше пример НЕ вызовет никаких проблем в Matlab, потому что там по умолчанию все уже является числом с плавающей запятой, поэтому подобная проблема может быть связана с различиями в результатах кода c и Matlab.

Просмотр ваших вычислений очень поможет в поиске того, что пошло не так.

Редактировать: В c и c , если вы сравниваете double с целым числом того же значения, у вас есть очень высокая вероятность того, что они не будут равны. То же самое с двумя двойными, но вам может повезти, если вы выполните для них точно такие же вычисления. Даже в Matlab это опасно, и, возможно, вам просто повезло, что, поскольку оба являются двойными, оба были усечены одинаково. По вашему недавнему редактированию кажется, что проблема в том, где вы оцениваете свой массив. Вы никогда не должны использовать == или != при сравнении чисел с плавающей запятой или удвоений в c (или на любых языках, когда вы используете переменные с плавающей запятой). Правильный способ сравнения — проверить, находятся ли они на небольшом расстоянии друг от друга.

Пример: использование == или != для сравнения двух двойников похоже на сравнение веса двух объектов путем подсчета количества атомов в них и принятия решения о том, что они не равны, даже если между ними есть разница в один атом.

Ответ №3:

MATLAB использует двойную точность, если вы не скажете иначе. Любые различия, которые вы видите при идентичной реализации в C , будут вызваны ошибками с плавающей запятой.