Плавающая точка должна обрабатывать большую величину входных данных, вплоть до определенной точки с данными float
и с любым разумным значением с double
данными
realmax('single')
ans =
3.4028e+38
realmax('double')
ans =
1.7977e+308
При значениях 1e7 в диапазоне +/- 1e5 вы можете ожидать, что квадрат евклидова расстояния будет находиться в диапазоне +/- 1e17 (5 + 5 + 7), который оба формата будут легко обрабатывать.
В любом случае, вы должны векторизовать код для удаления цикла (который Matlab имеет историю обработки очень неэффективно, особенно в старых версиях)
В новых версиях (2016b и новее) просто используйте:
tmp=(log10(G)-log10(C(:,2:end)))./log10(GSD);
dG = sqrt(sum(tmp.^2,2)); %row-by-row norm
Обратите внимание, что вы должны использовать ./
, который является поэлементным делением, а не /
, который является матричным правым делением.
Следующий код будет работать везде
tmp=bsxfun(@rdivide,bsxfun(@minus,log10(G),log10(C(:,2:end))),log10(GSD));
dG = sqrt(sum(tmp.^2,2)); %row-by-row norm
Я, однако, считаю, что использование log10 является математической ошибкой. Результат dG не будет евклидовой нормой. Вы должны придерживаться среднеквадратичного значения взвешенной разницы:
dG = sqrt(sum(bsxfun(@rdivide,bsxfun(@minus,G,C(:,2:end)),GSD).^2,2)); % all versions
dG = sqrt(sum((G-C(:,2:end)./GSD).^2,2)); %R2016b and later