GNU Octave,将数字舍入到单位精度

时间:2012-07-08 19:33:17

标签: linux matrix rounding precision 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 个答案:

答案 0 :(得分:22)

如何在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,使用圆函数

圆函数在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在尝试舍入时可能会有一些非常奇怪的行为,请记住,八度音很难均匀地将舍入应用于矩阵中的所有项。因此,如果你有多个具有完全不同的值的列,八度音可能会看到一个非常微小的值并且想:“嘿,我应该将其转换为指数:0.0001到1.0e-04,因此,同样的事情适用于整个矩阵。

答案 1 :(得分:4)

对于那些想要让它工作而不深入讨论为什么事情是这样的人(即八度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

答案 2 :(得分: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

第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