3

For matrices with dimensions equal or less then 2 the command is:

For instance:

>> mat2str(ones(2,2))

ans =

[1 1;1 1]

However, as the help states, this does not work for higher dimensions:

>> mat2str(rand(2,2,2))
Error using mat2str (line 49)
Input matrix must be 2-D.

How to output matrices with higher dimensions than 2 with that is code compatible, without resorting to custom made for loops?

4
  • 1
    Well I just learned a new command! Anyhow, I doubt that it's possible as there is no separator for third dimensions (like the comma and semicolon are for 2D). You could use sprintf with a cat(3, at the beginning to concatenate all of the 2D arrays together into a 3D array. Commented Mar 23, 2016 at 18:50
  • It was not trivial to find the command :). I did not get it how your suggestion with sprintf would work. Commented Mar 23, 2016 at 19:04
  • mat2str is a wrapper for sprintf, and utilizes loops. There's no reason to avoid them. But, as @Suever says, there's no way to enter a 3D+ array with the same syntax. Commented Mar 23, 2016 at 19:07
  • @hakanc Sorry, it is a little difficult to describe in a comment. I have added an answer and demo below. Commented Mar 23, 2016 at 19:15

1 Answer 1

5

This isn't directly possible because there is no built-in character to represent concatenation in the third dimension (an analog to the comma and semicolon in 2D). One potential workaround for this would be to perform mat2str on all "slices" in the third dimension and wrap them in a call to cat which, when executed, would concatenate all of the 2D matrices in the third dimension to recreate your input matrix.

M = reshape(1:8, [2 2 2]);

arrays = arrayfun(@(k)mat2str(M(:,:,k)), 1:size(M, 3), 'uni', 0);
result = ['cat(3', sprintf(', %s', arrays{:}), ')'];

result =

    'cat(3, [1 3;2 4], [5 7;6 8])'

isequal(eval(result), M)

    1

UPDATE

After thinking about this some more, a more elegant solution is to flatten the input matrix, run mat2str on that, and then in the string used to recreate the data, we utilize reshape combined with the original dimensions to provide a command which will recreate the data. This will work for any dimension of data.

result = sprintf('reshape(%s, %s);', mat2str(M(:)), mat2str(size(M)));

So for the following 4D input

M = randi([0 9], 1, 2, 3, 4);
result = sprintf('reshape(%s, %s);', mat2str(M(:)), mat2str(size(M)));

    'reshape([6;9;4;6;5;2;6;1;7;2;1;7;2;1;6;2;2;8;3;1;1;3;8;5], [1 2 3 4]);'

Now if we reconstruct the data using this generated string, we can ensure that we get the correct data back.

Mnew = eval(result);
size(Mnew)

    1   2   3   4

isequal(Mnew, M)

    1

By specifying both the class and precision inputs to mat2str, we can even better approximate the input data including floating point numbers.

M = rand(1,2,3,4,5);
result = sprintf('reshape(%s, %s);', mat2str(M(:),64,'class'), mat2str(size(M)));

isequal(eval(result), M)

    1
Sign up to request clarification or add additional context in comments.

8 Comments

I up voted the answer because it is a solution for 3D matrices, although I cannot clearly see how it is can be extended to higher dimensions. Coming from Python, I cannot really understand how one cannot define arrays with higher dimensions in a consistent way in matlab.
@hakanc I updated my solution with a more brief solution that will work for any dimension of data.
@hakanc one cannot define arrays with higher dimensions, yes you can! but in a string? why in a string? printed? Why would you print a 5 dimensional matrix? Creating them is easy, rand(2,2,2,2,2,2,2,2,2,2,2,2) works.....
Well done. Good job on creating a string which can be re-evaluated to the original matrix ... (although I fail to imagine in which cases you would want to do that)
@AnderBiguri Let's imagine that I have a 16 x 16 x 3 icon that I want to be returned by a function getSueverIcon() and I don't want to store the binary image file in version control. You would want some way (given an image file) to create a string which you can dump into an m-file to create the same image.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.