function [A] = forma(varargin);
%
% Estimates the formula matrix of the specified list of chemical species.
% It is possible to recognize 103 chemical elements.
%
% Created by A. Trujillo-Ortiz, R. Hernandez-Walls, K. Barba-Rojo
% and A. Castro-Perez
% Facultad de Ciencias Marinas
% Universidad Autonoma de Baja California
% Apdo. Postal 453
% Ensenada, Baja California
% Mexico.
% atrujo@uabc.mx
%
% Copyright. November 20, 2006.
%
persistent name;
if (isempty(name))
name = {'H' ,'He','Li','Be','B' ,'C' ,'N' ,'O' ,'F' ,'Ne','Na','Mg',...
'Al','Si','P' ,'S' ,'Cl','Ar','K' ,'Ca','Sc','Ti','V' ,'Cr',...
'Mn','Fe','Co','Ni','Cu','Zn','Ga','Ge','As','Se','Br','Kr',...
'Rb','Sr','Y' ,'Zr','Nb','Mo','Tc','Ru','Rh','Pd','Ag','Cd',...
'In','Sn','Sb','Te','I' ,'Xe','Cs','Ba','La','Ce','Pr','Nd',...
'Pm','Sm','Eu','Gd','Tb','Dy','Ho','Er','Tm','Yb','Lu','Hf',...
'Ta','W' ,'Re','Os','Ir','Pt','Au','Hg','Tl','Pb','Bi','Po',...
'At','Rn','Fr','Ra','Ac','Th','Pa','U' ,'Np','Pu','Am','Cm',...
'Bk','Cf','Es','Fm','Md','No','Lr'}';
end
varargin = unpack(varargin);
A = zeros(length(name),length(varargin));
Species = varargin;
for i=1:length(varargin),
[s,A(:,i)] = forve(varargin{i},A(:,i),name,1.0);
end
i = find(sum(A,2)>0);
A = A(i,:);
b = {name{i}}';
%Elements = b
function [out] = unpack(in);
out = {};
for i=1:length(in);
if (iscell(in{i}))
tmp = unpack(in{i});
out = {out{:},tmp{:}};
else
out = {out{:},in{i}};
end
end
function [s,b] = forve(s,b,name,factor)
coef = '';
sym = '';
while not(isempty(s)),
next = s(end);
s = s(1:end-1);
if isletter(next)
sym = strcat(next,sym);
i = strmatch(sym,name,'exact');
if any(i)
b(i) = b(i) + factor*stoi(coef);
coef = '';
sym = '';
end
elseif isnumber(next)
coef = strcat(next,coef);
sym = emptystring(sym);
elseif isright(next)
[s,b] = forve(s,b,name,factor*stoi(coef));
coef = '';
sym = emptystring(sym);
elseif isleft(next)
sym = emptystring(sym);
return;
end
end
sym = emptystring(sym);
function [s] = emptystring(s)
if (not(isempty(s)))
disp(['Unrecognized string: ',s]);
end
sym = '';
function [i] = isnumber(s)
i = or(and(ge(abs(s),48),le(abs(s),57)),eq(abs(s),46));
function [i] = isleft(s)
i = eq(abs(s),40);
function [i] = isright(s)
i = eq(abs(s),41);
function [n] = stoi(s)
if isempty(s)
n = 1;
else
n = str2num(s);
end