Packages

Various BEAM benchmarks in one place

Current section

Files

Jump to
beam_benchmarks src fasta.erl
Raw

src/fasta.erl

%% From https://github.com/madnight/benchmarksgame/blob/9f5a20ba09e668a20bb0f9765b33071fa9bb3f1d/LICENSE
%%
%% Copyright © 2004-2008 Brent Fulgham, 2005-2017 Isaac Gouy
%%
%% All rights reserved.
%%
%% Redistribution and use in source and binary forms, with or without
%% modification, are permitted provided that the following conditions are met:
%%
%% Redistributions of source code must retain the above copyright notice,
%% this list of conditions and the following disclaimer.
%%
%% Redistributions in binary form must reproduce the above copyright notice,
%% this list of conditions and the following disclaimer in the documentation
%% and/or other materials provided with the distribution.
%%
%% Neither the name of "The Computer Language Benchmarks Game" nor the name
%% of "The Computer Language Shootout Benchmarks" nor the names of its
%% contributors may be used to endorse or promote products derived from this
%% software without specific prior written permission.
%%
%% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
%% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
%% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
%% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
%% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
%% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
%% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
%% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
%% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
%% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
%% POSSIBILITY OF SUCH DAMAGE.
% The Computer Language Benchmarks Game
% http://benchmarksgame.alioth.debian.org/
%
% contributed by Alex Peake
%
% erl -noshell -noinput -run fasta main N
-module(fasta).
-export([main/1]).
-define(IM, 139968).
-define(IA, 3877).
-define(IC, 29573).
-define(ALU,"GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA").
-define(HS, [{$a, 0.3029549426680}, {$c, 0.1979883004921}, {$g, 0.1975473066391}, {$t, 0.3015094502008}]).
-define(IUB, [{$a, 0.27}, {$c, 0.12}, {$g, 0.12}, {$t, 0.27}, {$B, 0.02}, {$D, 0.02}, {$H, 0.02}, {$K, 0.02}, {$M, 0.02}, {$N, 0.02}, {$R, 0.02}, {$S, 0.02}, {$V, 0.02}, {$W, 0.02}, {$Y, 0.02}]).
-define(LINE_LENGTH, 60).
main(N) ->
Seed = 42,
write_fasta_cycle("ONE","Homo sapiens alu", ?ALU, N*2),
NewSeed = write_fasta_rand("TWO","IUB ambiguity codes", ?IUB, N*3, Seed),
write_fasta_rand("THREE","Homo sapiens frequency", ?HS, N*5, NewSeed),
halt(0).
%% Write a sequence in LINE_LENGTH lines
write_fasta_cycle(Id, Description, Seq, Total) ->
io:put_chars(">" ++ Id ++ " " ++ Description ++ "\n"),
write_fasta_cycle(Seq, Total).
write_fasta_cycle(Seq, Total) when Total =< ?LINE_LENGTH ->
{Seq1, _Remainder} = seq_len(Seq, Total),
io:put_chars(Seq1 ++ "\n");
write_fasta_cycle(Seq, Total) ->
{Seq1, Remainder} = seq_len(Seq, ?LINE_LENGTH),
io:put_chars(Seq1 ++ "\n"),
write_fasta_cycle(Remainder, Total - ?LINE_LENGTH).
%% Return a Len of a cycle of ALU
seq_len(Seq, Len) when length(Seq) >= Len ->
lists:split(Len, Seq);
seq_len(Seq, Len) when length(?ALU) < Len - length(Seq) ->
seq_len(Seq ++ ?ALU, Len);
seq_len(Seq, Len) ->
{Seq1, Seq2} = lists:split(Len - length(Seq), ?ALU),
{Seq ++ Seq1, Seq2}.
%% Write a random sequence in LINE_LENGTH lines
write_fasta_rand(Id, Description, Freq, Total, Seed) ->
io:put_chars(">" ++ Id ++ " " ++ Description ++ "\n"),
NewSeed = write_fasta_rand(Freq, Total, Seed),
NewSeed.
write_fasta_rand(Freq, Total, Seed) when Total =< ?LINE_LENGTH ->
{RandList, NewSeed} = rand_list(Freq, Total, [], Seed),
io:put_chars(RandList),
NewSeed;
write_fasta_rand(Freq, Total, Seed) ->
{RandList, NewSeed} = rand_list(Freq, ?LINE_LENGTH, [], Seed),
io:put_chars(RandList),
write_fasta_rand(Freq, Total - ?LINE_LENGTH, NewSeed).
%% Return a Len of a random list of Freq
rand_list(_Freq, 0, List, Seed) ->
{lists:reverse(["\n" | List]), Seed};
rand_list(Freq, Len, List, Seed) ->
{Rand, NewSeed} = rand(Seed),
rand_list(Freq, Len - 1, [choose_base(Freq, Rand) | List], NewSeed).
%% Functional random number generator
rand(Seed) ->
NewSeed = (Seed * ?IA + ?IC) rem ?IM,
{NewSeed / ?IM, NewSeed}.
%% Select the Base corresponding to the calculated cumulative Probability
choose_base([{Base,_}], _)
-> Base;
choose_base([{Base,Freq} | _], Prob) when Prob < Freq ->
Base;
choose_base([{_Base,Freq} | Bases], Prob) ->
choose_base(Bases, Prob - Freq).