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. Как мне это сделать?
3 ответов
как округлить элементы в матрице в Октаве:
существует множество различных способов округления матрицы и числа в октаве.
Вариант 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.2 f". "F" означает ожидать поплавка, 5 средств занимают 5 пространств. 2 означает Точность 2 единиц после десятичной точки.
ans = 100.12
ans = 3.12
ans = 2.12
ans = 4.12
Вариант 2, круглый к значительным числам используя эвал и 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 не имеет параметра точности в Октаве. Однако вы можете взломать его, умножив каждый элемент в матрице на 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.0 e-04, и, таким образом, то же самое применяется ко всей матрице.
для тех, кто хочет заставить его работать, не углубляясь в обсуждение, почему все так (а именно Октава 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
я нашел следующую функцию GNU Octave чрезвычайно полезной. Это позволяет задать пользовательское округление для каждого отдельного столбца матрицы MxN.
поместите эту функцию в файл с именем display_rounded_matrix.м
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);
который сделает то же самое, что и выше, но отправит вывод на выход.txt