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

3 visualizzazioni (ultimi 30 giorni)
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 Commenti
dani elias
dani elias il 16 Giu 2023
Modificato: dani elias il 16 Giu 2023
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};

Accedi per commentare.

Risposta accettata

chicken vector
chicken vector il 15 Giu 2023
Modificato: chicken vector il 15 Giu 2023
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 Commenti
chicken vector
chicken vector il 16 Giu 2023
Modificato: chicken vector il 16 Giu 2023
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.
dani elias
dani elias il 16 Giu 2023
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"

Accedi per commentare.

Più risposte (1)

Stephen23
Stephen23 il 16 Giu 2023
Modificato: Stephen23 il 16 Giu 2023
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 Commenti
Stephen23
Stephen23 il 16 Giu 2023
"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.

Accedi per commentare.

Categorie

Scopri di più su Data Type Conversion in Help Center e File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by