GNU Octave, округляет число до единицы точности
В GNU Octave версии 3.4.3 Я хочу округлить матрицу до 2 единиц точности по содержимому такой матрицы.
mymatrix=[1.1234567, 2.12345; 3.1234567891, 4.1234];
disp(mymatrix);
Отпечатки:
1.1235 2.1235
3.1235 4.1234
Как вы можете видеть, disp указывает точность на "5", я хочу, чтобы точность единиц была равна 2. Как мне это сделать?
Ответы
Ответ 1
Как округлить элементы в матрице в Octave:
Существует множество различных способов округления матрицы и округления числа в октаве.
Вариант 1, использование функции формата sprintf
mymatrix=[100.1234567, 2.12345; 3.1234567891, 4.1234];
rows = rows(mymatrix);
cols = columns(mymatrix);
for i = 1:rows
for j = 1:cols
sprintf("%5.2f", mymatrix(j,i))
endfor
endfor
Вывод, отметить маркер "% 5.2f" . "F" означает "плавать", 5 означает "5 пробелов". 2 означает точность 2 единиц после десятичной точки.
ans = 100.12
ans = 3.12
ans = 2.12
ans = 4.12
Вариант 2, округленный до значащих цифр с использованием eval и mat2str
mymatrix2=[100.1234567, 2.12345; 3.1234567891, 4.1234];
j = mat2str(mymatrix2, 3);
mymatrix2=eval(j)
Вывод, матрица округлена до 3 значащих цифр, отметьте 100.123 округленными до 100, в то время как 2.12345 округлен до 2.12
mymatrix2 =
100.0000 2.1200
3.1200 4.1200
Вариант 3, используйте круглую функцию
Функция round не имеет параметра точности в Octave. Однако вы можете взломать его, умножив каждый элемент в матрице на 100, округляя его до ближайшего int, а затем разделив каждый элемент на 100:
mymatrix=[100.1234567, 2.12345; 3.1234567891, 4.1234];
round(mymatrix .* 100) ./ 100
Выход, округление происходит правильно:
ans =
100.1200 2.1200
3.1200 4.1200
Вариант 4, укажите output_precision (num)
Вы заметили, что опция 3 выше сохранила конечные нули, что может быть нежелательным, поэтому вы можете сказать им уйти, установив output_precision:
mymatrix=[100.1234567, 2.12345; 3.1234567891, 4.1234];
disp(mymatrix);
output_precision(3)
disp(mymatrix)
Выход:
100.1235 2.1235
3.1235 4.1234
100.123 2.123
3.123 4.123
Октава может иметь какое-то действительно странное поведение при попытке округления, помните, что октава пытается применить равномерное округление ко всем элементам в матрице. Поэтому, если у вас есть несколько столбцов с совершенно разными значениями, октава может смотреть на одну частичную крошечную ценность и думать: "Эй, я должен преобразовать ее в экспоненциальный: от 0,0001 до 1,0e-04, и, таким образом, то же самое применяется ко всему матрица.
Ответ 2
для тех, кто хочет заставить его работать, не углубляясь в дискуссию, почему все так (а именно, октава round
по-прежнему не поддерживает второй аргумент, определяющий точность).
РЕШЕНИЕ
a = [0.056787654, 0.0554464; 0.056787654, 0.0554464];
a
round_digit = 2;
if exist('OCTAVE_VERSION', 'builtin') ~= 0;
a = a.*(10^(round_digit));
a = floor(a);
a = a.*(10^(-round_digit));
else
a = round(a, round_digit);
end
a
Ответ 3
Я нашел, что следующая функция GNU Octave чрезвычайно полезна. Это позволяет указать произвольное округление для каждого отдельного столбца матрицы MxN.
Поместите эту функцию в файл с именем display_rounded_matrix.m
function display_rounded_matrix(matrix, precision, outputFile)
%precision can be a single number, applied to all, or a
%matrix of values to be applied to the columns.
space_between_columns = "";
format_part = "%10.";
precision_format = cell(columns(precision), 1);
for i = 1:columns(precision),
precision_format{i,1} = strcat(format_part, num2str(precision(1,i)), "f");
end
if (nargin == 3 && outputFile != 0)
if (rows(precision) == 1 && columns(precision) == 1)
rows = rows(matrix);
cols = columns(matrix);
format = strcat(format_part, num2str(precision), "f");
for i = 1:rows
for j = 1:cols
fprintf(outputFile, sprintf(format, matrix(i,j)));
if (j ~= cols)
fprintf(outputFile, space_between_columns);
end
end
if i ~= rows
fprintf(outputFile, "\n");
end
end
fprintf(outputFile, "\n");
elseif (rows(precision) == 1 && columns(precision) == columns(matrix))
%here we have to custom make the rounding
rows = rows(matrix);
cols = columns(matrix);
for i = 1:rows
for j = 1:cols
fprintf(outputFile, sprintf(precision_format{j,1}, matrix(i,j)));
if (j ~= cols)
fprintf(outputFile, space_between_columns);
end
end
if i ~= rows
fprintf(outputFile, "\n");
end
end
fprintf(outputFile, "\n");
else
disp("STOP!, you invoked display_rounded_matrix with bad parameters");
end
elseif (nargin == 3 && outputFile == 0)
%print to screen instead
if (rows(precision) == 1 && columns(precision) == 1)
rows = rows(matrix);
cols = columns(matrix);
format = strcat(format_part, num2str(precision), "f");
for i = 1:rows
for j = 1:cols
printf(sprintf(format, matrix(i,j)));
if (j ~= cols)
printf(space_between_columns);
end
end
if i ~= rows
printf("\n");
end
end
printf("\n");
elseif (rows(precision) == 1 && columns(precision) == columns(matrix))
%here we have to custom make the rounding
rows = rows(matrix);
cols = columns(matrix);
for i = 1:rows
for j = 1:cols
%format = strcat(format_part, num2str(precision(1,j)), "f");
format = [format_part num2str(precision(1,j)) "f"];
printf(sprintf(format, matrix(i,j)));
if (j ~= cols)
printf(space_between_columns);
end
end
if i ~= rows
printf("\n");
end
end
printf("\n");
else
disp("STOP!, you invoked display_rounded_matrix with bad parameters");
end
elseif (nargin == 2)
display_rounded_matrix(matrix, precision, 0);
else
disp("STOP!, you invoked display_rounded_matrix with wrong number of arguments");
end
end
Затем вы можете вызвать его следующим образом:
A = [ 53.0 410400 0.0094; 52.56 778300 -0.0069; 53.56 451500 -0.0340 ];
specified_rounding = [2 0 5];
display_rounded_matrix(A, specified_rounding, outputFile=0);
На экране отобразится следующее (обратите внимание на различные округления для каждого столбца!
octave:5> display_rounded_matrix(A, specified_rounding, outputFile=0);
53.00 410400 0.00940
52.56 778300 -0.00690
53.56 451500 -0.03400
3-й параметр - это дескриптор файла, вы также можете перенаправить вывод в файл:
outputFile = fopen("output.txt", "w");
A = [ 53.0 410400 0.0094; 52.56 778300 -0.0069; 53.56 451500 -0.0340 ];
specified_rounding = [2 0 5];
display_rounded_matrix(A, specified_rounding, outputFile);
Что будет делать то же, что и выше, но отправьте вывод на output.txt