Sivakumar V
Sivakumar V

Reputation: 35

How to do genetic operations in matlab

I have two matrices. One is I an identity matrix and another A with diagonal 0's and mixed 1's and 0's in other places. By keeping identity matrix as it is, scan the rows from left to right.

I is identity matrix

I =

     1     0     0     0     0     0     0     0
     0     1     0     0     0     0     0     0
     0     0     1     0     0     0     0     0
     0     0     0     1     0     0     0     0
     0     0     0     0     1     0     0     0
     0     0     0     0     0     1     0     0
     0     0     0     0     0     0     1     0
     0     0     0     0     0     0     0     1

A matrix:

A =

     0     1     1     1     0     0     0     0
     1     0     1     1     0     0     0     0
     1     1     0     1     1     1     0     0
     1     1     1     0     1     1     1     0
     0     1     1     1     0     1     1     1
     0     0     1     1     1     0     1     1
     0     0     0     1     1     1     0     1
     0     0     0     0     1     1     1     0

Result matrix

Result =

     1     0     0     0     1     0     0     0
     0     1     0     0     0     1     0     0
     0     0     1     0     0     0     1     0
     0     0     0     1     0     0     0     1

Upvotes: 0

Views: 133

Answers (2)

zdim
zdim

Reputation: 66883

Update   Final update: Adjusted to work with matrices with only one 1.


Since I find it difficult to understand the problem and the stated procedure here is an explanation of what the code below does. I use row 3 (three) as an example, as far as concrete examples are feasible.

(1) Find all nodes to which node 3 is not connected, as they may transmit as the same time. For this do the following: take NOR (false and false => true) between the rows 3 of I and A and then add 1 from I (in column 3) to that. This is TempResult.

I(3,:)    :   0  0  1  0  0  0  0  0 
A(3,:)    :   1  1  0  1  1  1  0  0 
TempResult:   0  0  1  0  0  0  1  1 

(2) The TempResult indicates that nodes 7 and 8 are candidates (node 3 is excluded since it transmits already). Check for conflict by performing NOR between row 7 and row 3 (currently examined).

col 3:  1  1  0  1  1  1  0  0 
col 7:  0  0  0  1  1  1  0  1 
res  :  0  0  1  0  0  0  1  0 

(3) Apply NAND between the obtained row and the current Result (as it has been built up, up to this point), row by row. (Obtained vector is NAND-ed with the yet next row, consecutively through all rows of Result.)

(4) Take AND between the final row obtained by the above NAND-ing and the res of the step (2).

(5) Check each 1 past the first two: find its index and AND the 1 with A(index, index).

Post-process obtained matrix: Remove duplicate rows, and apply the final "filtering" (see code).

Some of this is taken verbatim as supplied in clarifications.

The procedure is stated in code comments.

function Result = nor_mat(A)
% Takes a square matrix A
I = eye(size(A,1));  % identity matrix of A's size
Result = []; 

for i = 1:size(A) 
    % NOR on tempRes i of 'I' and 'A' 
    tmp1 = ~I(i,:) & ~A(i,:); 
    % Find column (index) where 1 is in 'I' 
    one_ind = find(I(i,:)==1,1); 
    % Place the 1 from 'I" in the corresponding column of TempResult 
    tmp1(one_ind) = 1; 
    % For rows > 1: NAND between TempRes1 and previous rows in result 
    tempRes = tmp1; 
    if (i > 1) 
        tmp2 = tmp1; 
        for j = 1:size(Result,1) 
            row_tmp1 = tmp2 & Result(j,:); 
            row_tmp = ~row_tmp1; 
            tmp2 = row_tmp; 
        end 
        % Now do AND between the final 'tmp2' result and tmp1 
        tempRes = tmp1 & tmp2; 
    end 
    % Find (first two) non-zero columns, take first that does not come from I 
    col_two = find(tempRes, 2); 
    col = col_two( find(col_two ~= one_ind, 1) ); 
    % For matrices with one 1 (from I) the above won't find anything
    if isempty(col)
        col = i;
    end
    % Check for conflict: do NOR between the i-th and col-th row of A 
    res = ~A(i,:) & ~A(col,:); 
    % Place I's 1 in the corresponding column of the result-row 
    res(one_ind) = 1; 
    % Final clean up: Check all 1's after the first two 
    % Do AND on such elements with A's entry at that (index, index) 
    extra_ones = find(res==1); 
    if length(extra_ones) > 2 
        for k = 1:length(extra_ones); 
            ind = extra_ones(k); 
            res(ind) = ~res(ind) & ~A(ind, ind); 
        end 
    end 
    % Add this result-row to the 'Result' matrix 
    Result = [Result; res]; 
end 

% Additional adjustments. Uncomment if needed.
%% NOR between all rows of Result for indices of 1 in each row of Result
%Result_new = [];
%for i = 1:size(Result,1)
%    cols_one = find(Result(i,:)==1);
%    res_new = Result(cols_one(1),:);
%    for j = 2:length(cols_one)
%        res_tmp = res_new;
%        res_new = ~Result(cols_one(j),:) & ~res_tmp;
%    end
%    Result_new = [Result_new; res_new];
%end

Result = unique(Result, 'rows', 'stable'); 
% Final "filtering" 
ind = cumsum(Result); %cumulative sum (by column)  
Result(ind>1) = 0;  
Result(sum(Result')==0,:)=[]; 

% Print it 
for i = 1:size(Result, 1) 
    fprintf('%2d ', Result(i,:)); fprintf('\n'); 
end 
fprintf('\n'); 

The NOR operation (false and false ==> true) between A and B is implemented in the code above as [pseudo-code]: (not A) and (not B). In Matlab this can be written as: ~A & ~B (for vectors). In my understanding each row represents node(s) that may transmit at that time. This prints

1 0 0 0 1 0 0 0
0 1 0 0 0 1 0 0
0 0 1 0 0 0 1 0
0 0 0 1 0 0 0 1

Given the difficulty with understanding the evolving requirements below is the same code, but with printing statements that document the processing. The printing statements are indented so that the code can be followed. For yet more detailed printing un-comment further fprintfs. (Note: the editor shades everything after %, which is used in fprintf.)

function Result = nor_mat()
I = eye(size(A,1));
Result = [];


for i = 1:size(A)
        fprintf('--- row %d\n', i);
        fprintf('I(%d,:) :  ', i); fprintf('%2d ', I(i,:)); fprintf('\n');
        fprintf('A(%d,:) :  ', i); fprintf('%2d ', A(i,:) ); fprintf('\n');
    % NOR on row i of 'I' and 'A'
    tmp1 = ~I(i,:) & ~A(i,:);
    % Find column (index) where 1 is in 'I'
    one_ind = find(I(i,:)==1,1);
    % Place the 1 from 'I" in the corresponding column of TempResult
    tmp1(one_ind) = 1;
        fprintf('tmp1: '); fprintf('%2d ', tmp1(:) ); fprintf('\n');
        fprintf('Do NAND between tmp1 and previous rows of Result\n');
    tempRes = tmp1;
    % For rows > 1: NAND between tmp1 and previous rows in result
    if (i > 1)
        tmp2 = tmp1;
        for j = 1:size(Result,1)
                %fprintf('\tNAND result with Result(%d)\n', j);
                %fprintf('\t'); fprintf('%2d ', tmp2(:)); fprintf('\n');
                %fprintf('\t'); fprintf('%2d ', Result(j,:)); fprintf('\n');
            row_tmp1 = tmp2 & Result(j,:);
            row_tmp = ~row_tmp1;
                %fprintf('\t'); fprintf('%2d ', row_tmp(:)); fprintf('\n');
            tmp2 = row_tmp;
        end 
            %fprintf('tmp2: '); fprintf('%2d ', tmp2(:)); fprintf('\n');
        % Now do AND between the final 'row' result and tmp1
            fprintf('Do AND between result of the above and tmp1\n');
            fprintf('tmp1:  '); fprintf('%2d ', tempRes(:)); fprintf('\n');
        tempRes = tmp1 & tmp2;
    end
    % Find (first two) non-zero columns, take first that does not come from I
    col_two = find(tempRes, 2); 
    col = col_two( find(col_two ~= one_ind, 1) );
        fprintf('Choose col %d ("1" from I is in col %d)\n', col, one_ind);
        fprintf('Check columns %d and %d for conflict.\n', i, col);
        fprintf('col %d: ', i);   fprintf('%2d ', A(i,:));   fprintf('\n');
        fprintf('col %d: ', col); fprintf('%2d ', A(col,:)); fprintf('\n');
    % For matrices with only one zero there will only be one 1 (from identity)
    if isempty(col)
        col = i;
    end
    % Check for conflict: do NOR between the i-th and col-th row of A
    res = ~A(i,:) & ~A(col,:);
    % Place I's 1 in the corresponding column of result-row
    res(one_ind) = 1;
        fprintf('res  : '); fprintf('%2d ', res); fprintf('\n');
    % Final clean up: Check all 1's after the first two
    extra_ones = find(res==1);
        fprintf('Indices of all 1: '); fprintf('%d ', extra_ones); fprintf('\n');
        fprintf('(Check all 1 after the first two, against A at that index.)\n');
    if length(extra_ones) > 2
        for k = 1:length(extra_ones);
            ind = extra_ones(k); 
            res(ind) = ~res(ind) & ~A(ind, ind);
        end
    end
    % Add this result-row to the 'Result' matrix
    Result = [Result; res];
end

% Additional adjustment. Uncomment if needed.
%% NOR between all rows of Result for indices of 1 in each row of Result
%Result_new = [];
%for i = 1:size(Result,1)
%    cols_one = find(Result(i,:)==1);
%    fprintf('Found ones in row %d:\t', i);
%    fprintf('%2d ', cols_one); fprintf('\n');
%    res_new = Result(cols_one(1),:);
%    fprintf('Initialized w/ row %d:\t', cols_one(1));
%    fprintf('%2d ', res_new); fprintf('\n');
%    for j = 2:length(cols_one)
%        res_tmp = res_new;
%        res_new = ~Result(cols_one(j),:) & ~res_tmp;
%        fprintf('NOR-ed with %d row:\t', cols_one(j));
%        fprintf('%2d ', res_new); fprintf('\n');
%    end
%    Result_new = [Result_new; res_new];
%end
%fprintf('\nNew result:\n');
%for i = 1:size(Result_new, 1)
%    fprintf('%2d ', Result_new(i,:)); fprintf('\n');
%end
%fprintf('\n');

Result = unique(Result, 'rows', 'stable');
% Final "filtering"
ind = cumsum(Result); %cumulative sum (by column) 
Result(ind>1) = 0;
Result(sum(Result')==0,:)=[];

fprintf('Prune duplicate rows, filter (see code). Result:\n');
for i = 1:size(Result, 1)
    fprintf('%2d ', Result(i,:)); fprintf('\n');
end

The printout

--- row 1
I(1,:) :   1  0  0  0  0  0  0  0 
A(1,:) :   0  1  1  1  0  0  0  0 
tmp1:  1  0  0  0  1  1  1  1 
Do NAND between tmp1 and previous rows of Result
Choose col 5 ("1" from I is in col 1)
Check columns 1 and 5 for conflict.
col 1:  0  1  1  1  0  0  0  0 
col 5:  0  1  1  1  0  1  1  1 
res  :  1  0  0  0  1  0  0  0 
Indices of all 1: 1 5 
(Check all 1 after the first two, against A at that index.)
--- row 2
I(2,:) :   0  1  0  0  0  0  0  0 
A(2,:) :   1  0  1  1  0  0  0  0 
tmp1:  0  1  0  0  1  1  1  1 
Do NAND between tmp1 and previous rows of Result
Do AND between result of the above and tmp1
tmp1:   0  1  0  0  1  1  1  1 
Choose col 6 ("1" from I is in col 2)
Check columns 2 and 6 for conflict.
col 2:  1  0  1  1  0  0  0  0 
col 6:  0  0  1  1  1  0  1  1 
res  :  0  1  0  0  0  1  0  0 
Indices of all 1: 2 6 
(Check all 1 after the first two, against A at that index.)
--- row 3
I(3,:) :   0  0  1  0  0  0  0  0 
A(3,:) :   1  1  0  1  1  1  0  0 
tmp1:  0  0  1  0  0  0  1  1 
Do NAND between tmp1 and previous rows of Result
Do AND between result of the above and tmp1
tmp1:   0  0  1  0  0  0  1  1 
Choose col 7 ("1" from I is in col 3)
Check columns 3 and 7 for conflict.
col 3:  1  1  0  1  1  1  0  0 
col 7:  0  0  0  1  1  1  0  1 
res  :  0  0  1  0  0  0  1  0 
Indices of all 1: 3 7 
(Check all 1 after the first two, against A at that index.)
--- row 4
I(4,:) :   0  0  0  1  0  0  0  0 
A(4,:) :   1  1  1  0  1  1  1  0 
tmp1:  0  0  0  1  0  0  0  1 
Do NAND between tmp1 and previous rows of Result
Do AND between result of the above and tmp1
tmp1:   0  0  0  1  0  0  0  1 
Choose col 8 ("1" from I is in col 4)
Check columns 4 and 8 for conflict.
col 4:  1  1  1  0  1  1  1  0 
col 8:  0  0  0  0  1  1  1  0 
res  :  0  0  0  1  0  0  0  1 
Indices of all 1: 4 8 
(Check all 1 after the first two, against A at that index.)
--- row 5
I(5,:) :   0  0  0  0  1  0  0  0 
A(5,:) :   0  1  1  1  0  1  1  1 
tmp1:  1  0  0  0  1  0  0  0 
Do NAND between tmp1 and previous rows of Result
Do AND between result of the above and tmp1
tmp1:   1  0  0  0  1  0  0  0 
Choose col 1 ("1" from I is in col 5)
Check columns 5 and 1 for conflict.
col 5:  0  1  1  1  0  1  1  1 
col 1:  0  1  1  1  0  0  0  0 
res  :  1  0  0  0  1  0  0  0 
Indices of all 1: 1 5 
(Check all 1 after the first two, against A at that index.)
--- row 6
I(6,:) :   0  0  0  0  0  1  0  0 
A(6,:) :   0  0  1  1  1  0  1  1 
tmp1:  1  1  0  0  0  1  0  0 
Do NAND between tmp1 and previous rows of Result
Do AND between result of the above and tmp1
tmp1:   1  1  0  0  0  1  0  0 
Choose col 2 ("1" from I is in col 6)
Check columns 6 and 2 for conflict.
col 6:  0  0  1  1  1  0  1  1 
col 2:  1  0  1  1  0  0  0  0 
res  :  0  1  0  0  0  1  0  0 
Indices of all 1: 2 6 
(Check all 1 after the first two, against A at that index.)
--- row 7
I(7,:) :   0  0  0  0  0  0  1  0 
A(7,:) :   0  0  0  1  1  1  0  1 
tmp1:  1  1  1  0  0  0  1  0 
Do NAND between tmp1 and previous rows of Result
Do AND between result of the above and tmp1
tmp1:   1  1  1  0  0  0  1  0 
Choose col 1 ("1" from I is in col 7)
Check columns 7 and 1 for conflict.
col 7:  0  0  0  1  1  1  0  1 
col 1:  0  1  1  1  0  0  0  0 
res  :  1  0  0  0  0  0  1  0 
Indices of all 1: 1 7 
(Check all 1 after the first two, against A at that index.)
--- row 8
I(8,:) :   0  0  0  0  0  0  0  1 
A(8,:) :   0  0  0  0  1  1  1  0 
tmp1:  1  1  1  1  0  0  0  1 
Do NAND between tmp1 and previous rows of Result
Do AND between result of the above and tmp1
tmp1:   1  1  1  1  0  0  0  1 
Choose col 2 ("1" from I is in col 8)
Check columns 8 and 2 for conflict.
col 8:  0  0  0  0  1  1  1  0 
col 2:  1  0  1  1  0  0  0  0 
res  :  0  1  0  0  0  0  0  1 
Indices of all 1: 2 8 
(Check all 1 after the first two, against A at that index.)
Prune duplicate rows, filter (see code). Result:
 1  0  0  0  1  0  0  0 
 0  1  0  0  0  1  0  0 
 0  0  1  0  0  0  1  0 
 0  0  0  1  0  0  0  1 

Upvotes: 1

user3842532
user3842532

Reputation:

try this:

~(I|A)

where ~ is logical NOT and | is logical OR.

Upvotes: 1

Related Questions