web-dev-qa-db-ja.com

GNUオクターブ、数値を単位の精度に丸めます

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にしたいのですが、どうすればよいですか?

14
Eric Leschinski

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に丸められた行列有効数字、2.12345が2.12に丸められている間に100.123が100に丸められていることに注意してください

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

オクターブは、丸めを行おうとするときに実際に奇妙な動作をする可能性があります。オクターブは、行​​列内のすべての項目に丸めを均一に適用しようとすることに注意してください。したがって、大幅に異なる値を持つ複数の列がある場合、オクターブは、1つの特に小さな値を見て、次のように考えるかもしれません。マトリックス。

23
Eric Leschinski

なぜこれがこのようになっているのかを深く掘り下げることなく機能させたい場合(つまり、オクターブroundは、精度を定義する2番目の引数をまだサポートしていません)。

[〜#〜]回避策[〜#〜]

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
5
Ufos

次のようになりましたGNUオクターブ関数は非常に便利です。これにより、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に送信します

0
Eric Leschinski