Dividing a Square Matrix into Four Distinct Matrices Based on indexing element as well as the last digit

Assuming I have a square matrix of N x N, example for 2x2 we can have A = [10902425 3040701; 36904080 304], where each cell contains a number with at least eight digits. I aim to generate four distinct square matrices from A, namely A1=[10 30;36 30], A2=[90 40;90 04], A3=[24 70;40 00], and A4=[25 01;80 00]. The division of pixels is based on pairs, and a new matrix is formed. If the last number of pixel is not in pair,the put 0 as the leading number to make pair and the rest of pixel position will be 00. in a simple way each number in each position is divided into pair for example 10902425 -> 10| 90| 24| 25 , but for 304 it should be 30| 04 instead of 40 this will make easy during the reversing process (in my view). I need a help on both forwarding process as well as reversing to the original matrix
close all;
clear;
clc;
% Given matrix A
A = [10902425 3040701; 36904080 304];
% Extract the digits from A
A_digits = mod(A, 10);
% Generate A1
A1 = floor(A/100);
% Generate A2
A2 = zeros(size(A));
A2(A_digits == 0 | A_digits == 1) = mod(A(A_digits == 0 | A_digits == 1), 100);
% Generate A3
A3 = zeros(size(A));
A3(A_digits == 2 | A_digits == 4) = mod(A(A_digits == 2 | A_digits == 4), 100);
% Generate A4
A4 = zeros(size(A));
A4(A_digits == 5 | A_digits == 6) = mod(A(A_digits == 5 | A_digits == 6), 100);
% Display the resulting matrices
this code produce error

3 Comments

" need a help on both forwarding process as well as reversing to the original matrix"
The task is impossible, without extra information your algorithm cannot distinguish between e.g. 10000000 and 1.
It is also impossible to detect those swapped digits.
What is the actual goal?
Apologies for any lack of clarity in my previous responses plus question. I understand that there might have been some confusion in the beginning.
The objective is to ensure that each value in the matrix consists of 8 digits. If the digits in a value are not in pairs, a leading 0 is added to the last digit. If the digits are in pairs but the value has less than 8 digits, trailing 0s are added to the right side of the last digit until it reaches a total of 8 digits. Always the numbers are greater than 3 digits..
So far, I have successfully transformed the matrix A = [10902425 3040701; 36904080 304] into AA = [10902425 30407001; 36904080 30040000]. As a result, I obtained four separate matrices: A1 = [10 30; 36 30], A2 = [90 40; 90 4], A3 = [24 70; 40 00], and A4 = [25 01; 80 00]. This transformation was accomplished with the help of a specific method from @chicken vector. Now, I would like to reverse the process and convert A1, A2, A3, and A4 back to the original matrix, A. This is the codes:
A = [10902425 3040701; 36954080 285];
% Initialize the output matrix v with zeros
v = zeros(size(A));
for i = 1:size(A, 1)
for j = 1:size(A, 2)
num_str = num2str(A(i, j));
num_len = length(num_str);
% Check if any digit is not in pair
if mod(num_len, 2) ~= 0
% Add leading zero before the last number
num_str = strcat(num_str(1:end-1), '0', num_str(end));
end
% Check if the number of digits is less than eight
if num_len < 8
% Add trailing zeros to the right side
num_str = strcat(num_str, repmat('0', 1, 7 - num_len));
elseif num_len > 8
% Trim the string to eight digits
num_str = num_str(1:8);
end
% Convert the modified string back to a number and assign it to v
v(i, j) = str2num(num_str);
end
end
% Check if the last position has 8 digits
last_num_str = num2str(v(end));
last_num_len = length(last_num_str);
if last_num_len < 8
% Add trailing zeros to the last position
last_num_str = strcat(last_num_str, repmat('0', 1, 8 - last_num_len));
v(end) = str2num(last_num_str);
end
out = cellfun(@(x) reshape(x, 2, 4)', cellstr(string(v'.*10.^(8 - strlength(string(v'))))), 'UniformOutput', false);
out = cellfun(@(x) reshape(str2num(reshape(x, 2, 4)'),2,2)', cellstr([out{:}]), 'UniformOutput', false);
A1 = out{1};
A2 = out{2};
A3 = out{3};
A4 = out{4};
@dani elias: sure, I have already read this thread. Your comment does not address any of my points.

Sign in to comment.

 Accepted Answer

This will give you what you are looking for, except for the inverted number in case of odd number of digits:
A = [10902425 3040701; 36904080 304];
out = cellfun(@(x) reshape(x, 2, 4)', cellstr(string(A'.*10.^(8 - strlength(string(A'))))), 'UniformOutput', false);
out = cellfun(@(x) reshape(str2num(reshape(x, 2, 4)'),2,2)', cellstr([out{:}]), 'UniformOutput', false);
EDIT:
This is what you asked for.
Be careful that we are using numbers so in the final output 04 or 00 become 4 and 0.
B = cellstr(string(A'.*10.^(8 - strlength(string(A'))) - rem(strlength(string(A')),2).*((A'./10 - floor(A'./10)).*10).*10.^(7 - strlength(string(A'))).*9));
out = cellfun(@(x) reshape(x, 2, 4)', B, 'UniformOutput', false);
out = cellfun(@(x) reshape(str2num(reshape(x, 2, 4)'),2,2)', cellstr([out{:}]), 'UniformOutput', false);
Output:
out{1}
ans = 2×2
10 30 36 30
out{2}
ans = 2×2
90 40 90 4
out{3}
ans = 2×2
24 70 40 0
out{4}
ans = 2×2
25 1 80 0

5 Comments

thank you for this answer. is it possible to return to the original matrix??
If you use the first method yes, but if you invert the digits when you have odd number is impossible because you don’t know if the original number was supposed to be that, or the last two digits were inverted.
I saw it. in the second method, output seems to be correct. but for the first method especially for out{2}, at (2,2) position yield to 40 instead of 4 or 04.
As I said at the beginning:
"This will give you what you are looking for, except for the inverted number in case of odd number of digits:"
You can disregard the first method.
Actually the second method is the same with some additional manipulation of odd digits numbers.
A = [10902425 3040701; 36904080 304];
This add the trailing zeros to the number:
A'.*10.^(8 - strlength(string(A')))
ans = 2×2
10902425 36904080 30407010 30400000
This check what numbers have odd digits:
rem(strlength(string(A')),2)
ans = 2×2
0 0 1 1
This takes the last digit of every number:
((A'./10 - floor(A'./10)).*10)
ans = 2×2
5.0000 0 1.0000 4.0000
So together retain only the last digit of the odd digit numbers:
rem(strlength(string(A')),2).*((A'./10 - floor(A'./10)).*10)
ans = 2×2
0 0 1.0000 4.0000
This inverts the digit by substracting by 9:
10.^(7 - strlength(string(A'))).*9
ans = 2×2
1.0e+04 * 0.0001 0.0001 0.0009 9.0000
Example: to make 4000 become 400 you substract 10^3*(9*4))
where 4 is the last digit given by:
rem(strlength(string(A')),2).*((A'./10 - floor(A'./10)).*10);
And 10^3*9 is given by:
10.^(7 - strlength(string(A'))).*9;
The rest of the code is a series of 3 reshaping manipulations, 2 acting on char arrays and the last one on a matrix.
thank you once again for your help, I have tried to modified the code like this.
A = [10902425 3040701; 36954080 301];
% Initialize the output matrix v with zeros
v = zeros(size(A));
for i = 1:size(A, 1)
for j = 1:size(A, 2)
num_str = num2str(A(i, j));
num_len = length(num_str);
% Check if any digit is not in pair
if mod(num_len, 2) ~= 0
% Add leading zero before the last number
num_str = strcat(num_str(1:end-1), '0', num_str(end));
end
% Check if the number of digits is less than eight
if num_len < 8
% Add trailing zeros to the right side
num_str = strcat(num_str, repmat('0', 1, 7 - num_len));
elseif num_len > 8
% Trim the string to eight digits
num_str = num_str(1:8);
end
% Convert the modified string back to a number and assign it to v
v(i, j) = str2num(num_str);
end
end
% Check if the last position has 8 digits
last_num_str = num2str(v(end));
last_num_len = length(last_num_str);
if last_num_len < 8
% Add trailing zeros to the last position
last_num_str = strcat(last_num_str, repmat('0', 1, 8 - last_num_len));
v(end) = str2num(last_num_str);
end
% compare A and v
disp("A =");
disp(A);
disp("v =");
disp(v);
%from chicken vector-mathworks
out = cellfun(@(x) reshape(x, 2, 4)', cellstr(string(v'.*10.^(8 - strlength(string(v'))))), 'UniformOutput', false);
out = cellfun(@(x) reshape(str2num(reshape(x, 2, 4)'),2,2)', cellstr([out{:}]), 'UniformOutput', false);
A1 = out{1};
A2 = out{2};
A3 = out{3};
A4 = out{4};
disp(A1);
disp(A2);
disp(A3);
disp(A4);
outputs
A =
10902425 3040701
36954080 301
v =
10902425 30407001
36954080 30010000
A1 =
10 30
36 30
A2 =
90 40
95 1
A3 =
24 70
40 0
A4 =
25 1
80 0
now I need to convert it back to the original matrix either in form of "v" or "A"

Sign in to comment.

More Answers (1)

Simpler and more efficient.
My answer takes into account my comments here. Assumes no zero, negative, fractional, inf, etc. values.
format compact
A = [10902425,3040701;36904080,304]
A = 2×2
10902425 3040701 36904080 304
B = A.*10.^(8-fix(log10(A)))
B = 2×2
109024250 304070100 369040800 304000000
C = 10.^cat(3,7,5,3,1);
% A1=[10 30;36 30], A2=[90 40;90 04], A3=[24 70;40 00], A4=[25 01;80 00]
D = mod(fix(B./C),100)
D =
D(:,:,1) = 10 30 36 30 D(:,:,2) = 90 40 90 40 D(:,:,3) = 24 70 40 0 D(:,:,4) = 25 10 80 0
And back again:
E = sum(D.*C,3)
E = 2×2
109024250 304070100 369040800 304000000

6 Comments

Very nice and clean one! Rounding is much better than using strings indeed.
Just remember to add the digit inversion as per question:
B = A.*10.^(8-fix(log10(A))) - (log10(A)<7).*(A - floor(A./10).*10).*10.^(8 - ceil(log10(A))).*9;
"Just remember to add the digit inversion as per question:"
As I already wrote in my answer, this is excluded due to the impossibility of reliably detecting it (or more precisely, distinguishing it from a non-zero digit preceded by a zero).
If you had to include it how would you do this?
I am sure you can find a better way than me and I learn a lot from these answers.
@chicken vector,@Stephen23 ,thank you so much for your help! Your assistance in solving the question was invaluable. I truly appreciate your expertise and guidance.
"Your assistance in solving the question was invaluable. I truly appreciate your expertise and guidance."
@dani elias: you can show your appreciation by voting for answers that helped you.

Sign in to comment.

Categories

Find more on Programming in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!