2014-10-06 34 views
0

我试图用0-46氢,0-20碳,0-13氧等方法对所有可能的分子进行索引。我有7个我感兴趣的原子:H ,C,O,N,氯,氟和S.我写了下面的for循环来展示我想实现:Matlab:通过置换构建分子库

MassListIndex = [] 
%MassIndex = [h,c,o,n,cl,f,s] 
for h = 0:46; 
    for c = 0:20; 
    for o = 0:13; 
     for n = 0:15; 
      for cl=0:5; 
       for f=0:5; 
        for s=0:5; 
         MassListIndex = [MassListIndex;[h,c,o,n,cl,f,s]]; 
        end; 
       end; 
      end; 
     end; 
    end; 
end; 
end; 

这令我非常低效;我不想等待2个月左右的时间。我已经尝试过使用combinator.m脚本,但问题是只有一个输入集合的长度是'置换',即如果我想拥有多达46个氢,我还需要每个都有46个其他6个原子。这在计算上很重(46^7 = = 436亿)。

有什么办法可以使这种计算更有效吗?或者,我需要更多地考虑骑它的“废话排列”缩水我的名单(据我所知,分子H40C2从未被观察到的!)

感谢

+0

你在找经验公式吗?因为结构公式会变得更复杂 – 2014-10-06 21:53:25

+0

如果你有足够的RAM,定义'vectors = {0:46 0:20 0:13 0:15 0:20 0:20 0:13 0:15};'并应用[this] (http://stackoverflow.com/q/21895335/2586922)。或者为了节省RAM,可以尝试使用uint8数据类型:uint8 :5)uint8(0:5)}'。后者在我的计算机上只需要5秒钟,并产生所需的47755008x7结果 – 2014-10-06 22:02:05

+0

只有经验公式对于质量很重要,所以如果你把你的47755008x7矩阵和'bsxfun'与来自[IUPAC]的原子质量值(http: //www.degruyter.com/view/j/pac.2013.85.issue-5/pac-rep-13-03-02/pac-rep-13-03-02.xml),你有自己的答案。 “无意义排列”的算法[作为OP的练习](http://www.xkcd.com/1425/)。 – craigim 2014-10-06 23:21:03

回答

0

第一个问题是不是硬。至少不是如果你记得预先分配的话! 我改变了你的代码到这一点:

mxidx = 47*21*14*16*6*6*6; 
MassListIndex = zeros(mxidx,7); 
idx = 1; 
for h = 0:46; 
    for c = 0:20; 
     for o = 0:13; 
      for n = 0:15; 
       for cl=0:5; 
        for f=0:5; 
         for s=0:5; 
          MassListIndex(idx,:) = [h,c,o,n,cl,f,s]; 
          idx = idx + 1; 
         end; 
        end; 
       end; 
      end; 
     end; 
    end; 
end; 

它在我的电脑上不到一分钟就跑。 通常,如果您忘记预分配,Matlab会发出警告;并且无论何时(如本例中)预先知道矩阵的大小,您应该预先分配!另一方面,另一方面,47^7 = 506623120463(超过500亿元 - 它是47^7而不是46^7,因为列表0:46有47个元素)。所以即使你只使用一个字节公关。排在你矩阵(你当然不会),它仍然会占用更多的半TB!而且计算时间同样会很庞大!

但真的什么时候你会需要这个列表。你已经构建了您的列表的方式,你可以很容易地仅仅通过索引例如:计算一个条目

function m = MassListIndex(a,b) 
a = a - 1; 
lst = zeros(1,7); 
for i = 1:7 
    lst(8-i) = mod(a,47); 
    a = floor(a /47); 
end 
if nargin < 2 
    m = lst; 
else 
    m = lst(b); 
end 
end 

编辑:

如果你希望它也计算质量,你可以这样做:

function mass = getMassFromPermutationNumber(a) 
a = a - 1; 
lst = zeros(1,7); 
for i = 1:7 
    lst(8-i) = mod(a,47); 
    a = floor(a /47); 
end 
mass = lst*[1.00794;12.011;15.9994;20.1797;35.4527;18.9984;32.066]; 
end 

来源为群众:http://environmentalchemistry.com/yogi/periodic/mass.html

免责声明:我不是很擅长化学,所以请申请合理数量的怀疑!

+0

谢谢你的回应!列表的原因是然后计算每个排列的质量。该质量列表与HD质谱数据进行比较,因此我们可以确定检测到的化合物的分子式。那有意义吗? – PootersTheCat 2014-10-07 22:43:43

+0

我已经为我的答案添加了一个编辑,解释了如何在不列出列表的情况下从排列数中获得质量。如果你坚持列出清单,那么就没有办法花费大量的内存,而且我也没有办法显着加快这个过程(可能有一个 - 我只是看不到它)。 – 2014-10-08 08:53:23