În GNU Octave versiunea 3.4.3 vreau să rotunjesc o matrice la o precizie de 2 unități pe conținutul unei matrice, astfel.
mymatrix=[1.1234567, 2.12345; 3.1234567891, 4.1234];
disp(mymatrix);
Aceasta se tipărește:
1.1235 2.1235
3.1235 4.1234
După cum puteți vedea, disp forțează precizia la „5”, eu vreau ca precizia unităților să fie 2. Cum pot face acest lucru?
Cum se rotunjesc elementele dintr-o matrice în Octave:
Există multe moduri diferite de a rotunji o matrice și de a rotunji un număr în Octave.
Opțiunea 1, utilizarea funcției de format 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
Ieșire, observați simbolul „%5.2f”. „f” înseamnă că se așteaptă un float, iar 5 înseamnă că ocupă 5 spații. 2 înseamnă precizie de 2 unități după virgulă.
ans = 100.12
ans = 3.12
ans = 2.12
ans = 4.12
Opțiunea 2, rotunjire la cifre semnificative utilizând eval și mat2str
mymatrix2=[100.1234567, 2.12345; 3.1234567891, 4.1234];
j = mat2str(mymatrix2, 3);
mymatrix2=eval(j)
Ieșirematrice rotunjită la 3 cifre semnificative, observați că 100,123 a fost rotunjit la 100, în timp ce 2,12345 a fost rotunjit la 2,12.
mymatrix2 = 100.0000 2.1200
3.1200 4.1200
Opțiunea 3, utilizați funcția round
Funcția round nu are un parametru de precizie în Octave. Cu toate acestea, o puteți ocoli prin înmulțirea fiecărui element din matrice cu 100, rotunjirea la cel mai apropiat int, apoi împărțirea fiecărui element la 100:
mymatrix=[100.1234567, 2.12345; 3.1234567891, 4.1234];
round(mymatrix .* 100) ./ 100
Ieșire, rotunjirea are loc corect:
ans = 100.1200 2.1200
3.1200 4.1200
Opțiunea 4, specificați un parametru output_precision(num)
Ați observat că opțiunea 3 de mai sus a păstrat zerourile din urmă, ceea ce poate fi nedorit, așa că puteți să le spuneți să dispară prin setarea output_precision:
mymatrix=[100.1234567, 2.12345; 3.1234567891, 4.1234];
disp(mymatrix);
output_precision(3)
disp(mymatrix)
Output:
100.1235 2.1235
3.1235 4.1234
100.123 2.123
3.123 4.123
Octave are un comportament ciudat atunci când încearcă să facă rotunjirea, deoarece octave se străduiește să aplice uniform o rotunjire uniformă tuturor elementelor dintr-o matrice. Deci, dacă aveți mai multe coloane cu valori extrem de diferite, octave vede o valoare mică și spune: „Ar trebui să o convertesc într-o exponențială de genul 1.0e-04
, și astfel, același exponențial este aplicat întregii structuri de date din matrice.
pentru cei care vor să o facă să funcționeze fără a săpa adânc în discuții de ce lucrurile stau așa (și anume octave round
încă nu suportă un al doilea argument care să definească precizia).
SOLUȚIE:
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
Am găsit următoarea funcție GNU Octave extrem de utilă. Aceasta vă permite să specificați o rotunjire personalizată pentru fiecare coloană individuală a unei matrice MxN.
Puneți această funcție într-un fișier numit 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, "
");
end
end
fprintf(outputFile, "
");
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, "
");
end
end
fprintf(outputFile, "
");
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("
");
end
end
printf("
");
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("
");
end
end
printf("
");
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
Apoi o puteți invoca astfel:
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);
Aceasta va afișa pe ecran următoarele (observați rotunjimile diferite pentru fiecare coloană!
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
cel de-al treilea parametru este un mâner de fișier, ați putea redirecționa ieșirea și către un fișier:
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);
Ceea ce va face același lucru ca mai sus, dar va trimite ieșirea la output.txt
round
cu un al doilea argument?! – > Por Jonathon Reinhart.savannah.gnu.org
, dar explicația este următoarea. Comportamentulround(number, precision)
provine de la faptul că aveți un matematică simbolică [sym
], care înlocuiește pachetul implicit cu un singur argumentround
al matlab-ului de bază cu versiunea cu două argumente. Deoarece octave își propune să implementeze doar matlab-ul de bază, iar implementarea pachetelor sale este o altă etapă, astfel încât utilizatorii rămân cu stilul anilor ’80round
. – > Por Ufos.round(x, precision)
nu va rula pe mașina altcuiva, care nu are pachetul de matematică simbolică, prin urmare, luați în considerare scrierea unei funcții customg, și folosiți-o peste tot. – > Por Ufos.a = floor(a)
ar trebui să fie înlocuit cuif (a >= 0) a = floor(a); else a = ceil(a); endif;
– > Por Cromax.