2
votes

I have a vector of certain size and I want to reshape it into a square matrix. Here is an example: Let's say the vector is of size 784. Then I would create a matrix of size 28x28. In Matlab I would do it with the following command:

reshape(x,28,28)

Of course it can be possible that it is not possible to have an exact square matrix. In this case the matrix should as squarish as possible.

How can I do this calculation? That means how can I calculate the values a and b in reshape(x,a,b)?

4

4 Answers

2
votes

One possible approach:

x = rand(1, 784);
divisors = find(rem(numel(x), 1:numel(x)) == 0);
[~, idx] = min(abs(divisors - sqrt(numel(x))));
x = reshape(x, divisors(idx), numel(x) / divisors(idx));

Let me explain:

Suppose you have a vector named x:

x = rand(1, 784);

First, you find the divisors of the size of x:

divisors = find(rem(numel(x), 1:numel(x)) == 0);

Then, you proceed to choose the divisor which is closest to the square root of x's size:

[~, idx] = min(abs(divisors - sqrt(numel(x))));

Finally, you reshape x using that divisor (and the corresponding multiple):

x = reshape(x, divisors(idx), numel(x) / divisors(idx));
2
votes

Start with a equal to the square root of numel(x) rounded down. If that number doesn't divide numel(x), subtract 1 and try again. That way you end with a equal to the closest integer to sqrt(x) (from below) that divides numel(x). b would then be numel(x)/a, but you can simply use [] as the third argument to reshape:

a = floor(sqrt(numel(x)));
while mod(x,a)
    a = a-1;
end
result = reshape(x,a,[]);

Example:

x = 1:20;

gives

result =
     1     5     9    13    17
     2     6    10    14    18
     3     7    11    15    19
     4     8    12    16    20
0
votes

It is not a simple problem to find closest factors of an integer. You need to use the MATLAB answers to the question Input an integer, find the two closest integers which, when multiplied, equal the input. From that question if you use the answer that provides the function findIntegerFactorsCloseToSquarRoot, you can use the following code to reshape.

[a, b] =  findIntegerFactorsCloseToSquarRoot(numel(x));
reshape(x, a, b);
0
votes

I suggest you to first check whether the number is prime or not by isprime(784).

Then you can use prime_factors = factor(784) to get the integer factorization of the number. (Depending on the MATLAB version you may use ifactor(784))

The rest needs just a little more work on prime_factors.