Как вывести размеры матрицы вместе с ее содержимым?

Можно ли заставить GNU Octave выводить размеры матрицы вместе с ее содержимым? Например, это должно привести к чему-л. как это:

octave:1> X = [1 2; 3 4]

X [2x2] =

   1   2
   3   4


octave:2> X(1,:)

ans [1x2] =

   1   2

5 ответов

Решение

В MATLAB создайте display.m в папке с именем @double где-то на вашем пути с этим содержанием:

function display(v)
name = inputname(1);
if isempty(name)
    name = 'ans';
end
s = num2cell(size(v));
fprintf('\n%s [%d%s] =\n\n', name, s{1}, sprintf('x%d', s{2:end}));
builtin('disp', v);
end

Таким образом, вы переопределяете display метод для класса doubleи получите именно то, что вы описали. Тем не менее, это не будет работать для других классов, таких как int8, logical или же cell, Вы должны переопределить метод для всех интересующих вас классов. Пример:

>> A=ones(2,2,2)

A [2x2x2] =

(:,:,1) =
     1     1
     1     1
(:,:,2) =
     1     1
     1     1

Хотя ответ Мохсена действительно выполняет свою работу, я чувствовал, что отдельный m-файл для этой цели несколько избыточен (особенно если вы не хотите загромождать свой каталог дополнительными m-файлами). Я предлагаю вместо этого использовать однострочную локальную анонимную функцию (назовем ее dispf), так вот его фазы эволюции:)

Основная анонимная функция, которую я придумал:

dispf = @(x)fprintf('%s =\n\n%s\n', inputname(1), disp(x));

что по существу эквивалентно выводу в командном окне после ввода операторов (которые, конечно, не заканчиваются точкой с запятой). Ну, почти... потому что если inputname возвращает пустую строку, не печатает 'ans' (так и должно быть). Но это можно исправить:

dispf = @(x)fprintf('%s=\n\n%s\n', ...
    regexprep([inputname(1), ' '], '^ $', 'ans '), ...
    disp(x));

Это в основном использует regexprep сопоставить пустую строку и заменить ее 'ans', Наконец, мы добавляем размеры после имени переменной:

dispf = @(x)fprintf('%s%s =\n\n%s\n', ...
    regexprep([inputname(1), ' '], '^ $', 'ans '), ...
    strrep(mat2str(size(x)), ' ', 'x'), ...
    disp(x));

Теперь вы можете подключить этот однострочник в любой скрипт без необходимости дополнительного m-файла!

пример

Просто доказательство того, что это работает:

dispf = @(x)fprintf('%s%s =\n\n%s\n', ...
    regexprep([inputname(1), ' '], '^ $', 'ans '), ...
    strrep(mat2str(size(x)), ' ', 'x'), ...
    disp(x));

A = [1 2; 3 4];
dispf(A)
dispf(A(1, :))

Результат, как и ожидалось:

A [2x2] =

   1   2
   3   4

ans [1x2] =

   1   2

Я не знаю, работает ли он в Octave, но в MATLAB вы можете использовать format debug команда и получить размеры массива и немного больше:

>> format debug
>> X = [1 2; 3 4]

X =


Structure address = 7d19498 
m = 2
n = 2
pr = 373bafa0 
pi = 0
     1     2
     3     4

Вот еще один. Вы можете использовать его для перегрузки @double/display как объяснили другие, или назовите его как-нибудь еще и используйте его в качестве своей собственной функции отображения:

function display(x)
    % determine whether format is loose or compect
    loose = strcmp(get(0,'FormatSpacing'), 'loose');

    % print name or ans
    name = inputname(1);
    if isempty(name), name = 'ans'; end
    if loose, disp(' '); end
    disp([name ' =']);
    if loose, disp(' '); end

    % print size
    sz = size(x);
    if length(sz) == 2
        fprintf('    %s: %d-by-%d\n', class(x), sz(1), sz(2));
    elseif length(sz) == 3
        fprintf('    %s: %d-by-%d-by-%d\n', class(x), sz(1), sz(2), sz(3));
    else
        fprintf('    %s: %d-D\n', class(x), numel(sz));
    end
    if loose, disp(' '); end

    % print array
    disp(x);
end

Обратите внимание, что я немного изменил формат вывода по сравнению с тем, что у вас было:

>> format compact;
>> x = magic(5);
>> display(x)
x =
    double: 5-by-5
    17    24     1     8    15
    23     5     7    14    16
     4     6    13    20    22
    10    12    19    21     3
    11    18    25     2     9

Вот еще один способ сделать это. Преимущество этого метода в том, что он может работать с более сложными входами, чем упомянутые альтернативы.

function show(s)
t = regexp(s,'=');
if any(t)
    evalin('caller',['disp(size(' s(t+1:end) ')),' s])
else
    evalin('caller',['disp(size(' s ')),' s])
end

Чтобы использовать его, сохраните функцию и попробуйте это:

show x = rand(3)
show('y = {uint8(8);[6 7 8]}')

Обратите внимание, что он может использовать удобный синтаксис команды для простых входных данных и что вам нужна форма функции с командой в строковой форме для сложных входных данных (содержащих точки с запятой или апострофы).

Другие вопросы по тегам