How to output matrix dimensions together with its content?

后端 未结 5 794
醉话见心
醉话见心 2021-01-02 02:05

Is it possible to make GNU Octave to output matrix dimensions together with its content? For example, it should produce smth. like this:

octave:1> X = [1          


        
相关标签:
5条回答
  • 2021-01-02 02:40

    I don't know if it works in Octave, but in MATLAB you can use format debug command and get the dimensions of the array and a bit more:

    >> format debug
    >> X = [1 2; 3 4]
    
    X =
    
    
    Structure address = 7d19498 
    m = 2
    n = 2
    pr = 373bafa0 
    pi = 0
         1     2
         3     4
    
    0 讨论(0)
  • 2021-01-02 02:41

    Here is another one. You could either use it to overload @double/display as others have explained, or name it something else and use it as your own custom display function:

    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
    

    Note that I changed the format of the output a little bit from what you had:

    >> 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
    
    0 讨论(0)
  • 2021-01-02 02:43

    While Mohsen's answer does the job indeed, I felt that a separate m-file is somewhat an overkill for this purpose (especially if you don't want to clutter your directory with additional m-files). I suggest using a local anonymous function one-liner instead (let's name it dispf), so here are its evolution phases :)

    The basic anonymous function I came up with is:

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

    which is essentially equivalent to the output in the command window after entering statements (that do not end with a semicolon, of course). Well, almost... because if inputname returns an empty string, it doesn't print 'ans' (and it should). But this can be corrected:

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

    This is basically using regexprep to match an empty string and replace it with 'ans'. Finally, we append the dimensions after the variable name:

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

    Now you can plug this one-liner is into any script without the need for an additional m-file!

    Example

    Just a proof that it's working:

    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, :))
    

    The result is as expected:

    A [2x2] =
    
       1   2
       3   4
    
    ans [1x2] =
    
       1   2
    
    0 讨论(0)
  • 2021-01-02 02:49

    In MATLAB, create display.m in a folder called @double somewhere in your path with this content:

    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
    

    This way you override the display method for class double, and get exactly what you have described. However, this will not work for other classes like int8, logical or cell. You have to override the method for all classes you are interested in. Example:

    >> A=ones(2,2,2)
    
    A [2x2x2] =
    
    (:,:,1) =
         1     1
         1     1
    (:,:,2) =
         1     1
         1     1
    
    0 讨论(0)
  • Here is another way to do it. The advantage of this method is that it can deal with more complicated inputs than the mentioned alternatives.

    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
    

    To use it, save the function and try this:

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

    Note that it can take the convenient command syntax for simple inputs and that you need the function form with the command in string form for complicated inputs (containing semicolons or apostrophes).

    0 讨论(0)
提交回复
热议问题