通过生成真值表来对两个字符矩阵进行加扰的按位异或运算

时间:2014-08-23 17:04:15

标签: matlab matrix

我需要对四个字符执行XOR操作,其中每个字符都有一个位表示如下:

 A = 00

 G = 01

 C = 10

 T = 11

我需要创建一个XOR两个字符组合在一起的表,它以下列方式为XOR个字符对组合提供值。

  XOR   A  G  C  T

   A    A  G  C  T
   G    G  A  T  C
   C    C  T  A  G
   T    T  C  G  A

要获得输出,您需要将每个字符转换为其位表示XOR位,然后使用结果并将其转换回正确的字符。例如,通过XOR CG咨询表格的第三行和第二列:

C = 10
G = 01

C XOR G = 10 XOR 01 = 11 --> T

我最终希望将此规则应用于以5 x 5矩阵加扰字符。 举个例子:

A =  'GATT'    'AACT'    'ACAC'    'TTGA'    'GGCT'    
     'GCAC'    'TCAT'    'GTTC'    'GCCT'    'TTTA'    
     'AACG'    'GTTA'    'ACGT'    'CGTC'    'TGGA'    
     'CTAC'    'AAAA'    'GGGC'    'CCCT'    'TCGT'    
     'GTGT'    'GCGG'    'GTTT'    'TTGC'    'ATTA'


B =  'ATAC'    'AAAT'    'AGCT'    'AAGC'    'AAGT'    
     'TAGG'    'AAGT'    'ATGA'    'AAAG'    'AAGA'    
     'TAGC'    'CAGT'    'AGAT'    'GAAG'    'TCGA' 
     'GCTA'    'TTAC'    'GCCA'    'CCCC'    'TTTC'
     'CCAA'    'AGGA'    'GCAG'    'CAGC'    'TAAA'

我想生成一个矩阵C,以便A的每个元素都与XOR中的相应元素进行B

例如,考虑第一行和第一列:

A{1,1} XOR B{1,1} = GATT XOR ATAC = GTTG

如何为整个矩阵执行此操作?

1 个答案:

答案 0 :(得分:2)

看起来你又要回来了!

首先,让我们定义函数letterXOR,它接受​​两个4个字符的字符串,XOR两个字符串对应于您拥有的那个表。 Recalling from our previous post,让我们设置一个查找表,其中唯一的两位字符串对应一个字母。我们可以使用collections.Map类来帮助我们这样做。我们还需要使用collections.Map类的查找表,其中给定一个字母,我们生成一个两位字符串。我们需要这样做,因为你想将每个字母转换成它的两位表示,我们需要反向查找来做到这一点。之后,我们单独XOR位,然后使用正向查找表返回到我们开始的位置。就这样:

function [out] = letterXOR(A,B)
    codebook = containers.Map({'00','11','10','01'},{'A','T','G','C'}); %// Lookup
    invCodebook = containers.Map({'A','T','G','C'},{'00','11','10','01'}); %// Inv-lookup
    lettersA = arrayfun(@(x) x, A, 'uni', 0); %// Split up each letter into a cell
    lettersB = arrayfun(@(x) x, B, 'uni', 0);

    valuesA = values(invCodebook, lettersA); %// Obtain the binary bit strings
    valuesB = values(invCodebook, lettersB);

    %// Convert each into a matrix
    valuesAMatrix = cellfun(@(x) double(x) - 48, valuesA, 'uni', 0);
    valuesBMatrix = cellfun(@(x) double(x) - 48, valuesB, 'uni', 0);

    % XOR the bits now
    XORedBits = arrayfun(@(x) bitxor(valuesAMatrix{x}, valuesBMatrix{x}), 1:numel(A), 'uni', 0);

    %// Convert each bit pair into a string
    XORedString = cellfun(@(x) char(x + 48), XORedBits, 'uni', 0);

    %// Access lookup, then concatenate as a string
    out = cellfun(@(x) codebook(x), XORedString);

让我们慢慢浏览上面的代码。 letterXOR的输入应该是由ATGC组成的字母字符数组。我们首先定义正向和反向查找。然后,我们将输入字符串AB的每个字符拆分为单个字符的单元格数组,因为查找代码簿中的多个键需要它是这样的。然后我们弄清楚每个字符串中每个字符的位数。这些位实际上是字符串,因此我们需要做的是将每个位串转换为数字数组。我们只是将字符串转换为double并减去48,这是0的ASCII代码。转换为double后,您将获得48或49,这就是我们需要减去48的原因。

因此,每对比特被转换为1 x 2比特数组。然后,我们在1 x 2A之间取每个B位数组,使用bitxorXOR位。此时的输出仍然是1 x 2个数组。因此,我们需要将每个数组转换为一串位,然后使用我们的正向查找表来查找这些位的等效字符。在此之后,我们将所有字符连接在一起,以便为输出生成最终字符串。


确保将上述内容保存在名为letterXOR.m的函数中。一旦我们有了这个,我们现在只需要使用一个cellfun调用来对你的单元格数组中的每个四元素字符串进行异或,然后输出我们的最终矩阵。我们将使用arrayfun来执行此操作,arrayfun的输入将是5 x 5矩阵,该列是主要定义的列。我们这样做是因为MATLAB可以使用单个值访问2D数组中的元素。此值是矩阵中元素的列主索引。我们定义一个从1到25的向量,然后使用reshape将其转换为正确的2D形式。我们之所以需要这样做是因为我们希望确保输出矩阵(在您的示例中为C)以相同的方式构造。就这样:

ind = reshape(1:25, 5, 5); %// Define column major indices
C  = arrayfun(@(x) letterXOR(A{x},B{x}), ind, 'uni', 0); % // Get our output matrix

我们的最终输出C是:

C = 

'GTTG'    'AACA'    'ATCG'    'TTAC'    'GGTA'
'CCGT'    'TCGA'    'GACC'    'GCCC'    'TTCA'
'TATT'    'TTCT'    'ATGA'    'TGTT'    'ATAA'
'TGTC'    'TTAC'    'ATTC'    'AAAG'    'AGCG'
'TGGT'    'GTAG'    'AGTC'    'GTAA'    'TTTA'

祝你好运!