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