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