17

在 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。我该怎么做?

4

3 回答 3

29

如何在 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函数

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

Octave 在尝试进行舍入时有一些奇怪的行为,因为 octave 努力将统一的舍入统一应用于矩阵中的所有项目。因此,如果您有多个具有完全不同值的列,则 octave 会看到一个很小的值并说:“我应该将其转换为类似的指数1.0e-04,因此相同的指数将应用于矩阵中的整个数据结构。

于 2012-07-08T19:59:50.750 回答
6

对于那些想要让它工作而不深入讨论为什么会这样的人(即 octaveround仍然不支持定义精度的第二个参数)。

解决方法

a = [0.056787654, 0.0554464; 0.056787654, 0.0554464];
a
round_digit = 2;
if exist('OCTAVE_VERSION', 'builtin') ~= 0;
     a = a.*(10^(round_digit));
     if (a >= 0) a = floor(a); else a = ceil(a); endif;
     a = a.*(10^(-round_digit));
else
     a = round(a, round_digit);
end
a
于 2015-08-08T13:43:09.553 回答
0

我发现以下 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

第三个参数是文件句柄,您也可以将输出重定向到文件:

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

于 2012-08-06T00:17:50.420 回答